@tomei/sso 0.62.0 → 0.64.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/.commitlintrc.json +22 -22
  2. package/.gitlab-ci.yml +16 -16
  3. package/.husky/commit-msg +9 -15
  4. package/.husky/pre-commit +7 -7
  5. package/.prettierrc +4 -4
  6. package/Jenkinsfile +57 -57
  7. package/README.md +23 -23
  8. package/__tests__/unit/components/group/group.spec.ts +79 -79
  9. package/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.ts +88 -88
  10. package/__tests__/unit/components/group-privilege/group-privilege.spec.ts +68 -68
  11. package/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.ts +66 -66
  12. package/__tests__/unit/components/group-system-access/group-system-access.spec.ts +83 -83
  13. package/__tests__/unit/components/login-user/l.spec.ts +746 -746
  14. package/__tests__/unit/components/login-user/login.spec.ts +1164 -1164
  15. package/__tests__/unit/components/password-hash/password-hash.service.spec.ts +31 -31
  16. package/__tests__/unit/components/system/system.spec.ts +254 -254
  17. package/__tests__/unit/components/system-privilege/system-privilege.spec.ts +83 -83
  18. package/__tests__/unit/components/user-group/user-group.spec.ts +86 -86
  19. package/__tests__/unit/components/user-object-privilege/user-object-privilege.spec.ts +78 -78
  20. package/__tests__/unit/components/user-privilege/user-privilege.spec.ts +72 -72
  21. package/__tests__/unit/components/user-system-access/user-system-access.spec.ts +89 -89
  22. package/__tests__/unit/redis-client/redis.service.spec.ts +23 -23
  23. package/__tests__/unit/session/session.service.spec.ts +47 -47
  24. package/__tests__/unit/system-privilege/system-privilage.spec.ts +91 -91
  25. package/create-sso-user.sql +39 -39
  26. package/dist/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.js +1 -1
  27. package/dist/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.js.map +1 -1
  28. package/dist/__tests__/unit/components/group-privilege/group-privilege.spec.js +2 -2
  29. package/dist/__tests__/unit/components/group-privilege/group-privilege.spec.js.map +1 -1
  30. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.d.ts +1 -0
  31. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js +71 -0
  32. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js.map +1 -0
  33. package/dist/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.js +2 -2
  34. package/dist/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.js.map +1 -1
  35. package/dist/__tests__/unit/components/login-user/login-user.spec.d.ts +0 -0
  36. package/dist/__tests__/unit/components/login-user/login-user.spec.js +6 -0
  37. package/dist/__tests__/unit/components/login-user/login-user.spec.js.map +1 -0
  38. package/dist/__tests__/unit/components/system/system.spec.js +4 -4
  39. package/dist/__tests__/unit/components/system/system.spec.js.map +1 -1
  40. package/dist/__tests__/unit/session/session.service.spec.js +2 -2
  41. package/dist/__tests__/unit/session/session.service.spec.js.map +1 -1
  42. package/dist/src/components/login-history/index.d.ts +1 -0
  43. package/dist/src/components/login-history/index.js +1 -0
  44. package/dist/src/components/login-history/index.js.map +1 -1
  45. package/dist/src/components/login-history/login-history.repository.d.ts +2 -2
  46. package/dist/src/components/login-history/login-history.repository.js.map +1 -1
  47. package/dist/src/components/login-user/interfaces/user-info.interface.d.ts +1 -0
  48. package/dist/src/components/login-user/login-user.js +1 -0
  49. package/dist/src/components/login-user/login-user.js.map +1 -1
  50. package/dist/src/components/login-user/user.d.ts +28 -3
  51. package/dist/src/components/login-user/user.js +363 -25
  52. package/dist/src/components/login-user/user.js.map +1 -1
  53. package/dist/src/components/user-system-access/user-system-access.js +1 -1
  54. package/dist/src/components/user-system-access/user-system-access.js.map +1 -1
  55. package/dist/src/models/login-history.entity.d.ts +2 -2
  56. package/dist/src/models/login-history.entity.js +13 -13
  57. package/dist/src/models/login-history.entity.js.map +1 -1
  58. package/dist/src/models/user.entity.d.ts +1 -0
  59. package/dist/src/models/user.entity.js +8 -0
  60. package/dist/src/models/user.entity.js.map +1 -1
  61. package/dist/tsconfig.tsbuildinfo +1 -1
  62. package/eslint.config.mjs +58 -58
  63. package/jest.config.js +14 -14
  64. package/migrations/20240314080602-create-user-table.js +124 -124
  65. package/migrations/20240314080603-create-user-group-table.js +85 -85
  66. package/migrations/20240314080604-create-user-user-group-table.js +55 -55
  67. package/migrations/20240314080605-create-login-history-table.js +53 -53
  68. package/migrations/20240527064925-create-system-table.js +78 -78
  69. package/migrations/20240527064926-create-system-privilege-table.js +71 -71
  70. package/migrations/20240527065342-create-group-table.js +93 -93
  71. package/migrations/20240527065633-create-group-reporting-user-table.js +76 -76
  72. package/migrations/20240528011551-create-group-system-access-table.js +72 -72
  73. package/migrations/20240528023018-user-system-access-table.js +75 -75
  74. package/migrations/20240528032229-user-privilege-table.js +76 -76
  75. package/migrations/20240528063003-create-group-privilege-table.js +76 -76
  76. package/migrations/20240528063051-create-group-object-privilege-table.js +84 -84
  77. package/migrations/20240528063107-create-user-object-privilege-table.js +84 -84
  78. package/migrations/20240528063108-create-api-key-table.js +85 -85
  79. package/migrations/20241104104802-create-building-table.js +95 -95
  80. package/migrations/20250108091132-add-area-manager-user-id-to-building-table.js +14 -14
  81. package/migrations/20250108091133-add-passcode-to-user-table.js +36 -36
  82. package/migrations/20250210115636-create-user-reporting-hierarchy.js +76 -76
  83. package/migrations/20250326043818-crate-user-password-history.js +42 -42
  84. package/migrations/20250610070720-added-MFBypassYN-to-sso-user.js +30 -0
  85. package/migrations/20250805085707-add-bulk-approval-code-to-sso-user.js +29 -0
  86. package/package.json +87 -90
  87. package/sampledotenv +7 -7
  88. package/src/components/login-history/index.ts +1 -0
  89. package/src/components/login-history/login-history.repository.ts +4 -4
  90. package/src/components/login-history/login-history.ts +124 -0
  91. package/src/components/login-user/interfaces/user-info.interface.ts +1 -0
  92. package/src/components/login-user/login-user.ts +1 -0
  93. package/src/components/login-user/user.ts +441 -27
  94. package/src/components/user-system-access/user-system-access.ts +1 -1
  95. package/src/interfaces/login-history-search-attr.interface.ts +8 -0
  96. package/src/interfaces/login-history.interface.ts +11 -0
  97. package/src/models/login-history.entity.ts +2 -2
  98. package/src/models/user.entity.ts +7 -0
  99. package/tsconfig.build.json +5 -5
  100. package/tsconfig.json +23 -23
  101. package/coverage/clover.xml +0 -1452
  102. package/coverage/coverage-final.json +0 -47
  103. package/coverage/lcov-report/base.css +0 -224
  104. package/coverage/lcov-report/block-navigation.js +0 -87
  105. package/coverage/lcov-report/components/group/group.repository.ts.html +0 -118
  106. package/coverage/lcov-report/components/group/group.ts.html +0 -328
  107. package/coverage/lcov-report/components/group/index.html +0 -131
  108. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.repository.ts.html +0 -118
  109. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.ts.html +0 -322
  110. package/coverage/lcov-report/components/group-object-privilege/index.html +0 -131
  111. package/coverage/lcov-report/components/group-privilege/group-privilege.repository.ts.html +0 -118
  112. package/coverage/lcov-report/components/group-privilege/group-privilege.ts.html +0 -304
  113. package/coverage/lcov-report/components/group-privilege/index.html +0 -131
  114. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.repository.ts.html +0 -118
  115. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.ts.html +0 -328
  116. package/coverage/lcov-report/components/group-reporting-user/index.html +0 -131
  117. package/coverage/lcov-report/components/group-system-access/group-system-access.repository.ts.html +0 -118
  118. package/coverage/lcov-report/components/group-system-access/group-system-access.ts.html +0 -310
  119. package/coverage/lcov-report/components/group-system-access/index.html +0 -131
  120. package/coverage/lcov-report/components/login-history/index.html +0 -116
  121. package/coverage/lcov-report/components/login-history/login-history.repository.ts.html +0 -118
  122. package/coverage/lcov-report/components/login-user/index.html +0 -131
  123. package/coverage/lcov-report/components/login-user/login-user.ts.html +0 -5008
  124. package/coverage/lcov-report/components/login-user/user.repository.ts.html +0 -118
  125. package/coverage/lcov-report/components/password-hash/index.html +0 -116
  126. package/coverage/lcov-report/components/password-hash/password-hash.service.ts.html +0 -127
  127. package/coverage/lcov-report/components/system/index.html +0 -131
  128. package/coverage/lcov-report/components/system/system.repository.ts.html +0 -118
  129. package/coverage/lcov-report/components/system/system.ts.html +0 -910
  130. package/coverage/lcov-report/components/system-privilege/index.html +0 -131
  131. package/coverage/lcov-report/components/system-privilege/system-privilege.repository.ts.html +0 -121
  132. package/coverage/lcov-report/components/system-privilege/system-privilege.ts.html +0 -391
  133. package/coverage/lcov-report/components/user-group/index.html +0 -131
  134. package/coverage/lcov-report/components/user-group/user-group.repository.ts.html +0 -118
  135. package/coverage/lcov-report/components/user-group/user-group.ts.html +0 -355
  136. package/coverage/lcov-report/components/user-object-privilege/index.html +0 -131
  137. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.repository.ts.html +0 -118
  138. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.ts.html +0 -313
  139. package/coverage/lcov-report/components/user-privilege/index.html +0 -131
  140. package/coverage/lcov-report/components/user-privilege/user-privilege.repository.ts.html +0 -118
  141. package/coverage/lcov-report/components/user-privilege/user-privilege.ts.html +0 -307
  142. package/coverage/lcov-report/components/user-system-access/index.html +0 -131
  143. package/coverage/lcov-report/components/user-system-access/user-system-access.repository.ts.html +0 -118
  144. package/coverage/lcov-report/components/user-system-access/user-system-access.ts.html +0 -313
  145. package/coverage/lcov-report/enum/group-type.enum.ts.html +0 -109
  146. package/coverage/lcov-report/enum/index.html +0 -161
  147. package/coverage/lcov-report/enum/index.ts.html +0 -94
  148. package/coverage/lcov-report/enum/user-status.enum.ts.html +0 -106
  149. package/coverage/lcov-report/enum/yn.enum.ts.html +0 -97
  150. package/coverage/lcov-report/favicon.png +0 -0
  151. package/coverage/lcov-report/index.html +0 -371
  152. package/coverage/lcov-report/models/group-object-privilege.entity.ts.html +0 -334
  153. package/coverage/lcov-report/models/group-privilege.entity.ts.html +0 -316
  154. package/coverage/lcov-report/models/group-reporting-user.entity.ts.html +0 -340
  155. package/coverage/lcov-report/models/group-system-access.entity.ts.html +0 -325
  156. package/coverage/lcov-report/models/group.entity.ts.html +0 -436
  157. package/coverage/lcov-report/models/index.html +0 -311
  158. package/coverage/lcov-report/models/login-history.entity.ts.html +0 -253
  159. package/coverage/lcov-report/models/staff.entity.ts.html +0 -412
  160. package/coverage/lcov-report/models/system-privilege.entity.ts.html +0 -355
  161. package/coverage/lcov-report/models/system.entity.ts.html +0 -424
  162. package/coverage/lcov-report/models/user-group.entity.ts.html +0 -355
  163. package/coverage/lcov-report/models/user-object-privilege.entity.ts.html +0 -331
  164. package/coverage/lcov-report/models/user-privilege.entity.ts.html +0 -316
  165. package/coverage/lcov-report/models/user-system-access.entity.ts.html +0 -316
  166. package/coverage/lcov-report/models/user.entity.ts.html +0 -523
  167. package/coverage/lcov-report/prettify.css +0 -1
  168. package/coverage/lcov-report/prettify.js +0 -2
  169. package/coverage/lcov-report/redis-client/index.html +0 -116
  170. package/coverage/lcov-report/redis-client/redis.service.ts.html +0 -241
  171. package/coverage/lcov-report/session/index.html +0 -116
  172. package/coverage/lcov-report/session/session.service.ts.html +0 -247
  173. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  174. package/coverage/lcov-report/sorter.js +0 -196
  175. package/coverage/lcov.info +0 -2490
  176. package/coverage/test-report.xml +0 -129
  177. package/sonar-project.properties +0 -23
