import { Injectable, ConflictException } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import * as bcrypt from 'bcryptjs'; import * as crypto from 'crypto'; @Injectable() export class UsersService { constructor(private readonly prisma: PrismaService) {} findByUsername(username: string) { return this.prisma.user.findUnique({ where: { username } }); } findById(id: number) { return this.prisma.user.findUnique({ where: { id } }); } create(data: { username: string; email: string; passwordHash: string }) { return this.prisma.user.create({ data }); } updateProfile(id: number, data: { firstName?: string; lastName?: string; email?: string }) { return this.prisma.user.update({ where: { id }, data }); } findAll() { return this.prisma.user.findMany({ select: { id: true, username: true, email: true, firstName: true, lastName: true, role: true, isPremium: true, canShareRecipes: true, aiEngineEnabled: true, createdAt: true, }, orderBy: { username: 'asc' }, }); } setRole(id: number, role: string) { return this.prisma.user.update({ where: { id }, data: { role } }); } setPremium(id: number, isPremium: boolean) { return this.prisma.user.update({ where: { id }, data: { isPremium } }); } setRecipeSharing(id: number, canShareRecipes: boolean) { return this.prisma.user.update({ where: { id }, data: { canShareRecipes } }); } setAiEngineEnabled(id: number, aiEngineEnabled: boolean) { return this.prisma.user.update({ where: { id }, data: { aiEngineEnabled } }); } async adminCreate(data: { username: string; email: string; password: string; role?: string }) { const existing = await this.prisma.user.findFirst({ where: { OR: [{ username: data.username }, { email: data.email }] }, }); if (existing) { throw new ConflictException( existing.username === data.username ? 'Användarnamnet är redan taget' : 'E-postadressen används redan', ); } const passwordHash = await bcrypt.hash(data.password, 12); return this.prisma.user.create({ data: { username: data.username, email: data.email, passwordHash, role: data.role ?? 'user' }, }); } deleteUser(id: number) { return this.prisma.user.delete({ where: { id } }); } async resetPassword(id: number): Promise<{ temporaryPassword: string }> { // Generera läsbart 12-teckens lösenord (4 ord från slumpmässiga bytes) const temporaryPassword = crypto.randomBytes(9).toString('base64url').slice(0, 12); const passwordHash = await bcrypt.hash(temporaryPassword, 12); await this.prisma.user.update({ where: { id }, data: { passwordHash } }); return { temporaryPassword }; } async deleteUserAndData(userId: number) { await this.prisma.$transaction([ this.prisma.product.deleteMany({ where: { ownerId: userId } }), this.prisma.recipe.deleteMany({ where: { ownerId: userId } }), this.prisma.inventoryItem.deleteMany({ where: { userId } }), this.prisma.mealPlanEntry.deleteMany({ where: { userId } }), this.prisma.user.delete({ where: { id: userId } }), ]); } }