@tomei/sso 0.34.10 → 0.35.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. package/.commitlintrc.json +22 -22
  2. package/.eslintrc +16 -16
  3. package/.eslintrc.js +35 -35
  4. package/.gitlab-ci.yml +16 -16
  5. package/.husky/commit-msg +15 -15
  6. package/.husky/pre-commit +7 -7
  7. package/.prettierrc +4 -4
  8. package/Jenkinsfile +57 -57
  9. package/README.md +23 -23
  10. package/__tests__/unit/components/group/group.spec.ts +79 -79
  11. package/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.ts +88 -88
  12. package/__tests__/unit/components/group-privilege/group-privilege.spec.ts +68 -68
  13. package/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.ts +66 -66
  14. package/__tests__/unit/components/group-system-access/group-system-access.spec.ts +83 -83
  15. package/__tests__/unit/components/login-user/l.spec.ts +746 -746
  16. package/__tests__/unit/components/login-user/login.spec.ts +1164 -1164
  17. package/__tests__/unit/components/password-hash/password-hash.service.spec.ts +31 -31
  18. package/__tests__/unit/components/system/system.spec.ts +254 -254
  19. package/__tests__/unit/components/system-privilege/system-privilege.spec.ts +83 -83
  20. package/__tests__/unit/components/user-group/user-group.spec.ts +86 -86
  21. package/__tests__/unit/components/user-object-privilege/user-object-privilege.spec.ts +78 -78
  22. package/__tests__/unit/components/user-privilege/user-privilege.spec.ts +72 -72
  23. package/__tests__/unit/components/user-system-access/user-system-access.spec.ts +89 -89
  24. package/__tests__/unit/redis-client/redis.service.spec.ts +23 -23
  25. package/__tests__/unit/session/session.service.spec.ts +47 -47
  26. package/__tests__/unit/system-privilege/system-privilage.spec.ts +91 -91
  27. package/coverage/clover.xml +1452 -1452
  28. package/coverage/coverage-final.json +47 -47
  29. package/coverage/lcov-report/base.css +224 -224
  30. package/coverage/lcov-report/block-navigation.js +87 -87
  31. package/coverage/lcov-report/components/group/group.repository.ts.html +117 -117
  32. package/coverage/lcov-report/components/group/group.ts.html +327 -327
  33. package/coverage/lcov-report/components/group/index.html +130 -130
  34. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.repository.ts.html +117 -117
  35. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.ts.html +321 -321
  36. package/coverage/lcov-report/components/group-object-privilege/index.html +130 -130
  37. package/coverage/lcov-report/components/group-privilege/group-privilege.repository.ts.html +117 -117
  38. package/coverage/lcov-report/components/group-privilege/group-privilege.ts.html +303 -303
  39. package/coverage/lcov-report/components/group-privilege/index.html +130 -130
  40. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.repository.ts.html +117 -117
  41. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.ts.html +327 -327
  42. package/coverage/lcov-report/components/group-reporting-user/index.html +130 -130
  43. package/coverage/lcov-report/components/group-system-access/group-system-access.repository.ts.html +117 -117
  44. package/coverage/lcov-report/components/group-system-access/group-system-access.ts.html +309 -309
  45. package/coverage/lcov-report/components/group-system-access/index.html +130 -130
  46. package/coverage/lcov-report/components/login-history/index.html +115 -115
  47. package/coverage/lcov-report/components/login-history/login-history.repository.ts.html +117 -117
  48. package/coverage/lcov-report/components/login-user/index.html +130 -130
  49. package/coverage/lcov-report/components/login-user/login-user.ts.html +5007 -5007
  50. package/coverage/lcov-report/components/login-user/user.repository.ts.html +117 -117
  51. package/coverage/lcov-report/components/password-hash/index.html +115 -115
  52. package/coverage/lcov-report/components/password-hash/password-hash.service.ts.html +126 -126
  53. package/coverage/lcov-report/components/system/index.html +130 -130
  54. package/coverage/lcov-report/components/system/system.repository.ts.html +117 -117
  55. package/coverage/lcov-report/components/system/system.ts.html +909 -909
  56. package/coverage/lcov-report/components/system-privilege/index.html +130 -130
  57. package/coverage/lcov-report/components/system-privilege/system-privilege.repository.ts.html +120 -120
  58. package/coverage/lcov-report/components/system-privilege/system-privilege.ts.html +390 -390
  59. package/coverage/lcov-report/components/user-group/index.html +130 -130
  60. package/coverage/lcov-report/components/user-group/user-group.repository.ts.html +117 -117
  61. package/coverage/lcov-report/components/user-group/user-group.ts.html +354 -354
  62. package/coverage/lcov-report/components/user-object-privilege/index.html +130 -130
  63. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.repository.ts.html +117 -117
  64. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.ts.html +312 -312
  65. package/coverage/lcov-report/components/user-privilege/index.html +130 -130
  66. package/coverage/lcov-report/components/user-privilege/user-privilege.repository.ts.html +117 -117
  67. package/coverage/lcov-report/components/user-privilege/user-privilege.ts.html +306 -306
  68. package/coverage/lcov-report/components/user-system-access/index.html +130 -130
  69. package/coverage/lcov-report/components/user-system-access/user-system-access.repository.ts.html +117 -117
  70. package/coverage/lcov-report/components/user-system-access/user-system-access.ts.html +312 -312
  71. package/coverage/lcov-report/enum/group-type.enum.ts.html +108 -108
  72. package/coverage/lcov-report/enum/index.html +160 -160
  73. package/coverage/lcov-report/enum/index.ts.html +93 -93
  74. package/coverage/lcov-report/enum/user-status.enum.ts.html +105 -105
  75. package/coverage/lcov-report/enum/yn.enum.ts.html +96 -96
  76. package/coverage/lcov-report/index.html +370 -370
  77. package/coverage/lcov-report/models/group-object-privilege.entity.ts.html +333 -333
  78. package/coverage/lcov-report/models/group-privilege.entity.ts.html +315 -315
  79. package/coverage/lcov-report/models/group-reporting-user.entity.ts.html +339 -339
  80. package/coverage/lcov-report/models/group-system-access.entity.ts.html +324 -324
  81. package/coverage/lcov-report/models/group.entity.ts.html +435 -435
  82. package/coverage/lcov-report/models/index.html +310 -310
  83. package/coverage/lcov-report/models/login-history.entity.ts.html +252 -252
  84. package/coverage/lcov-report/models/staff.entity.ts.html +411 -411
  85. package/coverage/lcov-report/models/system-privilege.entity.ts.html +354 -354
  86. package/coverage/lcov-report/models/system.entity.ts.html +423 -423
  87. package/coverage/lcov-report/models/user-group.entity.ts.html +354 -354
  88. package/coverage/lcov-report/models/user-object-privilege.entity.ts.html +330 -330
  89. package/coverage/lcov-report/models/user-privilege.entity.ts.html +315 -315
  90. package/coverage/lcov-report/models/user-system-access.entity.ts.html +315 -315
  91. package/coverage/lcov-report/models/user.entity.ts.html +522 -522
  92. package/coverage/lcov-report/prettify.css +1 -1
  93. package/coverage/lcov-report/prettify.js +2 -2
  94. package/coverage/lcov-report/redis-client/index.html +115 -115
  95. package/coverage/lcov-report/redis-client/redis.service.ts.html +240 -240
  96. package/coverage/lcov-report/session/index.html +115 -115
  97. package/coverage/lcov-report/session/session.service.ts.html +246 -246
  98. package/coverage/lcov-report/sorter.js +196 -196
  99. package/coverage/lcov.info +2490 -2490
  100. package/coverage/test-report.xml +128 -128
  101. package/create-sso-user.sql +39 -39
  102. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.d.ts +1 -0
  103. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js +71 -0
  104. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js.map +1 -0
  105. package/dist/__tests__/unit/components/login-user/login-user.spec.d.ts +0 -0
  106. package/dist/__tests__/unit/components/login-user/login-user.spec.js +6 -0
  107. package/dist/__tests__/unit/components/login-user/login-user.spec.js.map +1 -0
  108. package/dist/__tests__/unit/components/login-user/login.spec.js +0 -661
  109. package/dist/__tests__/unit/components/login-user/login.spec.js.map +1 -1
  110. package/dist/src/components/group/group.js +8 -2
  111. package/dist/src/components/group/group.js.map +1 -1
  112. package/dist/src/components/system/system.d.ts +1 -0
  113. package/dist/src/components/system/system.js +36 -0
  114. package/dist/src/components/system/system.js.map +1 -1
  115. package/dist/src/components/system-privilege/system-privilege.d.ts +1 -0
  116. package/dist/src/components/system-privilege/system-privilege.js +36 -0
  117. package/dist/src/components/system-privilege/system-privilege.js.map +1 -1
  118. package/dist/tsconfig.tsbuildinfo +1 -1
  119. package/jest.config.js +14 -14
  120. package/migrations/20240314080602-create-user-table.js +124 -124
  121. package/migrations/20240314080603-create-user-group-table.js +85 -85
  122. package/migrations/20240314080604-create-user-user-group-table.js +55 -55
  123. package/migrations/20240314080605-create-login-history-table.js +53 -53
  124. package/migrations/20240527064925-create-system-table.js +78 -78
  125. package/migrations/20240527064926-create-system-privilege-table.js +67 -67
  126. package/migrations/20240527065342-create-group-table.js +89 -89
  127. package/migrations/20240527065633-create-group-reporting-user-table.js +76 -76
  128. package/migrations/20240528011551-create-group-system-access-table.js +72 -72
  129. package/migrations/20240528023018-user-system-access-table.js +75 -75
  130. package/migrations/20240528032229-user-privilege-table.js +75 -75
  131. package/migrations/20240528063003-create-group-privilege-table.js +75 -75
  132. package/migrations/20240528063051-create-group-object-privilege-table.js +84 -84
  133. package/migrations/20240528063107-create-user-object-privilege-table.js +83 -83
  134. package/package.json +89 -89
  135. package/sampledotenv +7 -7
  136. package/sonar-project.properties +22 -22
  137. package/src/components/group/group.ts +9 -2
  138. package/src/components/system/system.ts +68 -1
  139. package/src/components/system-privilege/system-privilege.ts +80 -1
  140. package/tsconfig.build.json +5 -5
  141. package/tsconfig.json +22 -22