@@ -100,6 +100,12 @@ class User extends general_1.UserBase {
100
100
  set MFAConfig(value) {
101
101
  this._MFAConfig = value;
102
102
  }
103
+ get MFABypassYN() {
104
+ return this._MFABypassYN;
105
+ }
106
+ set MFABypassYN(value) {
107
+ this._MFABypassYN = value;
108
+ }
103
109
  get RecoveryEmail() {
104
110
  return this._RecoveryEmail;
105
111
  }
@@ -203,6 +209,7 @@ class User extends general_1.UserBase {
203
209
  this.LastLoginAt = userInfo.LastLoginAt;
204
210
  this.MFAEnabled = userInfo.MFAEnabled;
205
211
  this.MFAConfig = userInfo.MFAConfig;
212
+ this.MFABypassYN = userInfo.MFABypassYN;
206
213
  this.RecoveryEmail = userInfo.RecoveryEmail;
207
214
  this.FailedLoginAttemptCount = userInfo.FailedLoginAttemptCount;
208
215
  this.LastFailedLoginAt = userInfo.LastFailedLoginAt;
@@ -253,6 +260,7 @@ class User extends general_1.UserBase {
253
260
  LastLoginAt: user.LastLoginAt,
254
261
  MFAEnabled: user.MFAEnabled,
255
262
  MFAConfig: user.MFAConfig,
263
+ MFABypassYN: user.MFABypassYN,
256
264
  RecoveryEmail: user.RecoveryEmail,
257
265
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
258
266
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -312,6 +320,7 @@ class User extends general_1.UserBase {
312
320
  LastLoginAt: user.LastLoginAt,
313
321
  MFAEnabled: user.MFAEnabled,
314
322
  MFAConfig: user.MFAConfig,
323
+ MFABypassYN: user.MFABypassYN,
315
324
  RecoveryEmail: user.RecoveryEmail,
316
325
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
317
326
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -389,6 +398,7 @@ class User extends general_1.UserBase {
389
398
  LastLoginAt: user.LastLoginAt,
390
399
  MFAEnabled: user.MFAEnabled,
391
400
  MFAConfig: user.MFAConfig,
401
+ MFABypassYN: user.MFABypassYN,
392
402
  RecoveryEmail: user.RecoveryEmail,
393
403
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
394
404
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -426,12 +436,10 @@ class User extends general_1.UserBase {
426
436
  this.staffs = userAttr.staffs;
427
437
  }
428
438
  else {
429
- console.error('User not found for email:', email);
430
439
  throw new general_1.ClassError('User', 'UserErrMsg0X', 'Invalid Credentials');
431
440
  }
432
441
  }
433
442
  if (this.ObjectId && this.Email !== email) {
434
- console.error('Email mismatch:', this.Email, email);
435
443
  throw new Error('Invalid credentials.');
436
444
  }
437
445
  const check2FA = yield User.check2FA(this, dbTransaction);
@@ -443,13 +451,11 @@ class User extends general_1.UserBase {
443
451
  },
444
452
  });
445
453
  if (!system) {
446
- console.error('Invalid system code:', systemCode);
447
- throw new Error('Invalid credentials.');
454
+ throw new Error('Access denied: invalid or unauthorized system.');
448
455
  }
449
456
  const passwordHashService = new password_hash_service_1.PasswordHashService();
450
457
  const isPasswordValid = yield passwordHashService.verify(password, this.Password);
451
458
  if (!isPasswordValid) {
452
- console.error('Invalid password for user:', this.UserId);
453
459
  throw new Error('Invalid credentials.');
454
460
  }
455
461
  yield this.checkSystemAccess(this.UserId, system.SystemCode, dbTransaction);
@@ -460,15 +466,13 @@ class User extends general_1.UserBase {
460
466
  this.Status = enum_1.UserStatus.ACTIVE;
461
467
  }
462
468
  else {
463
- console.error('User is still locked:', this.UserId);
464
- throw new Error('Invalid credentials.');
469
+ throw new Error('Your account has been locked. Please contact the administrator for assistance.');
465
470
  }
466
471
  }
467
472
  }
