@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,764 +1,764 @@
1
- import { ClassError, ObjectBase } from '@tomei/general';
2
- import { UserGroupRepository } from './user-group.repository';
3
- import { IUserGroupAttr } from '../../interfaces/user-group.interface';
4
- import { LoginUser, User } from '../../components/login-user';
5
- import { Group } from '../../components/group';
6
- import { ApplicationConfig } from '@tomei/config';
7
- import { ActionEnum, Activity } from '@tomei/activity-history';
8
- import GroupSystemAccessModel from '../../models/group-system-access.entity';
9
- import GroupModel from '../../models/group.entity';
10
- import SystemModel from '../../models/system.entity';
11
- import UserModel from '../../models/user.entity';
12
- import { Transaction } from 'sequelize';
13
-
14
- export class UserGroup extends ObjectBase {
15
- ObjectType = 'UserGroup';
16
- TableName = 'sso_UserGroup';
17
- ObjectName: string;
18
- ObjectId: string;
19
- UserGroupId: number;
20
- UserId: number;
21
- GroupCode: string;
22
- InheritGroupPrivilegeYN = 'Y';
23
- InheritGroupSystemAccessYN = 'Y';
24
- Status: string;
25
- private _CreatedAt: Date;
26
- private _UpdatedAt: Date;
27
- private _CreatedById: number;
28
- private _UpdatedById: number;
29
-
30
- protected static _Repository = new UserGroupRepository();
31
-
32
- get CreatedAt() {
33
- return this._CreatedAt;
34
- }
35
-
36
- get UpdatedAt() {
37
- return this._UpdatedAt;
38
- }
39
-
40
- get CreatedById() {
41
- return this._CreatedById;
42
- }
43
-
44
- get UpdatedById() {
45
- return this._UpdatedById;
46
- }
47
-
48
- private constructor(userGroupAttr?: IUserGroupAttr) {
49
- super();
50
- if (userGroupAttr) {
51
- this.UserGroupId = userGroupAttr.UserGroupId;
52
- this.UserId = userGroupAttr.UserId;
53
- this.GroupCode = userGroupAttr.GroupCode;
54
- this.Status = userGroupAttr.Status;
55
- this.InheritGroupPrivilegeYN = userGroupAttr.InheritGroupPrivilegeYN;
56
- this.InheritGroupSystemAccessYN =
57
- userGroupAttr.InheritGroupSystemAccessYN;
58
- this._CreatedById = userGroupAttr.CreatedById;
59
- this._CreatedAt = userGroupAttr.CreatedAt;
60
- this._UpdatedById = userGroupAttr.UpdatedById;
61
- this._UpdatedAt = userGroupAttr.UpdatedAt;
62
- }
63
- }
64
-
65
- static async init(dbTransaction: any, UserGroupId?: number) {
66
- try {
67
- const userGroup = new UserGroup();
68
- if (UserGroupId) {
69
- const userGroupAttr = await this._Repository.findOne({
70
- where: { UserGroupId },
71
- transaction: dbTransaction,
72
- });
73
- if (userGroupAttr) {
74
- userGroup.UserGroupId = userGroupAttr.UserGroupId;
75
- userGroup.UserId = userGroupAttr.UserId;
76
- userGroup.GroupCode = userGroupAttr.GroupCode;
77
- userGroup.Status = userGroupAttr.Status;
78
- userGroup.InheritGroupPrivilegeYN =
79
- userGroupAttr.InheritGroupPrivilegeYN;
80
- userGroup.InheritGroupSystemAccessYN =
81
- userGroupAttr.InheritGroupSystemAccessYN;
82
- userGroup._CreatedById = userGroupAttr.CreatedById;
83
- userGroup._CreatedAt = userGroupAttr.CreatedAt;
84
- userGroup._UpdatedById = userGroupAttr.UpdatedById;
85
- userGroup._UpdatedAt = userGroupAttr.UpdatedAt;
86
- } else {
87
- throw new ClassError(
88
- 'UserGroup',
89
- 'UserGroupErrMsg00',
90
- 'UserGroup Not Found',
91
- );
92
- }
93
- }
94
- return userGroup;
95
- } catch (error) {
96
- throw error;
97
- }
98
- }
99
-
100
- async create(
101
- loginUser: LoginUser,
102
- dbTransaction: any,
103
- group: Group,
104
- user: User,
105
- ) {
106
- //This method will create a user group record.
107
- try {
108
- // Part 1: Privilege Checking
109
- // Call loginUser.checkPrivileges() by passing:
110
- // SystemCode: "<get_from_app_config>"
111
- // PrivilegeCode: "USER_GROUP_CREATE"
112
- const systemCode =
113
- ApplicationConfig.getComponentConfigValue('system-code');
114
- const isPrivileged = await loginUser.checkPrivileges(
115
- systemCode,
116
- 'USER_GROUP_CREATE',
117
- );
118
-
119
- // If user does not have privilege to update user, throw a ClassError
120
- if (!isPrivileged) {
121
- throw new ClassError(
122
- 'UserGroup',
123
- 'UserGroupErrMsg0X',
124
- 'User does not have privilege to create user group.',
125
- );
126
- }
127
-
128
- // Part 2: Validation
129
- // Make sure group.GroupCode exists, if not throw new ClassError by passing:
130
- // Classname: "UserGroup"
131
- // MethodName: "create"
132
- // MessageCode: "UserGroupErrMsg02"
133
- // Message: "GroupCode is required."
134
- if (!group.GroupCode) {
135
- throw new ClassError(
136
- 'UserGroup',
137
- 'UserGroupErrMsg02',
138
- 'GroupCode is required.',
139
- );
140
- }
141
-
142
- // Make sure user.UserId exists, if not throw new ClassError by passing:
143
- // Classname: "UserGroup"
144
- // MethodName: "create"
145
- // MessageCode: "UserGroupErrMsg03"
146
- // Message: "UserId is required."
147
- if (!user.UserId) {
148
- throw new ClassError(
149
- 'UserGroup',
150
- 'UserGroupErrMsg03',
151
- 'UserId is required.',
152
- );
153
- }
154
-
155
- // Call UserGroup.findOne static method by passing:
156
- // loginUser
157
- // dbTransaction
158
- // GroupCode: group.GroupCode
159
- // UserId: user.UserId
160
- const userGroup = await UserGroup.findOne(
161
- dbTransaction,
162
- loginUser,
163
- group.GroupCode,
164
- user.UserId,
165
- );
166
-
167
- if (userGroup) {
168
- return userGroup;
169
- }
170
-
171
- // Part 3: Create
172
- // Set below attributes:
173
- // UserGroupId: this.createId()
174
- // UserId: Params.user.UserId
175
- // GroupCode: Params.group.GroupCode
176
- // Status: "Active"
177
- // CreatedById: loginUser.ObjectId
178
- // CreatedAt: current timestamp
179
- // UpdatedById: loginUser.ObjectId
180
- // UpdatedAt: current timestamp
181
- this.UserId = user.UserId;
182
- this.GroupCode = group.GroupCode;
183
- this.Status = 'Active';
184
- this._CreatedById = loginUser.UserId;
185
- this._CreatedAt = new Date();
186
- this._UpdatedById = loginUser.UserId;
187
- this._UpdatedAt = new Date();
188
-
189
- // Call UserGroup._Repo create() method by passing:
190
- // populate this instance attributes
191
- // dbTransaction
192
-
193
- const userData = await UserGroup._Repository.create(
194
- {
195
- UserId: this.UserId,
196
- GroupCode: this.GroupCode,
197
- Status: this.Status,
198
- CreatedById: this._CreatedById,
199
- CreatedAt: this._CreatedAt,
200
- UpdatedById: this._UpdatedById,
201
- UpdatedAt: this._UpdatedAt,
202
- InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
203
- InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
204
- },
205
- {
206
- transaction: dbTransaction,
207
- },
208
- );
209
-
210
- this.UserGroupId = userData.UserGroupId;
211
-
212
- // Part 4: Record Create UserGroup Activity
213
- // Initialise EntityValueAfter variable and set to this instance
214
- const EntityValueAfter = {
215
- UserGroupId: this.UserGroupId,
216
- UserId: this.UserId,
217
- GroupCode: this.GroupCode,
218
- Status: this.Status,
219
- CreatedById: this._CreatedById,
220
- CreatedAt: this._CreatedAt,
221
- UpdatedById: this._UpdatedById,
222
- UpdatedAt: this._UpdatedAt,
223
- InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
224
- InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
225
- };
226
- // Instantiate new activity from Activity class, call createId() method, then set:
227
- // Action: ActionEnum.Create
228
- // Description: Assign user to group.
229
- // EntityType: "UserGroup"
230
- // EntityId: this.UserGroupId
231
- // EntityValueBefore: <stringify of empty object>
232
- // EntityValueAfter: EntityValueAfter
233
- const activity = new Activity();
234
- activity.ActivityId = activity.createId();
235
- activity.Action = ActionEnum.CREATE;
236
- activity.Description = 'Assign user to group.';
237
- activity.EntityType = 'UserGroup';
238
- activity.EntityId = this.UserGroupId.toString();
239
- activity.EntityValueBefore = JSON.stringify({});
240
- activity.EntityValueAfter = JSON.stringify(EntityValueAfter);
241
- // Call new activity create method by passing:
242
- // dbTransaction
243
- // userId: loginUser.ObjectId
244
- // return this instance
245
- await activity.create(loginUser.ObjectId, dbTransaction);
246
-
247
- return this;
248
- } catch (error) {
249
- throw error;
250
- }
251
- }
252
-
253
- public static async findOne(
254
- dbTransaction: any,
255
- loginUser: LoginUser,
256
- GroupCode: string,
257
- UserId: number,
258
- ): Promise<UserGroup> {
259
- try {
260
- // Part 1: Privilege Checking
261
- // Call loginUser.checkPrivileges() by passing:
262
- // SystemCode: "<get_from_app_config>"
263
- // PrivilegeCode: "USER_GROUP_VIEW"
264
- const systemCode =
265
- ApplicationConfig.getComponentConfigValue('system-code');
266
- const isPrivileged = await loginUser.checkPrivileges(
267
- systemCode,
268
- 'USER_GROUP_VIEW',
269
- );
270
-
271
- // If user does not have privilege to view user group, throw a ClassError
272
- if (!isPrivileged) {
273
- throw new ClassError(
274
- 'UserGroup',
275
- 'UserGroupErrMsg0X',
276
- 'User does not have privilege to view user group.',
277
- );
278
- }
279
-
280
- // Part 2: Retrieve Record
281
- // Call UserGroup._Repo findOne method by passing:
282
- // where:
283
- // [Op.AND]:
284
- // UserId: Params.UserId
285
- // GroupCode: Params.GroupCode
286
- // dbTransaction
287
- const userGroupAttr = await UserGroup._Repository.findOne({
288
- where: {
289
- UserId,
290
- GroupCode,
291
- },
292
- transaction: dbTransaction,
293
- });
294
- // If record exists, instantiate UserGroup by calling the private constructor and passing the attributes. Then, returns the instance
295
- if (userGroupAttr) {
296
- return new UserGroup(userGroupAttr.get({ plain: true }));
297
- }
298
- // If record not exists, return null.
299
- return null;
300
- } catch (error) {
301
- throw error;
302
- }
303
- }
304
-
305
- public static async getUser(
306
- dbTransaction: any,
307
- loginUser: LoginUser,
308
- GroupCode: string,
309
- ) {
310
- try {
311
- // Part 1: Privilege Checking
312
- // Call loginUser.checkPrivileges() by passing:
313
- // SystemCode: "<get_from_app_config>"
314
- // PrivilegeCode: "USER_GROUP_VIEW"
315
- const systemCode =
316
- ApplicationConfig.getComponentConfigValue('system-code');
317
- const isPrivileged = await loginUser.checkPrivileges(
318
- systemCode,
319
- 'USER_GROUP_VIEW',
320
- );
321
-
322
- // If user does not have privilege to view user group, throw a ClassError
323
- if (!isPrivileged) {
324
- throw new ClassError(
325
- 'UserGroup',
326
- 'UserGroupErrMsg0X',
327
- 'User does not have privilege to view user group.',
328
- );
329
- }
330
-
331
- // Part 2: Retrieve Record
332
- // Call UserGroup._Repo findAll method by passing:
333
- // where:
334
- // GroupCode: Params.GroupCode
335
- // dbTransaction
336
- const userGroup = await UserGroup._Repository.findAll({
337
- where: {
338
- GroupCode,
339
- },
340
- include: [
341
- {
342
- model: UserModel,
343
- as: 'User',
344
- attributes: ['UserId', 'FullName', 'Email'],
345
- },
346
- ],
347
- transaction: dbTransaction,
348
- });
349
- // If record exists, instantiate UserGroup by calling the private constructor and passing the attributes. Then, returns the instance
350
- return userGroup;
351
- // If record not exists, return null.
352
- return null;
353
- } catch (error) {
354
- throw error;
355
- }
356
- }
357
-
358
- static async findAllInheritedSystemAccesses(
359
- UserId: number,
360
- loginUser: User,
361
- dbTransaction: any,
362
- ): Promise<
363
- {
364
- UserGroupId: number;
365
- GroupCode: string;
366
- GroupName: string;
367
- InheritGroupSystemAccessYN: string;
368
- CreatedAt: Date;
369
- UpdatedAt: Date;
370
- Systems: {
371
- SystemCode: string;
372
- SystemName: string;
373
- AccessStatus: string;
374
- CreatedAt: Date;
375
- UpdatedAt: Date;
376
- }[];
377
- }[]
378
- > {
379
- try {
380
- // Part 1: Privilege Checking
381
- // Call loginUser.checkPrivileges() to ensure the user has permission to retrieve system access information.
382
- // SystemCode: Retrieve from app config.
383
- // PrivilegeCode: 'USER_SYSTEM_ACCESS_LIST'.
384
- // If the privilege check fails, throw an error with a 403 Forbidden status.
385
- const systemCode =
386
- ApplicationConfig.getComponentConfigValue('system-code');
387
- const isPrivileged = await loginUser.checkPrivileges(
388
- systemCode,
389
- 'USER_SYSTEM_ACCESS_LIST',
390
- );
391
- if (!isPrivileged) {
392
- throw new ClassError(
393
- 'UserGroup',
394
- 'UserGroupErrMsg0X',
395
- 'User does not have privilege to view user system access.',
396
- 'findAllInheritedSystemAccesses',
397
- 403,
398
- );
399
- }
400
- // Part 2: Retrieve User Groups
401
- // Query the sso_UserGroup table to find all active groups the user belongs to.
402
- // Join with the sso_Group table to retrieve the GroupCode, GroupName, and InheritGroupSystemAccessYNfields.
403
- // Ensure that the value of InheritGroupSystemAccessYN is explicitly 'Y' or 'N' for each group.
404
- // If InheritGroupSystemAccessYN is not set, default it to 'N'.
405
- // Return only active groups (based on Status field).
406
- // The query should return the following fields for each group:
407
- // GroupCode
408
- // GroupName
409
- // InheritGroupSystemAccessYN
410
-
411
- const userGroups = await UserGroup._Repository.findAll({
412
- where: {
413
- UserId,
414
- Status: 'Active',
415
- },
416
- include: [
417
- {
418
- model: GroupModel,
419
- required: true,
420
- where: {
421
- Status: 'Active',
422
- },
423
- include: [
424
- {
425
- model: GroupSystemAccessModel,
426
- where: {
427
- Status: 'Active',
428
- },
429
- include: [
430
- {
431
- model: SystemModel,
432
- },
433
- ],
434
- },
435
- ],
436
- },
437
- ],
438
- transaction: dbTransaction,
439
- });
440
- const result: {
441
- UserGroupId: number;
442
- GroupCode: string;
443
- GroupName: string;
444
- InheritGroupSystemAccessYN: string;
445
- CreatedAt: Date;
446
- UpdatedAt: Date;
447
- Systems: {
448
- SystemCode: string;
449
- SystemName: string;
450
- AccessStatus: string;
451
- CreatedAt: Date;
452
- UpdatedAt: Date;
453
- }[];
454
- }[] = [];
455
- for (const userGroup of userGroups) {
456
- // Part 3: Retrieve System Access for Groups with Inheritance
457
- // For each group where InheritGroupSystemAccessYN = 'Y', query the sso_GroupSystemAccess table to retrieve system access details.
458
- // Join with the sso_System table to fetch system details (SystemName, SystemCode).
459
- // Ensure only active system accesses (AccessStatus = 'Active') are included.
460
- // For each system access, retrieve the following fields:
461
- // SystemName (from sso_System.Name)
462
- // SystemCode (from sso_System.SystemCode)
463
- // AccessStatus (from sso_GroupSystemAccess.Status)
464
- // CreatedAt (from sso_GroupSystemAccess.CreatedAt)
465
- // UpdatedAt (from sso_GroupSystemAccess.UpdatedAt)
466
- // Part 4: Handling Non-Inherited Groups
467
- // For groups where InheritGroupSystemAccessYN = 'N', return the group details without system access records.
468
- // Set the Systems field to an empty array or null to indicate no inherited access for those groups.
469
- // Part 5: Grouping Results
470
- // Group the results by GroupCode and GroupName.
471
- // For each group, create an object with the following structure:
472
- // GroupCode: Code of the group.
473
- // GroupName: Name of the group.
474
- // InheritGroupSystemAccessYN: 'Y' or 'N', indicating whether the user inherits system access from the group.
475
- // Systems: An array of system access objects (for groups where InheritGroupSystemAccessYN = 'Y'), each including:
476
- // SystemName
477
- // SystemCode
478
- // AccessStatus
479
- // CreatedAt
480
- // UpdatedAt
481
- // For groups where InheritGroupSystemAccessYN = 'N', Systems will be an empty array.
482
- const groupData = {
483
- UserGroupId: userGroup.UserGroupId,
484
- GroupCode: userGroup.GroupCode,
485
- GroupName: userGroup.Group.Name,
486
- InheritGroupSystemAccessYN: userGroup.InheritGroupSystemAccessYN,
487
- CreatedAt: userGroup.CreatedAt,
488
- UpdatedAt: userGroup.UpdatedAt,
489
- Systems: [],
490
- };
491
-
492
- if (userGroup.InheritGroupSystemAccessYN === 'Y') {
493
- groupData.Systems = userGroup.Group.GroupSystemAccesses.map(
494
- (groupSystemAccess) => {
495
- return {
496
- SystemCode: groupSystemAccess.System.SystemCode,
497
- SystemName: groupSystemAccess.System.Name,
498
- AccessStatus: groupSystemAccess.Status,
499
- CreatedAt: groupSystemAccess.CreatedAt,
500
- UpdatedAt: groupSystemAccess.UpdatedAt,
501
- };
502
- },
503
- );
504
- }
505
-
506
- result.push(groupData);
507
- }
508
-
509
- // Part 6: Return Grouped Data
510
- // Return the array of grouped system accesses for the user's groups, including both inherited ('Y') and non-inherited ('N') system accesses.
511
- return result;
512
- } catch (error) {
513
- throw error;
514
- }
515
- }
516
-
517
- public async update(
518
- loginUser: LoginUser,
519
- dbTransaction: Transaction,
520
- UpdatedProperties: {
521
- InheritGroupPrivilegeYN?: string;
522
- InheritGroupSystemAccessYN?: string;
523
- },
524
- ): Promise<UserGroup> {
525
- try {
526
- // Part 1: Privilege Checking
527
- // Call loginUser.checkPrivileges() to ensure the user has permission to retrieve system access information.
528
- // SystemCode: Retrieve from app config.
529
- // PrivilegeCode: 'USER_GROUP_UPDATE'.
530
- const systemCode =
531
- ApplicationConfig.getComponentConfigValue('system-code');
532
- const isPrivileged = await loginUser.checkPrivileges(
533
- systemCode,
534
- 'USER_GROUP_UPDATE',
535
- );
536
- // If the privilege check fails, throw an error with a 403 Forbidden status.
537
- if (!isPrivileged) {
538
- throw new ClassError(
539
- 'UserGroup',
540
- 'UserGroupErrMsg0X',
541
- 'User does not have privilege to update user group.',
542
- 'update',
543
- 403,
544
- );
545
- }
546
- // Part 2: Validation
547
- // Check to make sure that at least one of the UpdatedProperties is exist if not throw error.
548
- if (
549
- !UpdatedProperties.InheritGroupPrivilegeYN &&
550
- !UpdatedProperties.InheritGroupSystemAccessYN
551
- ) {
552
- throw new ClassError(
553
- 'UserGroup',
554
- 'UserGroupErrMsg04',
555
- 'At least one of the properties to update is required.',
556
- 'update',
557
- 400,
558
- );
559
- }
560
- // Part 3: Update User Group
561
- // Call the UserGroup._Repo.update() method to perform the update operation, passing:
562
- // InheritGroupPrivilegeYN (if exist): updatedProperties.InheritGroupPrivilegeYN
563
- // InheritGroupSystemAccessYN (if exist): updatedProperties.InheritGroupSystemAccessYN
564
- // UpdatedById: loginUser.UserId (to indicate who updated the record).
565
- // UpdatedAt: Set to the current date and time.
566
- // dbTransaction: The database transaction instance.
567
- const entityValueBefore = {
568
- UserGroupId: this.UserGroupId,
569
- UserId: this.UserId,
570
- GroupCode: this.GroupCode,
571
- Status: this.Status,
572
- CreatedById: this._CreatedById,
573
- CreatedAt: this._CreatedAt,
574
- UpdatedById: this._UpdatedById,
575
- UpdatedAt: this._UpdatedAt,
576
- InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
577
- InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
578
- };
579
-
580
- this._UpdatedById = loginUser.UserId;
581
- this._UpdatedAt = new Date();
582
- if (UpdatedProperties.InheritGroupPrivilegeYN) {
583
- this.InheritGroupPrivilegeYN =
584
- UpdatedProperties.InheritGroupPrivilegeYN;
585
- }
586
- if (UpdatedProperties.InheritGroupSystemAccessYN) {
587
- this.InheritGroupSystemAccessYN =
588
- UpdatedProperties.InheritGroupSystemAccessYN;
589
- }
590
-
591
- await UserGroup._Repository.update(
592
- {
593
- InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
594
- InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
595
- UpdatedById: this._UpdatedById,
596
- UpdatedAt: this._UpdatedAt,
597
- },
598
- {
599
- where: {
600
- UserGroupId: this.UserGroupId,
601
- },
602
- transaction: dbTransaction,
603
- },
604
- );
605
-
606
- // Part 2: Record Activity History
607
- // Initialize a variable entityValueBefore to store the current state of the record before the update.
608
- const entityValueAfter = {
609
- UserGroupId: this.UserGroupId,
610
- UserId: this.UserId,
611
- GroupCode: this.GroupCode,
612
- Status: this.Status,
613
- CreatedById: this._CreatedById,
614
- CreatedAt: this._CreatedAt,
615
- UpdatedById: this._UpdatedById,
616
- UpdatedAt: this._UpdatedAt,
617
- InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
618
- InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
619
- };
620
- // Create an instance of the Activity class and set the following properties:
621
- // ActivityId: Call activity.createId().
622
- // Action: Set to ActionEnum.Update.
623
- // Description: Set to Update User Group.
624
- // EntityType: Set to UserGroup.
625
- // EntityId: Use the ID of the updated record.
626
- // EntityValueBefore: Stringify entityValueBefore to capture the state before the update.
627
- // EntityValueAfter: Stringify the updated record to capture the new state after the update.
628
- const activity = new Activity();
629
- activity.ActivityId = activity.createId();
630
- activity.Action = ActionEnum.UPDATE;
631
- activity.Description = 'Update User Group';
632
- activity.EntityType = 'UserGroup';
633
- activity.EntityId = this.UserGroupId.toString();
634
- activity.EntityValueBefore = JSON.stringify(entityValueBefore);
635
- activity.EntityValueAfter = JSON.stringify(entityValueAfter);
636
-
637
- // Call the activity create a method with the following parameters:
638
- // dbTransaction
639
- // userId: loginUser.UserId
640
- // Part 3: Return Updated Record
641
-
642
- await activity.create(loginUser.ObjectId, dbTransaction);
643
- // Retrieve the updated user group record from the database or return the updated instance as needed.
644
- return this;
645
- } catch (error) {
646
- throw error;
647
- }
648
- }
649
-
650
- public static async isUserMemberOfGroup(
651
- dbTransaction: any,
652
- loginUser: LoginUser,
653
- UserId: number,
654
- GroupCode: string,
655
- ): Promise<boolean> {
656
- try {
657
- // Part 1: Privilege Checking
658
- // Call loginUser.checkPrivileges() to ensure the user has permission to retrieve system access information.
659
- // SystemCode: Retrieve from app config.
660
- // PrivilegeCode: 'USER_GROUP_VIEW'.
661
- const systemCode =
662
- ApplicationConfig.getComponentConfigValue('system-code');
663
- const isPrivileged = await loginUser.checkPrivileges(
664
- systemCode,
665
- 'USER_GROUP_VIEW',
666
- );
667
- // If the privilege check fails, throw an error with a 403 Forbidden status.
668
- if (!isPrivileged) {
669
- throw new ClassError(
670
- 'UserGroup',
671
- 'UserGroupErrMsg0X',
672
- 'User does not have privilege to view user group.',
673
- 'isUserMemberOfGroup',
674
- 403,
675
- );
676
- }
677
- // Part 2: Retrieve User Group
678
- // Query the sso_UserGroup table to find the user group record with the given UserId and GroupCode.
679
- // If the record exists, return true; otherwise, return false.
680
- const userGroup = await UserGroup.findOne(
681
- dbTransaction,
682
- loginUser,
683
- GroupCode,
684
- UserId,
685
- );
686
- return !!userGroup;
687
- } catch (error) {
688
- throw error;
689
- }
690
- }
691
-
692
- public async delete(
693
- loginUser: LoginUser,
694
- dbTransaction: Transaction,
695
- ): Promise<void> {
696
- try {
697
- // Part 1: Privilege Checking
698
- // Call loginUser.checkPrivileges() to ensure the user has permission to delete user group records.
699
- // SystemCode: Retrieve from app config.
700
- // PrivilegeCode: 'USER_GROUP_DELETE'.
701
- const systemCode =
702
- ApplicationConfig.getComponentConfigValue('system-code');
703
- const isPrivileged = await loginUser.checkPrivileges(
704
- systemCode,
705
- 'USER_GROUP_DELETE',
706
- );
707
- // If the privilege check fails, throw an error with a 403 Forbidden status.
708
- if (!isPrivileged) {
709
- throw new ClassError(
710
- 'UserGroup',
711
- 'UserGroupErrMsg0X',
712
- 'User does not have privilege to delete user group.',
713
- 'delete',
714
- 403,
715
- );
716
- }
717
- // Part 2: Delete User Group
718
- // Call the UserGroup._Repo.destroy() method to delete the user group record with the given UserGroupId.
719
- // Pass the dbTransaction parameter to ensure the operation is part of the current transaction.
720
- await UserGroup._Repository.delete({
721
- where: {
722
- UserGroupId: this.UserGroupId,
723
- },
724
- transaction: dbTransaction,
725
- });
726
- // Part 3: Record Activity History
727
- // Initialize a variable entityValueBefore to store the current state of the record before the update.
728
- const entityValueBefore = {
729
- UserGroupId: this.UserGroupId,
730
- UserId: this.UserId,
731
- GroupCode: this.GroupCode,
732
- Status: this.Status,
733
- CreatedById: this._CreatedById,
734
- CreatedAt: this._CreatedAt,
735
- UpdatedById: this._UpdatedById,
736
- UpdatedAt: this._UpdatedAt,
737
- InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
738
- InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
739
- };
740
- // Create an instance of the Activity class and set the following properties:
741
- // ActivityId: Call activity.createId().
742
- // Action: Set to ActionEnum.Delete.
743
- // Description: Set to Delete User Group.
744
- // EntityType: Set to UserGroup.
745
- // EntityId: Use the ID of the deleted record.
746
- // EntityValueBefore: Stringify entityValueBefore to capture the state before the delete.
747
- // EntityValueAfter: Set to an empty string to indicate the record has been deleted.
748
- const activity = new Activity();
749
- activity.ActivityId = activity.createId();
750
- activity.Action = ActionEnum.DELETE;
751
- activity.Description = `Delete User Group ${this.UserGroupId}`;
752
- activity.EntityType = 'UserGroup';
753
- activity.EntityId = this.UserGroupId.toString();
754
- activity.EntityValueBefore = JSON.stringify(entityValueBefore);
755
- activity.EntityValueAfter = JSON.stringify({});
756
- // Call the activity create method with the following parameters:
757
- // dbTransaction
758
- // userId: loginUser.UserId
759
- await activity.create(loginUser.ObjectId, dbTransaction);
760
- } catch (error) {
761
- throw error;
762
- }
763
- }
764
- }
1
+ import { ClassError, ObjectBase } from '@tomei/general';
2
+ import { UserGroupRepository } from './user-group.repository';
3
+ import { IUserGroupAttr } from '../../interfaces/user-group.interface';
4
+ import { LoginUser, User } from '../../components/login-user';
5
+ import { Group } from '../../components/group';
6
+ import { ApplicationConfig } from '@tomei/config';
7
+ import { ActionEnum, Activity } from '@tomei/activity-history';
8
+ import GroupSystemAccessModel from '../../models/group-system-access.entity';
9
+ import GroupModel from '../../models/group.entity';
10
+ import SystemModel from '../../models/system.entity';
11
+ import UserModel from '../../models/user.entity';
12
+ import { Transaction } from 'sequelize';
13
+
14
+ export class UserGroup extends ObjectBase {
15
+ ObjectType = 'UserGroup';
16
+ TableName = 'sso_UserGroup';
17
+ ObjectName: string;
18
+ ObjectId: string;
19
+ UserGroupId: number;
20
+ UserId: number;
21
+ GroupCode: string;
22
+ InheritGroupPrivilegeYN = 'Y';
23
+ InheritGroupSystemAccessYN = 'Y';
24
+ Status: string;
25
+ private _CreatedAt: Date;
26
+ private _UpdatedAt: Date;
27
+ private _CreatedById: number;
28
+ private _UpdatedById: number;
29
+
30
+ protected static _Repository = new UserGroupRepository();
31
+
32
+ get CreatedAt() {
33
+ return this._CreatedAt;
34
+ }
35
+
36
+ get UpdatedAt() {
37
+ return this._UpdatedAt;
38
+ }
39
+
40
+ get CreatedById() {
41
+ return this._CreatedById;
42
+ }
43
+
44
+ get UpdatedById() {
45
+ return this._UpdatedById;
46
+ }
47
+
48
+ private constructor(userGroupAttr?: IUserGroupAttr) {
49
+ super();
50
+ if (userGroupAttr) {
51
+ this.UserGroupId = userGroupAttr.UserGroupId;
52
+ this.UserId = userGroupAttr.UserId;
53
+ this.GroupCode = userGroupAttr.GroupCode;
54
+ this.Status = userGroupAttr.Status;
55
+ this.InheritGroupPrivilegeYN = userGroupAttr.InheritGroupPrivilegeYN;
56
+ this.InheritGroupSystemAccessYN =
57
+ userGroupAttr.InheritGroupSystemAccessYN;
58
+ this._CreatedById = userGroupAttr.CreatedById;
59
+ this._CreatedAt = userGroupAttr.CreatedAt;
60
+ this._UpdatedById = userGroupAttr.UpdatedById;
61
+ this._UpdatedAt = userGroupAttr.UpdatedAt;
62
+ }
63
+ }
64
+
65
+ static async init(dbTransaction: any, UserGroupId?: number) {
66
+ try {
67
+ const userGroup = new UserGroup();
68
+ if (UserGroupId) {
69
+ const userGroupAttr = await this._Repository.findOne({
70
+ where: { UserGroupId },
71
+ transaction: dbTransaction,
72
+ });
73
+ if (userGroupAttr) {
74
+ userGroup.UserGroupId = userGroupAttr.UserGroupId;
75
+ userGroup.UserId = userGroupAttr.UserId;
76
+ userGroup.GroupCode = userGroupAttr.GroupCode;
77
+ userGroup.Status = userGroupAttr.Status;
78
+ userGroup.InheritGroupPrivilegeYN =
79
+ userGroupAttr.InheritGroupPrivilegeYN;
80
+ userGroup.InheritGroupSystemAccessYN =
81
+ userGroupAttr.InheritGroupSystemAccessYN;
82
+ userGroup._CreatedById = userGroupAttr.CreatedById;
83
+ userGroup._CreatedAt = userGroupAttr.CreatedAt;
84
+ userGroup._UpdatedById = userGroupAttr.UpdatedById;
85
+ userGroup._UpdatedAt = userGroupAttr.UpdatedAt;
86
+ } else {
87
+ throw new ClassError(
88
+ 'UserGroup',
89
+ 'UserGroupErrMsg00',
90
+ 'UserGroup Not Found',
91
+ );
92
+ }
93
+ }
94
+ return userGroup;
95
+ } catch (error) {
96
+ throw error;
97
+ }
98
+ }
99
+
100
+ async create(
101
+ loginUser: LoginUser,
102
+ dbTransaction: any,
103
+ group: Group,
104
+ user: User,
105
+ ) {
106
+ //This method will create a user group record.
107
+ try {
108
+ // Part 1: Privilege Checking
109
+ // Call loginUser.checkPrivileges() by passing:
110
+ // SystemCode: "<get_from_app_config>"
111
+ // PrivilegeCode: "USER_GROUP_CREATE"
112
+ const systemCode =
113
+ ApplicationConfig.getComponentConfigValue('system-code');
114
+ const isPrivileged = await loginUser.checkPrivileges(
115
+ systemCode,
116
+ 'USER_GROUP_CREATE',
117
+ );
118
+
119
+ // If user does not have privilege to update user, throw a ClassError
120
+ if (!isPrivileged) {
121
+ throw new ClassError(
122
+ 'UserGroup',
123
+ 'UserGroupErrMsg0X',
124
+ 'User does not have privilege to create user group.',
125
+ );
126
+ }
127
+
128
+ // Part 2: Validation
129
+ // Make sure group.GroupCode exists, if not throw new ClassError by passing:
130
+ // Classname: "UserGroup"
131
+ // MethodName: "create"
132
+ // MessageCode: "UserGroupErrMsg02"
133
+ // Message: "GroupCode is required."
134
+ if (!group.GroupCode) {
135
+ throw new ClassError(
136
+ 'UserGroup',
137
+ 'UserGroupErrMsg02',
138
+ 'GroupCode is required.',
139
+ );
140
+ }
141
+
142
+ // Make sure user.UserId exists, if not throw new ClassError by passing:
143
+ // Classname: "UserGroup"
144
+ // MethodName: "create"
145
+ // MessageCode: "UserGroupErrMsg03"
146
+ // Message: "UserId is required."
147
+ if (!user.UserId) {
148
+ throw new ClassError(
149
+ 'UserGroup',
150
+ 'UserGroupErrMsg03',
151
+ 'UserId is required.',
152
+ );
153
+ }
154
+
155
+ // Call UserGroup.findOne static method by passing:
156
+ // loginUser
157
+ // dbTransaction
158
+ // GroupCode: group.GroupCode
159
+ // UserId: user.UserId
160
+ const userGroup = await UserGroup.findOne(
161
+ dbTransaction,
162
+ loginUser,
163
+ group.GroupCode,
164
+ user.UserId,
165
+ );
166
+
167
+ if (userGroup) {
168
+ return userGroup;
169
+ }
170
+
171
+ // Part 3: Create
172
+ // Set below attributes:
173
+ // UserGroupId: this.createId()
174
+ // UserId: Params.user.UserId
175
+ // GroupCode: Params.group.GroupCode
176
+ // Status: "Active"
177
+ // CreatedById: loginUser.ObjectId
178
+ // CreatedAt: current timestamp
179
+ // UpdatedById: loginUser.ObjectId
180
+ // UpdatedAt: current timestamp
181
+ this.UserId = user.UserId;
182
+ this.GroupCode = group.GroupCode;
183
+ this.Status = 'Active';
184
+ this._CreatedById = loginUser.UserId;
185
+ this._CreatedAt = new Date();
186
+ this._UpdatedById = loginUser.UserId;
187
+ this._UpdatedAt = new Date();
188
+
189
+ // Call UserGroup._Repo create() method by passing:
190
+ // populate this instance attributes
191
+ // dbTransaction
192
+
193
+ const userData = await UserGroup._Repository.create(
194
+ {
195
+ UserId: this.UserId,
196
+ GroupCode: this.GroupCode,
197
+ Status: this.Status,
198
+ CreatedById: this._CreatedById,
199
+ CreatedAt: this._CreatedAt,
200
+ UpdatedById: this._UpdatedById,
201
+ UpdatedAt: this._UpdatedAt,
202
+ InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
203
+ InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
204
+ },
205
+ {
206
+ transaction: dbTransaction,
207
+ },
208
+ );
209
+
210
+ this.UserGroupId = userData.UserGroupId;
211
+
212
+ // Part 4: Record Create UserGroup Activity
213
+ // Initialise EntityValueAfter variable and set to this instance
214
+ const EntityValueAfter = {
215
+ UserGroupId: this.UserGroupId,
216
+ UserId: this.UserId,
217
+ GroupCode: this.GroupCode,
218
+ Status: this.Status,
219
+ CreatedById: this._CreatedById,
220
+ CreatedAt: this._CreatedAt,
221
+ UpdatedById: this._UpdatedById,
222
+ UpdatedAt: this._UpdatedAt,
223
+ InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
224
+ InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
225
+ };
226
+ // Instantiate new activity from Activity class, call createId() method, then set:
227
+ // Action: ActionEnum.Create
228
+ // Description: Assign user to group.
229
+ // EntityType: "UserGroup"
230
+ // EntityId: this.UserGroupId
231
+ // EntityValueBefore: <stringify of empty object>
232
+ // EntityValueAfter: EntityValueAfter
233
+ const activity = new Activity();
234
+ activity.ActivityId = activity.createId();
235
+ activity.Action = ActionEnum.CREATE;
236
+ activity.Description = 'Assign user to group.';
237
+ activity.EntityType = 'UserGroup';
238
+ activity.EntityId = this.UserGroupId.toString();
239
+ activity.EntityValueBefore = JSON.stringify({});
240
+ activity.EntityValueAfter = JSON.stringify(EntityValueAfter);
241
+ // Call new activity create method by passing:
242
+ // dbTransaction
243
+ // userId: loginUser.ObjectId
244
+ // return this instance
245
+ await activity.create(loginUser.ObjectId, dbTransaction);
246
+
247
+ return this;
248
+ } catch (error) {
249
+ throw error;
250
+ }
251
+ }
252
+
253
+ public static async findOne(
254
+ dbTransaction: any,
255
+ loginUser: LoginUser,
256
+ GroupCode: string,
257
+ UserId: number,
258
+ ): Promise<UserGroup> {
259
+ try {
260
+ // Part 1: Privilege Checking
261
+ // Call loginUser.checkPrivileges() by passing:
262
+ // SystemCode: "<get_from_app_config>"
263
+ // PrivilegeCode: "USER_GROUP_VIEW"
264
+ const systemCode =
265
+ ApplicationConfig.getComponentConfigValue('system-code');
266
+ const isPrivileged = await loginUser.checkPrivileges(
267
+ systemCode,
268
+ 'USER_GROUP_VIEW',
269
+ );
270
+
271
+ // If user does not have privilege to view user group, throw a ClassError
272
+ if (!isPrivileged) {
273
+ throw new ClassError(
274
+ 'UserGroup',
275
+ 'UserGroupErrMsg0X',
276
+ 'User does not have privilege to view user group.',
277
+ );
278
+ }
279
+
280
+ // Part 2: Retrieve Record
281
+ // Call UserGroup._Repo findOne method by passing:
282
+ // where:
283
+ // [Op.AND]:
284
+ // UserId: Params.UserId
285
+ // GroupCode: Params.GroupCode
286
+ // dbTransaction
287
+ const userGroupAttr = await UserGroup._Repository.findOne({
288
+ where: {
289
+ UserId,
290
+ GroupCode,
291
+ },
292
+ transaction: dbTransaction,
293
+ });
294
+ // If record exists, instantiate UserGroup by calling the private constructor and passing the attributes. Then, returns the instance
295
+ if (userGroupAttr) {
296
+ return new UserGroup(userGroupAttr.get({ plain: true }));
297
+ }
298
+ // If record not exists, return null.
299
+ return null;
300
+ } catch (error) {
301
+ throw error;
302
+ }
303
+ }
304
+
305
+ public static async getUser(
306
+ dbTransaction: any,
307
+ loginUser: LoginUser,
308
+ GroupCode: string,
309
+ ) {
310
+ try {
311
+ // Part 1: Privilege Checking
312
+ // Call loginUser.checkPrivileges() by passing:
313
+ // SystemCode: "<get_from_app_config>"
314
+ // PrivilegeCode: "USER_GROUP_VIEW"
315
+ const systemCode =
316
+ ApplicationConfig.getComponentConfigValue('system-code');
317
+ const isPrivileged = await loginUser.checkPrivileges(
318
+ systemCode,
319
+ 'USER_GROUP_VIEW',
320
+ );
321
+
322
+ // If user does not have privilege to view user group, throw a ClassError
323
+ if (!isPrivileged) {
324
+ throw new ClassError(
325
+ 'UserGroup',
326
+ 'UserGroupErrMsg0X',
327
+ 'User does not have privilege to view user group.',
328
+ );
329
+ }
330
+
331
+ // Part 2: Retrieve Record
332
+ // Call UserGroup._Repo findAll method by passing:
333
+ // where:
334
+ // GroupCode: Params.GroupCode
335
+ // dbTransaction
336
+ const userGroup = await UserGroup._Repository.findAll({
337
+ where: {
338
+ GroupCode,
339
+ },
340
+ include: [
341
+ {
342
+ model: UserModel,
343
+ as: 'User',
344
+ attributes: ['UserId', 'FullName', 'Email'],
345
+ },
346
+ ],
347
+ transaction: dbTransaction,
348
+ });
349
+ // If record exists, instantiate UserGroup by calling the private constructor and passing the attributes. Then, returns the instance
350
+ return userGroup;
351
+ // If record not exists, return null.
352
+ return null;
353
+ } catch (error) {
354
+ throw error;
355
+ }
356
+ }
357
+
358
+ static async findAllInheritedSystemAccesses(
359
+ UserId: number,
360
+ loginUser: User,
361
+ dbTransaction: any,
362
+ ): Promise<
363
+ {
364
+ UserGroupId: number;
365
+ GroupCode: string;
366
+ GroupName: string;
367
+ InheritGroupSystemAccessYN: string;
368
+ CreatedAt: Date;
369
+ UpdatedAt: Date;
370
+ Systems: {
371
+ SystemCode: string;
372
+ SystemName: string;
373
+ AccessStatus: string;
374
+ CreatedAt: Date;
375
+ UpdatedAt: Date;
376
+ }[];
377
+ }[]
378
+ > {
379
+ try {
380
+ // Part 1: Privilege Checking
381
+ // Call loginUser.checkPrivileges() to ensure the user has permission to retrieve system access information.
382
+ // SystemCode: Retrieve from app config.
383
+ // PrivilegeCode: 'USER_SYSTEM_ACCESS_LIST'.
384
+ // If the privilege check fails, throw an error with a 403 Forbidden status.
385
+ const systemCode =
386
+ ApplicationConfig.getComponentConfigValue('system-code');
387
+ const isPrivileged = await loginUser.checkPrivileges(
388
+ systemCode,
389
+ 'USER_SYSTEM_ACCESS_LIST',
390
+ );
391
+ if (!isPrivileged) {
392
+ throw new ClassError(
393
+ 'UserGroup',
394
+ 'UserGroupErrMsg0X',
395
+ 'User does not have privilege to view user system access.',
396
+ 'findAllInheritedSystemAccesses',
397
+ 403,
398
+ );
399
+ }
400
+ // Part 2: Retrieve User Groups
401
+ // Query the sso_UserGroup table to find all active groups the user belongs to.
402
+ // Join with the sso_Group table to retrieve the GroupCode, GroupName, and InheritGroupSystemAccessYNfields.
403
+ // Ensure that the value of InheritGroupSystemAccessYN is explicitly 'Y' or 'N' for each group.
404
+ // If InheritGroupSystemAccessYN is not set, default it to 'N'.
405
+ // Return only active groups (based on Status field).
406
+ // The query should return the following fields for each group:
407
+ // GroupCode
408
+ // GroupName
409
+ // InheritGroupSystemAccessYN
410
+
411
+ const userGroups = await UserGroup._Repository.findAll({
412
+ where: {
413
+ UserId,
414
+ Status: 'Active',
415
+ },
416
+ include: [
417
+ {
418
+ model: GroupModel,
419
+ required: true,
420
+ where: {
421
+ Status: 'Active',
422
+ },
423
+ include: [
424
+ {
425
+ model: GroupSystemAccessModel,
426
+ where: {
427
+ Status: 'Active',
428
+ },
429
+ include: [
430
+ {
431
+ model: SystemModel,
432
+ },
433
+ ],
434
+ },
435
+ ],
436
+ },
437
+ ],
438
+ transaction: dbTransaction,
439
+ });
440
+ const result: {
441
+ UserGroupId: number;
442
+ GroupCode: string;
443
+ GroupName: string;
444
+ InheritGroupSystemAccessYN: string;
445
+ CreatedAt: Date;
446
+ UpdatedAt: Date;
447
+ Systems: {
448
+ SystemCode: string;
449
+ SystemName: string;
450
+ AccessStatus: string;
451
+ CreatedAt: Date;
452
+ UpdatedAt: Date;
453
+ }[];
454
+ }[] = [];
455
+ for (const userGroup of userGroups) {
456
+ // Part 3: Retrieve System Access for Groups with Inheritance
457
+ // For each group where InheritGroupSystemAccessYN = 'Y', query the sso_GroupSystemAccess table to retrieve system access details.
458
+ // Join with the sso_System table to fetch system details (SystemName, SystemCode).
459
+ // Ensure only active system accesses (AccessStatus = 'Active') are included.
460
+ // For each system access, retrieve the following fields:
461
+ // SystemName (from sso_System.Name)
462
+ // SystemCode (from sso_System.SystemCode)
463
+ // AccessStatus (from sso_GroupSystemAccess.Status)
464
+ // CreatedAt (from sso_GroupSystemAccess.CreatedAt)
465
+ // UpdatedAt (from sso_GroupSystemAccess.UpdatedAt)
466
+ // Part 4: Handling Non-Inherited Groups
467
+ // For groups where InheritGroupSystemAccessYN = 'N', return the group details without system access records.
468
+ // Set the Systems field to an empty array or null to indicate no inherited access for those groups.
469
+ // Part 5: Grouping Results
470
+ // Group the results by GroupCode and GroupName.
471
+ // For each group, create an object with the following structure:
472
+ // GroupCode: Code of the group.
473
+ // GroupName: Name of the group.
474
+ // InheritGroupSystemAccessYN: 'Y' or 'N', indicating whether the user inherits system access from the group.
475
+ // Systems: An array of system access objects (for groups where InheritGroupSystemAccessYN = 'Y'), each including:
476
+ // SystemName
477
+ // SystemCode
478
+ // AccessStatus
479
+ // CreatedAt
480
+ // UpdatedAt
481
+ // For groups where InheritGroupSystemAccessYN = 'N', Systems will be an empty array.
482
+ const groupData = {
483
+ UserGroupId: userGroup.UserGroupId,
484
+ GroupCode: userGroup.GroupCode,
485
+ GroupName: userGroup.Group.Name,
486
+ InheritGroupSystemAccessYN: userGroup.InheritGroupSystemAccessYN,
487
+ CreatedAt: userGroup.CreatedAt,
488
+ UpdatedAt: userGroup.UpdatedAt,
489
+ Systems: [],
490
+ };
491
+
492
+ if (userGroup.InheritGroupSystemAccessYN === 'Y') {
493
+ groupData.Systems = userGroup.Group.GroupSystemAccesses.map(
494
+ (groupSystemAccess) => {
495
+ return {
496
+ SystemCode: groupSystemAccess.System.SystemCode,
497
+ SystemName: groupSystemAccess.System.Name,
498
+ AccessStatus: groupSystemAccess.Status,
499
+ CreatedAt: groupSystemAccess.CreatedAt,
500
+ UpdatedAt: groupSystemAccess.UpdatedAt,
501
+ };
502
+ },
503
+ );
504
+ }
505
+
506
+ result.push(groupData);
507
+ }
508
+
509
+ // Part 6: Return Grouped Data
510
+ // Return the array of grouped system accesses for the user's groups, including both inherited ('Y') and non-inherited ('N') system accesses.
511
+ return result;
512
+ } catch (error) {
513
+ throw error;
514
+ }
515
+ }
516
+
517
+ public async update(
518
+ loginUser: LoginUser,
519
+ dbTransaction: Transaction,
520
+ UpdatedProperties: {
521
+ InheritGroupPrivilegeYN?: string;
522
+ InheritGroupSystemAccessYN?: string;
523
+ },
524
+ ): Promise<UserGroup> {
525
+ try {
526
+ // Part 1: Privilege Checking
527
+ // Call loginUser.checkPrivileges() to ensure the user has permission to retrieve system access information.
528
+ // SystemCode: Retrieve from app config.
529
+ // PrivilegeCode: 'USER_GROUP_UPDATE'.
530
+ const systemCode =
531
+ ApplicationConfig.getComponentConfigValue('system-code');
532
+ const isPrivileged = await loginUser.checkPrivileges(
533
+ systemCode,
534
+ 'USER_GROUP_UPDATE',
535
+ );
536
+ // If the privilege check fails, throw an error with a 403 Forbidden status.
537
+ if (!isPrivileged) {
538
+ throw new ClassError(
539
+ 'UserGroup',
540
+ 'UserGroupErrMsg0X',
541
+ 'User does not have privilege to update user group.',
542
+ 'update',
543
+ 403,
544
+ );
545
+ }
546
+ // Part 2: Validation
547
+ // Check to make sure that at least one of the UpdatedProperties is exist if not throw error.
548
+ if (
549
+ !UpdatedProperties.InheritGroupPrivilegeYN &&
550
+ !UpdatedProperties.InheritGroupSystemAccessYN
551
+ ) {
552
+ throw new ClassError(
553
+ 'UserGroup',
554
+ 'UserGroupErrMsg04',
555
+ 'At least one of the properties to update is required.',
556
+ 'update',
557
+ 400,
558
+ );
559
+ }
560
+ // Part 3: Update User Group
561
+ // Call the UserGroup._Repo.update() method to perform the update operation, passing:
562
+ // InheritGroupPrivilegeYN (if exist): updatedProperties.InheritGroupPrivilegeYN
563
+ // InheritGroupSystemAccessYN (if exist): updatedProperties.InheritGroupSystemAccessYN
564
+ // UpdatedById: loginUser.UserId (to indicate who updated the record).
565
+ // UpdatedAt: Set to the current date and time.
566
+ // dbTransaction: The database transaction instance.
567
+ const entityValueBefore = {
568
+ UserGroupId: this.UserGroupId,
569
+ UserId: this.UserId,
570
+ GroupCode: this.GroupCode,
571
+ Status: this.Status,
572
+ CreatedById: this._CreatedById,
573
+ CreatedAt: this._CreatedAt,
574
+ UpdatedById: this._UpdatedById,
575
+ UpdatedAt: this._UpdatedAt,
576
+ InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
577
+ InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
578
+ };
579
+
580
+ this._UpdatedById = loginUser.UserId;
581
+ this._UpdatedAt = new Date();
582
+ if (UpdatedProperties.InheritGroupPrivilegeYN) {
583
+ this.InheritGroupPrivilegeYN =
584
+ UpdatedProperties.InheritGroupPrivilegeYN;
585
+ }
586
+ if (UpdatedProperties.InheritGroupSystemAccessYN) {
587
+ this.InheritGroupSystemAccessYN =
588
+ UpdatedProperties.InheritGroupSystemAccessYN;
589
+ }
590
+
591
+ await UserGroup._Repository.update(
592
+ {
593
+ InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
594
+ InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
595
+ UpdatedById: this._UpdatedById,
596
+ UpdatedAt: this._UpdatedAt,
597
+ },
598
+ {
599
+ where: {
600
+ UserGroupId: this.UserGroupId,
601
+ },
602
+ transaction: dbTransaction,
603
+ },
604
+ );
605
+
606
+ // Part 2: Record Activity History
607
+ // Initialize a variable entityValueBefore to store the current state of the record before the update.
608
+ const entityValueAfter = {
609
+ UserGroupId: this.UserGroupId,
610
+ UserId: this.UserId,
611
+ GroupCode: this.GroupCode,
612
+ Status: this.Status,
613
+ CreatedById: this._CreatedById,
614
+ CreatedAt: this._CreatedAt,
615
+ UpdatedById: this._UpdatedById,
616
+ UpdatedAt: this._UpdatedAt,
617
+ InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
618
+ InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
619
+ };
620
+ // Create an instance of the Activity class and set the following properties:
621
+ // ActivityId: Call activity.createId().
622
+ // Action: Set to ActionEnum.Update.
623
+ // Description: Set to Update User Group.
624
+ // EntityType: Set to UserGroup.
625
+ // EntityId: Use the ID of the updated record.
626
+ // EntityValueBefore: Stringify entityValueBefore to capture the state before the update.
627
+ // EntityValueAfter: Stringify the updated record to capture the new state after the update.
628
+ const activity = new Activity();
629
+ activity.ActivityId = activity.createId();
630
+ activity.Action = ActionEnum.UPDATE;
631
+ activity.Description = 'Update User Group';
632
+ activity.EntityType = 'UserGroup';
633
+ activity.EntityId = this.UserGroupId.toString();
634
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
635
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
636
+
637
+ // Call the activity create a method with the following parameters:
638
+ // dbTransaction
639
+ // userId: loginUser.UserId
640
+ // Part 3: Return Updated Record
641
+
642
+ await activity.create(loginUser.ObjectId, dbTransaction);
643
+ // Retrieve the updated user group record from the database or return the updated instance as needed.
644
+ return this;
645
+ } catch (error) {
646
+ throw error;
647
+ }
648
+ }
649
+
650
+ public static async isUserMemberOfGroup(
651
+ dbTransaction: any,
652
+ loginUser: LoginUser,
653
+ UserId: number,
654
+ GroupCode: string,
655
+ ): Promise<boolean> {
656
+ try {
657
+ // Part 1: Privilege Checking
658
+ // Call loginUser.checkPrivileges() to ensure the user has permission to retrieve system access information.
659
+ // SystemCode: Retrieve from app config.
660
+ // PrivilegeCode: 'USER_GROUP_VIEW'.
661
+ const systemCode =
662
+ ApplicationConfig.getComponentConfigValue('system-code');
663
+ const isPrivileged = await loginUser.checkPrivileges(
664
+ systemCode,
665
+ 'USER_GROUP_VIEW',
666
+ );
667
+ // If the privilege check fails, throw an error with a 403 Forbidden status.
668
+ if (!isPrivileged) {
669
+ throw new ClassError(
670
+ 'UserGroup',
671
+ 'UserGroupErrMsg0X',
672
+ 'User does not have privilege to view user group.',
673
+ 'isUserMemberOfGroup',
674
+ 403,
675
+ );
676
+ }
677
+ // Part 2: Retrieve User Group
678
+ // Query the sso_UserGroup table to find the user group record with the given UserId and GroupCode.
679
+ // If the record exists, return true; otherwise, return false.
680
+ const userGroup = await UserGroup.findOne(
681
+ dbTransaction,
682
+ loginUser,
683
+ GroupCode,
684
+ UserId,
685
+ );
686
+ return !!userGroup;
687
+ } catch (error) {
688
+ throw error;
689
+ }
690
+ }
691
+
692
+ public async delete(
693
+ loginUser: LoginUser,
694
+ dbTransaction: Transaction,
695
+ ): Promise<void> {
696
+ try {
697
+ // Part 1: Privilege Checking
698
+ // Call loginUser.checkPrivileges() to ensure the user has permission to delete user group records.
699
+ // SystemCode: Retrieve from app config.
700
+ // PrivilegeCode: 'USER_GROUP_DELETE'.
701
+ const systemCode =
702
+ ApplicationConfig.getComponentConfigValue('system-code');
703
+ const isPrivileged = await loginUser.checkPrivileges(
704
+ systemCode,
705
+ 'USER_GROUP_DELETE',
706
+ );
707
+ // If the privilege check fails, throw an error with a 403 Forbidden status.
708
+ if (!isPrivileged) {
709
+ throw new ClassError(
710
+ 'UserGroup',
711
+ 'UserGroupErrMsg0X',
712
+ 'User does not have privilege to delete user group.',
713
+ 'delete',
714
+ 403,
715
+ );
716
+ }
717
+ // Part 2: Delete User Group
718
+ // Call the UserGroup._Repo.destroy() method to delete the user group record with the given UserGroupId.
719
+ // Pass the dbTransaction parameter to ensure the operation is part of the current transaction.
720
+ await UserGroup._Repository.delete({
721
+ where: {
722
+ UserGroupId: this.UserGroupId,
723
+ },
724
+ transaction: dbTransaction,
725
+ });
726
+ // Part 3: Record Activity History
727
+ // Initialize a variable entityValueBefore to store the current state of the record before the update.
728
+ const entityValueBefore = {
729
+ UserGroupId: this.UserGroupId,
730
+ UserId: this.UserId,
731
+ GroupCode: this.GroupCode,
732
+ Status: this.Status,
733
+ CreatedById: this._CreatedById,
734
+ CreatedAt: this._CreatedAt,
735
+ UpdatedById: this._UpdatedById,
736
+ UpdatedAt: this._UpdatedAt,
737
+ InheritGroupPrivilegeYN: this.InheritGroupPrivilegeYN,
738
+ InheritGroupSystemAccessYN: this.InheritGroupSystemAccessYN,
739
+ };
740
+ // Create an instance of the Activity class and set the following properties:
741
+ // ActivityId: Call activity.createId().
742
+ // Action: Set to ActionEnum.Delete.
743
+ // Description: Set to Delete User Group.
744
+ // EntityType: Set to UserGroup.
745
+ // EntityId: Use the ID of the deleted record.
746
+ // EntityValueBefore: Stringify entityValueBefore to capture the state before the delete.
747
+ // EntityValueAfter: Set to an empty string to indicate the record has been deleted.
748
+ const activity = new Activity();
749
+ activity.ActivityId = activity.createId();
750
+ activity.Action = ActionEnum.DELETE;
751
+ activity.Description = `Delete User Group ${this.UserGroupId}`;
752
+ activity.EntityType = 'UserGroup';
753
+ activity.EntityId = this.UserGroupId.toString();
754
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
755
+ activity.EntityValueAfter = JSON.stringify({});
756
+ // Call the activity create method with the following parameters:
757
+ // dbTransaction
758
+ // userId: loginUser.UserId
759
+ await activity.create(loginUser.ObjectId, dbTransaction);
760
+ } catch (error) {
761
+ throw error;
762
+ }
763
+ }
764
+ }