@tomei/sso 0.51.8 → 0.51.10

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomei/sso",
3
- "version": "0.51.8",
3
+ "version": "0.51.10",
4
4
  "description": "Tomei SSO Package",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -754,6 +754,71 @@ export class Group extends TreeNodeBase<Group> {
754
754
  }
755
755
  }
756
756
 
757
+ public static async getSystemAccessRoles(
758
+ loginUser: LoginUser,
759
+ dbTransaction: any,
760
+ SystemCode: string,
761
+ Page: number,
762
+ Rows: number,
763
+ Search: {
764
+ GroupCode?: string;
765
+ Status?: string;
766
+ },
767
+ ) {
768
+ // Part 1: Privilege Checking
769
+ const systemCode = ApplicationConfig.getComponentConfigValue('system-code');
770
+ const isPrivileged = await loginUser.checkPrivileges(
771
+ systemCode,
772
+ 'SYSTEM_ACCESS_VIEW',
773
+ );
774
+
775
+ if (!isPrivileged) {
776
+ throw new ClassError(
777
+ 'Group',
778
+ 'GroupErrMsg06',
779
+ 'You do not have the privilege to view system access',
780
+ );
781
+ }
782
+
783
+ try {
784
+ // Part 2: Retrieve System Access and returns
785
+ const queryObj: any = { SystemCode: SystemCode };
786
+
787
+ if (Search) {
788
+ Object.entries(Search).forEach(([key, value]) => {
789
+ queryObj[key] = value;
790
+ });
791
+ }
792
+
793
+ let options: any = {
794
+ where: queryObj,
795
+ distinct: true,
796
+ transaction: dbTransaction,
797
+ };
798
+
799
+ if (Page && Rows) {
800
+ options = {
801
+ ...options,
802
+ limit: Rows,
803
+ offset: Rows * (Page - 1),
804
+ order: [['CreatedAt', 'DESC']],
805
+ include: {
806
+ model: GroupModel,
807
+ where: {
808
+ Type: 'Role',
809
+ },
810
+ },
811
+ };
812
+ }
813
+
814
+ const systemAccess =
815
+ await Group._GroupSystemAccessRepo.findAndCountAll(options);
816
+ return systemAccess;
817
+ } catch (error) {
818
+ return error;
819
+ }
820
+ }
821
+
757
822
  private static async getInheritedSystemAccess(
758
823
  dbTransaction: any,
759
824
  group: Group,
@@ -1097,6 +1162,175 @@ export class Group extends TreeNodeBase<Group> {
1097
1162
  }
1098
1163
  }
1099
1164
 
