import { PrismaClient } from '@prisma/client' import {CreateUserData, PublicUser, User} from 'src/modules/user/models'; import { PasswordService, PasswordServiceImpl, LoginUserFormData } from 'src/modules/auth' import { Uuid } from '@theoryofnekomata/uuid-buffer'; import { notFoundFactory } from '../../packages/prisma-error-utils'; import {UserNotFoundError} from './responses'; export interface UserService { create(data: CreateUserData): Promise; getFromCredentials(args: LoginUserFormData): Promise; getFromId(id: User['id']): Promise; } export class UserServiceImpl implements UserService { private readonly prismaClient: PrismaClient private readonly passwordService: PasswordService constructor() { this.prismaClient = new PrismaClient() this.passwordService = new PasswordServiceImpl() } async create(data: CreateUserData): Promise { const newUser = await this.prismaClient.user.create({ data: { ...data, id: Uuid.v4(), password: await this.passwordService.hash(data.password), }, select: { id: true, username: true, password: false, }, }) return { ...newUser, id: Uuid.from(newUser.id), } } async getFromCredentials(args: LoginUserFormData): Promise { const { password: hashedPassword, ...existingUser } = await this.prismaClient.user.findUnique({ where: { username: args.username, }, rejectOnNotFound: notFoundFactory(UserNotFoundError), }) await this.passwordService.assertEqual(args.password, hashedPassword) return { ...existingUser, id: Uuid.from(existingUser.id), } } async getFromId(id: User['id']): Promise { const existingUser = await this.prismaClient.user.findUnique({ where: { id, }, select: { id: true, username: true, }, rejectOnNotFound: notFoundFactory(UserNotFoundError), }); return { ...existingUser, id: Uuid.from(existingUser.id), }; } }