@tomei/sso 0.60.4-dev.7 → 0.60.4-dev.8

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 (147) hide show
  1. package/.commitlintrc.json +22 -22
  2. package/.gitlab-ci.yml +16 -16
  3. package/.husky/commit-msg +9 -9
  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/coverage/clover.xml +1452 -1452
  26. package/coverage/coverage-final.json +47 -47
  27. package/coverage/lcov-report/base.css +224 -224
  28. package/coverage/lcov-report/block-navigation.js +87 -87
  29. package/coverage/lcov-report/components/group/group.repository.ts.html +117 -117
  30. package/coverage/lcov-report/components/group/group.ts.html +327 -327
  31. package/coverage/lcov-report/components/group/index.html +130 -130
  32. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.repository.ts.html +117 -117
  33. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.ts.html +321 -321
  34. package/coverage/lcov-report/components/group-object-privilege/index.html +130 -130
  35. package/coverage/lcov-report/components/group-privilege/group-privilege.repository.ts.html +117 -117
  36. package/coverage/lcov-report/components/group-privilege/group-privilege.ts.html +303 -303
  37. package/coverage/lcov-report/components/group-privilege/index.html +130 -130
  38. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.repository.ts.html +117 -117
  39. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.ts.html +327 -327
  40. package/coverage/lcov-report/components/group-reporting-user/index.html +130 -130
  41. package/coverage/lcov-report/components/group-system-access/group-system-access.repository.ts.html +117 -117
  42. package/coverage/lcov-report/components/group-system-access/group-system-access.ts.html +309 -309
  43. package/coverage/lcov-report/components/group-system-access/index.html +130 -130
  44. package/coverage/lcov-report/components/login-history/index.html +115 -115
  45. package/coverage/lcov-report/components/login-history/login-history.repository.ts.html +117 -117
  46. package/coverage/lcov-report/components/login-user/index.html +130 -130
  47. package/coverage/lcov-report/components/login-user/login-user.ts.html +5015 -5008
  48. package/coverage/lcov-report/components/login-user/user.repository.ts.html +117 -117
  49. package/coverage/lcov-report/components/password-hash/index.html +115 -115
  50. package/coverage/lcov-report/components/password-hash/password-hash.service.ts.html +126 -126
  51. package/coverage/lcov-report/components/system/index.html +130 -130
  52. package/coverage/lcov-report/components/system/system.repository.ts.html +117 -117
  53. package/coverage/lcov-report/components/system/system.ts.html +909 -909
  54. package/coverage/lcov-report/components/system-privilege/index.html +130 -130
  55. package/coverage/lcov-report/components/system-privilege/system-privilege.repository.ts.html +120 -120
  56. package/coverage/lcov-report/components/system-privilege/system-privilege.ts.html +390 -390
  57. package/coverage/lcov-report/components/user-group/index.html +130 -130
  58. package/coverage/lcov-report/components/user-group/user-group.repository.ts.html +117 -117
  59. package/coverage/lcov-report/components/user-group/user-group.ts.html +354 -354
  60. package/coverage/lcov-report/components/user-object-privilege/index.html +130 -130
  61. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.repository.ts.html +117 -117
  62. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.ts.html +312 -312
  63. package/coverage/lcov-report/components/user-privilege/index.html +130 -130
  64. package/coverage/lcov-report/components/user-privilege/user-privilege.repository.ts.html +117 -117
  65. package/coverage/lcov-report/components/user-privilege/user-privilege.ts.html +306 -306
  66. package/coverage/lcov-report/components/user-system-access/index.html +130 -130
  67. package/coverage/lcov-report/components/user-system-access/user-system-access.repository.ts.html +117 -117
  68. package/coverage/lcov-report/components/user-system-access/user-system-access.ts.html +312 -312
  69. package/coverage/lcov-report/enum/group-type.enum.ts.html +108 -108
  70. package/coverage/lcov-report/enum/index.html +160 -160
  71. package/coverage/lcov-report/enum/index.ts.html +93 -93
  72. package/coverage/lcov-report/enum/user-status.enum.ts.html +105 -105
  73. package/coverage/lcov-report/enum/yn.enum.ts.html +96 -96
  74. package/coverage/lcov-report/index.html +370 -370
  75. package/coverage/lcov-report/models/group-object-privilege.entity.ts.html +333 -333
  76. package/coverage/lcov-report/models/group-privilege.entity.ts.html +315 -315
  77. package/coverage/lcov-report/models/group-reporting-user.entity.ts.html +339 -339
  78. package/coverage/lcov-report/models/group-system-access.entity.ts.html +324 -324
  79. package/coverage/lcov-report/models/group.entity.ts.html +435 -435
  80. package/coverage/lcov-report/models/index.html +310 -310
  81. package/coverage/lcov-report/models/login-history.entity.ts.html +252 -252
  82. package/coverage/lcov-report/models/staff.entity.ts.html +411 -411
  83. package/coverage/lcov-report/models/system-privilege.entity.ts.html +354 -354
  84. package/coverage/lcov-report/models/system.entity.ts.html +423 -423
  85. package/coverage/lcov-report/models/user-group.entity.ts.html +354 -354
  86. package/coverage/lcov-report/models/user-object-privilege.entity.ts.html +330 -330
  87. package/coverage/lcov-report/models/user-privilege.entity.ts.html +315 -315
  88. package/coverage/lcov-report/models/user-system-access.entity.ts.html +315 -315
  89. package/coverage/lcov-report/models/user.entity.ts.html +522 -522
  90. package/coverage/lcov-report/prettify.css +1 -1
  91. package/coverage/lcov-report/prettify.js +2 -2
  92. package/coverage/lcov-report/redis-client/index.html +115 -115
  93. package/coverage/lcov-report/redis-client/redis.service.ts.html +240 -240
  94. package/coverage/lcov-report/session/index.html +115 -115
  95. package/coverage/lcov-report/session/session.service.ts.html +246 -246
  96. package/coverage/lcov-report/sorter.js +196 -196
  97. package/coverage/lcov.info +2490 -2490
  98. package/coverage/test-report.xml +128 -128
  99. package/create-sso-user.sql +39 -39
  100. package/dist/src/components/login-user/interfaces/user-info.interface.d.ts +1 -0
  101. package/dist/src/components/login-user/login-user.js +1 -0
  102. package/dist/src/components/login-user/login-user.js.map +1 -1
  103. package/dist/src/components/login-user/user.d.ts +5 -0
  104. package/dist/src/components/login-user/user.js +207 -0
  105. package/dist/src/components/login-user/user.js.map +1 -1
  106. package/dist/src/models/user.entity.d.ts +1 -0
  107. package/dist/src/models/user.entity.js +8 -0
  108. package/dist/src/models/user.entity.js.map +1 -1
  109. package/dist/tsconfig.tsbuildinfo +1 -1
  110. package/eslint.config.mjs +58 -58
  111. package/jest.config.js +14 -14
  112. package/migrations/20240314080602-create-user-table.js +124 -124
  113. package/migrations/20240314080603-create-user-group-table.js +85 -85
  114. package/migrations/20240314080604-create-user-user-group-table.js +55 -55
  115. package/migrations/20240314080605-create-login-history-table.js +53 -53
  116. package/migrations/20240527064925-create-system-table.js +78 -78
  117. package/migrations/20240527064926-create-system-privilege-table.js +71 -71
  118. package/migrations/20240527065342-create-group-table.js +93 -93
  119. package/migrations/20240527065633-create-group-reporting-user-table.js +76 -76
  120. package/migrations/20240528011551-create-group-system-access-table.js +72 -72
  121. package/migrations/20240528023018-user-system-access-table.js +75 -75
  122. package/migrations/20240528032229-user-privilege-table.js +76 -76
  123. package/migrations/20240528063003-create-group-privilege-table.js +76 -76
  124. package/migrations/20240528063051-create-group-object-privilege-table.js +84 -84
  125. package/migrations/20240528063107-create-user-object-privilege-table.js +84 -84
  126. package/migrations/20240528063108-create-api-key-table.js +85 -85
  127. package/migrations/20241104104802-create-building-table.js +95 -95
  128. package/migrations/20250108091132-add-area-manager-user-id-to-building-table.js +14 -14
  129. package/migrations/20250108091133-add-passcode-to-user-table.js +36 -36
  130. package/migrations/20250210115636-create-user-reporting-hierarchy.js +76 -76
  131. package/migrations/20250326043818-crate-user-password-history.js +42 -42
  132. package/migrations/20250610070720-added-MFBypassYN-to-sso-user.js +30 -0
  133. package/package.json +90 -90
  134. package/sampledotenv +7 -7
  135. package/src/components/login-user/interfaces/user-info.interface.ts +1 -0
  136. package/src/components/login-user/login-user.ts +1 -0
  137. package/src/components/login-user/user.ts +260 -0
  138. package/src/models/user.entity.ts +7 -0
  139. package/tsconfig.build.json +5 -5
  140. package/tsconfig.json +23 -23
  141. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.d.ts +0 -1
  142. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js +0 -71
  143. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js.map +0 -1
  144. package/dist/__tests__/unit/components/login-user/login-user.spec.d.ts +0 -0
  145. package/dist/__tests__/unit/components/login-user/login-user.spec.js +0 -6
  146. package/dist/__tests__/unit/components/login-user/login-user.spec.js.map +0 -1
  147. package/sonar-project.properties +0 -23
