eletrotupi / tcc/ api/src/services/auth.service.tsa8152cd7c2236ab5a4cb9335628c0878ecb8fce4
2.3 KB | 103 lines Raw
1
import { prisma } from '@app/lib/prisma';
2
import bcrypt from "bcryptjs";
3

4
import {
5
  generateToken as createJWT,
6
  generatePasswordResetToken,
7
  getPasswordResetExpiration,
8
  isTokenExpired
9
} from '@app/lib/jwt';
10

11
import {
12
  findUserByEmail
13
} from '@app/services/user.service'; // Replace with a barrel import
14

15
import {
16
  LoginInput,
17
  PasswordResetRequestInput,
18
  PasswordResetInput
19
} from '@app/schemas'
20

21
import { getQueue, MailJobName } from '@app/lib/queue';
22

23
class InvalidCredentialsError extends Error {
24
  constructor() { super('Invalid credentials') }
25
}
26

27
class InvalidOrExpiredTokenError extends Error {
28
  constructor() { super('Invalid or Expired reset token') }
29
}
30

31
export const login = async({ email, password }: LoginInput) => {
32
  const user = await findUserByEmail(email);
33

34
  if (!user || !bcrypt.compareSync(password, user.encryptedPassword)) {
35
    throw new InvalidCredentialsError();
36
  }
37

38
  const token = generateToken(user.id, user.email);
39

40
  return { user, token };
41
};
42

43
export const requestPasswordReset = async ({ email }: PasswordResetRequestInput) => {
44
  const user = await findUserByEmail(email);
45

46
  if (!user) {
47
    return { success: true };
48
  }
49

50
  const resetToken = generatePasswordResetToken();
51
  const resetExpires = getPasswordResetExpiration();
52

53
  await prisma.user.update({
54
    where: {
55
      id: user.id
56
    },
57
    data: {
58
      passwordResetToken: resetToken,
59
      passwordResetExpires: resetExpires
60
    }
61
  });
62

63
  const mailQueue = getQueue('mail');
64
  const job = await mailQueue.add(MailJobName.PasswordReset, {
65
    userId: user.id,
66
    token: resetToken
67
  });
68

69
  return {
70
    success: true,
71
    token: resetToken
72
  };
73
};
74

75
export const resetPassword = async ({ token, newPassword }: PasswordResetInput) => {
76
  const user = await prisma.user.findFirst({
77
    where: {
78
      passwordResetToken: token,
79
      passwordResetExpires: { not: null }
80
    }
81
  });
82

83
  if (!user || !user.passwordResetExpires || isTokenExpired(user.passwordResetExpires)) {
84
    throw new InvalidOrExpiredTokenError();
85
  }
86

87
  await prisma.user.update({
88
    where: { id: user.id },
89
    data: {
90
      encryptedPassword: bcrypt.hashSync(newPassword, 10),
91
      passwordResetToken: null,
92
      passwordResetExpires: null
93
    }
94
  });
95

96
  return {
97
    success: true
98
  };
99
};
100

101
export const generateToken = (userId: number, email: string) => {
102
  return createJWT(userId, email);
103
};