api: lint & dispatch push token to feed the app internal user data
Parents:
9e314411 file(s) changed
- api/src/controllers/auth.ts +54 -48
api/src/controllers/auth.ts
1 -
import { Request, Response, NextFunction } from 'express';
2 -
import { AuthenticatedRequest } from '@app/middleware/auth';
1 +
import { Request, Response, NextFunction } from "express";
2 +
import { AuthenticatedRequest } from "@app/middleware/auth";
3 3
4 4
import {
5 5
login,
6 6
generateToken,
7 7
requestPasswordReset,
8 8
resetPassword,
9 9
activateUser,
10 -
storeActivationCode
11 -
} from '@app/services/auth.service';
10 +
storeActivationCode,
11 +
} from "@app/services/auth.service";
12 12
13 -
import {
14 -
verifyToken
15 -
} from '@app/lib/jwt';
13 +
import { verifyToken } from "@app/lib/jwt";
16 14
17 15
import {
18 16
findUserByEmail,
19 17
findUserById,
20 18
findUserByActivationCode,
21 -
} from '@app/services/user.service'
19 +
} from "@app/services/user.service";
22 20
23 21
import {
24 22
LoginSchema,
25 23
PasswordResetSchema,
26 24
PasswordResetRequestSchema,
27 -
ActivateUserSchema
28 -
} from '@app/schemas';
25 +
ActivateUserSchema,
26 +
} from "@app/schemas";
29 27
30 -
import { addMinutes } from 'date-fns';
31 -
import { getQueue, MailJobName } from '@app/lib/queue';
32 -
import crypto from 'crypto';
28 +
import { addMinutes } from "date-fns";
29 +
import { getQueue, MailJobName } from "@app/lib/queue";
30 +
import crypto from "crypto";
33 31
34 32
export const AuthController = {
35 33
login: async (req: Request, res: Response, next: NextFunction) => {
36 34
try {
37 35
const parsed = LoginSchema.safeParse(req.body);
38 36
39 37
if (!parsed.success) {
40 38
return res.status(400).json({
41 -
errors: parsed.error!.issues
39 +
errors: parsed.error!.issues,
42 40
});
43 41
}
44 42
45 43
const { user, token } = await login(parsed.data);
46 44
47 -
if (!user.active && (new Date() > new Date(user.activationCodeExpiresAt!))) {
48 -
const code = [...Array(6)].map(() => crypto.randomInt(9))
49 -
.join("");
45 +
if (
46 +
!user.active &&
47 +
new Date() > new Date(user.activationCodeExpiresAt!)
48 +
) {
49 +
const code = [...Array(6)].map(() => crypto.randomInt(9)).join("");
50 50
51 51
const expiresAt = addMinutes(new Date(), 5);
52 52
await storeActivationCode(user.id, code, expiresAt);
53 53
54 -
const mailQueue = getQueue('mail');
54 +
const mailQueue = getQueue("mail");
55 55
const job = await mailQueue.add(MailJobName.ActivateAccountEmail, {
56 56
userId: user.id,
57 -
code: code
57 +
code: code,
58 58
});
59 59
}
60 60
61 61
return res.json({
62 62
token,
63 -
user
63 +
user,
64 64
});
65 65
} catch (err: any) {
66 -
if (err.message === 'Invalid credentials') {
67 -
return res.status(401).json({ error: 'Invalid credentials' });
66 +
if (err.message === "Invalid credentials") {
67 +
return res.status(401).json({ error: "Invalid credentials" });
68 68
}
69 69
next(err);
70 70
}
71 71
},
72 72
73 73
forgotPassword: async (req: Request, res: Response, next: NextFunction) => {
74 74
try {
75 -
76 75
const parsed = PasswordResetRequestSchema.safeParse(req.body);
77 76
78 77
if (!parsed.success) {
79 78
return res.status(400).json({
80 -
errors: parsed.error!.issues
79 +
errors: parsed.error!.issues,
81 80
});
82 81
}
83 82
84 83
const result = await requestPasswordReset(parsed.data);
85 -
return res.status(200).json(result)
84 +
return res.status(200).json(result);
86 85
} catch (err) {
87 86
next(err);
88 87
}
89 88
},
90 89
▸ 1 unchanged lines
92 91
try {
93 92
const parsed = PasswordResetSchema.safeParse(req.body);
94 93
95 94
if (!parsed.success) {
96 95
return res.status(400).json({
97 -
errors: parsed.error!.issues
96 +
errors: parsed.error!.issues,
98 97
});
99 98
}
100 99
101 100
const result = await resetPassword(parsed.data);
102 101
return res.status(200).json(result);
103 102
} catch (err: any) {
104 -
if (err.message.includes('token')) {
103 +
if (err.message.includes("token")) {
105 104
return res.status(400).json({ error: err.message });
106 105
}
107 106
next(err);
108 107
}
109 108
},
110 109
111 110
verify: async (req: Request, res: Response, next: NextFunction) => {
112 111
try {
113 112
const authHeader = req.headers.authorization;
114 113
115 -
if (!authHeader || !authHeader.startsWith('Bearer ')) {
116 -
return res.status(401).json({ error: 'No token provided' });
114 +
if (!authHeader || !authHeader.startsWith("Bearer ")) {
115 +
return res.status(401).json({ error: "No token provided" });
117 116
}
118 117
119 118
const token = authHeader.substring(7);
120 119
const payload = verifyToken(token);
121 120
const user = await findUserByEmail(payload.email);
▸ 1 unchanged lines
123 122
if (!user) {
124 123
// XXX: Investigate which actual cases this would happen
125 124
// But the possible reason is that a token is living inside
126 125
// the user's phone, but somehow he was banned/deleted
127 126
return res.status(404).json({
128 -
errors: "User does not exist anymore"
127 +
errors: "User does not exist anymore",
129 128
});
130 129
}
131 130
132 131
res.json({
133 132
valid: true,
▸ 4 unchanged lines
138 137
email: user.email,
139 138
lastName: user.lastName,
140 139
updatedAt: user.updatedAt,
141 140
active: user.active,
142 141
avatarKey: user.avatarKey,
143 -
avatarURL: user.avatarURL
144 -
}
142 +
avatarURL: user.avatarURL,
143 +
pushToken: user.pushToken,
144 +
},
145 145
});
146 146
} catch (err: any) {
147 -
if (err.name === 'JsonWebTokenError' || err.name === 'TokenExpiredError') {
148 -
return res.status(401).json({ error: 'Invalid or expired token' });
147 +
if (
148 +
err.name === "JsonWebTokenError" ||
149 +
err.name === "TokenExpiredError"
150 +
) {
151 +
return res.status(401).json({ error: "Invalid or expired token" });
149 152
}
150 153
next(err);
151 154
}
152 155
},
153 156
▸ 1 unchanged lines
155 158
try {
156 159
const parsed = ActivateUserSchema.safeParse(req.body);
157 160
158 161
if (!parsed.success) {
159 162
return res.status(400).json({
160 -
errors: parsed.error!.issues
163 +
errors: parsed.error!.issues,
161 164
});
162 165
}
163 166
164 167
const user = await findUserByActivationCode(String(parsed.data.code));
165 168
166 169
if (!user) {
167 170
return res.status(422).json({
168 -
error: "Código incorreto. Verifique o código e tente novamente"
169 -
})
171 +
error: "Código incorreto. Verifique o código e tente novamente",
172 +
});
170 173
}
171 174
172 175
const result = await activateUser(user);
173 176
174 177
return res.status(200).json({
175 -
user: result
178 +
user: result,
176 179
});
177 180
} catch (err: any) {
178 181
next(err);
179 182
}
180 183
},
181 184
182 -
resendActivationCode: async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
185 +
resendActivationCode: async (
186 +
req: AuthenticatedRequest,
187 +
res: Response,
188 +
next: NextFunction,
189 +
) => {
183 190
try {
184 191
const user = await findUserById(req.userId!);
185 192
186 193
if (!user) {
187 194
return res.status(400).json({
188 -
errors: "Usuário não encontrado"
189 -
})
195 +
errors: "Usuário não encontrado",
196 +
});
190 197
}
191 198
192 -
const code = [...Array(6)].map(() => crypto.randomInt(9))
193 -
.join("");
199 +
const code = [...Array(6)].map(() => crypto.randomInt(9)).join("");
194 200
195 201
const expiresAt = addMinutes(new Date(), 5);
196 202
await storeActivationCode(user.id, code, expiresAt);
197 203
198 -
const mailQueue = getQueue('mail');
204 +
const mailQueue = getQueue("mail");
199 205
const job = await mailQueue.add(MailJobName.ActivateAccountEmail, {
200 206
userId: user.id,
201 -
code: code
207 +
code: code,
202 208
});
203 209
204 210
res.json({
205 -
user
206 -
})
211 +
user,
212 +
});
207 213
} catch (err: any) {
208 214
next(err);
209 215
}
210 -
}
216 +
},
211 217
};