api: dispatch a reset password email

Pedro Lucas Porcellis porcellis@eletrotupi.com 1 month ago f217e8c7216589be03ffe264c1931b4c2369d5b1
Parents: c387557
6 file(s) changed
  • api/src/controllers/auth.ts +8 -0
  • api/src/lib/queue/processors/mail.ts +6 -4
  • api/src/lib/queue/types.ts +2 -2
  • api/src/models/user.ts +2 -1
  • api/src/services/mail/index.ts +1 -0
  • api/src/services/mail/sendPasswordReset.ts +33 -0
api/src/controllers/auth.ts
@@ -6,10 +6,13 @@ initiatePasswordReset,
6 6 resetPassword,
7 7 findUserByEmail
8 8 } from '@app/models/user';
9 +
9 10 import {
10 11 validateRequiredFields
11 12 } from '@app/utils/validators';
13 +
12 14 import { verifyToken } from '@app/lib/jwt';
15 + import { getQueue, MailJobName } from '@app/lib/queue';
13 16
14 17 export const AuthController = {
15 18 login: async (req: Request, res: Response, next: NextFunction) => {
@@ -61,6 +64,11 @@ });
61 64 }
62 65
63 66 const result = await initiatePasswordReset(email);
67 + const mailQueue = getQueue('mail');
68 + const job = await mailQueue.add(MailJobName.PasswordReset, {
69 + userId: result.id,
70 + token: result.token
71 + });
64 72
65 73 // In production, don't send token in response
66 74 // Instead, send email with reset link
api/src/lib/queue/processors/mail.ts
@@ -6,7 +6,8 @@ PasswordResetPayload,
6 6 } from '@app/lib/queue/types';
7 7
8 8 import {
9 - sendWelcomeEmail
9 + sendWelcomeEmail,
10 + sendResetPasswordEmail
10 11 } from '@app/services/mail'
11 12
12 13 export async function mailProcessor(job: Job<MailJobData['data']>): Promise<void> {
@@ -14,8 +15,6 @@ // job.name is the discriminant
14 15 switch (job.name as MailJobName) {
15 16 case MailJobName.WelcomeEmail: {
16 17 const data = job.data as WelcomeEmailPayload;
17 - // await sendWelcomeEmail(data.userId);
18 -
19 18 console.log("Dispatching an welcome email", data);
20 19
21 20 sendWelcomeEmail(Number(data.userId));
@@ -25,7 +24,10 @@ }
25 24
26 25 case MailJobName.PasswordReset: {
27 26 const data = job.data as PasswordResetPayload;
28 - // await sendPasswordResetEmail(data.userId, data.token);
27 + console.log("Dispatching an welcome email", data);
28 +
29 + await sendResetPasswordEmail(data.userId, data.token);
30 +
29 31 break;
30 32 }
31 33
api/src/lib/queue/types.ts
@@ -4,8 +4,8 @@ WelcomeEmail = 'mail:welcome',
4 4 PasswordReset = 'mail:password-reset',
5 5 }
6 6
7 - export type WelcomeEmailPayload = { userId: string };
8 - export type PasswordResetPayload = { userId: string; token: string };
7 + export type WelcomeEmailPayload = { userId: number };
8 + export type PasswordResetPayload = { userId: number; token: string };
9 9
10 10 export type MailJobData =
11 11 | { name: MailJobName.WelcomeEmail; data: WelcomeEmailPayload }
api/src/models/user.ts
@@ -109,7 +109,8 @@ // For now, return token for testing
109 109 return {
110 110 success: true,
111 111 token: resetToken,
112 - email: user.email
112 + email: user.email,
113 + id: user.id
113 114 };
114 115 };
115 116
api/src/services/mail/index.ts
@@ -1,1 +1,2 @@
1 1 export { sendWelcomeEmail } from '@app/services/mail/welcome';
2 + export { sendResetPasswordEmail } from '@app/services/mail/sendPasswordReset'
api/src/services/mail/sendPasswordReset.ts
@@ -0,0 +1,33 @@
1 + import { findUserById } from '@app/models/user';
2 + import { sendEmail } from '@app/lib/mail';
3 +
4 + const email = (firstName: string, token: string) => {
5 + return (`
6 + Oi, ${firstName}.
7 +
8 + Ouvimos por aí que você precisa trocar a senha?
9 +
10 + Segue o código para você digitar no app: ${token}
11 +
12 + Qualquer coisa prende o grito!
13 + `)
14 + }
15 +
16 + export async function sendResetPasswordEmail(userId: number, token: string): Promise<void> {
17 + const user = await findUserById(userId)!;
18 +
19 + console.log("Email/passwdReset: ", user);
20 +
21 + const { data, error } = await sendEmail({
22 + to: user!.email,
23 + subject: "Esqueceu a senha do orbit?",
24 + text: email(user!.firstName, token)
25 + });
26 +
27 + if (error) {
28 + console.error("Error sending email: ", error);
29 + }
30 +
31 + console.log("Email sent successfully!");
32 + console.log("Email ID:", data?.id);
33 + }