2
2
const jwt = require ( "jsonwebtoken" ) ;
3
3
const { v4 : uuidv4 } = require ( "uuid" ) ;
4
4
const { Op } = require ( "sequelize" ) ;
5
+ const moment = require ( "moment" ) ;
5
6
6
7
// Local Imports
7
8
const logger = require ( "../config/logger" ) ;
@@ -384,6 +385,7 @@ const setLastLogin = async (user) => {
384
385
385
386
const updatedUser = await User . update (
386
387
{
388
+ loginAttempts : 0 ,
387
389
lastLoginAt : date ,
388
390
metaData : {
389
391
...user . metaData ,
@@ -409,6 +411,67 @@ const setLastLogin = async (user) => {
409
411
return ;
410
412
} ;
411
413
414
+ // Record failed login attempt
415
+ const handleInvalidLoginAttempt = async ( { user, errMessage} ) => {
416
+ const loginAttempts = user . loginAttempts + 1 ;
417
+ const accountLocked = user . accountLocked ;
418
+
419
+ if ( loginAttempts === 5 ) {
420
+ const newAccLockedData = {
421
+ isLocked : true ,
422
+ lockedReason : [ ...new Set ( [ ...accountLocked . lockedReason , "reachedMaxLoginAttempts" ] ) ] ,
423
+ } ;
424
+
425
+ // Update user record
426
+ await User . update (
427
+ {
428
+ loginAttempts : loginAttempts ,
429
+ accountLocked : newAccLockedData ,
430
+ } ,
431
+ { where : { id : user . id } }
432
+ ) ;
433
+
434
+ // Queue notification
435
+ await sendAccountLockedEmail ( user ) ;
436
+ } else {
437
+ // Update user record
438
+ await User . update ( { loginAttempts : loginAttempts } ,
439
+ { where : { id : user . id } }
440
+ ) ;
441
+ }
442
+
443
+ // Incorrect E-mail password combination error
444
+ const invalidCredentialsErr = new Error ( errMessage ) ;
445
+ invalidCredentialsErr . status = 403 ;
446
+ throw invalidCredentialsErr ;
447
+ } ;
448
+
449
+ // Function to send account locked email
450
+ const sendAccountLockedEmail = async ( user ) => {
451
+ // Get support email recipients
452
+ const supportEmailRecipients = await getSupportContactEmails ( ) ;
453
+
454
+ await NotificationQueue . create ( {
455
+ type : "email" ,
456
+ templateName : "accountLocked" ,
457
+ notificationOrigin : "User Authentication" ,
458
+ deliveryType : "immediate" ,
459
+ metaData : {
460
+ notificationId : `ACC_LOCKED_${ moment ( ) . format ( "YYYYMMDD_HHmmss_SSS" ) } ` ,
461
+ recipientName : user . firstName ,
462
+ notificationOrigin : "User Authentication" ,
463
+ subject : "Your account has been locked" ,
464
+ mainRecipients : [ user . email ] ,
465
+ notificationDescription :
466
+ "Account locked because of too many failed login attempts" ,
467
+ userName : user . firstName ,
468
+ userEmail : user . email ,
469
+ supportEmailRecipients,
470
+ } ,
471
+ createdBy : user . id ,
472
+ } ) ;
473
+ } ;
474
+
412
475
const deleteUser = async ( id , reason ) => {
413
476
try {
414
477
if ( ! reason || reason === "" ) {
@@ -472,5 +535,6 @@ module.exports = {
472
535
generatePassword,
473
536
setLastLogin,
474
537
setLastLoginAndReturn,
538
+ handleInvalidLoginAttempt,
475
539
deleteUser,
476
540
} ;
0 commit comments