@tomei/sso 0.61.0 → 0.61.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 (134) hide show
  1. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.d.ts +1 -0
  2. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js +71 -0
  3. package/dist/__tests__/unit/components/group-privilege/group-privilege.test.js.map +1 -0
  4. package/dist/__tests__/unit/components/login-user/login-user.spec.d.ts +0 -0
  5. package/dist/__tests__/unit/components/login-user/login-user.spec.js +6 -0
  6. package/dist/__tests__/unit/components/login-user/login-user.spec.js.map +1 -0
  7. package/dist/src/components/login-history/login-history.d.ts +23 -0
  8. package/dist/src/components/login-history/login-history.js +88 -0
  9. package/dist/src/components/login-history/login-history.js.map +1 -0
  10. package/dist/src/components/login-user/user.js +3 -2
  11. package/dist/src/components/login-user/user.js.map +1 -1
  12. package/dist/src/interfaces/login-history-search-attr.interface.d.ts +8 -0
  13. package/dist/src/interfaces/login-history-search-attr.interface.js +3 -0
  14. package/dist/src/interfaces/login-history-search-attr.interface.js.map +1 -0
  15. package/dist/src/interfaces/login-history.interface.d.ts +11 -0
  16. package/dist/src/interfaces/login-history.interface.js +3 -0
  17. package/dist/src/interfaces/login-history.interface.js.map +1 -0
  18. package/dist/tsconfig.tsbuildinfo +1 -1
  19. package/package.json +1 -1
  20. package/src/components/api-key/api-key.repository.ts +15 -15
  21. package/src/components/api-key/api-key.ts +448 -448
  22. package/src/components/api-key/index.ts +4 -4
  23. package/src/components/building/building.repository.ts +27 -27
  24. package/src/components/building/index.ts +2 -2
  25. package/src/components/group/group.repository.ts +26 -26
  26. package/src/components/group/group.ts +2284 -2284
  27. package/src/components/group/index.ts +3 -3
  28. package/src/components/group-object-privilege/group-object-privilege.repository.ts +25 -25
  29. package/src/components/group-object-privilege/group-object-privilege.ts +278 -278
  30. package/src/components/group-object-privilege/index.ts +2 -2
  31. package/src/components/group-privilege/group-privilege.repository.ts +29 -29
  32. package/src/components/group-privilege/group-privilege.ts +84 -84
  33. package/src/components/group-privilege/index.ts +2 -2
  34. package/src/components/group-reporting-user/group-reporting-user.repository.ts +23 -23
  35. package/src/components/group-reporting-user/group-reporting-user.ts +506 -506
  36. package/src/components/group-reporting-user/index.ts +3 -3
  37. package/src/components/group-system-access/group-system-access.repository.ts +43 -43
  38. package/src/components/group-system-access/group-system-access.ts +90 -90
  39. package/src/components/group-system-access/index.ts +2 -2
  40. package/src/components/index.ts +20 -20
  41. package/src/components/login-user/index.ts +5 -5
  42. package/src/components/login-user/interfaces/check-user-info-duplicated.interface.ts +7 -7
  43. package/src/components/login-user/interfaces/index.ts +1 -1
  44. package/src/components/login-user/interfaces/system-access.interface.ts +13 -13
  45. package/src/components/login-user/interfaces/user-info.interface.ts +34 -34
  46. package/src/components/login-user/login-user.ts +362 -362
  47. package/src/components/login-user/user.repository.ts +11 -11
  48. package/src/components/login-user/user.ts +3 -2
  49. package/src/components/password-hash/index.ts +2 -2
  50. package/src/components/password-hash/interfaces/index.ts +1 -1
  51. package/src/components/password-hash/interfaces/password-hash-service.interface.ts +4 -4
  52. package/src/components/password-hash/password-hash.service.ts +14 -14
  53. package/src/components/staff/index.ts +2 -2
  54. package/src/components/staff/staff.repository.ts +27 -27
  55. package/src/components/system/index.ts +3 -3
  56. package/src/components/system/system.repository.ts +11 -11
  57. package/src/components/system/system.ts +456 -456
  58. package/src/components/system-privilege/index.ts +4 -4
  59. package/src/components/system-privilege/system-privilege.repository.ts +18 -18
  60. package/src/components/system-privilege/system-privilege.ts +541 -541
  61. package/src/components/user-group/index.ts +2 -2
  62. package/src/components/user-group/user-group.repository.ts +19 -19
  63. package/src/components/user-group/user-group.ts +764 -764
  64. package/src/components/user-object-privilege/index.ts +2 -2
  65. package/src/components/user-object-privilege/user-object-privilege.repository.ts +11 -11
  66. package/src/components/user-object-privilege/user-object-privilege.ts +79 -79
  67. package/src/components/user-password-history/index.ts +2 -2
  68. package/src/components/user-password-history/user-password-history.repository.ts +39 -39
  69. package/src/components/user-password-history/user-password-history.ts +187 -187
  70. package/src/components/user-privilege/index.ts +2 -2
  71. package/src/components/user-privilege/user-privilege.repository.ts +25 -25
  72. package/src/components/user-privilege/user-privilege.ts +662 -662
  73. package/src/components/user-reporting-hierarchy/index.ts +2 -2
  74. package/src/components/user-reporting-hierarchy/user-reporting-hierarchy.repository.ts +30 -30
  75. package/src/components/user-reporting-hierarchy/user-reporting-hierarchy.ts +505 -505
  76. package/src/components/user-system-access/index.ts +2 -2
  77. package/src/components/user-system-access/user-system-access.repository.ts +41 -41
  78. package/src/database.ts +15 -15
  79. package/src/enum/api-key.enum.ts +5 -5
  80. package/src/enum/building-type.enum.ts +6 -6
  81. package/src/enum/group-type.enum.ts +8 -8
  82. package/src/enum/index.ts +6 -6
  83. package/src/enum/login-status.enum.ts +4 -4
  84. package/src/enum/object-status.enum.ts +4 -4
  85. package/src/enum/user-status.enum.ts +7 -7
  86. package/src/enum/yn.enum.ts +4 -4
  87. package/src/index.ts +8 -8
  88. package/src/interfaces/api-key-attr.interface.ts +16 -16
  89. package/src/interfaces/group-object-privilege.interface.ts +14 -14
  90. package/src/interfaces/group-privilege.interface.ts +10 -10
  91. package/src/interfaces/group-reporting-user.interface.ts +11 -11
  92. package/src/interfaces/group-search-attr.interface.ts +9 -9
  93. package/src/interfaces/group-system-access.interface.ts +10 -10
  94. package/src/interfaces/group.interface.ts +17 -17
  95. package/src/interfaces/index.ts +13 -13
  96. package/src/interfaces/system-login.interface.ts +6 -6
  97. package/src/interfaces/system-privilege-search.interface.ts +5 -5
  98. package/src/interfaces/system-privilege.interface.ts +11 -11
  99. package/src/interfaces/system-search-attr.interface.ts +5 -5
  100. package/src/interfaces/system.interface.ts +15 -15
  101. package/src/interfaces/user-group.interface.ts +12 -12
  102. package/src/interfaces/user-object-privilege.interface.ts +14 -14
  103. package/src/interfaces/user-password-history.interface.ts +6 -6
  104. package/src/interfaces/user-privilege.interface.ts +10 -10
  105. package/src/interfaces/user-reporting-hierarchy.interface.ts +11 -11
  106. package/src/interfaces/user-session.interface.ts +5 -5
  107. package/src/interfaces/user-system-access.interface.ts +10 -10
  108. package/src/models/api-key-entity.ts +101 -101
  109. package/src/models/building.entity.ts +103 -103
  110. package/src/models/group-object-privilege.entity.ts +91 -91
  111. package/src/models/group-privilege.entity.ts +78 -78
  112. package/src/models/group-reporting-user.entity.ts +95 -95
  113. package/src/models/group-system-access.entity.ts +81 -81
  114. package/src/models/group.entity.ts +127 -127
  115. package/src/models/staff.entity.ts +91 -91
  116. package/src/models/system-privilege.entity.ts +90 -90
  117. package/src/models/system.entity.ts +113 -113
  118. package/src/models/user-group.entity.ts +91 -91
  119. package/src/models/user-object-privilege.entity.ts +90 -90
  120. package/src/models/user-password-history.ts +51 -51
  121. package/src/models/user-privilege.entity.ts +78 -78
  122. package/src/models/user-reporting-hierarchy.entity.ts +102 -102
  123. package/src/models/user-system-access.entity.ts +87 -87
  124. package/src/models/user.entity.ts +193 -193
  125. package/src/redis-client/__mocks__/jest-initial-setup.ts +2 -2
  126. package/src/redis-client/__mocks__/redis-mock.ts +28 -28
  127. package/src/redis-client/index.ts +1 -1
  128. package/src/redis-client/redis.service.ts +75 -75
  129. package/src/session/index.ts +2 -2
  130. package/src/session/interfaces/index.ts +1 -1
  131. package/src/session/interfaces/session-service.interface.ts +26 -26
  132. package/src/session/session.service.ts +96 -96
  133. package/src/types/auth-context.ts +10 -10
  134. package/src/types/index.ts +1 -1
