Files
recipe-app/backend/src/users/users.service.ts
T
Nils-Johan Gynther 054a19ed7c MAJOR UPPDATE: "First Ai"
feat: add AI categorization for products and enhance user management

- Integrated AI service for category suggestions in receipt import and product management.
- Added premium subscription feature for users with corresponding API endpoints.
- Implemented admin interface for managing pending product suggestions.
- Enhanced user management to include premium status and corresponding UI updates.
- Updated database schema to support new fields for premium status and product status.
2026-04-19 10:34:21 +02:00

72 lines
2.5 KiB
TypeScript

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, 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 } });
}
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 };
}
updateEmail(id: number, email: string) {
return this.prisma.user.update({ where: { id }, data: { email } });
}
}