468
473
  catch (error) {
469
474
  yield this.incrementFailedLoginAttemptCount(dbTransaction);
470
- console.error('Login failed for user:', this.UserId, error);
471
- throw new Error('Invalid credentials.');
475
+ throw error;
472
476
  }
473
477
  const system = yield User._SystemRepository.findOne({
474
478
  where: {
@@ -507,7 +511,6 @@ class User extends general_1.UserBase {
507
511
  });
508
512
  const sessionName = config_1.ApplicationConfig.getComponentConfigValue('sessionName');
509
513
  if (!sessionName) {
510
- console.error('Session name is not set in the configuration');
511
514
  throw new Error('Session name is not set in the configuration');
512
515
  }
513
516
  const userSession = yield this._SessionService.retrieveUserSession(this.ObjectId, sessionName);
@@ -560,7 +563,6 @@ class User extends general_1.UserBase {
560
563
  transaction: dbTransaction,
561
564
  });
562
565
  }
563
- console.error('Login failed:', error);
564
566
  throw error;
565
567
  }
566
568
  });
@@ -594,13 +596,13 @@ class User extends general_1.UserBase {
594
596
  ],
595
597
  dbTransaction,
596
598
  });
597
- outer: for (const usergroup of userGroups) {
599
+ for (const usergroup of userGroups) {
598
600
  const group = usergroup.Group;
599
601
  const groupSystemAccess = yield User.getInheritedSystemAccess(dbTransaction, group);
600
602
  for (const system of groupSystemAccess) {
601
603
  if (system.SystemCode === systemCode) {
602
604
  isUserHaveAccess = true;
603
- break outer;
605
+ break;
604
606
  }
605
607
  }
606
608
  }
@@ -610,7 +612,6 @@ class User extends general_1.UserBase {
610
612
  }
611
613
  }