package/package.json CHANGED
@@ -1,90 +1,90 @@
1
- {
2
- "name": "@tomei/sso",
3
- "version": "0.60.4-dev.7",
4
- "description": "Tomei SSO Package",
5
- "main": "dist/index.js",
6
- "scripts": {
7
- "start:dev": "tsc -w",
8
- "build": "tsc",
9
- "prepare": "husky install",
10
- "format": "prettier --write \"src/**/*.ts\"",
11
- "lint": "npx eslint . --fix",
12
- "test": "jest --forceExit --detectOpenHandles --coverage"
13
- },
14
- "repository": {
15
- "type": "git",
16
- "url": "git+ssh://git@gitlab.com/tomei-package/sso.git"
17
- },
18
- "keywords": [
19
- "tomei",
20
- "sso"
21
- ],
22
- "author": "Tomei",
23
- "license": "ISC",
24
- "bugs": {
25
- "url": "https://gitlab.com/tomei-package/sso/issues"
26
- },
27
- "homepage": "https://gitlab.com/tomei-package/sso#readme",
28
- "devDependencies": {
29
- "@commitlint/cli": "^19.6.0",
30
- "@commitlint/config-conventional": "^19.6.0",
31
- "@eslint/js": "^9.15.0",
32
- "@tsconfig/node18": "^18.2.4",
33
- "@types/bcrypt": "^5.0.2",
34
- "@types/jest": "^29.5.14",
35
- "@types/node": "^22.9.3",
36
- "@types/redis": "^4.0.11",
37
- "@types/validator": "^13.12.2",
38
- "@typescript-eslint/eslint-plugin": "^8.15.0",
39
- "@typescript-eslint/parser": "^8.15.0",
40
- "cls-hooked": "^4.2.2",
41
- "dotenv": "^16.4.5",
42
- "eslint": "^9.15.0",
43
- "eslint-config-prettier": "^9.1.0",
44
- "eslint-plugin-import": "^2.31.0",
45
- "eslint-plugin-prettier": "^5.2.1",
46
- "globals": "^15.12.0",
47
- "husky": "^9.1.7",
48
- "jest": "^29.7.0",
49
- "jest-mock-extended": "^3.0.7",
50
- "jest-sonar-reporter": "^2.0.0",
51
- "lint-staged": "^15.2.10",
52
- "prettier": "^3.3.3",
53
- "redis-mock": "^0.56.3",
54
- "ts-jest": "^29.2.5",
55
- "ts-node": "^10.9.2",
56
- "tsc-watch": "^6.2.1",
57
- "tsconfig-paths": "^4.2.0",
58
- "tslint": "^6.1.3",
59
- "typescript": "^5.7.2",
60
- "typescript-eslint": "^8.15.0"
61
- },
62
- "publishConfig": {
63
- "access": "public"
64
- },
65
- "peerDependencies": {
66
- "@tomei/activity-history": "^0.4.0",
67
- "@tomei/config": "^0.3.21",
68
- "@tomei/general": "^0.21.3",
69
- "@tomei/mailer": "^0.5.21",
70
- "argon2": "^0.41.1",
71
- "redis": "^4.7.0",
72
- "reflect-metadata": "^0.2.2",
73
- "sequelize": "^6.37.5",
74
- "sequelize-cli": "^6.6.2",
75
- "sequelize-typescript": "^2.1.6",
76
- "speakeasy": "^2.0.0",
77
- "uuid": "^11.0.3"
78
- },
79
- "lint-staged": {
80
- "*/**/*.{js,ts,tsx}": [
81
- "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
82
- "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
83
- ]
84
- },
85
- "jestSonar": {
86
- "reportPath": "coverage",
87
- "reportFile": "test-report.xml",
88
- "indent": 2
89
- }
90
- }
1
+ {
2
+ "name": "@tomei/sso",
3
+ "version": "0.60.4-dev.8",
4
+ "description": "Tomei SSO Package",
5
+ "main": "dist/index.js",
6
+ "scripts": {
7
+ "start:dev": "tsc -w",
8
+ "build": "tsc",
9
+ "prepare": "husky install",
10
+ "format": "prettier --write \"src/**/*.ts\"",
11
+ "lint": "npx eslint . --fix",
12
+ "test": "jest --forceExit --detectOpenHandles --coverage"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+ssh://git@gitlab.com/tomei-package/sso.git"
17
+ },
18
+ "keywords": [
19
+ "tomei",
20
+ "sso"
21
+ ],
22
+ "author": "Tomei",
23
+ "license": "ISC",
24
+ "bugs": {
25
+ "url": "https://gitlab.com/tomei-package/sso/issues"
26
+ },
27
+ "homepage": "https://gitlab.com/tomei-package/sso#readme",
28
+ "devDependencies": {
29
+ "@commitlint/cli": "^19.6.0",
30
+ "@commitlint/config-conventional": "^19.6.0",
31
+ "@eslint/js": "^9.15.0",
32
+ "@tsconfig/node18": "^18.2.4",
33
+ "@types/bcrypt": "^5.0.2",
34
+ "@types/jest": "^29.5.14",
35
+ "@types/node": "^22.9.3",
36
+ "@types/redis": "^4.0.11",
37
+ "@types/validator": "^13.12.2",
38
+ "@typescript-eslint/eslint-plugin": "^8.15.0",
39
+ "@typescript-eslint/parser": "^8.15.0",
40
+ "cls-hooked": "^4.2.2",
41
+ "dotenv": "^16.4.5",
42
+ "eslint": "^9.15.0",
43
+ "eslint-config-prettier": "^9.1.0",
44
+ "eslint-plugin-import": "^2.31.0",
45
+ "eslint-plugin-prettier": "^5.2.1",
46
+ "globals": "^15.12.0",
47
+ "husky": "^9.1.7",
48
+ "jest": "^29.7.0",
49
+ "jest-mock-extended": "^3.0.7",
50
+ "jest-sonar-reporter": "^2.0.0",
51
+ "lint-staged": "^15.2.10",
52
+ "prettier": "^3.3.3",
53
+ "redis-mock": "^0.56.3",
54
+ "ts-jest": "^29.2.5",
55
+ "ts-node": "^10.9.2",
56
+ "tsc-watch": "^6.2.1",
57
+ "tsconfig-paths": "^4.2.0",
58
+ "tslint": "^6.1.3",
59
+ "typescript": "^5.7.2",
60
+ "typescript-eslint": "^8.15.0"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public"
64
+ },
65
+ "peerDependencies": {
66
+ "@tomei/activity-history": "^0.4.0",
67
+ "@tomei/config": "^0.3.21",
68
+ "@tomei/general": "^0.21.3",
69
+ "@tomei/mailer": "^0.5.21",
70
+ "argon2": "^0.41.1",
71
+ "redis": "^4.7.0",
72
+ "reflect-metadata": "^0.2.2",
73
+ "sequelize": "^6.37.5",
74
+ "sequelize-cli": "^6.6.2",
75
+ "sequelize-typescript": "^2.1.6",
76
+ "speakeasy": "^2.0.0",
77
+ "uuid": "^11.0.3"
78
+ },
79
+ "lint-staged": {
80
+ "*/**/*.{js,ts,tsx}": [
81
+ "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
82
+ "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
83
+ ]
84
+ },
85
+ "jestSonar": {
86
+ "reportPath": "coverage",
87
+ "reportFile": "test-report.xml",
88
+ "indent": 2
89
+ }
90
+ }
package/sampledotenv CHANGED
@@ -1,8 +1,8 @@
1
- DATABASE_URL=
2
- SHADOW_DATABASE_URL=
3
- REDIS_URL=
4
- REDIS_PASSWORD=
5
- SMTP_HOST=
6
- SMTP_PORT=
7
- EMAIL_SENDER=
1
+ DATABASE_URL=
2
+ SHADOW_DATABASE_URL=
3
+ REDIS_URL=
4
+ REDIS_PASSWORD=
5
+ SMTP_HOST=
6
+ SMTP_PORT=
7
+ EMAIL_SENDER=
8
8
  EMAIL_PASSWORD=
