@flusys/nestjs-iam 6.0.0 → 6.0.2

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.
@@ -18,9 +18,9 @@ const _permissionwithcompanyentity = require("../entities/permission-with-compan
18
18
  const _rolewithcompanyentity = require("../entities/role-with-company.entity");
19
19
  const _roleentity = require("../entities/role.entity");
20
20
  const _useriampermissionentity = require("../entities/user-iam-permission.entity");
21
+ const _actiontypeenum = require("../enums/action-type.enum");
21
22
  const _iamentitytypeenum = require("../enums/iam-entity-type.enum");
22
23
  const _iampermissiontypeenum = require("../enums/iam-permission-type.enum");
23
- const _actiontypeenum = require("../enums/action-type.enum");
24
24
  const _permissiontypeenum = require("../enums/permission-type.enum");
25
25
  const _iamconfigservice = require("./iam-config.service");
26
26
  const _iamdatasourceservice = require("./iam-datasource.service");
@@ -67,6 +67,18 @@ let PermissionService = class PermissionService {
67
67
  const entity = enableCompanyFeature ? _rolewithcompanyentity.RoleWithCompany : _roleentity.Role;
68
68
  return this.dataSourceProvider.getRepository(entity);
69
69
  }
70
+ async getActionsMap(actionIds) {
71
+ const actionRepo = await this.getActionRepository();
72
+ const actions = await actionRepo.find({
73
+ where: {
74
+ id: (0, _typeorm.In)(actionIds)
75
+ }
76
+ });
77
+ return new Map(actions.map((a)=>[
78
+ a.id,
79
+ a
80
+ ]));
81
+ }
70
82
  // User-Action Permissions
71
83
  async assignUserActions(dto) {
72
84
  if (!this.iamConfigService.isDirectPermissionEnabled()) {
@@ -143,12 +155,13 @@ let PermissionService = class PermissionService {
143
155
  const result = await permissionRepo.delete(whereDelete);
144
156
  removed = result.affected || 0;
145
157
  }
146
- await this.invalidateUserPermissionCache(dto.userId, branchId, companyId);
158
+ await this.permissionCacheService.invalidateUser(dto.userId, enableCompanyFeature ? companyId : null, [
159
+ branchId
160
+ ]);
147
161
  return this.buildOperationResult(dto.items.length, added, removed);
148
162
  }
149
163
  async getUserActions(userId, branchId, companyId) {
150
164
  const permissionRepo = await this.getPermissionRepository();
151
- const actionRepo = await this.getActionRepository();
152
165
  const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
153
166
  const where = {
154
167
  permissionType: _iampermissiontypeenum.IamPermissionType.USER_ACTION,
@@ -166,16 +179,7 @@ let PermissionService = class PermissionService {
166
179
  return [];
167
180
  }
168
181
  const actionIds = permissions.map((p)=>p.targetId);
169
- const actionWhere = {
170
- id: (0, _typeorm.In)(actionIds)
171
- };
172
- const actions = await actionRepo.find({
173
- where: actionWhere
174
- });
175
- const actionMap = new Map(actions.map((a)=>[
176
- a.id,
177
- a
178
- ]));
182
+ const actionMap = await this.getActionsMap(actionIds);
179
183
  return permissions.filter((p)=>actionMap.has(p.targetId)).map((p)=>{
180
184
  const action = actionMap.get(p.targetId);
181
185
  return {
@@ -272,7 +276,6 @@ let PermissionService = class PermissionService {
272
276
  }
273
277
  async getRoleActions(roleId) {
274
278
  const permissionRepo = await this.getPermissionRepository();
275
- const actionRepo = await this.getActionRepository();
276
279
  const permissions = await permissionRepo.find({
277
280
  where: {
278
281
  permissionType: _iampermissiontypeenum.IamPermissionType.ROLE_ACTION,
@@ -284,16 +287,7 @@ let PermissionService = class PermissionService {
284
287
  return [];
285
288
  }
286
289
  const actionIds = permissions.map((p)=>p.targetId);
287
- const actionWhere = {
288
- id: (0, _typeorm.In)(actionIds)
289
- };
290
- const actions = await actionRepo.find({
291
- where: actionWhere
292
- });
293
- const actionMap = new Map(actions.map((a)=>[
294
- a.id,
295
- a
296
- ]));
290
+ const actionMap = await this.getActionsMap(actionIds);
297
291
  return permissions.filter((p)=>actionMap.has(p.targetId)).map((p)=>{
298
292
  const action = actionMap.get(p.targetId);
299
293
  return {
@@ -320,8 +314,7 @@ let PermissionService = class PermissionService {
320
314
  }
321
315
  if (itemsToRemove.length > 0) {
322
316
  const actionIdsToRemove = itemsToRemove.map((item)=>item.id);
323
- const cascadeResult = await this.removeCompanyActionsWithCascade(manager, dto.companyId, actionIdsToRemove);
324
- removed = cascadeResult.removedCompanyActions;
317
+ removed = await this.removeCompanyActionsWithCascade(manager, dto.companyId, actionIdsToRemove);
325
318
  }
326
319
  });
327
320
  await this.invalidateCompanyMembersCache(dto.companyId);
@@ -377,37 +370,28 @@ let PermissionService = class PermissionService {
377
370
  'id'
378
371
  ]
379
372
  });
380
- let removedRoleActions = 0;
381
- let removedUserActions = 0;
382
373
  if (companyRoles.length > 0) {
383
374
  const roleIds = companyRoles.map((role)=>role.id);
384
- const roleResult = await permissionRepo.delete({
375
+ await permissionRepo.delete({
385
376
  permissionType: _iampermissiontypeenum.IamPermissionType.ROLE_ACTION,
386
377
  sourceType: _iamentitytypeenum.IamEntityType.ROLE,
387
378
  sourceId: (0, _typeorm.In)(roleIds),
388
379
  targetType: _iamentitytypeenum.IamEntityType.ACTION,
389
380
  targetId: (0, _typeorm.In)(actionIds)
390
381
  });
391
- removedRoleActions = roleResult.affected || 0;
392
382
  }
393
383
  if (this.iamConfigService.isCompanyFeatureEnabled()) {
394
- const userResult = await permissionRepo.delete({
384
+ await permissionRepo.delete({
395
385
  permissionType: _iampermissiontypeenum.IamPermissionType.USER_ACTION,
396
386
  companyId,
397
387
  targetType: _iamentitytypeenum.IamEntityType.ACTION,
398
388
  targetId: (0, _typeorm.In)(actionIds)
399
389
  });
400
- removedUserActions = userResult.affected || 0;
401
390
  }
402
- return {
403
- removedCompanyActions: companyResult.affected || 0,
404
- removedRoleActions,
405
- removedUserActions
406
- };
391
+ return companyResult.affected || 0;
407
392
  }
408
393
  /** Get all actions assigned to a company (whitelist) */ async getCompanyActions(companyId) {
409
394
  const permissionRepo = await this.getPermissionRepository();
410
- const actionRepo = await this.getActionRepository();
411
395
  const permissions = await permissionRepo.find({
412
396
  where: {
413
397
  permissionType: _iampermissiontypeenum.IamPermissionType.COMPANY_ACTION,
@@ -419,15 +403,7 @@ let PermissionService = class PermissionService {
419
403
  return [];
420
404
  }
421
405
  const actionIds = permissions.map((p)=>p.targetId);
422
- const actions = await actionRepo.find({
423
- where: {
424
- id: (0, _typeorm.In)(actionIds)
425
- }
426
- });
427
- const actionMap = new Map(actions.map((a)=>[
428
- a.id,
429
- a
430
- ]));
406
+ const actionMap = await this.getActionsMap(actionIds);
431
407
  return permissions.filter((p)=>actionMap.has(p.targetId)).map((p)=>{
432
408
  const action = actionMap.get(p.targetId);
433
409
  return {
@@ -530,7 +506,9 @@ let PermissionService = class PermissionService {
530
506
  const result = await permissionRepo.delete(whereDelete);
531
507
  removed = result.affected || 0;
532
508
  }
533
- await this.invalidateUserPermissionCache(dto.userId, branchId, companyId);
509
+ await this.permissionCacheService.invalidateUser(dto.userId, enableCompanyFeature ? companyId : null, [
510
+ branchId
511
+ ]);
534
512
  return this.buildOperationResult(dto.items.length, added, removed);
535
513
  }
536
514
  /** Get user's roles (branch-scoped, filtered by companyId and branchId if provided) */ async getUserRoles(userId, branchId, companyId) {
@@ -581,9 +559,8 @@ let PermissionService = class PermissionService {
581
559
  const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
582
560
  const cacheOptions = {
583
561
  userId,
584
- companyId,
585
- branchId,
586
- enableCompanyFeature
562
+ companyId: enableCompanyFeature ? companyId : null,
563
+ branchId
587
564
  };
588
565
  const cachedData = await this.permissionCacheService.getMyPermissions(cacheOptions);
589
566
  if (cachedData) {
@@ -612,42 +589,25 @@ let PermissionService = class PermissionService {
612
589
  cachedEndpoints: cachedData.backendCodes.length
613
590
  };
614
591
  }
615
- /** Get current tenant ID for multi-tenant cache keys */ getCurrentTenantId() {
616
- if (!this.iamConfigService.isMultiTenant()) {
617
- return undefined;
618
- }
619
- const tenant = this.dataSourceProvider.getCurrentTenant();
620
- return tenant?.id;
621
- }
622
- /** Get parent IDs by codes, using cache first (tenant-aware) */ async getParentIdsByCodesWithCache(codes) {
623
- const tenantId = this.getCurrentTenantId();
624
- const cachedMap = await this.permissionCacheService.getActionIdsByCodes(codes, tenantId);
625
- if (cachedMap) {
626
- return new Set(Object.values(cachedMap));
627
- }
592
+ /** Resolve action IDs for the given codes */ async getParentIdsByCodesWithCache(codes) {
628
593
  const actionRepo = await this.getActionRepository();
629
- const allActions = await actionRepo.find({
594
+ const actions = await actionRepo.find({
595
+ where: {
596
+ code: (0, _typeorm.In)(codes)
597
+ },
630
598
  select: [
631
599
  'id',
632
600
  'code'
633
601
  ]
634
602
  });
635
- const fullMap = {};
636
- for (const action of allActions){
637
- if (action.code) {
638
- fullMap[action.code] = action.id;
639
- }
640
- }
641
- await this.permissionCacheService.setActionCodeMap(fullMap, tenantId);
642
- return new Set(codes.map((code)=>fullMap[code]).filter(Boolean));
603
+ return new Set(actions.map((action)=>action.id));
643
604
  }
644
605
  /** Fetch permissions from DB and cache them (empty permissions are also cached) */ async fetchAndCachePermissions(userId, branchId, companyId) {
645
606
  const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
646
607
  const cacheOptions = {
647
608
  userId,
648
- companyId,
649
- branchId,
650
- enableCompanyFeature
609
+ companyId: enableCompanyFeature ? companyId : null,
610
+ branchId
651
611
  };
652
612
  const emptyData = {
653
613
  frontendActions: [],
@@ -700,7 +660,8 @@ let PermissionService = class PermissionService {
700
660
  const actionRepo = await this.getActionRepository();
701
661
  const actions = await actionRepo.find({
702
662
  where: {
703
- id: (0, _typeorm.In)(Array.from(actionIds))
663
+ id: (0, _typeorm.In)(Array.from(actionIds)),
664
+ isActive: true
704
665
  }
705
666
  });
706
667
  const backendActions = actions.filter((a)=>a.actionType === _actiontypeenum.ActionType.BACKEND || a.actionType === _actiontypeenum.ActionType.BOTH);
@@ -716,10 +677,7 @@ let PermissionService = class PermissionService {
716
677
  })),
717
678
  backendCodes
718
679
  };
719
- await Promise.all([
720
- this.permissionCacheService.setMyPermissions(cacheOptions, cacheData),
721
- this.permissionCacheService.setPermissions(cacheOptions, backendCodes)
722
- ]);
680
+ await this.permissionCacheService.setMyPermissions(cacheOptions, cacheData);
723
681
  return cacheData;
724
682
  }
725
683
  // Helper Methods
@@ -753,9 +711,11 @@ let PermissionService = class PermissionService {
753
711
  const baseWhere = {
754
712
  permissionType: _iampermissiontypeenum.IamPermissionType.USER_ROLE,
755
713
  sourceType: _iamentitytypeenum.IamEntityType.USER,
756
- sourceId: userId,
757
- companyId: companyId
714
+ sourceId: userId
758
715
  };
716
+ if (companyId) {
717
+ baseWhere.companyId = companyId;
718
+ }
759
719
  if (branchId) {
760
720
  // Get company-wide + branch-specific roles
761
721
  const companyWidePermissions = await permissionRepo.find({
@@ -839,14 +799,6 @@ let PermissionService = class PermissionService {
839
799
  }
840
800
  return Array.from(actionIds);
841
801
  }
842
- /** Invalidate permission cache for a user */ async invalidateUserPermissionCache(userId, branchId, companyId) {
843
- const branchIds = branchId !== undefined ? [
844
- branchId
845
- ] : [
846
- null
847
- ];
848
- await this.permissionCacheService.invalidateUser(userId, companyId, branchIds);
849
- }
850
802
  async invalidateRoleMembersCache(roleId) {
851
803
  const permissionRepo = await this.getPermissionRepository();
852
804
  const roleRepo = await this.getRoleRepository();
@@ -884,7 +836,7 @@ let PermissionService = class PermissionService {
884
836
  ...new Set(userBranches.map((p)=>p.branchId))
885
837
  ];
886
838
  }
887
- return this.permissionCacheService.invalidateRole(roleId, userIds, companyId, branchIds);
839
+ return this.permissionCacheService.invalidateUsers(userIds, companyId, branchIds);
888
840
  }
889
841
  /** Invalidate permission cache for all users in a company */ async invalidateCompanyMembersCache(companyId) {
890
842
  if (!this.iamConfigService.isCompanyFeatureEnabled()) {
@@ -905,6 +857,127 @@ let PermissionService = class PermissionService {
905
857
  }
906
858
  return await this.permissionCacheService.invalidateUsers(userIds, companyId, branchIds);
907
859
  }
860
+ async revokeCompanyPermissions(companyId) {
861
+ if (!this.iamConfigService.isCompanyFeatureEnabled()) {
862
+ return;
863
+ }
864
+ const permissionRepo = await this.getPermissionRepository();
865
+ const roleRepo = await this.getRoleRepository();
866
+ const dataSource = permissionRepo.manager.connection;
867
+ const companyRoles = await roleRepo.find({
868
+ where: {
869
+ companyId,
870
+ deletedAt: (0, _typeorm.IsNull)()
871
+ },
872
+ select: [
873
+ 'id'
874
+ ]
875
+ });
876
+ const roleIds = companyRoles.map((role)=>role.id);
877
+ const affectedUserRows = await permissionRepo.find({
878
+ where: {
879
+ permissionType: (0, _typeorm.In)([
880
+ _iampermissiontypeenum.IamPermissionType.USER_ROLE,
881
+ _iampermissiontypeenum.IamPermissionType.USER_ACTION
882
+ ]),
883
+ companyId
884
+ },
885
+ select: [
886
+ 'userId'
887
+ ]
888
+ });
889
+ const affectedUserIds = [
890
+ ...new Set(affectedUserRows.map((row)=>row.userId).filter((id)=>!!id))
891
+ ];
892
+ await dataSource.transaction(async (manager)=>{
893
+ const txRepo = manager.getRepository(permissionRepo.target);
894
+ await txRepo.delete({
895
+ permissionType: _iampermissiontypeenum.IamPermissionType.COMPANY_ACTION,
896
+ sourceType: _iamentitytypeenum.IamEntityType.COMPANY,
897
+ sourceId: companyId
898
+ });
899
+ if (roleIds.length > 0) {
900
+ await txRepo.delete({
901
+ permissionType: _iampermissiontypeenum.IamPermissionType.ROLE_ACTION,
902
+ sourceType: _iamentitytypeenum.IamEntityType.ROLE,
903
+ sourceId: (0, _typeorm.In)(roleIds)
904
+ });
905
+ }
906
+ await txRepo.delete({
907
+ permissionType: (0, _typeorm.In)([
908
+ _iampermissiontypeenum.IamPermissionType.USER_ROLE,
909
+ _iampermissiontypeenum.IamPermissionType.USER_ACTION
910
+ ]),
911
+ companyId
912
+ });
913
+ if (roleIds.length > 0) {
914
+ const txRoleRepo = manager.getRepository(roleRepo.target);
915
+ await txRoleRepo.delete(roleIds);
916
+ }
917
+ });
918
+ if (affectedUserIds.length > 0) {
919
+ await this.permissionCacheService.invalidateUsers(affectedUserIds, companyId);
920
+ }
921
+ }
922
+ async revokeBranchPermissions(branchId, companyId) {
923
+ if (!this.iamConfigService.isCompanyFeatureEnabled()) {
924
+ return;
925
+ }
926
+ const permissionRepo = await this.getPermissionRepository();
927
+ const where = {
928
+ permissionType: (0, _typeorm.In)([
929
+ _iampermissiontypeenum.IamPermissionType.USER_ROLE,
930
+ _iampermissiontypeenum.IamPermissionType.USER_ACTION
931
+ ]),
932
+ branchId,
933
+ companyId
934
+ };
935
+ const affectedUserRows = await permissionRepo.find({
936
+ where,
937
+ select: [
938
+ 'userId'
939
+ ]
940
+ });
941
+ const affectedUserIds = [
942
+ ...new Set(affectedUserRows.map((row)=>row.userId).filter((id)=>!!id))
943
+ ];
944
+ await permissionRepo.delete(where);
945
+ if (affectedUserIds.length > 0) {
946
+ await this.permissionCacheService.invalidateUsers(affectedUserIds, companyId, [
947
+ branchId
948
+ ]);
949
+ }
950
+ }
951
+ async revokeUserCompanyAccess(userId, companyId) {
952
+ const permissionRepo = await this.getPermissionRepository();
953
+ await permissionRepo.delete({
954
+ permissionType: (0, _typeorm.In)([
955
+ _iampermissiontypeenum.IamPermissionType.USER_ROLE,
956
+ _iampermissiontypeenum.IamPermissionType.USER_ACTION
957
+ ]),
958
+ sourceType: _iamentitytypeenum.IamEntityType.USER,
959
+ sourceId: userId,
960
+ companyId
961
+ });
962
+ await this.permissionCacheService.invalidateUser(userId, companyId);
963
+ }
964
+ async revokeUserBranchAccess(userId, branchId, companyId) {
965
+ const permissionRepo = await this.getPermissionRepository();
966
+ const where = {
967
+ permissionType: (0, _typeorm.In)([
968
+ _iampermissiontypeenum.IamPermissionType.USER_ROLE,
969
+ _iampermissiontypeenum.IamPermissionType.USER_ACTION
970
+ ]),
971
+ sourceType: _iamentitytypeenum.IamEntityType.USER,
972
+ sourceId: userId,
973
+ branchId,
974
+ companyId
975
+ };
976
+ await permissionRepo.delete(where);
977
+ await this.permissionCacheService.invalidateUser(userId, companyId, [
978
+ branchId
979
+ ]);
980
+ }
908
981
  // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
909
982
  constructor(permissionCacheService, iamConfigService, dataSourceProvider){
910
983
  _define_property(this, "permissionCacheService", void 0);
@@ -959,6 +1032,54 @@ _ts_decorate([
959
1032
  ]),
960
1033
  _ts_metadata("design:returntype", Promise)
961
1034
  ], PermissionService.prototype, "assignUserRoles", null);
1035
+ _ts_decorate([
1036
+ (0, _nestjsshared.LogAction)({
1037
+ action: 'iam.revokeCompanyPermissions',
1038
+ module: 'iam'
1039
+ }),
1040
+ _ts_metadata("design:type", Function),
1041
+ _ts_metadata("design:paramtypes", [
1042
+ String
1043
+ ]),
1044
+ _ts_metadata("design:returntype", Promise)
1045
+ ], PermissionService.prototype, "revokeCompanyPermissions", null);
1046
+ _ts_decorate([
1047
+ (0, _nestjsshared.LogAction)({
1048
+ action: 'iam.revokeBranchPermissions',
1049
+ module: 'iam'
1050
+ }),
1051
+ _ts_metadata("design:type", Function),
1052
+ _ts_metadata("design:paramtypes", [
1053
+ String,
1054
+ String
1055
+ ]),
1056
+ _ts_metadata("design:returntype", Promise)
1057
+ ], PermissionService.prototype, "revokeBranchPermissions", null);
1058
+ _ts_decorate([
1059
+ (0, _nestjsshared.LogAction)({
1060
+ action: 'iam.revokeUserCompanyAccess',
1061
+ module: 'iam'
1062
+ }),
1063
+ _ts_metadata("design:type", Function),
1064
+ _ts_metadata("design:paramtypes", [
1065
+ String,
1066
+ String
1067
+ ]),
1068
+ _ts_metadata("design:returntype", Promise)
1069
+ ], PermissionService.prototype, "revokeUserCompanyAccess", null);
1070
+ _ts_decorate([
1071
+ (0, _nestjsshared.LogAction)({
1072
+ action: 'iam.revokeUserBranchAccess',
1073
+ module: 'iam'
1074
+ }),
1075
+ _ts_metadata("design:type", Function),
1076
+ _ts_metadata("design:paramtypes", [
1077
+ String,
1078
+ String,
1079
+ String
1080
+ ]),
1081
+ _ts_metadata("design:returntype", Promise)
1082
+ ], PermissionService.prototype, "revokeUserBranchAccess", null);
962
1083
  PermissionService = _ts_decorate([
963
1084
  (0, _common.Injectable)({
964
1085
  scope: _common.Scope.REQUEST
@@ -12,10 +12,16 @@ const _classes = require("@flusys/nestjs-shared/classes");
12
12
  const _modules = require("@flusys/nestjs-shared/modules");
13
13
  const _utils = require("@flusys/nestjs-shared/utils");
14
14
  const _common = require("@nestjs/common");
15
+ const _typeorm = require("typeorm");
16
+ const _permissionwithcompanyentity = require("../entities/permission-with-company.entity");
15
17
  const _rolewithcompanyentity = require("../entities/role-with-company.entity");
16
18
  const _roleentity = require("../entities/role.entity");
19
+ const _useriampermissionentity = require("../entities/user-iam-permission.entity");
20
+ const _iamentitytypeenum = require("../enums/iam-entity-type.enum");
21
+ const _iampermissiontypeenum = require("../enums/iam-permission-type.enum");
17
22
  const _iamconfigservice = require("./iam-config.service");
18
23
  const _iamdatasourceservice = require("./iam-datasource.service");
24
+ const _permissioncacheservice = require("./permission-cache.service");
19
25
  function _define_property(obj, key, value) {
20
26
  if (key in obj) {
21
27
  Object.defineProperty(obj, key, {
@@ -44,6 +50,42 @@ function _ts_param(paramIndex, decorator) {
44
50
  };
45
51
  }
46
52
  let RoleService = class RoleService extends _classes.ApiService {
53
+ async beforeDeleteOperation(dto, user, queryRunner) {
54
+ await super.beforeDeleteOperation(dto, user, queryRunner);
55
+ const roleIds = Array.isArray(dto.id) ? dto.id : [
56
+ dto.id
57
+ ];
58
+ if (roleIds.length === 0) {
59
+ return;
60
+ }
61
+ const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
62
+ const permissionEntity = enableCompanyFeature ? _permissionwithcompanyentity.UserIamPermissionWithCompany : _useriampermissionentity.UserIamPermission;
63
+ const permissionRepo = queryRunner.manager.getRepository(permissionEntity);
64
+ const userRoleRows = await permissionRepo.find({
65
+ where: {
66
+ permissionType: _iampermissiontypeenum.IamPermissionType.USER_ROLE,
67
+ sourceType: _iamentitytypeenum.IamEntityType.USER,
68
+ targetType: _iamentitytypeenum.IamEntityType.ROLE,
69
+ targetId: (0, _typeorm.In)(roleIds)
70
+ }
71
+ });
72
+ const affectedUserIds = [
73
+ ...new Set(userRoleRows.map((row)=>row.userId).filter((id)=>!!id))
74
+ ];
75
+ await permissionRepo.delete({
76
+ permissionType: _iampermissiontypeenum.IamPermissionType.ROLE_ACTION,
77
+ sourceType: _iamentitytypeenum.IamEntityType.ROLE,
78
+ sourceId: (0, _typeorm.In)(roleIds)
79
+ });
80
+ await permissionRepo.delete({
81
+ permissionType: _iampermissiontypeenum.IamPermissionType.USER_ROLE,
82
+ targetType: _iamentitytypeenum.IamEntityType.ROLE,
83
+ targetId: (0, _typeorm.In)(roleIds)
84
+ });
85
+ if (affectedUserIds.length > 0) {
86
+ await this.permissionCacheService.invalidateUsers(affectedUserIds);
87
+ }
88
+ }
47
89
  resolveEntity() {
48
90
  return this.iamConfigService.isCompanyFeatureEnabled() ? _rolewithcompanyentity.RoleWithCompany : _roleentity.Role;
49
91
  }
@@ -117,8 +159,8 @@ let RoleService = class RoleService extends _classes.ApiService {
117
159
  deletedById: entity.deletedById
118
160
  };
119
161
  }
120
- constructor(cacheManager, utilsService, iamConfigService, dataSourceProvider){
121
- super('role', cacheManager, utilsService, RoleService.name, true, 'iam', undefined, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "iamConfigService", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.iamConfigService = iamConfigService;
162
+ constructor(cacheManager, utilsService, iamConfigService, dataSourceProvider, permissionCacheService){
163
+ super('role', cacheManager, utilsService, RoleService.name, true, 'iam', undefined, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "iamConfigService", void 0), _define_property(this, "permissionCacheService", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.iamConfigService = iamConfigService, this.permissionCacheService = permissionCacheService;
122
164
  }
123
165
  };
124
166
  RoleService = _ts_decorate([
@@ -129,11 +171,13 @@ RoleService = _ts_decorate([
129
171
  _ts_param(1, (0, _common.Inject)(_modules.UtilsService)),
130
172
  _ts_param(2, (0, _common.Inject)(_iamconfigservice.IAMConfigService)),
131
173
  _ts_param(3, (0, _common.Inject)(_iamdatasourceservice.IAMDataSourceService)),
174
+ _ts_param(4, (0, _common.Inject)(_permissioncacheservice.PermissionCacheService)),
132
175
  _ts_metadata("design:type", Function),
133
176
  _ts_metadata("design:paramtypes", [
134
177
  typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
135
178
  typeof _modules.UtilsService === "undefined" ? Object : _modules.UtilsService,
136
179
  typeof _iamconfigservice.IAMConfigService === "undefined" ? Object : _iamconfigservice.IAMConfigService,
137
- typeof _iamdatasourceservice.IAMDataSourceService === "undefined" ? Object : _iamdatasourceservice.IAMDataSourceService
180
+ typeof _iamdatasourceservice.IAMDataSourceService === "undefined" ? Object : _iamdatasourceservice.IAMDataSourceService,
181
+ typeof _permissioncacheservice.PermissionCacheService === "undefined" ? Object : _permissioncacheservice.PermissionCacheService
138
182
  ])
139
183
  ], RoleService);
@@ -1,6 +1,7 @@
1
1
  import { ILoggedUserInfo, SingleResponseDto } from '@flusys/nestjs-shared';
2
- import { ActionResponseDto, ActionTreeQueryDto, CreateActionDto, UpdateActionDto } from '../dtos/action.dto';
2
+ import { ActionResponseDto, ActionTreeForPermissionDto, ActionTreeQueryDto, CreateActionDto, UpdateActionDto } from '../dtos/action.dto';
3
3
  import { ActionService } from '../services/action.service';
4
+ import { IAMConfigService } from '../services/iam-config.service';
4
5
  declare const ActionController_base: abstract new (service: ActionService) => {
5
6
  readonly enabledEndpoints: import("@flusys/nestjs-shared").ApiEndpoint[] | "all";
6
7
  service: ActionService;
@@ -18,8 +19,9 @@ declare const ActionController_base: abstract new (service: ActionService) => {
18
19
  };
19
20
  export declare class ActionController extends ActionController_base {
20
21
  actionService: ActionService;
21
- constructor(actionService: ActionService);
22
- getActionsForPermission(user: ILoggedUserInfo): Promise<SingleResponseDto<ActionResponseDto[]>>;
22
+ private readonly iamConfigService;
23
+ constructor(actionService: ActionService, iamConfigService: IAMConfigService);
24
+ getActionsForPermission(dto: ActionTreeForPermissionDto, user: ILoggedUserInfo): Promise<SingleResponseDto<ActionResponseDto[]>>;
23
25
  getActionTree(query: ActionTreeQueryDto, user: ILoggedUserInfo): Promise<SingleResponseDto<ActionResponseDto[]>>;
24
26
  }
25
27
  export {};
@@ -29,6 +29,9 @@ export declare class ActionResponseDto extends IdentityResponseDto {
29
29
  export declare class ActionTreeDto extends ActionResponseDto {
30
30
  children: ActionTreeDto[];
31
31
  }
32
+ export declare class ActionTreeForPermissionDto {
33
+ companyId?: string;
34
+ }
32
35
  export declare class ActionTreeQueryDto {
33
36
  search?: string;
34
37
  isActive?: boolean;
@@ -9,7 +9,7 @@ import { UserIamPermissionWithCompany } from './permission-with-company.entity';
9
9
  import { RoleWithCompany } from './role-with-company.entity';
10
10
  import { Role } from './role.entity';
11
11
  import { UserIamPermission } from './user-iam-permission.entity';
12
- export declare const IAMCoreEntities: (typeof Role | typeof UserIamPermission)[];
12
+ export declare const IAMCoreEntities: (typeof UserIamPermission | typeof Role)[];
13
13
  export declare const IAMCompanyEntities: (typeof UserIamPermissionWithCompany | typeof RoleWithCompany)[];
14
- export declare const IAMAllEntities: (typeof Role | typeof UserIamPermission)[];
14
+ export declare const IAMAllEntities: (typeof UserIamPermission | typeof Role)[];
15
15
  export declare function getIAMEntitiesByConfig(enableCompanyFeature: boolean, permissionMode?: 'FULL' | 'RBAC' | 'DIRECT'): any[];
@@ -25,13 +25,14 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
+ import { ACTION_PERMISSIONS, createApiController, CurrentUser, ILoggedUserInfo, SingleResponseDto } from '@flusys/nestjs-shared';
28
29
  import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
29
- import { createApiController, CurrentUser, ILoggedUserInfo, SingleResponseDto, ACTION_PERMISSIONS } from '@flusys/nestjs-shared';
30
- import { ACTION_MESSAGES } from '../config';
31
30
  import { Body, Controller, Inject, Post, UseGuards } from '@nestjs/common';
32
31
  import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
33
- import { ActionResponseDto, ActionTreeQueryDto, CreateActionDto, UpdateActionDto } from '../dtos/action.dto';
32
+ import { ACTION_MESSAGES } from '../config';
33
+ import { ActionResponseDto, ActionTreeForPermissionDto, ActionTreeQueryDto, CreateActionDto, UpdateActionDto } from '../dtos/action.dto';
34
34
  import { ActionService } from '../services/action.service';
35
+ import { IAMConfigService } from '../services/iam-config.service';
35
36
  export class ActionController extends createApiController(CreateActionDto, UpdateActionDto, ActionResponseDto, {
36
37
  entityName: 'action',
37
38
  security: {
@@ -79,8 +80,8 @@ export class ActionController extends createApiController(CreateActionDto, Updat
79
80
  }
80
81
  }
81
82
  }) {
82
- async getActionsForPermission(user) {
83
- const actions = await this.actionService.getActionsForPermission(user);
83
+ async getActionsForPermission(dto, user) {
84
+ const actions = await this.actionService.getActionsForPermission(user, dto?.companyId);
84
85
  return {
85
86
  success: true,
86
87
  message: 'Actions retrieved successfully',
@@ -97,8 +98,8 @@ export class ActionController extends createApiController(CreateActionDto, Updat
97
98
  data: tree
98
99
  };
99
100
  }
100
- constructor(actionService){
101
- super(actionService), _define_property(this, "actionService", void 0), this.actionService = actionService;
101
+ constructor(actionService, iamConfigService){
102
+ super(actionService), _define_property(this, "actionService", void 0), _define_property(this, "iamConfigService", void 0), this.actionService = actionService, this.iamConfigService = iamConfigService;
102
103
  }
103
104
  }
104
105
  _ts_decorate([
@@ -107,15 +108,20 @@ _ts_decorate([
107
108
  ApiBearerAuth(),
108
109
  ApiOperation({
109
110
  summary: 'Get actions for permission assignment',
110
- description: 'Returns actions available for permission assignment. If company feature enabled, filtered by company whitelist.'
111
+ description: "Returns actions available for permission assignment, filtered by company whitelist when company feature is enabled. Optional companyId scopes the whitelist to a specific company (must match the caller's own company); defaults to the caller's session company when omitted."
111
112
  }),
112
113
  ApiResponse({
113
114
  status: 200,
114
115
  type: SingleResponseDto
115
116
  }),
116
- _ts_param(0, CurrentUser()),
117
+ ApiBody({
118
+ type: ActionTreeForPermissionDto
119
+ }),
120
+ _ts_param(0, Body()),
121
+ _ts_param(1, CurrentUser()),
117
122
  _ts_metadata("design:type", Function),
118
123
  _ts_metadata("design:paramtypes", [
124
+ typeof ActionTreeForPermissionDto === "undefined" ? Object : ActionTreeForPermissionDto,
119
125
  typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
120
126
  ]),
121
127
  _ts_metadata("design:returntype", Promise)
@@ -149,8 +155,10 @@ ActionController = _ts_decorate([
149
155
  ApiTags('IAM - Actions'),
150
156
  Controller('iam/actions'),
151
157
  _ts_param(0, Inject(ActionService)),
158
+ _ts_param(1, Inject(IAMConfigService)),
152
159
  _ts_metadata("design:type", Function),
153
160
  _ts_metadata("design:paramtypes", [
154
- typeof ActionService === "undefined" ? Object : ActionService
161
+ typeof ActionService === "undefined" ? Object : ActionService,
162
+ typeof IAMConfigService === "undefined" ? Object : IAMConfigService
155
163
  ])
156
164
  ], ActionController);