@@ -12,6 +12,7 @@ import {
12
12
updateUserById as _updateUserById ,
13
13
updateUserPrivilegeById as _updateUserPrivilegeById ,
14
14
updateUserVerification as _updateUserVerification ,
15
+ updateUserPassword as _updateUserPassword ,
15
16
} from "../model/repository" ;
16
17
import {
17
18
validateEmail ,
@@ -25,8 +26,13 @@ import { upload } from "../config/multer";
25
26
import { uploadFileToFirebase } from "../utils/utils" ;
26
27
import redisClient from "../config/redis" ;
27
28
import crypto from "crypto" ;
28
- import { sendAccVerificationMail } from "../utils/mailer" ;
29
- import { ACCOUNT_VERIFICATION_SUBJ } from "../utils/constants" ;
29
+ import { sendMail } from "../utils/mailer" ;
30
+ import {
31
+ ACCOUNT_VERIFICATION_SUBJ ,
32
+ ACCOUNT_VERIFICATION_TEMPLATE ,
33
+ RESET_PASSWORD_SUBJ ,
34
+ RESET_PASSWORD_TEMPLATE ,
35
+ } from "../utils/constants" ;
30
36
31
37
export async function createUser (
32
38
req : Request ,
@@ -114,10 +120,11 @@ export const sendVerificationMail = async (
114
120
115
121
const emailToken = crypto . randomBytes ( 16 ) . toString ( "hex" ) ;
116
122
await redisClient . set ( email , emailToken , { EX : 60 * 5 } ) ; // expire in 5 minutes
117
- await sendAccVerificationMail (
123
+ await sendMail (
118
124
email ,
119
125
ACCOUNT_VERIFICATION_SUBJ ,
120
126
user . username ,
127
+ ACCOUNT_VERIFICATION_TEMPLATE ,
121
128
emailToken
122
129
) ;
123
130
@@ -334,6 +341,87 @@ export async function updateUser(
334
341
}
335
342
}
336
343
344
+ export const sendResetPasswordMail = async (
345
+ req : Request ,
346
+ res : Response
347
+ ) : Promise < Response > => {
348
+ try {
349
+ const { email } = req . body ;
350
+ const user = await _findUserByEmail ( email ) ;
351
+
352
+ if ( ! user ) {
353
+ return res . status ( 404 ) . json ( { message : `User not found` } ) ;
354
+ }
355
+
356
+ const emailToken = crypto . randomBytes ( 16 ) . toString ( "hex" ) ;
357
+ await redisClient . set ( email , emailToken , { EX : 60 * 5 } ) ; // expire in 5 minutes
358
+ await sendMail (
359
+ email ,
360
+ RESET_PASSWORD_SUBJ ,
361
+ user . username ,
362
+ RESET_PASSWORD_TEMPLATE ,
363
+ emailToken
364
+ ) ;
365
+
366
+ return res . status ( 200 ) . json ( {
367
+ message : "Reset password email sent. Please check your inbox." ,
368
+ data : { email, id : user . id } ,
369
+ } ) ;
370
+ } catch ( error ) {
371
+ return res . status ( 500 ) . json ( {
372
+ message : "Unknown error when sending reset password email!" ,
373
+ error,
374
+ } ) ;
375
+ }
376
+ } ;
377
+
378
+ export const resetPassword = async (
379
+ req : Request ,
380
+ res : Response
381
+ ) : Promise < Response > => {
382
+ try {
383
+ const { email, token, password } = req . body ;
384
+
385
+ const user = await _findUserByEmail ( email ) ;
386
+ if ( ! user ) {
387
+ return res . status ( 404 ) . json ( { message : `User not found` } ) ;
388
+ }
389
+
390
+ const expectedToken = await redisClient . get ( email ) ;
391
+
392
+ if ( expectedToken !== token ) {
393
+ return res
394
+ . status ( 400 )
395
+ . json ( { message : "Invalid token. Please request for a new one." } ) ;
396
+ }
397
+
398
+ const { isValid : isValidPassword , message : passwordMessage } =
399
+ validatePassword ( password ) ;
400
+ if ( ! isValidPassword ) {
401
+ return res . status ( 400 ) . json ( { message : passwordMessage } ) ;
402
+ }
403
+
404
+ const salt = bcrypt . genSaltSync ( 10 ) ;
405
+ const hashedPassword = bcrypt . hashSync ( password , salt ) ;
406
+
407
+ const updatedUser = await _updateUserPassword ( email , hashedPassword ) ;
408
+
409
+ if ( ! updatedUser ) {
410
+ return res
411
+ . status ( 404 )
412
+ . json ( { message : `User's password not reset.` } ) ;
413
+ }
414
+
415
+ return res
416
+ . status ( 200 )
417
+ . json ( { message : `User's password successfully reset.` } ) ;
418
+ } catch ( error ) {
419
+ return res
420
+ . status ( 500 )
421
+ . json ( { message : "Unknown error when resetting user password!" , error } ) ;
422
+ }
423
+ } ;
424
+
337
425
export async function updateUserPrivilege (
338
426
req : Request ,
339
427
res : Response
0 commit comments