@@ -1,664 +1,3 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const session_service_1 = require("../../../../src/session/session.service");
13
- const login_user_1 = require("../../../../src/components/login-user/login-user");
14
- const config_1 = require("@tomei/config");
15
- const user_repository_1 = require("../../../../src/components/login-user/user.repository");
16
- const general_1 = require("@tomei/general");
17
- const user_status_enum_1 = require("../../../../src/enum/user-status.enum");
18
- const system_privilege_entity_1 = require("../../../../src/models/system-privilege.entity");
19
- const group_system_access_repository_1 = require("../../../../src/components/group-system-access/group-system-access.repository");
20
- const group_repository_1 = require("../../../../src/components/group/group.repository");
21
- describe('LoginUser', () => {
22
- afterAll(() => {
23
- jest.restoreAllMocks();
24
- });
25
- describe('init', () => {
26
- let sessionService;
27
- let userId;
28
- let dbTransaction;
29
- beforeEach(() => {
30
- sessionService = {};
31
- userId = 1;
32
- dbTransaction = null;
33
- });
34
- it('should initialize LoginUser with valid userId', () => __awaiter(void 0, void 0, void 0, function* () {
35
- const user = {
36
- UserId: 1,
37
- FullName: 'John Doe',
38
- Email: 'john.doe@example.com',
39
- Password: 'password',
40
- Status: 'active',
41
- DefaultPasswordChangedYN: 'yes',
42
- FirstLoginAt: new Date(),
43
- LastLoginAt: new Date(),
44
- MFAEnabled: 1,
45
- MFAConfig: 'config',
46
- RecoveryEmail: 'john.doe@example.com',
47
- FailedLoginAttemptCount: 0,
48
- LastFailedLoginAt: null,
49
- LastPasswordChangedAt: new Date(),
50
- NeedToChangePasswordYN: 'no',
51
- CreatedById: 1,
52
- CreatedAt: new Date(),
53
- UpdatedById: 1,
54
- UpdatedAt: new Date(),
55
- Staff: {
56
- FullName: 'John Doe',
57
- IdNo: '1234567890',
58
- Mobile: '1234567890',
59
- },
60
- };
61
- const findOneMock = jest
62
- .spyOn(user_repository_1.UserRepository.prototype, 'findOne')
63
- .mockResolvedValueOnce(user);
64
- const result = yield login_user_1.LoginUser.init(sessionService, userId, dbTransaction);
65
- expect(findOneMock).toHaveBeenCalledTimes(1);
66
- expect(findOneMock).toHaveBeenCalledWith({
67
- where: {
68
- UserId: userId,
69
- },
70
- include: [
71
- {
72
- model: expect.anything(),
73
- },
74
- ],
75
- });
76
- expect(result).toBeInstanceOf(login_user_1.LoginUser);
77
- expect(result.UserId).toBe(user.UserId);
78
- expect(result.FullName).toBe(user.FullName);
79
- expect(result.Email).toBe(user.Email);
80
- expect(result.Password).toBe(user.Password);
81
- expect(result.Status).toBe(user.Status);
82
- expect(result.DefaultPasswordChangedYN).toBe(user.DefaultPasswordChangedYN);
83
- expect(result.FirstLoginAt).toBe(user.FirstLoginAt);
84
- expect(result.LastLoginAt).toBe(user.LastLoginAt);
85
- expect(result.MFAEnabled).toBe(user.MFAEnabled);
86
- expect(result.MFAConfig).toBe(user.MFAConfig);
87
- expect(result.RecoveryEmail).toBe(user.RecoveryEmail);
88
- expect(result.FailedLoginAttemptCount).toBe(user.FailedLoginAttemptCount);
89
- expect(result.LastFailedLoginAt).toBe(user.LastFailedLoginAt);
90
- expect(result.LastPasswordChangedAt).toBe(user.LastPasswordChangedAt);
91
- expect(result.NeedToChangePasswordYN).toBe(user.NeedToChangePasswordYN);
92
- expect(result.CreatedById).toBe(user.CreatedById);
93
- expect(result.CreatedAt).toBe(user.CreatedAt);
94
- expect(result.UpdatedById).toBe(user.UpdatedById);
95
- expect(result.UpdatedAt).toBe(user.UpdatedAt);
96
- }));
97
- it('should throw an error when user is not found', () => __awaiter(void 0, void 0, void 0, function* () {
98
- const findOneMock = jest
99
- .spyOn(user_repository_1.UserRepository.prototype, 'findOne')
100
- .mockResolvedValueOnce(null);
101
- yield expect(login_user_1.LoginUser.init(sessionService, userId, dbTransaction)).rejects.toThrow(Error);
102
- expect(findOneMock).toHaveBeenCalledTimes(1);
103
- expect(findOneMock).toHaveBeenCalledWith({
104
- where: {
105
- UserId: userId,
106
- },
107
- include: [
108
- {
109
- model: expect.anything(),
110
- },
111
- ],
112
- });
113
- }));
114
- });
115
- describe('shouldReleaseLock', () => {
116
- const minuteToAutoRelease = 5;
117
- const autoReleaseYN = 'Y';
118
- beforeEach(() => {
119
- jest
120
- .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
121
- .mockImplementation((componentName, configKey) => {
122
- if (configKey === 'minuteToAutoRelease') {
123
- return minuteToAutoRelease;
124
- }
125
- if (configKey === 'autoReleaseYN') {
126
- return autoReleaseYN;
127
- }
128
- });
129
- });
130
- it('should return true if autoReleaseYN is "Y" and time difference is greater than minuteToAutoRelease', () => __awaiter(void 0, void 0, void 0, function* () {
131
- const lastFailedLoginAt = new Date();
132
- lastFailedLoginAt.setMinutes(lastFailedLoginAt.getMinutes() - 10);
133
- const result = login_user_1.LoginUser.shouldReleaseLock(lastFailedLoginAt);
134
- expect(result).toBe(true);
135
- }));
136
- it('should return false if autoReleaseYN is "Y" and time difference is less than or equal to minuteToAutoRelease', () => __awaiter(void 0, void 0, void 0, function* () {
137
- const lastFailedLoginAt = new Date();
138
- lastFailedLoginAt.setMinutes(lastFailedLoginAt.getMinutes() - 3);
139
- const result = login_user_1.LoginUser.shouldReleaseLock(lastFailedLoginAt);
140
- expect(result).toBe(false);
141
- }));
142
- it('should return false if autoReleaseYN is "N"', () => __awaiter(void 0, void 0, void 0, function* () {
143
- const lastFailedLoginAt = new Date();
144
- const result = login_user_1.LoginUser.shouldReleaseLock(lastFailedLoginAt);
145
- expect(result).toBe(false);
146
- }));
147
- });
148
- describe('releaseLock', () => {
149
- it('should release the lock for a user', () => __awaiter(void 0, void 0, void 0, function* () {
150
- const UserId = 1;
151
- const dbTransaction = null;
152
- const updateMock = jest
153
- .spyOn(login_user_1.LoginUser['_Repository'], 'update')
154
- .mockImplementationOnce(() => Promise.resolve({}));
155
- login_user_1.LoginUser['releaseLock'](UserId, dbTransaction);
156
- expect(updateMock).toHaveBeenCalledTimes(1);
157
- expect(updateMock).toHaveBeenCalledWith({
158
- FailedLoginAttemptCount: 0,
159
- Status: 'Active',
160
- }, {
161
- where: {
162
- UserId,
163
- },
164
- transaction: dbTransaction,
165
- });
166
- }));
167
- });
168
- describe('checkUserInfoDuplicated', () => {
169
- it('should throw an error if duplicate user info is found', () => __awaiter(void 0, void 0, void 0, function* () {
170
- const dbTransaction = null;
171
- const query = {
172
- Email: 'test@example.com',
173
- IdType: 'passport',
174
- IdNo: '123456789',
175
- ContactNo: '1234567890',
176
- };
177
- jest
178
- .spyOn(login_user_1.LoginUser['_Repository'], 'findAll')
179
- .mockResolvedValueOnce([{ id: 1 }]);
180
- yield expect(login_user_1.LoginUser['checkUserInfoDuplicated'](dbTransaction, query)).rejects.toThrowError();
181
- }));
182
- it('should not throw an error if duplicate user info is not found', () => __awaiter(void 0, void 0, void 0, function* () {
183
- const dbTransaction = null;
184
- const query = {
185
- Email: 'test@example.com',
186
- IdType: 'passport',
187
- IdNo: '123456789',
188
- ContactNo: '1234567890',
189
- };
190
- jest.spyOn(login_user_1.LoginUser['_Repository'], 'findAll').mockResolvedValueOnce([]);
191
- yield expect(login_user_1.LoginUser['checkUserInfoDuplicated'](dbTransaction, query)).resolves.not.toThrowError();
192
- }));
193
- });
194
- describe('generateDefaultPassword', () => {
195
- const passwordPolicy = {
196
- minLen: 6,
197
- maxLen: 10,
198
- nonAcceptableChar: 'i,l,o',
199
- numOfCapitalLetters: 1,
200
- numOfNumbers: 1,
201
- numOfSpecialChars: 1,
202
- };
203
- beforeEach(() => {
204
- jest
205
- .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
206
- .mockImplementation((componentName, configKey) => {
207
- if (configKey === 'passwordPolicy') {
208
- return passwordPolicy;
209
- }
210
- });
211
- });
212
- it('should generate a default password with the specified length', () => {
213
- const password = login_user_1.LoginUser['generateDefaultPassword']();
214
- expect(password.length).toBeGreaterThanOrEqual(6);
215
- expect(password.length).toBeLessThanOrEqual(10);
216
- });
217
- it('should generate a default password with at least one capital letter', () => {
218
- const password = login_user_1.LoginUser['generateDefaultPassword']();
219
- expect(/[A-Z]/.test(password)).toBe(true);
220
- });
221
- it('should generate a default password with at least one number', () => {
222
- const password = login_user_1.LoginUser['generateDefaultPassword']();
223
- expect(/[0-9]/.test(password)).toBe(true);
224
- });
225
- it('should generate a default password with at least one special character', () => {
226
- const password = login_user_1.LoginUser['generateDefaultPassword']();
227
- expect(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?~`]/.test(password)).toBe(true);
228
- });
229
- it('should generate a default password without any non-acceptable characters', () => {
230
- const password = login_user_1.LoginUser['generateDefaultPassword']();
231
- const nonAcceptableChars = ['i', 'l', 'o'];
232
- expect(nonAcceptableChars.some((char) => password.includes(char))).toBe(false);
233
- });
234
- });
235
- describe('setPassword', () => {
236
- const passwordPolicy = {
237
- minLen: 6,
238
- maxLen: 10,
239
- nonAcceptableChar: 'i,l,o',
240
- numOfCapitalLetters: 1,
241
- numOfNumbers: 1,
242
- numOfSpecialChars: 1,
243
- };
244
- beforeEach(() => {
245
- jest
246
- .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
247
- .mockImplementation((componentName, configKey) => {
248
- if (configKey === 'passwordPolicy') {
249
- return passwordPolicy;
250
- }
251
- });
252
- });
253
- it('should set the password for the user', () => __awaiter(void 0, void 0, void 0, function* () {
254
- const dbTransaction = null;
255
- const sessionService = yield session_service_1.SessionService.init();
256
- const user = yield login_user_1.LoginUser.init(sessionService);
257
- const password = 'N3wP@ssw0';
258
- const result = yield login_user_1.LoginUser['setPassword'](dbTransaction, user, password);
259
- expect(result).toBeInstanceOf(login_user_1.LoginUser);
260
- yield expect(login_user_1.LoginUser['setPassword'](dbTransaction, user, password)).resolves.not.toThrowError();
261
- expect(result.Password).toBeDefined();
262
- }));
263
- it('should throw an error if the password does not meet the security requirements', () => __awaiter(void 0, void 0, void 0, function* () {
264
- const dbTransaction = null;
265
- const sessionService = yield session_service_1.SessionService.init();
266
- const user = yield login_user_1.LoginUser.init(sessionService);
267
- const password = 'weakpassword';
268
- yield expect(login_user_1.LoginUser['setPassword'](dbTransaction, user, password)).rejects.toThrow();
269
- }));
270
- });
271
- describe('incrementFailedLoginAttemptCount', () => {
272
- afterAll(() => {
273
- jest.restoreAllMocks();
274
- });
275
- it('should increment FailedLoginAttemptCount and update user status', () => __awaiter(void 0, void 0, void 0, function* () {
276
- const sessionService = yield session_service_1.SessionService.init();
277
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
278
- loginUser['FailedLoginAttemptCount'] = 2;
279
- loginUser['LastFailedLoginAt'] = new Date();
280
- loginUser['Status'] = user_status_enum_1.UserStatus.ACTIVE;
281
- const dbTransaction = null;
282
- jest
283
- .spyOn(login_user_1.LoginUser['_Repository'], 'update')
284
- .mockReturnValueOnce(null);
285
- jest
286
- .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
287
- .mockImplementation((componentName, configKey) => {
288
- if (configKey === 'maxFailedLoginAttempts') {
289
- return 3;
290
- }
291
- if (configKey === 'autoReleaseYN') {
292
- return 'Y';
293
- }
294
- });
295
- yield loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
296
- expect(login_user_1.LoginUser['_Repository'].update).toHaveBeenCalledWith({
297
- FailedLoginAttemptCount: 3,
298
- LastFailedLoginAt: expect.any(Date),
299
- Status: user_status_enum_1.UserStatus.ACTIVE,
300
- }, {
301
- where: {
302
- UserId: loginUser.UserId,
303
- },
304
- transaction: dbTransaction,
305
- });
306
- }));
307
- it('should throw an error if maxFailedLoginAttempts or autoReleaseYN is missing', () => __awaiter(void 0, void 0, void 0, function* () {
308
- const sessionService = yield session_service_1.SessionService.init();
309
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
310
- loginUser['FailedLoginAttemptCount'] = 2;
311
- loginUser['LastFailedLoginAt'] = new Date();
312
- loginUser['Status'] = user_status_enum_1.UserStatus.ACTIVE;
313
- const dbTransaction = null;
314
- jest
315
- .spyOn(login_user_1.LoginUser['_Repository'], 'update')
316
- .mockReturnValueOnce(null);
317
- jest
318
- .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
319
- .mockImplementationOnce((componentName, configKey) => {
320
- if (configKey === 'maxFailedLoginAttempts') {
321
- return undefined;
322
- }
323
- if (configKey === 'autoReleaseYN') {
324
- return undefined;
325
- }
326
- });
327
- yield expect(loginUser['incrementFailedLoginAttemptCount'](dbTransaction)).rejects.toThrow(new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Missing maxFailedLoginAttempts and or autoReleaseYN. Please set in config file.'));
328
- }));
329
- it('should lock the user account if the failed login attempts exceed the maximum allowed', () => __awaiter(void 0, void 0, void 0, function* () {
330
- const sessionService = yield session_service_1.SessionService.init();
331
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
332
- loginUser['FailedLoginAttemptCount'] = 3;
333
- loginUser['LastFailedLoginAt'] = new Date();
334
- loginUser['Status'] = user_status_enum_1.UserStatus.ACTIVE;
335
- const dbTransaction = null;
336
- jest
337
- .spyOn(login_user_1.LoginUser['_Repository'], 'update')
338
- .mockReturnValueOnce(null);
339
- jest
340
- .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
341
- .mockImplementation((componentName, configKey) => {
342
- if (configKey === 'maxFailedLoginAttempts') {
343
- return 3;
344
- }
345
- if (configKey === 'autoReleaseYN') {
346
- return 'Y';
347
- }
348
- });
349
- try {
350
- yield loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
351
- expect(false).toBe(true);
352
- }
353
- catch (error) {
354
- expect(login_user_1.LoginUser['_Repository'].update).toHaveBeenCalledWith({
355
- FailedLoginAttemptCount: 4,
356
- LastFailedLoginAt: expect.any(Date),
357
- Status: user_status_enum_1.UserStatus.LOCKED,
358
- }, {
359
- where: {
360
- UserId: loginUser.UserId,
361
- },
362
- transaction: dbTransaction,
363
- });
364
- expect(error).toBeInstanceOf(general_1.ClassError);
365
- expect(error.message).toBe('Your account has been temporarily locked due to too many failed login attempts, please try again later.');
366
- }
367
- }));
368
- it('should permanently lock the user account if the failed login attempts exceed the maximum allowed and autoReleaseYN is N', () => __awaiter(void 0, void 0, void 0, function* () {
369
- const sessionService = yield session_service_1.SessionService.init();
370
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
371
- loginUser['FailedLoginAttemptCount'] = 3;
372
- loginUser['LastFailedLoginAt'] = new Date();
373
- loginUser['Status'] = user_status_enum_1.UserStatus.ACTIVE;
374
- const dbTransaction = null;
375
- jest
376
- .spyOn(login_user_1.LoginUser['_Repository'], 'update')
377
- .mockReturnValueOnce(null);
378
- jest
379
- .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
380
- .mockImplementation((componentName, configKey) => {
381
- if (configKey === 'maxFailedLoginAttempts') {
382
- return 3;
383
- }
384
- if (configKey === 'autoReleaseYN') {
385
- return 'N';
386
- }
387
- });
388
- try {
389
- yield loginUser['incrementFailedLoginAttemptCount'](dbTransaction);
390
- expect(false).toBe(true);
391
- }
392
- catch (error) {
393
- expect(login_user_1.LoginUser['_Repository'].update).toHaveBeenCalledWith({
394
- FailedLoginAttemptCount: 4,
395
- LastFailedLoginAt: expect.any(Date),
396
- Status: user_status_enum_1.UserStatus.LOCKED,
397
- }, {
398
- where: {
399
- UserId: loginUser.UserId,
400
- },
401
- transaction: dbTransaction,
402
- });
403
- expect(error).toBeInstanceOf(general_1.ClassError);
404
- expect(error.message).toBe('Your account has been locked due to too many failed login attempts, please contact IT Support for instructions on how to unlock your account');
405
- }
406
- }));
407
- });
408
- describe('combineSystemAccess', () => {
409
- it('should combine user and group system access and remove duplicates', () => __awaiter(void 0, void 0, void 0, function* () {
410
- const sessionService = yield session_service_1.SessionService.init();
411
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
412
- const dbTransaction = null;
413
- const groups = [
414
- { InheritParentSystemAccessYN: true },
415
- { InheritParentSystemAccessYN: false },
416
- ];
417
- jest
418
- .spyOn(login_user_1.LoginUser, 'getInheritedSystemAccess')
419
- .mockResolvedValueOnce([
420
- { SystemCode: 'system1' },
421
- { SystemCode: 'system2' },
422
- ]);
423
- jest
424
- .spyOn(login_user_1.LoginUser['_UserSystemAccessRepo'], 'findAll')
425
- .mockResolvedValueOnce([{ SystemCode: 'system3' }]);
426
- const result = yield login_user_1.LoginUser['combineSystemAccess'](loginUser, dbTransaction, groups);
427
- expect(result).toEqual([
428
- { SystemCode: 'system3' },
429
- { SystemCode: 'system1' },
430
- { SystemCode: 'system2' },
431
- ]);
432
- }));
433
- });
434
- describe('checkPrivileges', () => {
435
- it('should return true if user has the specified privilege', () => __awaiter(void 0, void 0, void 0, function* () {
436
- const systemCode = 'SS';
437
- const privilegeName = 'Privilege 1';
438
- const sessionService = yield session_service_1.SessionService.init();
439
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
440
- loginUser.ObjectId = '1';
441
- const rus = jest
442
- .spyOn(session_service_1.SessionService.prototype, 'retrieveUserSession')
443
- .mockResolvedValueOnce({
444
- systemLogins: [
445
- {
446
- id: '1',
447
- sessionId: 'sessionId',
448
- code: systemCode,
449
- privileges: [privilegeName],
450
- },
451
- ],
452
- });
453
- const hasPrivilege = yield loginUser.checkPrivileges(systemCode, privilegeName);
454
- expect(hasPrivilege).toBe(true);
455
- expect(rus).toHaveBeenCalledWith(loginUser.ObjectId);
456
- }));
457
- it('should return false if user does not have the specified privilege', () => __awaiter(void 0, void 0, void 0, function* () {
458
- const systemCode = 'SS';
459
- const privilegeName = 'Privilege 1';
460
- const sessionService = yield session_service_1.SessionService.init();
461
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
462
- loginUser.ObjectId = '1';
463
- const rus = jest
464
- .spyOn(session_service_1.SessionService.prototype, 'retrieveUserSession')
465
- .mockResolvedValueOnce({
466
- systemLogins: [
467
- {
468
- id: '1',
469
- sessionId: 'sessionId',
470
- code: systemCode,
471
- privileges: [],
472
- },
473
- ],
474
- });
475
- const hasPrivilege = yield loginUser.checkPrivileges(systemCode, privilegeName);
476
- expect(hasPrivilege).toBe(false);
477
- expect(rus).toHaveBeenCalledWith(loginUser.ObjectId);
478
- }));
479
- it('should throw an error if ObjectId is not set', () => __awaiter(void 0, void 0, void 0, function* () {
480
- const systemCode = 'SS';
481
- const privilegeName = 'Privilege 1';
482
- const sessionService = yield session_service_1.SessionService.init();
483
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
484
- loginUser.ObjectId = null;
485
- yield expect(loginUser.checkPrivileges(systemCode, privilegeName)).rejects.toThrowError();
486
- }));
487
- });
488
- describe('getObjectPrivileges', () => {
489
- it('should return an array of privileges', () => __awaiter(void 0, void 0, void 0, function* () {
490
- const systemCode = 'system1';
491
- const dbTransaction = null;
492
- const sessionService = yield session_service_1.SessionService.init();
493
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
494
- const findAllMock = jest
495
- .spyOn(login_user_1.LoginUser['_UserObjectPrivilegeRepo'], 'findAll')
496
- .mockResolvedValue([
497
- {
498
- PrivilegeCode: 'privilege1',
499
- Privilege: {
500
- PrivilegeCode: 'privilege1',
501
- SystemCode: systemCode,
502
- Name: 'privilege1',
503
- },
504
- },
505
- {
506
- PrivilegeCode: 'privilege2',
507
- Privilege: {
508
- PrivilegeCode: 'privilege2',
509
- Name: 'privilege2',
510
- },
511
- },
512
- ]);
513
- const result = yield loginUser['getObjectPrivileges'](systemCode, dbTransaction);
514
- expect(findAllMock).toHaveBeenCalledTimes(1);
515
- expect(findAllMock).toHaveBeenCalledWith({
516
- where: {
517
- UserId: loginUser.UserId,
518
- },
519
- include: {
520
- model: system_privilege_entity_1.default,
521
- where: {
522
- SystemCode: systemCode,
523
- Status: 'Active',
524
- },
525
- },
526
- transaction: dbTransaction,
527
- });
528
- expect(result).toEqual(['privilege1', 'privilege2']);
529
- }));
530
- it('should throw an error if an exception occurs', () => __awaiter(void 0, void 0, void 0, function* () {
531
- const systemCode = 'system1';
532
- const dbTransaction = null;
533
- const sessionService = yield session_service_1.SessionService.init();
534
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
535
- jest
536
- .spyOn(login_user_1.LoginUser['_UserObjectPrivilegeRepo'], 'findAll')
537
- .mockRejectedValue(new Error('Database error'));
538
- yield expect(loginUser['getObjectPrivileges'](systemCode, dbTransaction)).rejects.toThrow(Error);
539
- }));
540
- });
541
- describe('getUserPersonalPrivileges', () => {
542
- it('should return an array of privileges', () => __awaiter(void 0, void 0, void 0, function* () {
543
- const sessionService = yield session_service_1.SessionService.init();
544
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
545
- const systemCode = 'system1';
546
- const dbTransaction = null;
547
- const findAllMock = jest.spyOn(login_user_1.LoginUser['_UserPrivilegeRepo'], 'findAll');
548
- findAllMock.mockResolvedValue([
549
- { Privilege: { Name: 'privilege1' } },
550
- { Privilege: { Name: 'privilege2' } },
551
- ]);
552
- const privileges = yield loginUser['getUserPersonalPrivileges'](systemCode, dbTransaction);
553
- expect(privileges).toEqual(['privilege1', 'privilege2']);
554
- expect(findAllMock).toHaveBeenCalledTimes(1);
555
- expect(findAllMock).toHaveBeenCalledWith({
556
- where: {
557
- UserId: loginUser.UserId,
558
- Status: 'Active',
559
- },
560
- include: {
561
- model: system_privilege_entity_1.default,
562
- where: {
563
- SystemCode: systemCode,
564
- Status: 'Active',
565
- },
566
- },
567
- transaction: dbTransaction,
568
- });
569
- }));
570
- it('should throw an error if an error occurs', () => __awaiter(void 0, void 0, void 0, function* () {
571
- const sessionService = yield session_service_1.SessionService.init();
572
- const loginUser = yield login_user_1.LoginUser.init(sessionService);
573
- const systemCode = 'system1';
574
- const dbTransaction = null;
575
- const findAllMock = jest.spyOn(login_user_1.LoginUser['_UserPrivilegeRepo'], 'findAll');
576
- findAllMock.mockRejectedValue(new Error('Database error'));
577
- yield expect(loginUser['getUserPersonalPrivileges'](systemCode, dbTransaction)).rejects.toThrow(Error);
578
- expect(findAllMock).toHaveBeenCalledTimes(1);
579
- expect(findAllMock).toHaveBeenCalledWith({
580
- where: {
581
- UserId: loginUser.UserId,
582
- Status: 'Active',
583
- },
584
- include: {
585
- model: system_privilege_entity_1.default,
586
- where: {
587
- SystemCode: systemCode,
588
- Status: 'Active',
589
- },
590
- },
591
- transaction: dbTransaction,
592
- });
593
- }));
594
- });
595
- describe('getInheritedSystemAccess', () => {
596
- it('should return group system access with its parent group system access if applicable', () => __awaiter(void 0, void 0, void 0, function* () {
597
- const dbTransaction = null;
598
- const group = {
599
- GroupCode: 'group1',
600
- InheritParentPrivilegeYN: 'Y',
601
- ParentGroupCode: 'parentGroup',
602
- };
603
- const parentGroup = {
604
- GroupCode: 'parentGroup',
605
- InheritParentPrivilegeYN: 'N',
606
- ParentGroupCode: null,
607
- };
608
- const systemAccess = [
609
- {
610
- SystemCode: 'system1',
611
- GroupCode: 'group1',
612
- System: { SystemCode: 'system1' },
613
- },
614
- {
615
- SystemCode: 'system2',
616
- GroupCode: 'group1',
617
- System: { SystemCode: 'system1' },
618
- },
619
- ];
620
- const parentSystemAccess = [
621
- {
622
- SystemCode: 'system3',
623
- GroupCode: 'parentGroup',
624
- System: { SystemCode: 'system3' },
625
- },
626
- ];
627
- const groupFindByPkMock = jest
628
- .spyOn(group_repository_1.GroupRepository.prototype, 'findByPk')
629
- .mockResolvedValueOnce(parentGroup);
630
- const systemAccessFindAllMock = jest
631
- .spyOn(group_system_access_repository_1.GroupSystemAccessRepository.prototype, 'findAll')
632
- .mockImplementation((options) => {
633
- if (options.where.GroupCode === group.GroupCode) {
634
- return Promise.resolve(systemAccess);
635
- }
636
- else if (options.where.GroupCode === parentGroup.GroupCode) {
637
- return Promise.resolve(parentSystemAccess);
638
- }
639
- });
640
- const result = yield login_user_1.LoginUser['getInheritedSystemAccess'](dbTransaction, group);
641
- console.log(result);
642
- expect(result).toEqual([
643
- {
644
- SystemCode: 'system1',
645
- GroupCode: 'group1',
646
- System: { SystemCode: 'system1' },
647
- },
648
- {
649
- SystemCode: 'system2',
650
- GroupCode: 'group1',
651
- System: { SystemCode: 'system1' },
652
- },
653
- {
654
- SystemCode: 'system3',
655
- GroupCode: 'parentGroup',
656
- System: { SystemCode: 'system3' },
657
- },
658
- ]);
659
- expect(groupFindByPkMock).toHaveBeenCalledWith(group.ParentGroupCode, dbTransaction);
660
- expect(systemAccessFindAllMock).toHaveBeenCalledTimes(2);
661
- }));
662
- });
663
- });
664
3
  //# sourceMappingURL=login.spec.js.map