1165
+ public static async getSystemPrivilegeRoles(
1166
+ loginUser: LoginUser,
1167
+ dbTransaction: any,
1168
+ SystemCode: string,
1169
+ search?: {
1170
+ GroupCode?: string[];
1171
+ Status?: string;
1172
+ },
1173
+ ) {
1174
+ try {
1175
+ //Part 1: Privilege Checking
1176
+ const systemCode =
1177
+ ApplicationConfig.getComponentConfigValue('system-code');
1178
+ const isPrivileged = await loginUser.checkPrivileges(
1179
+ systemCode,
1180
+ 'GROUP_PRIVILEGE_VIEW',
1181
+ );
1182
+
1183
+ if (!isPrivileged) {
1184
+ throw new ClassError(
1185
+ 'Group',
1186
+ 'GroupErrMsg11',
1187
+ 'You do not have the privilege to view group privileges',
1188
+ );
1189
+ }
1190
+
1191
+ //Part 2: Retrieve Roles Based on Privilege
1192
+ //Retrieve Roles based on privilege on a system
1193
+ let systemWhere: any = {};
1194
+
1195
+ if (search) {
1196
+ if (search.GroupCode.length) {
1197
+ }
1198
+ }
1199
+
1200
+ if (SystemCode) {
1201
+ systemWhere = {
1202
+ SystemCode: {
1203
+ [Op.substring]: SystemCode,
1204
+ },
1205
+ };
1206
+ }
1207
+
1208
+ const groupCodesPrivileges: {
1209
+ SystemPrivilegeId: string;
1210
+ GroupCodes: { Code: string; Name: string }[];
1211
+ }[] = [];
1212
+
1213
+ const allGroupCodePrivileges = await Group._GroupPrivilegeRepo.findAll({
1214
+ include: [
1215
+ {
1216
+ model: SystemPrivilegeModel,
1217
+ where: systemWhere,
1218
+ },
1219
+ {
1220
+ model: GroupModel,
1221
+ where: {
1222
+ Type: 'Role',
1223
+ },
1224
+ },
1225
+ ],
1226
+ transaction: dbTransaction,
1227
+ });
1228
+
1229
+ // Use a Map to group by SystemPrivilegeId
1230
+ const privilegesMap = new Map<string, { Code: string; Name: string }[]>();
1231
+
1232
+ for (const groupCodePrivilege of allGroupCodePrivileges) {
1233
+ const { SystemPrivilegeId, GroupCode, Group } = groupCodePrivilege; // `Group` contains Name from GroupModel
1234
+
1235
+ if (!privilegesMap.has(SystemPrivilegeId)) {
1236
+ // Initialize with an empty array if not already present
1237
+ privilegesMap.set(SystemPrivilegeId, []);
1238
+ }
1239
+
1240
+ // Add the GroupCode and Name to the array if it exists and is not already present
1241
+ if (GroupCode && Group?.Name) {
1242
+ const groupCodes = privilegesMap.get(SystemPrivilegeId);
1243
+ const newGroupEntry = { Code: GroupCode, Name: Group.Name };
1244
+
1245
+ // Ensure no duplicates
1246
+ if (
1247
+ groupCodes &&
1248
+ !groupCodes.some(
1249
+ (g) => g.Code === GroupCode && g.Name === Group.Name,
1250
+ )
1251
+ ) {
1252
+ groupCodes.push(newGroupEntry);
1253
+ }
1254
+ }
1255
+ }
1256
+
1257
+ // Convert the Map to the desired array format
1258
+ privilegesMap.forEach((groupCodes, SystemPrivilegeId) => {
1259
+ groupCodesPrivileges.push({
1260
+ SystemPrivilegeId,
1261
+ GroupCodes: groupCodes,
1262
+ });
1263
+ });
1264
+
1265
+ const allPrivileges = await SystemPrivilegeModel.findAll({
1266
+ where: systemWhere,
1267
+ transaction: dbTransaction,
1268
+ });
1269
+
1270
+ const groupPrivilegeRoles: {
1271
+ SystemPrivilegeId: string;
1272
+ PrivilegeCode: string;
1273
+ Description: string;
1274
+ GroupCodes: { Code: string; Name: string }[];
1275
+ }[] = [];
1276
+
1277
+ // Iterate through allPrivileges to check for matches in groupCodesPrivileges
1278
+ for (const privilege of allPrivileges) {
1279
+ const matchingGroupPrivilege = groupCodesPrivileges.find(
1280
+ (groupPrivilege) =>
1281
+ groupPrivilege.SystemPrivilegeId === privilege.SystemPrivilegeId,
1282
+ );
1283
+
1284
+ if (matchingGroupPrivilege) {
1285
+ // If match is found, push to groupPrivilegeRoles with GroupCodes
1286
+ groupPrivilegeRoles.push({
1287
+ SystemPrivilegeId: privilege.SystemPrivilegeId,
1288
+ PrivilegeCode: privilege.PrivilegeCode,
1289
+ Description: privilege.Description,
1290
+ GroupCodes: matchingGroupPrivilege.GroupCodes,
1291
+ });
1292
+ } else {
1293
+ // If no match is found, push with an empty array of GroupCodes
1294
+ groupPrivilegeRoles.push({
1295
+ SystemPrivilegeId: privilege.SystemPrivilegeId,
1296
+ PrivilegeCode: privilege.PrivilegeCode,
1297
+ Description: privilege.Description,
1298
+ GroupCodes: [],
1299
+ });
1300
+ }
1301
+ }
1302
+
1303
+ const filteredGroupPrivilegeRoles = groupPrivilegeRoles
1304
+ .map((role) => {
1305
+ if (search.GroupCode?.length) {
1306
+ // Filter GroupCodes to only include matching Codes
1307
+ const matchingGroupCodes = role.GroupCodes.filter((groupCode) =>
1308
+ search.GroupCode.includes(groupCode.Code),
1309
+ );
1310
+
1311
+ // If there are no matching GroupCodes, exclude this role
1312
+ if (matchingGroupCodes.length === 0) {
1313
+ return null;
1314
+ }
1315
+
1316
+ // Return the role with filtered GroupCodes
1317
+ return {
1318
+ ...role,
1319
+ GroupCodes: matchingGroupCodes,
1320
+ };
1321
+ }
1322
+
1323
+ // If search.GroupCode is not provided, include all data
1324
+ return role;
1325
+ })
1326
+ .filter(Boolean); // Remove any null values
1327
+
1328
+ return filteredGroupPrivilegeRoles;
1329
+ } catch (error) {
1330
+ throw error;
1331
+ }
1332
+ }
1333
+
1100
1334
  public static async getInheritedSystemPrivileges(
1101
1335
  dbTransaction: any,
1102
1336
  GroupCode: string,
@@ -1,3 +1,4 @@
1
+ import { Op, Transaction } from 'sequelize';
1
2
  import { ClassError, ObjectBase } from '@tomei/general';
2
3
  import { GroupReportingUserRepository } from './group-reporting-user.repository';
3
4
  import { IGroupReportingUserAttr } from '../../interfaces/group-reporting-user.interface';
@@ -6,7 +7,6 @@ import UserModel from '../../models/user.entity';
6
7
  import { Group } from '../group/group';
7
8
  import { ApplicationConfig } from '@tomei/config';
8
9
  import { ActionEnum, Activity } from '@tomei/activity-history';
9
- import { Transaction } from 'sequelize';
10
10
 
11
11
  export class GroupReportingUser extends ObjectBase {
12
12
  ObjectId: string;
@@ -216,6 +216,151 @@ export class GroupReportingUser extends ObjectBase {
216
216
  }
217
217
  }
218
218
 
219
+ async updateGroupReportingUser(
220
+ loginUser: User, //The user performing the operation(typically the logged -in user).
221
+ dbTransaction: any, //Database transaction object to ensure the operation is atomic.
222
+ groupCode: string, //The code of the group to which the user is being assigned.
223
+ userId: number, //The ID of the user to be added to the group.
224
+ rank: number, //The rank to be assigned to the user in the group.
225
+ status: 'Active' | 'Inactive', //The initial status of the user in the group.
226
+ ): Promise<GroupReportingUser> {
227
+ // Returns a GroupReportingUser instance representing the updated record.
228
+ try {
229
+ //Update a group reporting user entry in the sso_GroupReportingUser table.
230
+
231
+ // Validate Input Parameters
232
+ // Ensure groupCode exists in the sso_Group table by calling the Group.init() method.
233
+ await Group.init(dbTransaction, groupCode);
234
+ // Ensure userId exists in the sso_User table by calling the User.init() method.
235
+ await User.init(dbTransaction, userId);
236
+ // Privilege Checking
237
+ // Call the loginUser.checkPrivileges() method by passing:
238
+ // SystemCode: Retrieve from app config.
239
+ // PrivilegeCode: "GROUP_REPORTING_USER_UPDATE".
240
+
241
+ const systemCode =
242
+ ApplicationConfig.getComponentConfigValue('system-code');
243
+ const isPrivileged = await loginUser.checkPrivileges(
244
+ systemCode,
245
+ 'GROUP_REPORTING_USER_CREATE',
246
+ );
247
+ if (!isPrivileged) {
248
+ throw new ClassError(
249
+ 'GroupReportingUser',
250
+ 'GroupReportingUserErrMsg02',
251
+ 'Insufficient privileges to update a user to the group',
252
+ );
253
+ }
254
+
255
+ //Get the current groupReportingUser
256
+ const currentGroupReportingUser = await GroupReportingUser._Repo.findOne({
257
+ where: {
258
+ GroupCode: groupCode,
259
+ GroupReportingUserId: this.GroupReportingUserId,
260
+ },
261
+ transaction: dbTransaction,
262
+ });
263
+
264
+ // Check for Duplicate User in Group
265
+ // Query the sso_GroupReportingUser table to see if the userId already exists in the specified groupCode.
266
+ const groupReportingUser = await GroupReportingUser._Repo.findOne({
267
+ where: {
268
+ GroupCode: groupCode,
269
+ UserId: userId,
270
+ GroupReportingUserId: {
271
+ [Op.ne]: this.GroupReportingUserId,
272
+ },
273
+ },
274
+ transaction: dbTransaction,
275
+ });
276
+ // If the user already exists in the group, throw an error indicating the user is already part of the group.
277
+ if (groupReportingUser) {
278
+ throw new ClassError(
279
+ 'GroupReportingUser',
280
+ 'GroupReportingUserErrMsg03',
281
+ 'User already exists in the group',
282
+ 'updateGroupReportingUser',
283
+ );
284
+ }
285
+ //Query the sso_GroupReportingUser table to see if the rank already exists in the specified groupCode.
286
+ //If the rank already exists in the group, throw an error indicating the rank is already in of the group.
287
+ const groupReportingUserRank = await GroupReportingUser._Repo.findOne({
288
+ where: {
289
+ GroupCode: groupCode,
290
+ Rank: rank,
291
+ GroupReportingUserId: {
292
+ [Op.ne]: this.GroupReportingUserId,
293
+ },
294
+ },
295
+ transaction: dbTransaction,
296
+ });
297
+ if (groupReportingUserRank) {
298
+ throw new ClassError(
299
+ 'GroupReportingUser',
300
+ 'GroupReportingUserErrMsg04',
301
+ 'Rank already exists in the group',
302
+ 'updateGroupReportingUser',
303
+ );
304
+ }
305
+
306
+ // UPDATE GroupReportingUser Entry
307
+ // If validation and privilege checks pass, insert a new record in the sso_GroupReportingUser table with the provided groupCode, userId, rank, status, and loginUser.UserId.Automatically capture the current timestamp for CreatedAt.
308
+ this.GroupCode = groupCode;
309
+ this.UserId = userId;
310
+ this.Rank = rank;
311
+ this.Status = status;
312
+ this._CreatedById = currentGroupReportingUser.CreatedById;
313
+ this._CreatedAt = currentGroupReportingUser.CreatedAt;
314
+ this._UpdatedAt = new Date();
315
+ this._UpdatedById = loginUser.UserId;
316
+
317
+ const entityValueAfter: any = {
318
+ GroupCode: groupCode,
319
+ UserId: userId,
320
+ Rank: rank,
321
+ Status: status,
322
+ CreatedById: currentGroupReportingUser.CreatedById,
323
+ CreatedAt: this._CreatedAt,
324
+ UpdatedById: loginUser.UserId,
325
+ UpdatedAt: this._UpdatedAt,
326
+ };
327
+
328
+ await GroupReportingUser._Repo.update(entityValueAfter, {
329
+ where: {
330
+ GroupReportingUserId: this.GroupReportingUserId,
331
+ },
332
+ transaction: dbTransaction,
333
+ });
334
+
335
+ // Record Update Activity
336
+ // Instantiate a new activity from the Activity class, and set:\
337
+ // ActivityId: activity.createId()
338
+ // Action: ActionEnum.Update
339
+ // Description: Update Group Reporting User
340
+ // EntityType: GroupReportingUser
341
+ // EntityId: newGroupReportingUser.GroupReportingUserId
342
+ // EntityValueBefore: Stringified empty object({})
343
+ // EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity)
344
+ const activity = new Activity();
345
+ activity.ActivityId = activity.createId();
346
+ activity.Action = ActionEnum.UPDATE;
347
+ activity.Description = 'Update Group Reporting User';
348
+ activity.EntityType = 'GroupReportingUser';
349
+ activity.EntityId = this.GroupReportingUserId.toString();
350
+ activity.EntityValueBefore = JSON.stringify({});
351
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
352
+ // Call the activity create() method by passing:
353
+ // dbTransaction
354
+ // userId: loginUser.UserId
355
+ await activity.create(loginUser.ObjectId, dbTransaction);
356
+ // Return the Updated GroupReportingUser
357
+ // Return the updated GroupReportingUser instance, including all the relevant details like GroupReportingUserId, groupCode, userId, rank, status, and timestamps for CreatedAt.
358
+ return this;
359
+ } catch (error) {
360
+ throw error;
361
+ }
362
+ }
363
+
219
364
  public static async findAllGroupReportingUsers(
220
365
  loginUser: User, //The authenticated user requesting the information.
221
366
  dbTransaction: any, //The database transaction to be used for this operation.