612
614
  catch (error) {
613
- console.error('Error checking system access:', error);
614
615
  throw error;
615
616
  }
616
617
  });
@@ -1085,6 +1086,7 @@ class User extends general_1.UserBase {
1085
1086
  LastLoginAt: null,
1086
1087
  MFAEnabled: null,
1087
1088
  MFAConfig: null,
1089
+ MFABypassYN: yn_enum_1.YN.No,
1088
1090
  RecoveryEmail: null,
1089
1091
  FailedLoginAttemptCount: 0,
1090
1092
  LastFailedLoginAt: null,
@@ -1173,7 +1175,7 @@ class User extends general_1.UserBase {
1173
1175
  throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Your account has been locked due to too many failed login attempts, please contact IT Support for instructions on how to unlock your account');
1174
1176
  }
1175
1177
  if (this.Status == enum_1.UserStatus.LOCKED) {
1176
- throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid credentials.');
1178
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Your account has been locked due to too many failed login attempts, please contact IT Support for instructions on how to unlock your account.');
1177
1179
  }
1178
1180
  });
1179
1181
  }
@@ -1221,7 +1223,7 @@ class User extends general_1.UserBase {
1221
1223
  transaction: dbTransaction,
1222
1224
  });
1223
1225
  let systemAccesses = dataSystemAccesses;
