import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; import { PrismaService } from '@ghostfolio/api/services/prisma.service'; import { InfoItem } from '@ghostfolio/common/interfaces'; import { permissions } from '@ghostfolio/common/permissions'; import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { Currency } from '@prisma/client'; import * as bent from 'bent'; import { subDays } from 'date-fns'; @Injectable() export class InfoService { private static DEMO_USER_ID = '9b112b4d-3b7d-4bad-9bdd-3b0f7b4dac2f'; public constructor( private readonly configurationService: ConfigurationService, private jwtService: JwtService, private prisma: PrismaService ) {} public async get(): Promise { const platforms = await this.prisma.platform.findMany({ orderBy: { name: 'asc' }, select: { id: true, name: true } }); const globalPermissions: string[] = []; if (this.configurationService.get('ENABLE_FEATURE_SOCIAL_LOGIN')) { globalPermissions.push(permissions.enableSocialLogin); } if (this.configurationService.get('ENABLE_FEATURE_STATISTICS')) { globalPermissions.push(permissions.enableStatistics); } if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { globalPermissions.push(permissions.enableSubscription); } return { globalPermissions, platforms, currencies: Object.values(Currency), demoAuthToken: this.getDemoAuthToken(), lastDataGathering: await this.getLastDataGathering(), statistics: await this.getStatistics() }; } private getDemoAuthToken() { return this.jwtService.sign({ id: InfoService.DEMO_USER_ID }); } private async getLastDataGathering() { const lastDataGathering = await this.prisma.property.findUnique({ where: { key: 'LAST_DATA_GATHERING' } }); return lastDataGathering?.value ? new Date(lastDataGathering.value) : null; } private async getStatistics() { if (!this.configurationService.get('ENABLE_FEATURE_STATISTICS')) { return undefined; } const activeUsers1d = await this.countActiveUsers(1); const activeUsers30d = await this.countActiveUsers(30); const gitHubStargazers = await this.countGitHubStargazers(); return { activeUsers1d, activeUsers30d, gitHubStargazers }; } private async countActiveUsers(aDays: number) { return await this.prisma.user.count({ orderBy: { Analytics: { updatedAt: 'desc' } }, where: { AND: [ { NOT: { Analytics: null } }, { Analytics: { updatedAt: { gt: subDays(new Date(), aDays) } } } ] } }); } private async countGitHubStargazers(): Promise { try { const get = bent( `https://api.github.com/repos/ghostfolio/ghostfolio`, 'GET', 'json', 200, { 'User-Agent': 'request' } ); const { stargazers_count } = await get(); return stargazers_count; } catch (error) { console.error(error); return undefined; } } }