import { Injectable, Logger, Inject } from "@nestjs/common"; import { CACHE_MANAGER } from "@nestjs/cache-manager"; import { Cache } from "cache-manager"; import { UsersRepository } from "./repositories/users.repository"; import { UpdateUserDto } from "./dto/update-user.dto"; @Injectable() export class UsersService { private readonly logger = new Logger(UsersService.name); constructor( private readonly usersRepository: UsersRepository, @Inject(CACHE_MANAGER) private cacheManager: Cache, ) {} private async clearUserCache(username?: string) { if (username) { await this.cacheManager.del(`users/profile/${username}`); } } async create(data: { username: string; email: string; passwordHash: string; emailHash: string; }) { return await this.usersRepository.create(data); } async findByEmailHash(emailHash: string) { return await this.usersRepository.findByEmailHash(emailHash); } async findOneWithPrivateData(uuid: string) { return await this.usersRepository.findOneWithPrivateData(uuid); } async findAll(limit: number, offset: number) { const [data, totalCount] = await Promise.all([ this.usersRepository.findAll(limit, offset), this.usersRepository.countAll(), ]); return { data, totalCount }; } async findPublicProfile(username: string) { return await this.usersRepository.findByUsername(username); } async findOne(uuid: string) { return await this.usersRepository.findOne(uuid); } async update(uuid: string, data: UpdateUserDto) { this.logger.log(`Updating user profile for ${uuid}`); const result = await this.usersRepository.update(uuid, data); if (result[0]) { await this.clearUserCache(result[0].username); } return result; } async updateConsent( uuid: string, termsVersion: string, privacyVersion: string, ) { return await this.usersRepository.update(uuid, { termsVersion, privacyVersion, gdprAcceptedAt: new Date(), }); } async setTwoFactorSecret(uuid: string, secret: string) { return await this.usersRepository.update(uuid, { twoFactorSecret: secret, }); } async toggleTwoFactor(uuid: string, enabled: boolean) { return await this.usersRepository.update(uuid, { isTwoFactorEnabled: enabled, }); } async getTwoFactorSecret(uuid: string): Promise { return await this.usersRepository.getTwoFactorSecret(uuid); } async exportUserData(uuid: string) { const user = await this.findOneWithPrivateData(uuid); if (!user) return null; const [userContents, userFavorites] = await Promise.all([ this.usersRepository.getUserContents(uuid), this.usersRepository.getUserFavorites(uuid), ]); return { profile: user, contents: userContents, favorites: userFavorites, exportedAt: new Date(), }; } async remove(uuid: string) { return await this.usersRepository.softDeleteUserAndContents(uuid); } }