api: activate user account

Pedro Lucas Porcellis porcellis@eletrotupi.com 16 days ago e6b6493185741dd24cf765760d87180cb7e1f6a1
Parents: 6d8c0a7
5 file(s) changed
  • api/src/controllers/auth.ts +12 -3
  • api/src/controllers/users.ts +2 -2
  • api/src/schemas/auth.schema.ts +1 -2
  • api/src/services/auth.service.ts +3 -3
  • api/src/services/user.service.ts +8 -0
api/src/controllers/auth.ts
@@ -14,6 +14,7 @@
14 14 import {
15 15 findUserByEmail,
16 16 findUserById,
17 + findUserByActivationCode
17 18 } from '@app/services/user.service'
18 19
19 20 import {
@@ -35,6 +36,11 @@ });
35 36 }
36 37
37 38 const { user, token } = await login(parsed.data);
39 +
40 + if (!user.active) {
41 + // TODO: generate a new activation code and send an email
42 + // if the code has expired
43 + }
38 44
39 45 return res.json({
40 46 token,
@@ -136,14 +142,17 @@ errors: parsed.error!.issues
136 142 });
137 143 }
138 144
139 - const user = await findUserById(parsed.data.userId);
145 + const user = await findUserByActivationCode(String(parsed.data.code));
140 146
141 147 if (!user) {
142 148 return res.status(403).json({ error: "Usuario não encontrado" })
143 149 }
144 150
145 - const result = await activateUser(user, parsed.data);
146 - return res.status(200).json(result);
151 + const result = await activateUser(user);
152 +
153 + return res.status(200).json({
154 + user: result
155 + });
147 156 } catch (err: any) {
148 157 next(err);
149 158 }
api/src/controllers/users.ts
@@ -50,8 +50,8 @@
50 50 const user = await createUser(parsed.data);
51 51 const jwtToken = generateToken(user.id, user.email);
52 52
53 - const code = [...Array(6)].map(() => crypto.randomInt(100))
54 - .join(" ");
53 + const code = [...Array(6)].map(() => crypto.randomInt(9))
54 + .join("");
55 55
56 56 const expiresAt = addMinutes(new Date(), 5);
57 57 await storeActivationCode(user.id, code, expiresAt);
api/src/schemas/auth.schema.ts
@@ -15,8 +15,7 @@ newPassword: z.string().min(6)
15 15 });
16 16
17 17 export const ActivateUserSchema = z.object({
18 - userId: z.number(),
19 - code: z.number().max(6)
18 + code: z.number()
20 19 });
21 20
22 21 export type LoginInput = z.infer<typeof LoginSchema>;
api/src/services/auth.service.ts
@@ -31,7 +31,7 @@ constructor() { super('Invalid or Expired reset token') }
31 31 }
32 32
33 33 export const login = async({ email, password }: LoginInput) => {
34 - const user = await findUserByEmail(email);
34 + const user = await findUserByEmail(email)!;
35 35
36 36 if (!user || !bcrypt.compareSync(password, user.encryptedPassword)) {
37 37 throw new InvalidCredentialsError();
@@ -104,13 +104,13 @@ export const generateToken = (userId: number, email: string) => {
104 104 return createJWT(userId, email);
105 105 };
106 106
107 - export const activateUser = async(user: User, input: ActivateUserInput): Promise<User> => {
107 + export const activateUser = async(user: User): Promise<User> => {
108 108 return await prisma.user.update({
109 109 where: {
110 110 id: user.id
111 111 },
112 112 data: {
113 - isActive: true,
113 + active: true,
114 114 activationCode: null,
115 115 activationCodeExpiresAt: null
116 116 }
api/src/services/user.service.ts
@@ -34,6 +34,14 @@ }
34 34 });
35 35 };
36 36
37 + export const findUserByActivationCode = async(code: string): Promise<User | null> => {
38 + return await prisma.user.findFirst({
39 + where: {
40 + activationCode: code
41 + }
42 + });
43 + }
44 +
37 45 export const updateUser = async (input: UpdateUserInput): Promise<User> => {
38 46 const { password, ...data } = input;
39 47