Web API for code.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

78 lines
1.9 KiB

  1. import { PrismaClient } from '@prisma/client'
  2. import {CreateUserData, PublicUser, User} from 'src/modules/user/models';
  3. import { PasswordService, PasswordServiceImpl, LoginUserFormData } from 'src/modules/auth'
  4. import { Uuid } from '@theoryofnekomata/uuid-buffer';
  5. import { notFoundFactory } from '../../packages/prisma-error-utils';
  6. import {UserNotFoundError} from './responses';
  7. export interface UserService {
  8. create(data: CreateUserData): Promise<PublicUser>;
  9. getFromCredentials(args: LoginUserFormData): Promise<PublicUser>;
  10. getFromId(id: User['id']): Promise<PublicUser>;
  11. }
  12. export class UserServiceImpl implements UserService {
  13. private readonly prismaClient: PrismaClient
  14. private readonly passwordService: PasswordService
  15. constructor() {
  16. this.prismaClient = new PrismaClient()
  17. this.passwordService = new PasswordServiceImpl()
  18. }
  19. async create(data: CreateUserData): Promise<PublicUser> {
  20. const newUser = await this.prismaClient.user.create({
  21. data: {
  22. ...data,
  23. id: Uuid.v4(),
  24. password: await this.passwordService.hash(data.password),
  25. },
  26. select: {
  27. id: true,
  28. username: true,
  29. password: false,
  30. },
  31. })
  32. return {
  33. ...newUser,
  34. id: Uuid.from(newUser.id),
  35. }
  36. }
  37. async getFromCredentials(args: LoginUserFormData): Promise<PublicUser> {
  38. const { password: hashedPassword, ...existingUser } = await this.prismaClient.user.findUnique({
  39. where: {
  40. username: args.username,
  41. },
  42. rejectOnNotFound: notFoundFactory(UserNotFoundError),
  43. })
  44. await this.passwordService.assertEqual(args.password, hashedPassword)
  45. return {
  46. ...existingUser,
  47. id: Uuid.from(existingUser.id),
  48. }
  49. }
  50. async getFromId(id: User['id']): Promise<PublicUser> {
  51. const existingUser = await this.prismaClient.user.findUnique({
  52. where: {
  53. id,
  54. },
  55. select: {
  56. id: true,
  57. username: true,
  58. },
  59. rejectOnNotFound: notFoundFactory(UserNotFoundError),
  60. });
  61. return {
  62. ...existingUser,
  63. id: Uuid.from(existingUser.id),
  64. };
  65. }
  66. }