@@ -20,6 +20,7 @@ export interface IUserAttr extends IUserInfo {
20
20
  LastLoginAt: Date;
21
21
  MFAEnabled: number;
22
22
  MFAConfig: string;
23
+ MFABypassYN: string;
23
24
  RecoveryEmail: string;
24
25
  FailedLoginAttemptCount: number;
25
26
  LastFailedLoginAt: Date;
@@ -61,6 +61,7 @@ export class LoginUser extends User implements ILoginUser {
61
61
  LastLoginAt: user.LastLoginAt,
62
62
  MFAEnabled: user.MFAEnabled,
63
63
  MFAConfig: user.MFAConfig,
64
+ MFABypassYN: user.MFABypassYN,
64
65
  RecoveryEmail: user.RecoveryEmail,
65
66
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
66
67
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -49,6 +49,7 @@ export class User extends UserBase {
49
49
  private _LastLoginAt: Date;
50
50
  private _MFAEnabled: number;
51
51
  private _MFAConfig: string;
52
+ private _MFABypassYN: string;
52
53
  private _RecoveryEmail: string;
53
54
  private _FailedLoginAttemptCount: number;
54
55
  private _LastFailedLoginAt: Date;
@@ -162,6 +163,14 @@ export class User extends UserBase {
162
163
  this._MFAConfig = value;
163
164
  }
164
165
 
166
+ get MFABypassYN(): string {
167
+ return this._MFABypassYN;
168
+ }
169
+
170
+ private set MFABypassYN(value: string) {
171
+ this._MFABypassYN = value;
172
+ }
173
+
165
174
  get RecoveryEmail(): string {
166
175
  return this._RecoveryEmail;
167
176
  }
@@ -296,6 +305,7 @@ export class User extends UserBase {
296
305
  this.LastLoginAt = userInfo.LastLoginAt;
297
306
  this.MFAEnabled = userInfo.MFAEnabled;
298
307
  this.MFAConfig = userInfo.MFAConfig;
308
+ this.MFABypassYN = userInfo.MFABypassYN;
299
309
  this.RecoveryEmail = userInfo.RecoveryEmail;
300
310
  this.FailedLoginAttemptCount = userInfo.FailedLoginAttemptCount;
301
311
  this.LastFailedLoginAt = userInfo.LastFailedLoginAt;
@@ -352,6 +362,7 @@ export class User extends UserBase {
352
362
  LastLoginAt: user.LastLoginAt,
353
363
  MFAEnabled: user.MFAEnabled,
354
364
  MFAConfig: user.MFAConfig,
365
+ MFABypassYN: user.MFABypassYN,
355
366
  RecoveryEmail: user.RecoveryEmail,
356
367
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
357
368
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -416,6 +427,7 @@ export class User extends UserBase {
416
427
  LastLoginAt: user.LastLoginAt,
417
428
  MFAEnabled: user.MFAEnabled,
418
429
  MFAConfig: user.MFAConfig,
430
+ MFABypassYN: user.MFABypassYN,
419
431
  RecoveryEmail: user.RecoveryEmail,
420
432
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
421
433
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -510,6 +522,7 @@ export class User extends UserBase {
510
522
  LastLoginAt: user.LastLoginAt,
511
523
  MFAEnabled: user.MFAEnabled,
512
524
  MFAConfig: user.MFAConfig,
525
+ MFABypassYN: user.MFABypassYN,
513
526
  RecoveryEmail: user.RecoveryEmail,
514
527
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
515
528
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -1571,6 +1584,7 @@ export class User extends UserBase {
1571
1584
  LastLoginAt: null,
1572
1585
  MFAEnabled: null,
1573
1586
  MFAConfig: null,
1587
+ MFABypassYN: YN.No,
1574
1588
  RecoveryEmail: null,
1575
1589
  FailedLoginAttemptCount: 0,
1576
1590
  LastFailedLoginAt: null,
@@ -2601,6 +2615,7 @@ export class User extends UserBase {
2601
2615
  LastLoginAt: user.LastLoginAt,
2602
2616
  MFAEnabled: user.MFAEnabled,
2603
2617
  MFAConfig: user.MFAConfig,
2618
+ MFABypassYN: user.MFABypassYN,
2604
2619
  RecoveryEmail: user.RecoveryEmail,
2605
2620
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
2606
2621
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -2727,6 +2742,7 @@ export class User extends UserBase {
2727
2742
  LastLoginAt: user.LastLoginAt,
2728
2743
  MFAEnabled: user.MFAEnabled,
2729
2744
  MFAConfig: user.MFAConfig,
2745
+ MFABypassYN: user.MFABypassYN,
2730
2746
  RecoveryEmail: user.RecoveryEmail,
2731
2747
  FailedLoginAttemptCount: user.FailedLoginAttemptCount,
2732
2748
  LastFailedLoginAt: user.LastFailedLoginAt,
@@ -2790,6 +2806,7 @@ export class User extends UserBase {
2790
2806
  LastLoginAt: this.LastLoginAt,
2791
2807
  MFAEnabled: this.MFAEnabled,
2792
2808
  MFAConfig: this.MFAConfig,
2809
+ MFABypassYN: this.MFABypassYN,
2793
2810
  RecoveryEmail: this.RecoveryEmail,
2794
2811
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2795
2812
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -2821,6 +2838,7 @@ export class User extends UserBase {
2821
2838
  LastLoginAt: this.LastLoginAt,
2822
2839
  MFAEnabled: this.MFAEnabled,
2823
2840
  MFAConfig: this.MFAConfig,
2841
+ MFABypassYN: this.MFABypassYN,
2824
2842
  RecoveryEmail: this.RecoveryEmail,
2825
2843
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2826
2844
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -2911,6 +2929,7 @@ export class User extends UserBase {
2911
2929
  LastLoginAt: this.LastLoginAt,
2912
2930
  MFAEnabled: this.MFAEnabled,
2913
2931
  MFAConfig: this.MFAConfig,
2932
+ MFABypassYN: this.MFABypassYN,
2914
2933
  RecoveryEmail: this.RecoveryEmail,
2915
2934
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2916
2935
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -2942,6 +2961,7 @@ export class User extends UserBase {
2942
2961
  LastLoginAt: this.LastLoginAt,
2943
2962
  MFAEnabled: this.MFAEnabled,
2944
2963
  MFAConfig: this.MFAConfig,
2964
+ MFABypassYN: this.MFABypassYN,
2945
2965
  RecoveryEmail: this.RecoveryEmail,
2946
2966
  FailedLoginAttemptCount: this.FailedLoginAttemptCount,
2947
2967
  LastFailedLoginAt: this.LastFailedLoginAt,
@@ -3131,4 +3151,244 @@ export class User extends UserBase {
3131
3151
  throw error;
3132
3152
  }
3133
3153
  }
3154
+
3155
+ public async enable2FABypass(loginUser: LoginUser, dbTransaction: any) {
3156
+ try {
3157
+ // 1. Check if MFABypassYN is already enabled
3158
+ if (this.MFABypassYN === YN.Yes) {
3159
+ throw new ClassError(
3160
+ 'User',
3161
+ 'UserErrMsg0X',
3162
+ 'Bypass already enabled.',
3163
+ 'enable2FABypass',
3164
+ );
3165
+ }
3166
+
3167
+ // 2. Check if user has MANAGE_MFA privilege
3168
+ const systemCode =
3169
+ ApplicationConfig.getComponentConfigValue('system-code');
3170
+ const isPrivileged = await loginUser.checkPrivileges(
3171
+ systemCode,
3172
+ 'MANAGE_MFA',
3173
+ );
3174
+ if (!isPrivileged) {
3175
+ throw new ClassError(
3176
+ 'LoginUser',
3177
+ 'LoginUserErrMsg0X',
3178
+ 'You do not have permission to enable MFA bypass.',
3179
+ );
3180
+ }
3181
+
3182
+ const entityValueBefore: IUserAttr = {
3183
+ UserId: this.UserId,
3184
+ UserName: this.UserName,
3185
+ FullName: this.FullName,
3186
+ IDNo: this.IDNo,
3187
+ IDType: this.IDType,
3188
+ ContactNo: this.ContactNo,
3189
+ Email: this.Email,
3190
+ Password: this.Password,
3191
+ Status: this.Status,
3192
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
3193
+ FirstLoginAt: this.FirstLoginAt,
3194
+ LastLoginAt: this.LastLoginAt,
3195
+ MFAEnabled: this.MFAEnabled,
3196
+ MFAConfig: this.MFAConfig,
3197
+ MFABypassYN: this.MFABypassYN,
3198
+ RecoveryEmail: this.RecoveryEmail,
3199
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
3200
+ LastFailedLoginAt: this.LastFailedLoginAt,
3201
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
3202
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
3203
+ CreatedById: this.CreatedById,
3204
+ CreatedAt: this.CreatedAt,
3205
+ UpdatedById: this.UpdatedById,
3206
+ UpdatedAt: this.UpdatedAt,
3207
+ PasscodeHash: this.PasscodeHash,
3208
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
3209
+ };
3210
+
3211
+ // 3. Update user record
3212
+ this.MFABypassYN = YN.Yes;
3213
+ this.UpdatedAt = new Date();
3214
+ this.UpdatedById = loginUser.UserId;
3215
+
3216
+ await User._Repository.update(
3217
+ {
3218
+ MFABypassYN: this.MFABypassYN,
3219
+ UpdatedAt: this.UpdatedAt,
3220
+ UpdatedById: this.UpdatedById,
3221
+ },
3222
+ {
3223
+ where: {
3224
+ UserId: this.UserId,
3225
+ },
3226
+ transaction: dbTransaction,
3227
+ },
3228
+ );
3229
+
3230
+ const entityValueAfter: IUserAttr = {
3231
+ UserId: this.UserId,
3232
+ UserName: this.UserName,
3233
+ FullName: this.FullName,
3234
+ IDNo: this.IDNo,
3235
+ IDType: this.IDType,
3236
+ ContactNo: this.ContactNo,
3237
+ Email: this.Email,
3238
+ Password: this.Password,
3239
+ Status: this.Status,
3240
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
3241
+ FirstLoginAt: this.FirstLoginAt,
3242
+ LastLoginAt: this.LastLoginAt,
3243
+ MFAEnabled: this.MFAEnabled,
3244
+ MFAConfig: this.MFAConfig,
3245
+ MFABypassYN: this.MFABypassYN,
3246
+ RecoveryEmail: this.RecoveryEmail,
3247
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
3248
+ LastFailedLoginAt: this.LastFailedLoginAt,
3249
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
3250
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
3251
+ CreatedById: this.CreatedById,
3252
+ CreatedAt: this.CreatedAt,
3253
+ UpdatedById: this.UpdatedById,
3254
+ UpdatedAt: this.UpdatedAt,
3255
+ PasscodeHash: this.PasscodeHash,
3256
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
3257
+ };
3258
+
3259
+ // Record update activity using Activity class create method.
3260
+ const activity = new Activity();
3261
+ activity.ActivityId = activity.createId();
3262
+ activity.Action = ActionEnum.UPDATE;
3263
+ activity.Description = `Enable 2FA Bypass For User ${this.Email}`;
3264
+ activity.EntityType = this.ObjectType;
3265
+ activity.EntityId = this.UserId.toString();
3266
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
3267
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
3268
+
3269
+ await activity.create(loginUser.ObjectId, dbTransaction);
3270
+ } catch (error) {
3271
+ throw error;
3272
+ }
3273
+ }
3274
+
3275
+ public async disable2FABypass(loginUser: LoginUser, dbTransaction: any) {
3276
+ try {
3277
+ // 1. Check if MFABypassYN is already disabled
3278
+ if (this.MFABypassYN === YN.No) {
3279
+ throw new ClassError(
3280
+ 'User',
3281
+ 'UserErrMsg0X',
3282
+ 'Bypass already disabled.',
3283
+ 'disable2FABypass',
3284
+ );
3285
+ }
3286
+
3287
+ // 2. Check if user has MANAGE_MFA privilege
3288
+ const systemCode =
3289
+ ApplicationConfig.getComponentConfigValue('system-code');
3290
+ const isPrivileged = await loginUser.checkPrivileges(
3291
+ systemCode,
3292
+ 'MANAGE_MFA',
3293
+ );
3294
+ if (!isPrivileged) {
3295
+ throw new ClassError(
3296
+ 'LoginUser',
3297
+ 'LoginUserErrMsg0X',
3298
+ 'You do not have permission to enable MFA bypass.',
3299
+ );
3300
+ }
3301
+
3302
+ const entityValueBefore: IUserAttr = {
3303
+ UserId: this.UserId,
3304
+ UserName: this.UserName,
3305
+ FullName: this.FullName,
3306
+ IDNo: this.IDNo,
3307
+ IDType: this.IDType,
3308
+ ContactNo: this.ContactNo,
3309
+ Email: this.Email,
3310
+ Password: this.Password,
3311
+ Status: this.Status,
3312
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
3313
+ FirstLoginAt: this.FirstLoginAt,
3314
+ LastLoginAt: this.LastLoginAt,
3315
+ MFAEnabled: this.MFAEnabled,
3316
+ MFAConfig: this.MFAConfig,
3317
+ MFABypassYN: this.MFABypassYN,
3318
+ RecoveryEmail: this.RecoveryEmail,
3319
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
3320
+ LastFailedLoginAt: this.LastFailedLoginAt,
3321
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
3322
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
3323
+ CreatedById: this.CreatedById,
3324
+ CreatedAt: this.CreatedAt,
3325
+ UpdatedById: this.UpdatedById,
3326
+ UpdatedAt: this.UpdatedAt,
3327
+ PasscodeHash: this.PasscodeHash,
3328
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
3329
+ };
3330
+
3331
+ // 3. Update user record
3332
+ this.MFABypassYN = YN.No;
3333
+ this.UpdatedAt = new Date();
3334
+ this.UpdatedById = loginUser.UserId;
3335
+
3336
+ await User._Repository.update(
3337
+ {
3338
+ MFABypassYN: this.MFABypassYN,
3339
+ UpdatedAt: this.UpdatedAt,
3340
+ UpdatedById: this.UpdatedById,
3341
+ },
3342
+ {
3343
+ where: {
3344
+ UserId: this.UserId,
3345
+ },
3346
+ transaction: dbTransaction,
3347
+ },
3348
+ );
3349
+
3350
+ const entityValueAfter: IUserAttr = {
3351
+ UserId: this.UserId,
3352
+ UserName: this.UserName,
3353
+ FullName: this.FullName,
3354
+ IDNo: this.IDNo,
3355
+ IDType: this.IDType,
3356
+ ContactNo: this.ContactNo,
3357
+ Email: this.Email,
3358
+ Password: this.Password,
3359
+ Status: this.Status,
3360
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
3361
+ FirstLoginAt: this.FirstLoginAt,
3362
+ LastLoginAt: this.LastLoginAt,
3363
+ MFAEnabled: this.MFAEnabled,
3364
+ MFAConfig: this.MFAConfig,
3365
+ MFABypassYN: this.MFABypassYN,
3366
+ RecoveryEmail: this.RecoveryEmail,
3367
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
3368
+ LastFailedLoginAt: this.LastFailedLoginAt,
3369
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
3370
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
3371
+ CreatedById: this.CreatedById,
3372
+ CreatedAt: this.CreatedAt,
3373
+ UpdatedById: this.UpdatedById,
3374
+ UpdatedAt: this.UpdatedAt,
3375
+ PasscodeHash: this.PasscodeHash,
3376
+ PasscodeUpdatedAt: this.PasscodeUpdatedAt,
3377
+ };
3378
+
3379
+ // Record update activity using Activity class create method.
3380
+ const activity = new Activity();
3381
+ activity.ActivityId = activity.createId();
3382
+ activity.Action = ActionEnum.UPDATE;
3383
+ activity.Description = `Disable 2FA Bypass For User ${this.Email}`;
3384
+ activity.EntityType = this.ObjectType;
3385
+ activity.EntityId = this.UserId.toString();
3386
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
3387
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
3388
+
3389
+ await activity.create(loginUser.ObjectId, dbTransaction);
3390
+ } catch (error) {
3391
+ throw error;
3392
+ }
3393
+ }
3134
3394
  }
@@ -88,6 +88,13 @@ export default class User extends Model {
88
88
  })
89
89
  DefaultPasswordChangedYN: YN;
90
90
 
91
+ @Column({
92
+ allowNull: true,
93
+ type: DataType.CHAR(1),
94
+ defaultValue: 'N',
95
+ })
96
+ MFABypassYN: YN;
97
+
91
98
  @Column({
92
99
  type: DataType.DATE,
93
100
  })
@@ -1,6 +1,6 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "include": ["**/*.ts"],
4
- "exclude": ["node_modules", "__tests__", "dist", "**/*spec.ts"]
5
- }
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["**/*.ts"],
4
+ "exclude": ["node_modules", "__tests__", "dist", "**/*spec.ts"]
5
+ }
6
6
 
package/tsconfig.json CHANGED
@@ -1,24 +1,24 @@
1
- {
2
- "compilerOptions": {
3
- "module": "commonjs",
4
- "declaration": true,
5
- "removeComments": true,
6
- "emitDecoratorMetadata": true,
7
- "experimentalDecorators": true,
8
- "allowSyntheticDefaultImports": true,
9
- "moduleResolution": "node",
10
- "target": "es6",
11
- "sourceMap": true,
12
- "outDir": "./dist",
13
- "baseUrl": "./src",
14
- "rootDir": "./",
15
- "incremental": true,
16
- "skipLibCheck": true,
17
- "noImplicitAny": false,
18
- "strictBindCallApply": false,
19
- "forceConsistentCasingInFileNames": false,
20
- "noFallthroughCasesInSwitch": false,
21
- "strictNullChecks": false,
22
- },
23
- "exclude": ["node_modules", "dist"]
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "declaration": true,
5
+ "removeComments": true,
6
+ "emitDecoratorMetadata": true,
7
+ "experimentalDecorators": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "moduleResolution": "node",
10
+ "target": "es6",
11
+ "sourceMap": true,
12
+ "outDir": "./dist",
13
+ "baseUrl": "./src",
14
+ "rootDir": "./",
15
+ "incremental": true,
16
+ "skipLibCheck": true,
17
+ "noImplicitAny": false,
18
+ "strictBindCallApply": false,
19
+ "forceConsistentCasingInFileNames": false,
20
+ "noFallthroughCasesInSwitch": false,
21
+ "strictNullChecks": false,
22
+ },
23
+ "exclude": ["node_modules", "dist"]
24
24
  }