@@ -1,362 +1,362 @@
1
- import { ILoginUser } from '@tomei/general';
2
- import { User } from './user';
3
- import { ISystemLogin } from '../../../src/interfaces/system-login.interface';
4
- import GroupModel from '../../models/group.entity';
5
- import { ISessionService } from '../../session/interfaces/session-service.interface';
6
- import { RedisService } from '../../redis-client/redis.service';
7
- import { UserRepository } from './user.repository';
8
- import { IUserAttr, IUserInfo } from './interfaces/user-info.interface';
9
- import Staff from '../../models/staff.entity';
10
- import UserModel from '../../models/user.entity';
11
- import { createHash, randomBytes, randomUUID } from 'crypto';
12
- import { UserGroupRepository } from '../user-group/user-group.repository';
13
- import GroupSystemAccessModel from '../../models/group-system-access.entity';
14
- import SystemModel from '../../models/system.entity';
15
- import { ApplicationConfig } from '@tomei/config';
16
-
17
- export class LoginUser extends User implements ILoginUser {
18
- session = {
19
- Id: null,
20
- };
21
-
22
- static async init(
23
- sessionService: ISessionService,
24
- userId?: number,
25
- dbTransaction = null,
26
- ): Promise<LoginUser> {
27
- User._RedisService = await RedisService.init();
28
- if (userId) {
29
- if (dbTransaction) {
30
- User._Repository = new UserRepository();
31
- }
32
- const user = await User._Repository.findOne({
33
- where: {
34
- UserId: userId,
35
- },
36
- include: [
37
- {
38
- model: Staff,
39
- },
40
- ],
41
- transaction: dbTransaction,
42
- });
43
-
44
- if (!user) {
45
- throw new Error('Invalid credentials.');
46
- }
47
-
48
- if (user) {
49
- const userAttr: IUserAttr = {
50
- UserId: user.UserId,
51
- UserName: user.UserName,
52
- FullName: user?.FullName || null,
53
- IDNo: user?.IdNo || null,
54
- IDType: user?.IdType || null,
55
- ContactNo: user?.ContactNo || null,
56
- Email: user.Email,
57
- Password: user.Password,
58
- Status: user.Status,
59
- DefaultPasswordChangedYN: user.DefaultPasswordChangedYN,
60
- FirstLoginAt: user.FirstLoginAt,
61
- LastLoginAt: user.LastLoginAt,
62
- MFAEnabled: user.MFAEnabled,
63
- MFAConfig: user.MFAConfig,
64
- RecoveryEmail: user.RecoveryEmail,
65
- FailedLoginAttemptCount: user.FailedLoginAttemptCount,
66
- LastFailedLoginAt: user.LastFailedLoginAt,
67
- LastPasswordChangedAt: user.LastPasswordChangedAt,
68
- NeedToChangePasswordYN: user.NeedToChangePasswordYN,
69
- PasscodeHash: user.PasscodeHash,
70
- PasscodeUpdatedAt: user.PasscodeUpdatedAt,
71
- CreatedById: user.CreatedById,
72
- CreatedAt: user.CreatedAt,
73
- UpdatedById: user.UpdatedById,
74
- UpdatedAt: user.UpdatedAt,
75
- staffs: user?.Staff,
76
- };
77
-
78
- return new LoginUser(sessionService, dbTransaction, userAttr);
79
- } else {
80
- throw new Error('User not found');
81
- }
82
- }
83
- return new LoginUser(sessionService, dbTransaction);
84
- }
85
-
86
- async checkPrivileges(
87
- systemCode: string,
88
- privilegeName: string,
89
- ): Promise<boolean> {
90
- try {
91
- if (!this.ObjectId) {
92
- throw new Error('ObjectId(UserId) is not set');
93
- }
94
-
95
- const sessionName =
96
- ApplicationConfig.getComponentConfigValue('sessionName');
97
- if (!sessionName) {
98
- throw new Error('Session name is not set');
99
- }
100
-
101
- const userSession = await this._SessionService.retrieveUserSession(
102
- this.ObjectId,
103
- sessionName,
104
- );
105
-
106
- const systemLogin = userSession.systemLogins.find(
107
- (system) => system.code === systemCode,
108
- );
109
-
110
- if (!systemLogin) {
111
- return false;
112
- }
113
-
114
- const privileges = systemLogin.privileges;
115
- const hasPrivilege = privileges.includes(privilegeName);
116
- return hasPrivilege;
117
- } catch (error) {
118
- throw error;
119
- }
120
- }
121
-
122
- async checkSession(
123
- systemCode: string,
124
- sessionId: string,
125
- userId: string,
126
- ): Promise<ISystemLogin> {
127
- try {
128
- const sessionName =
129
- ApplicationConfig.getComponentConfigValue('sessionName');
130
- if (!sessionName) {
131
- throw new Error('Session name is not set');
132
- }
133
- const userSession = await this._SessionService.retrieveUserSession(
134
- userId,
135
- sessionName,
136
- );
137
-
138
- if (userSession.systemLogins.length === 0) {
139
- throw new Error('Session expired.');
140
- }
141
-
142
- const systemLogin = userSession.systemLogins.find(
143
- (sl) => sl.code === systemCode,
144
- );
145
-
146
- if (!systemLogin) {
147
- throw new Error('Session expired.');
148
- }
149
-
150
- if (systemLogin.sessionId !== sessionId) {
151
- throw new Error('Session expired.');
152
- }
153
-
154
- await this._SessionService.refreshDuration(userId, sessionName);
155
-
156
- return systemLogin;
157
- } catch (error) {
158
- throw error;
159
- }
160
- }
161
-
162
- async logout(systemCode: string) {
163
- try {
164
- if (!this.ObjectId) {
165
- throw new Error('ObjectId(UserId) is not set');
166
- }
167
-
168
- const sessionName =
169
- ApplicationConfig.getComponentConfigValue('sessionName');
170
- if (!sessionName) {
171
- throw new Error('Session name is not set');
172
- }
173
-
174
- const userSession = await this._SessionService.retrieveUserSession(
175
- this.ObjectId,
176
- sessionName,
177
- );
178
- const index = userSession.systemLogins.findIndex(
179
- (system) => system.code === systemCode,
180
- );
181
- userSession.systemLogins.splice(index, 1);
182
- this._SessionService.setUserSession(
183
- this.ObjectId,
184
- userSession,
185
- sessionName,
186
- );
187
- } catch (error) {
188
- throw error;
189
- }
190
- }
191
-
192
- async getProfile(dbTransaction: any) {
193
- const user = await User._Repository.findOne({
194
- where: {
195
- UserId: this.UserId,
196
- Status: 'Active',
197
- },
198
- include: [
199
- {
200
- model: Staff,
201
- },
202
- ],
203
- transaction: dbTransaction,
204
- });
205
- return user;
206
- }
207
-
208
- public static async getGroups(loginUser: User, dbTransaction: any) {
209
- // This method will retrieve all user groups.
210
-
211
- // Part 2: Retrieve User Groups & Returns
212
- const userGroups = await User._UserGroupRepo.findAll({
213
- where: {
214
- UserId: loginUser.ObjectId,
215
- Status: 'Active',
216
- },
217
- include: [{ model: UserModel, as: 'User' }, { model: GroupModel }],
218
- transaction: dbTransaction,
219
- });
220
-
221
- return userGroups;
222
- }
223
-
224
- public static async getSystems(loginUser: User, dbTransaction: any) {
225
- // This method will retrieve all system records which user has accessed to.
226
-
227
- // Part 2: Retrieve System Access
228
- const groups = await this.getGroups(loginUser, dbTransaction);
229
- const systemAccess = await User.combineSystemAccess(
230
- loginUser,
231
- dbTransaction,
232
- groups,
233
- );
234
- const output = [];
235
- if (systemAccess) {
236
- for (let i = 0; i < systemAccess.length; i++) {
237
- const system = await User._SystemRepository.findOne({
238
- where: {
239
- SystemCode: systemAccess[i].SystemCode,
240
- Status: 'Active',
241
- },
242
- });
243
- output.push({
244
- UserSystemAccessId: systemAccess[i].UserSystemAccessId,
245
- UserId: systemAccess[i].UserId,
246
- SystemCode: systemAccess[i].SystemCode,
247
- Status: systemAccess[i].Status,
248
- CreatedById: systemAccess[i].CreatedById,
249
- UpdatedById: systemAccess[i].UpdatedById,
250
- CreatedAt: systemAccess[i].CreatedAt,
251
- UpdatedAt: systemAccess[i].UpdatedAt,
252
- inheritedBy: ['OWN'],
253
- System: system,
254
- });
255
- }
256
- }
257
-
258
- let userGroupRepository = new UserGroupRepository();
259
- const userGroups = await userGroupRepository.findAll({
260
- where: {
261
- UserId: loginUser.UserId,
262
- Status: 'Active',
263
- },
264
- include: [
265
- {
266
- model: GroupModel,
267
- required: true,
268
- where: {
269
- Status: 'Active',
270
- },
271
- include: [
272
- {
273
- model: GroupSystemAccessModel,
274
- where: {
275
- Status: 'Active',
276
- },
277
- include: [
278
- {
279
- model: SystemModel,
280
- },
281
- ],
282
- },
283
- ],
284
- },
285
- ],
286
- transaction: dbTransaction,
287
- });
288
-
289
- if (userGroups) {
290
- for (let i = 0; i < userGroups.length; i++) {
291
- let systemAccessList = userGroups[i].Group.GroupSystemAccesses;
292
- for (let j = 0; j < systemAccessList.length; j++) {
293
- let systemDetails = systemAccessList[j];
294
- let isFound = output.findIndex(
295
- (e) => e.SystemCode === systemDetails.SystemCode,
296
- );
297
- if (isFound > -1) {
298
- output[isFound].inheritedBy.push(userGroups[i].GroupCode);
299
- } else {
300
- output.push({
301
- UserSystemAccessId: systemDetails.GroupSystemAccessId,
302
- UserId: systemDetails.GroupSystemAccessId,
303
- SystemCode: systemDetails.SystemCode,
304
- Status: systemDetails.Status,
305
- CreatedById: systemDetails.CreatedById,
306
- UpdatedById: systemDetails.UpdatedById,
307
- CreatedAt: systemDetails.CreatedAt,
308
- UpdatedAt: systemDetails.UpdatedAt,
309
- inheritedBy: [userGroups[i].GroupCode],
310
- System: systemDetails.System,
311
- });
312
- }
313
- }
314
- }
315
- }
316
-
317
- // Part 3: Map Result to System Object
318
- return output;
319
- }
320
-
321
- async setSession(systemCode: string, sessionId: string, dbTransaction: any) {
322
- // fetch user session if exists
323
- const sessionName =
324
- ApplicationConfig.getComponentConfigValue('sessionName');
325
-
326
- if (!sessionName) {
327
- throw new Error('Session name is not set in the configuration');
328
- }
329
-
330
- const userSession = await this._SessionService.retrieveUserSession(
331
- this.ObjectId,
332
- sessionName,
333
- );
334
- const systemLogin = userSession.systemLogins.find(
335
- (system) => system.code === systemCode,
336
- );
337
-
338
- if (systemLogin) {
339
- const privileges = await this.getPrivileges(systemCode, dbTransaction);
340
- systemLogin.sessionId = sessionId;
341
- systemLogin.privileges = privileges;
342
- userSession.systemLogins.map((system) =>
343
- system.code === systemCode ? systemLogin : system,
344
- );
345
- } else {
346
- // if not, add new system login into the userSession
347
- const newLogin = {
348
- id: systemCode,
349
- code: systemCode,
350
- sessionId: sessionId,
351
- privileges: await this.getPrivileges(systemCode, dbTransaction),
352
- };
353
- userSession.systemLogins.push(newLogin);
354
- }
355
- // then update userSession inside the redis storage with 1 day duration of time-to-live
356
- this._SessionService.setUserSession(
357
- this.ObjectId,
358
- userSession,
359
- sessionName,
360
- );
361
- }
362
- }
1
+ import { ILoginUser } from '@tomei/general';
2
+ import { User } from './user';
3
+ import { ISystemLogin } from '../../../src/interfaces/system-login.interface';
4
+ import GroupModel from '../../models/group.entity';
5
+ import { ISessionService } from '../../session/interfaces/session-service.interface';
6
+ import { RedisService } from '../../redis-client/redis.service';
7
+ import { UserRepository } from './user.repository';
8
+ import { IUserAttr, IUserInfo } from './interfaces/user-info.interface';
9
+ import Staff from '../../models/staff.entity';
10
+ import UserModel from '../../models/user.entity';
11
+ import { createHash, randomBytes, randomUUID } from 'crypto';
12
+ import { UserGroupRepository } from '../user-group/user-group.repository';
13
+ import GroupSystemAccessModel from '../../models/group-system-access.entity';
14
+ import SystemModel from '../../models/system.entity';
15
+ import { ApplicationConfig } from '@tomei/config';
16
+
17
+ export class LoginUser extends User implements ILoginUser {
18
+ session = {
19
+ Id: null,
20
+ };
21
+
22
+ static async init(
23
+ sessionService: ISessionService,
24
+ userId?: number,
25
+ dbTransaction = null,
26
+ ): Promise<LoginUser> {
27
+ User._RedisService = await RedisService.init();
28
+ if (userId) {
29
+ if (dbTransaction) {
30
+ User._Repository = new UserRepository();
31
+ }
32
+ const user = await User._Repository.findOne({
33
+ where: {
34
+ UserId: userId,
35
+ },
36
+ include: [
37
+ {
38
+ model: Staff,
39
+ },
40
+ ],
41
+ transaction: dbTransaction,
42
+ });
43
+
44
+ if (!user) {
45
+ throw new Error('Invalid credentials.');
46
+ }
47
+
48
+ if (user) {
49
+ const userAttr: IUserAttr = {
50
+ UserId: user.UserId,
51
+ UserName: user.UserName,
52
+ FullName: user?.FullName || null,
53
+ IDNo: user?.IdNo || null,
54
+ IDType: user?.IdType || null,
55
+ ContactNo: user?.ContactNo || null,
56
+ Email: user.Email,
57
+ Password: user.Password,
58
+ Status: user.Status,
59
+ DefaultPasswordChangedYN: user.DefaultPasswordChangedYN,
60
+ FirstLoginAt: user.FirstLoginAt,
61
+ LastLoginAt: user.LastLoginAt,
62
+ MFAEnabled: user.MFAEnabled,
63
+ MFAConfig: user.MFAConfig,
64
+ RecoveryEmail: user.RecoveryEmail,
65
+ FailedLoginAttemptCount: user.FailedLoginAttemptCount,
66
+ LastFailedLoginAt: user.LastFailedLoginAt,
67
+ LastPasswordChangedAt: user.LastPasswordChangedAt,
68
+ NeedToChangePasswordYN: user.NeedToChangePasswordYN,
69
+ PasscodeHash: user.PasscodeHash,
70
+ PasscodeUpdatedAt: user.PasscodeUpdatedAt,
71
+ CreatedById: user.CreatedById,
72
+ CreatedAt: user.CreatedAt,
73
+ UpdatedById: user.UpdatedById,
74
+ UpdatedAt: user.UpdatedAt,
75
+ staffs: user?.Staff,
76
+ };
77
+
78
+ return new LoginUser(sessionService, dbTransaction, userAttr);
79
+ } else {
80
+ throw new Error('User not found');
81
+ }
82
+ }
83
+ return new LoginUser(sessionService, dbTransaction);
84
+ }
85
+
86
+ async checkPrivileges(
87
+ systemCode: string,
88
+ privilegeName: string,
89
+ ): Promise<boolean> {
90
+ try {
91
+ if (!this.ObjectId) {
92
+ throw new Error('ObjectId(UserId) is not set');
93
+ }
94
+
95
+ const sessionName =
96
+ ApplicationConfig.getComponentConfigValue('sessionName');
97
+ if (!sessionName) {
98
+ throw new Error('Session name is not set');
99
+ }
100
+
101
+ const userSession = await this._SessionService.retrieveUserSession(
102
+ this.ObjectId,
103
+ sessionName,
104
+ );
105
+
106
+ const systemLogin = userSession.systemLogins.find(
107
+ (system) => system.code === systemCode,
108
+ );
109
+
110
+ if (!systemLogin) {
111
+ return false;
112
+ }
113
+
114
+ const privileges = systemLogin.privileges;
115
+ const hasPrivilege = privileges.includes(privilegeName);
116
+ return hasPrivilege;
117
+ } catch (error) {
118
+ throw error;
119
+ }
120
+ }
121
+
122
+ async checkSession(
123
+ systemCode: string,
124
+ sessionId: string,
125
+ userId: string,
126
+ ): Promise<ISystemLogin> {
127
+ try {
128
+ const sessionName =
129
+ ApplicationConfig.getComponentConfigValue('sessionName');
130
+ if (!sessionName) {
131
+ throw new Error('Session name is not set');
132
+ }
133
+ const userSession = await this._SessionService.retrieveUserSession(
134
+ userId,
135
+ sessionName,
136
+ );
137
+
138
+ if (userSession.systemLogins.length === 0) {
139
+ throw new Error('Session expired.');
140
+ }
141
+
142
+ const systemLogin = userSession.systemLogins.find(
143
+ (sl) => sl.code === systemCode,
144
+ );
145
+
146
+ if (!systemLogin) {
147
+ throw new Error('Session expired.');
148
+ }
149
+
150
+ if (systemLogin.sessionId !== sessionId) {
151
+ throw new Error('Session expired.');
152
+ }
153
+
154
+ await this._SessionService.refreshDuration(userId, sessionName);
155
+
156
+ return systemLogin;
157
+ } catch (error) {
158
+ throw error;
159
+ }
160
+ }
161
+
162
+ async logout(systemCode: string) {
163
+ try {
164
+ if (!this.ObjectId) {
165
+ throw new Error('ObjectId(UserId) is not set');
166
+ }
167
+
168
+ const sessionName =
169
+ ApplicationConfig.getComponentConfigValue('sessionName');
170
+ if (!sessionName) {
171
+ throw new Error('Session name is not set');
172
+ }
173
+
174
+ const userSession = await this._SessionService.retrieveUserSession(
175
+ this.ObjectId,
176
+ sessionName,
177
+ );
178
+ const index = userSession.systemLogins.findIndex(
179
+ (system) => system.code === systemCode,
180
+ );
181
+ userSession.systemLogins.splice(index, 1);
182
+ this._SessionService.setUserSession(
183
+ this.ObjectId,
184
+ userSession,
185
+ sessionName,
186
+ );
187
+ } catch (error) {
188
+ throw error;
189
+ }
190
+ }
191
+
192
+ async getProfile(dbTransaction: any) {
193
+ const user = await User._Repository.findOne({
194
+ where: {
195
+ UserId: this.UserId,
196
+ Status: 'Active',
197
+ },
198
+ include: [
199
+ {
200
+ model: Staff,
201
+ },
202
+ ],
203
+ transaction: dbTransaction,
204
+ });
205
+ return user;
206
+ }
207
+
208
+ public static async getGroups(loginUser: User, dbTransaction: any) {
209
+ // This method will retrieve all user groups.
210
+
211
+ // Part 2: Retrieve User Groups & Returns
212
+ const userGroups = await User._UserGroupRepo.findAll({
213
+ where: {
214
+ UserId: loginUser.ObjectId,
215
+ Status: 'Active',
216
+ },
217
+ include: [{ model: UserModel, as: 'User' }, { model: GroupModel }],
218
+ transaction: dbTransaction,
219
+ });
220
+
221
+ return userGroups;
222
+ }
223
+
224
+ public static async getSystems(loginUser: User, dbTransaction: any) {
225
+ // This method will retrieve all system records which user has accessed to.
226
+
227
+ // Part 2: Retrieve System Access
228
+ const groups = await this.getGroups(loginUser, dbTransaction);
229
+ const systemAccess = await User.combineSystemAccess(
230
+ loginUser,
231
+ dbTransaction,
232
+ groups,
233
+ );
234
+ const output = [];
235
+ if (systemAccess) {
236
+ for (let i = 0; i < systemAccess.length; i++) {
237
+ const system = await User._SystemRepository.findOne({
238
+ where: {
239
+ SystemCode: systemAccess[i].SystemCode,
240
+ Status: 'Active',
241
+ },
242
+ });
243
+ output.push({
244
+ UserSystemAccessId: systemAccess[i].UserSystemAccessId,
245
+ UserId: systemAccess[i].UserId,
246
+ SystemCode: systemAccess[i].SystemCode,
247
+ Status: systemAccess[i].Status,
248
+ CreatedById: systemAccess[i].CreatedById,
249
+ UpdatedById: systemAccess[i].UpdatedById,
250
+ CreatedAt: systemAccess[i].CreatedAt,
251
+ UpdatedAt: systemAccess[i].UpdatedAt,
252
+ inheritedBy: ['OWN'],
253
+ System: system,
254
+ });
255
+ }
256
+ }
257
+
258
+ let userGroupRepository = new UserGroupRepository();
259
+ const userGroups = await userGroupRepository.findAll({
260
+ where: {
261
+ UserId: loginUser.UserId,
262
+ Status: 'Active',
263
+ },
264
+ include: [
265
+ {
266
+ model: GroupModel,
267
+ required: true,
268
+ where: {
269
+ Status: 'Active',
270
+ },
271
+ include: [
272
+ {
273
+ model: GroupSystemAccessModel,
274
+ where: {
275
+ Status: 'Active',
276
+ },
277
+ include: [
278
+ {
279
+ model: SystemModel,
280
+ },
281
+ ],
282
+ },
283
+ ],
284
+ },
285
+ ],
286
+ transaction: dbTransaction,
287
+ });
288
+
289
+ if (userGroups) {
290
+ for (let i = 0; i < userGroups.length; i++) {
291
+ let systemAccessList = userGroups[i].Group.GroupSystemAccesses;
292
+ for (let j = 0; j < systemAccessList.length; j++) {
293
+ let systemDetails = systemAccessList[j];
294
+ let isFound = output.findIndex(
295
+ (e) => e.SystemCode === systemDetails.SystemCode,
296
+ );
297
+ if (isFound > -1) {
298
+ output[isFound].inheritedBy.push(userGroups[i].GroupCode);
299
+ } else {
300
+ output.push({
301
+ UserSystemAccessId: systemDetails.GroupSystemAccessId,
302
+ UserId: systemDetails.GroupSystemAccessId,
303
+ SystemCode: systemDetails.SystemCode,
304
+ Status: systemDetails.Status,
305
+ CreatedById: systemDetails.CreatedById,
306
+ UpdatedById: systemDetails.UpdatedById,
307
+ CreatedAt: systemDetails.CreatedAt,
308
+ UpdatedAt: systemDetails.UpdatedAt,
309
+ inheritedBy: [userGroups[i].GroupCode],
310
+ System: systemDetails.System,
311
+ });
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ // Part 3: Map Result to System Object
318
+ return output;
319
+ }
320
+
321
+ async setSession(systemCode: string, sessionId: string, dbTransaction: any) {
322
+ // fetch user session if exists
323
+ const sessionName =
324
+ ApplicationConfig.getComponentConfigValue('sessionName');
325
+
326
+ if (!sessionName) {
327
+ throw new Error('Session name is not set in the configuration');
328
+ }
329
+
330
+ const userSession = await this._SessionService.retrieveUserSession(
331
+ this.ObjectId,
332
+ sessionName,
333
+ );
334
+ const systemLogin = userSession.systemLogins.find(
335
+ (system) => system.code === systemCode,
336
+ );
337
+
338
+ if (systemLogin) {
339
+ const privileges = await this.getPrivileges(systemCode, dbTransaction);
340
+ systemLogin.sessionId = sessionId;
341
+ systemLogin.privileges = privileges;
342
+ userSession.systemLogins.map((system) =>
343
+ system.code === systemCode ? systemLogin : system,
344
+ );
345
+ } else {
346
+ // if not, add new system login into the userSession
347
+ const newLogin = {
348
+ id: systemCode,
349
+ code: systemCode,
350
+ sessionId: sessionId,
351
+ privileges: await this.getPrivileges(systemCode, dbTransaction),
352
+ };
353
+ userSession.systemLogins.push(newLogin);
354
+ }
355
+ // then update userSession inside the redis storage with 1 day duration of time-to-live
356
+ this._SessionService.setUserSession(
357
+ this.ObjectId,
358
+ userSession,
359
+ sessionName,
360
+ );
361
+ }
362
+ }