1224
- if (group.InheritParentPrivilegeYN === 'Y' && group.ParentGroupCode) {
1226
+ if (group.InheritParentSystemAccessYN === 'Y' && group.ParentGroupCode) {
1225
1227
  const GroupCode = group.ParentGroupCode;
1226
1228
  const parentGroup = yield User._GroupRepo.findByPk(GroupCode, dbTransaction);
1227
1229
  const dataParentSystemAccesses = yield User.getInheritedSystemAccess(dbTransaction, parentGroup);
@@ -1346,13 +1348,31 @@ class User extends general_1.UserBase {
1346
1348
  console.error('Invalid JSON string on MFAConfig:', error);
1347
1349
  }
1348
1350
  }
1349
- const isVerified = yield speakeasy.totp.verify({
1351
+ const isCurrentValid = yield speakeasy.totp.verify({
1350
1352
  secret: userMFAConfig.totp.secret,
1351
1353
  encoding: 'base32',
1352
1354
  token: mfaToken,
1355
+ window: 0,
1353
1356
  });
1354
- if (!isVerified) {
1355
- return false;
1357
+ if (!isCurrentValid) {
1358
+ const isExpired = yield speakeasy.totp.verify({
1359
+ secret: userMFAConfig.totp.secret,
1360
+ encoding: 'base32',
1361
+ token: mfaToken,
1362
+ window: 2,
1363
+ });
1364
+ if (isExpired) {
1365
+ return {
1366
+ success: false,
1367
+ reason: 'MFA token has expired. Please try again.',
1368
+ };
1369
+ }
1370
+ else {
1371
+ return {
1372
+ success: false,
1373
+ reason: 'Invalid MFA token. Check your authenticator app.',
1374
+ };
1375
+ }
1356
1376
  }
1357
1377
  user.MFAEnabled = 1;
1358
1378
  yield user.save({ transaction: dbTransaction });
@@ -1365,7 +1385,7 @@ class User extends general_1.UserBase {
1365
1385
  systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1366
1386
  }
1367
1387
  const systemLogin = userSession.systemLogins.find((e) => e.code === systemCode);
1368
- return `${userId}:${systemLogin.sessionId}`;
1388
+ return { success: true, sessionId: `${userId}:${systemLogin.sessionId}` };
1369
1389
  });
1370
1390
  }
1371
1391
  verify2FACode(userId, mfaToken, systemCode, dbTransaction) {
@@ -1388,13 +1408,31 @@ class User extends general_1.UserBase {
1388
1408
  console.error('Invalid JSON string on MFAConfig:', error);
1389
1409
  }
1390
1410
  }
1391
- const isVerified = yield speakeasy.totp.verify({
1411
+ const isCurrentValid = yield speakeasy.totp.verify({
1392
1412
  secret: userMFAConfig.totp.secret,
1393
1413
  encoding: 'base32',
1394
1414
  token: mfaToken,
1415
+ window: 0,
1395
1416
  });
1396
- if (!isVerified) {
1397
- return false;
1417
+ if (!isCurrentValid) {
1418
+ const isExpired = yield speakeasy.totp.verify({
1419
+ secret: userMFAConfig.totp.secret,
1420
+ encoding: 'base32',
1421
+ token: mfaToken,
1422
+ window: 2,
1423
+ });
1424
+ if (isExpired) {
1425
+ return {
1426
+ success: false,
1427
+ reason: 'MFA token has expired. Please try again.',
1428
+ };
1429
+ }
1430
+ else {
1431
+ return {
1432
+ success: false,
1433
+ reason: 'Invalid MFA token. Check your authenticator app.',
1434
+ };
1435
+ }
1398
1436
  }
1399
1437
  const sessionName = config_1.ApplicationConfig.getComponentConfigValue('sessionName');
1400
1438
  if (!sessionName) {
@@ -1405,7 +1443,7 @@ class User extends general_1.UserBase {
1405
1443
  systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1406
1444
  }
1407
1445
  const systemLogin = userSession.systemLogins.find((e) => e.code === systemCode);
1408
- return `${userId}:${systemLogin.sessionId}`;
1446
+ return { success: true, sessionId: `${userId}:${systemLogin.sessionId}` };
1409
1447
  });
1410
1448
  }
1411
1449
  bypass2FA(systemCode, dbTransaction) {
@@ -1429,7 +1467,10 @@ class User extends general_1.UserBase {
1429
1467
  systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1430
1468
  }
1431
1469
  const systemLogin = userSession.systemLogins.find((e) => e.code === systemCode);
1432
- return `${this.UserId}:${systemLogin.sessionId}`;
1470
+ return {
1471
+ success: true,
1472
+ sessionId: `${this.UserId}:${systemLogin.sessionId}`,
1473
+ };
1433
1474
  }
1434
1475
  catch (error) {
1435
1476
  throw error;
@@ -1759,6 +1800,7 @@ class User extends general_1.UserBase {
1759
1800
  LastLoginAt: user.LastLoginAt,
1760
1801
  MFAEnabled: user.MFAEnabled,
1761
1802
  MFAConfig: user.MFAConfig,
1803
+ MFABypassYN: user.MFABypassYN,
1762
1804
  RecoveryEmail: user.RecoveryEmail,
1763
1805
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
1764
1806
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -1841,6 +1883,7 @@ class User extends general_1.UserBase {
1841
1883
  LastLoginAt: user.LastLoginAt,
1842
1884
  MFAEnabled: user.MFAEnabled,
1843
1885
  MFAConfig: user.MFAConfig,
1886
+ MFABypassYN: user.MFABypassYN,
1844
1887
  RecoveryEmail: user.RecoveryEmail,
1845
1888
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
1846
1889
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -1886,6 +1929,7 @@ class User extends general_1.UserBase {
1886
1929
  LastLoginAt: this.LastLoginAt,
1887
1930
  MFAEnabled: this.MFAEnabled,
1888
1931
  MFAConfig: this.MFAConfig,
1932
+ MFABypassYN: this.MFABypassYN,
1889
1933
  RecoveryEmail: this.RecoveryEmail,
1890
1934
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
1891
1935
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -1915,6 +1959,7 @@ class User extends general_1.UserBase {
1915
1959
  LastLoginAt: this.LastLoginAt,
1916
1960
  MFAEnabled: this.MFAEnabled,
1917
1961
  MFAConfig: this.MFAConfig,
1962
+ MFABypassYN: this.MFABypassYN,
1918
1963
  RecoveryEmail: this.RecoveryEmail,
1919
1964
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
1920
1965
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -1976,6 +2021,7 @@ class User extends general_1.UserBase {
1976
2021
  LastLoginAt: this.LastLoginAt,
1977
2022
  MFAEnabled: this.MFAEnabled,
1978
2023
  MFAConfig: this.MFAConfig,
2024
+ MFABypassYN: this.MFABypassYN,
1979
2025
  RecoveryEmail: this.RecoveryEmail,
1980
2026
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
1981
2027
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -2005,6 +2051,7 @@ class User extends general_1.UserBase {
2005
2051
  LastLoginAt: this.LastLoginAt,
2006
2052
  MFAEnabled: this.MFAEnabled,
2007
2053
  MFAConfig: this.MFAConfig,
2054
+ MFABypassYN: this.MFABypassYN,
2008
2055
  RecoveryEmail: this.RecoveryEmail,
2009
2056
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2010
2057
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -2131,6 +2178,297 @@ class User extends general_1.UserBase {
2131
2178
  }
2132
2179
  });
2133
2180
  }
2181
+ enable2FABypass(loginUser, dbTransaction) {
2182
+ return __awaiter(this, void 0, void 0, function* () {
2183
+ try {
2184
+ if (this.MFABypassYN === yn_enum_1.YN.Yes) {
2185
+ throw new general_1.ClassError('User', 'UserErrMsg0X', 'Bypass already enabled.', 'enable2FABypass');
2186
+ }
2187
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
2188
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'MANAGE_MFA');
2189
+ if (!isPrivileged) {
2190
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'You do not have permission to enable MFA bypass.');
2191
+ }
2192
+ const entityValueBefore = {
2193
+ UserId: this.UserId,
2194
+ UserName: this.UserName,
2195
+ FullName: this.FullName,
2196
+ IDNo: this.IDNo,
2197
+ IDType: this.IDType,
2198
+ ContactNo: this.ContactNo,
2199
+ Email: this.Email,
2200
+ Password: this.Password,
2201
+ Status: this.Status,
2202
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
2203
+ FirstLoginAt: this.FirstLoginAt,
2204
+ LastLoginAt: this.LastLoginAt,
2205
+ MFAEnabled: this.MFAEnabled,
2206
+ MFAConfig: this.MFAConfig,
2207
+ MFABypassYN: this.MFABypassYN,
2208
+ RecoveryEmail: this.RecoveryEmail,
2209
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2210
+ LastFailedLoginAt: this.LastFailedLoginAt,
2211
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
2212
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
2213
+ CreatedById: this.CreatedById,
2214
+ CreatedAt: this.CreatedAt,
2215
+ UpdatedById: this.UpdatedById,
2216
+ UpdatedAt: this.UpdatedAt,
2217
+ PasscodeHash: this.PasscodeHash,
2218
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
2219
+ };
2220
+ this.MFABypassYN = yn_enum_1.YN.Yes;
2221
+ this.MFAEnabled = 0;
2222
+ this.UpdatedAt = new Date();
2223
+ this.UpdatedById = loginUser.UserId;
2224
+ yield User._Repository.update({
2225
+ MFABypassYN: this.MFABypassYN,
2226
+ MFAEnabled: this.MFAEnabled,
2227
+ UpdatedAt: this.UpdatedAt,
2228
+ UpdatedById: this.UpdatedById,
2229
+ }, {
2230
+ where: {
2231
+ UserId: this.UserId,
2232
+ },
2233
+ transaction: dbTransaction,
2234
+ });
2235
+ const entityValueAfter = {
2236
+ UserId: this.UserId,
2237
+ UserName: this.UserName,
2238
+ FullName: this.FullName,
2239
+ IDNo: this.IDNo,
2240
+ IDType: this.IDType,
2241
+ ContactNo: this.ContactNo,
2242
+ Email: this.Email,
2243
+ Password: this.Password,
2244
+ Status: this.Status,
2245
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
2246
+ FirstLoginAt: this.FirstLoginAt,
2247
+ LastLoginAt: this.LastLoginAt,
2248
+ MFAEnabled: this.MFAEnabled,
2249
+ MFAConfig: this.MFAConfig,
2250
+ MFABypassYN: this.MFABypassYN,
2251
+ RecoveryEmail: this.RecoveryEmail,
2252
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2253
+ LastFailedLoginAt: this.LastFailedLoginAt,
2254
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
2255
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
2256
+ CreatedById: this.CreatedById,
2257
+ CreatedAt: this.CreatedAt,
2258
+ UpdatedById: this.UpdatedById,
2259
+ UpdatedAt: this.UpdatedAt,
2260
+ PasscodeHash: this.PasscodeHash,
2261
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
2262
+ };
2263
+ const activity = new activity_history_1.Activity();
2264
+ activity.ActivityId = activity.createId();
2265
+ activity.Action = activity_history_1.ActionEnum.UPDATE;
2266
+ activity.Description = `Enable 2FA Bypass For User ${this.Email}`;
2267
+ activity.EntityType = this.ObjectType;
2268
+ activity.EntityId = this.UserId.toString();
2269
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
2270
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
2271
+ yield activity.create(loginUser.ObjectId, dbTransaction);
2272
+ }
2273
+ catch (error) {
2274
+ throw error;
2275
+ }
2276
+ });
2277
+ }
2278
+ disable2FABypass(loginUser, dbTransaction) {
2279
+ return __awaiter(this, void 0, void 0, function* () {
2280
+ try {
2281
+ if (this.MFABypassYN === yn_enum_1.YN.No) {
2282
+ throw new general_1.ClassError('User', 'UserErrMsg0X', 'Bypass already disabled.', 'disable2FABypass');
2283
+ }
2284
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
2285
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'MANAGE_MFA');
2286
+ if (!isPrivileged) {
2287
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'You do not have permission to enable MFA bypass.');
2288
+ }
2289
+ const entityValueBefore = {
2290
+ UserId: this.UserId,
2291
+ UserName: this.UserName,
2292
+ FullName: this.FullName,
2293
+ IDNo: this.IDNo,
2294
+ IDType: this.IDType,
2295
+ ContactNo: this.ContactNo,
2296
+ Email: this.Email,
2297
+ Password: this.Password,
2298
+ Status: this.Status,
2299
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
2300
+ FirstLoginAt: this.FirstLoginAt,
2301
+ LastLoginAt: this.LastLoginAt,
2302
+ MFAEnabled: this.MFAEnabled,
2303
+ MFAConfig: this.MFAConfig,
2304
+ MFABypassYN: this.MFABypassYN,
2305
+ RecoveryEmail: this.RecoveryEmail,
2306
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2307
+ LastFailedLoginAt: this.LastFailedLoginAt,
2308
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
2309
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
2310
+ CreatedById: this.CreatedById,
2311
+ CreatedAt: this.CreatedAt,
2312
+ UpdatedById: this.UpdatedById,
2313
+ UpdatedAt: this.UpdatedAt,
2314
+ PasscodeHash: this.PasscodeHash,
2315
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
2316
+ };
2317
+ this.MFABypassYN = yn_enum_1.YN.No;
2318
+ this.MFAEnabled = 0;
2319
+ this.UpdatedAt = new Date();
2320
+ this.UpdatedById = loginUser.UserId;
2321
+ yield User._Repository.update({
2322
+ MFABypassYN: this.MFABypassYN,
2323
+ MFAEnabled: this.MFAEnabled,
2324
+ UpdatedAt: this.UpdatedAt,
2325
+ UpdatedById: this.UpdatedById,
2326
+ }, {
2327
+ where: {
2328
+ UserId: this.UserId,
2329
+ },
2330
+ transaction: dbTransaction,
2331
+ });
2332
+ const entityValueAfter = {
2333
+ UserId: this.UserId,
2334
+ UserName: this.UserName,
2335
+ FullName: this.FullName,
2336
+ IDNo: this.IDNo,
2337
+ IDType: this.IDType,
2338
+ ContactNo: this.ContactNo,
2339
+ Email: this.Email,
2340
+ Password: this.Password,
2341
+ Status: this.Status,
2342
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
2343
+ FirstLoginAt: this.FirstLoginAt,
2344
+ LastLoginAt: this.LastLoginAt,
2345
+ MFAEnabled: this.MFAEnabled,
2346
+ MFAConfig: this.MFAConfig,
2347
+ MFABypassYN: this.MFABypassYN,
2348
+ RecoveryEmail: this.RecoveryEmail,
2349
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2350
+ LastFailedLoginAt: this.LastFailedLoginAt,
2351
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
2352
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
2353
+ CreatedById: this.CreatedById,
2354
+ CreatedAt: this.CreatedAt,
2355
+ UpdatedById: this.UpdatedById,
2356
+ UpdatedAt: this.UpdatedAt,
2357
+ PasscodeHash: this.PasscodeHash,
2358
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
2359
+ };
2360
+ const activity = new activity_history_1.Activity();
2361
+ activity.ActivityId = activity.createId();
2362
+ activity.Action = activity_history_1.ActionEnum.UPDATE;
2363
+ activity.Description = `Disable 2FA Bypass For User ${this.Email}`;
2364
+ activity.EntityType = this.ObjectType;
2365
+ activity.EntityId = this.UserId.toString();
2366
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
2367
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
2368
+ yield activity.create(loginUser.ObjectId, dbTransaction);
2369
+ }
2370
+ catch (error) {
2371
+ throw error;
2372
+ }
2373
+ });
2374
+ }
2375
+ reset2FA(loginUser, dbTransaction) {
2376
+ return __awaiter(this, void 0, void 0, function* () {
2377
+ try {
2378
+ if (this.MFAEnabled === 0) {
2379
+ throw new general_1.ClassError('User', 'UserErrMsg0X', 'User not yet setup 2FA.', 'reset2FA');
2380
+ }
2381
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
2382
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'MANAGE_MFA');
2383
+ if (!isPrivileged) {
2384
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'You do not have permission to reset 2FA.');
2385
+ }
2386
+ const entityValueBefore = {
2387
+ UserId: this.UserId,
2388
+ UserName: this.UserName,
2389
+ FullName: this.FullName,
2390
+ IDNo: this.IDNo,
2391
+ IDType: this.IDType,
2392
+ ContactNo: this.ContactNo,
2393
+ Email: this.Email,
2394
+ Password: this.Password,
2395
+ Status: this.Status,
2396
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
2397
+ FirstLoginAt: this.FirstLoginAt,
2398
+ LastLoginAt: this.LastLoginAt,
2399
+ MFAEnabled: this.MFAEnabled,
2400
+ MFAConfig: this.MFAConfig,
2401
+ MFABypassYN: this.MFABypassYN,
2402
+ RecoveryEmail: this.RecoveryEmail,
2403
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2404
+ LastFailedLoginAt: this.LastFailedLoginAt,
2405
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
2406
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
2407
+ CreatedById: this.CreatedById,
2408
+ CreatedAt: this.CreatedAt,
2409
+ UpdatedById: this.UpdatedById,
2410
+ UpdatedAt: this.UpdatedAt,
2411
+ PasscodeHash: this.PasscodeHash,
2412
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
2413
+ };
2414
+ this.MFAEnabled = 0;
2415
+ this.MFABypassYN = yn_enum_1.YN.No;
2416
+ this.UpdatedAt = new Date();
2417
+ this.UpdatedById = loginUser.UserId;
2418
+ yield User._Repository.update({
2419
+ MFAEnabled: this.MFAEnabled,
2420
+ MFABypassYN: this.MFABypassYN,
2421
+ UpdatedAt: this.UpdatedAt,
2422
+ UpdatedById: this.UpdatedById,
2423
+ }, {
2424
+ where: {
2425
+ UserId: this.UserId,
2426
+ },
2427
+ transaction: dbTransaction,
2428
+ });
2429
+ const entityValueAfter = {
2430
+ UserId: this.UserId,
2431
+ UserName: this.UserName,
2432
+ FullName: this.FullName,
2433
+ IDNo: this.IDNo,
2434
+ IDType: this.IDType,
2435
+ ContactNo: this.ContactNo,
2436
+ Email: this.Email,
2437
+ Password: this.Password,
2438
+ Status: this.Status,
2439
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
2440
+ FirstLoginAt: this.FirstLoginAt,
2441
+ LastLoginAt: this.LastLoginAt,
2442
+ MFAEnabled: this.MFAEnabled,
2443
+ MFAConfig: this.MFAConfig,
2444
+ MFABypassYN: this.MFABypassYN,
2445
+ RecoveryEmail: this.RecoveryEmail,
2446
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2447
+ LastFailedLoginAt: this.LastFailedLoginAt,
2448
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
2449
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
2450
+ CreatedById: this.CreatedById,
2451
+ CreatedAt: this.CreatedAt,
2452
+ UpdatedById: this.UpdatedById,
2453
+ UpdatedAt: this.UpdatedAt,
2454
+ PasscodeHash: this.PasscodeHash,
2455
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
2456
+ };
2457
+ const activity = new activity_history_1.Activity();
2458
+ activity.ActivityId = activity.createId();
2459
+ activity.Action = activity_history_1.ActionEnum.UPDATE;
2460
+ activity.Description = `Reset 2FA for User ${this.Email}`;
2461
+ activity.EntityType = this.ObjectType;
2462
+ activity.EntityId = this.UserId.toString();
2463
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
2464
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
2465
+ yield activity.create(loginUser.ObjectId, dbTransaction);
2466
+ }
2467
+ catch (error) {
2468
+ throw error;
2469
+ }
2470
+ });
2471
+ }
2134
2472
  }
2135
2473
  exports.User = User;
2136
2474
  User._Repository = new user_repository_1.UserRepository();