eletrotupi / tcc/ api/src/services/auth.service.ts507c97f5ff722b353a218e5ce11526754af998a2
2.9 KB | 130 lines Raw
1
import { prisma } from '@app/lib/prisma';
2
import { User } from '@prisma/client';
3
import bcrypt from "bcryptjs";
4

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

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

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

23
import { getQueue, MailJobName } from '@app/lib/queue';
24

25
class InvalidCredentialsError extends Error {
26
  constructor() { super('Invalid credentials') }
27
}
28

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

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

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

40
  const token = generateToken(user.id, user.email);
41

42
  return { user, token };
43
};
44

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

48
  if (!user) {
49
    return { success: true };
50
  }
51

52
  const resetToken = generatePasswordResetToken();
53
  const resetExpires = getPasswordResetExpiration();
54

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

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

71
  return {
72
    success: true,
73
    token: resetToken
74
  };
75
};
76

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

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

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

98
  return {
99
    success: true
100
  };
101
};
102

103
export const generateToken = (userId: number, email: string) => {
104
  return createJWT(userId, email);
105
};
106

107
export const activateUser = async(user: User): Promise<User> => {
108
  return await prisma.user.update({
109
    where: {
110
      id: user.id
111
    },
112
    data: {
113
      active: true,
114
      activationCode: null,
115
      activationCodeExpiresAt: null
116
    }
117
  });
118
}
119

120
export const storeActivationCode = async(userId: number, code: string, expiresAt: Date): Promise<User> => {
121
  return await prisma.user.update({
122
    where: {
123
      id: userId
124
    },
125
    data: {
126
      activationCode: code,
127
      activationCodeExpiresAt: expiresAt
128
    }
129
  })
130
}