@flusys/nestjs-iam 7.0.2 → 8.0.0-beta.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.
- package/config/index.d.ts +3 -3
- package/controllers/action.controller.d.ts +4 -4
- package/controllers/company-action-permission.controller.d.ts +2 -2
- package/controllers/index.d.ts +6 -6
- package/controllers/my-permission.controller.d.ts +3 -3
- package/controllers/role-permission.controller.d.ts +4 -4
- package/controllers/role.controller.d.ts +2 -2
- package/controllers/user-action-permission.controller.d.ts +4 -4
- package/docs/iam-swagger.config.d.ts +2 -2
- package/docs/index.d.ts +1 -1
- package/dtos/action.dto.d.ts +2 -2
- package/dtos/index.d.ts +3 -3
- package/entities/action.entity.d.ts +2 -2
- package/entities/index.d.ts +11 -11
- package/entities/permission-with-company.entity.d.ts +1 -1
- package/entities/role-with-company.entity.d.ts +1 -1
- package/entities/role.entity.d.ts +1 -1
- package/entities/user-iam-permission.entity.d.ts +1 -1
- package/enums/index.d.ts +4 -4
- package/fesm/284.js +1262 -0
- package/fesm/867.js +3699 -0
- package/fesm/chunks/364.js +86 -0
- package/fesm/config/index.js +133 -3
- package/fesm/controllers/index.js +18 -7
- package/fesm/docs/index.js +240 -1
- package/fesm/dtos/index.js +1090 -3
- package/fesm/entities/index.js +670 -31
- package/fesm/enums/index.js +97 -4
- package/fesm/helpers/index.js +125 -2
- package/fesm/index.js +806 -11
- package/fesm/interfaces/index.js +17 -3
- package/fesm/modules/index.js +259 -1
- package/fesm/runtime.js +134 -0
- package/fesm/services/index.js +43 -6
- package/fesm/types/index.js +15 -1
- package/helpers/company-access.helper.d.ts +2 -2
- package/helpers/index.d.ts +2 -2
- package/helpers/permission-mode.helper.d.ts +1 -1
- package/index.d.ts +11 -11
- package/interfaces/action.interface.d.ts +2 -2
- package/interfaces/iam-module-options.interface.d.ts +3 -3
- package/interfaces/index.d.ts +3 -3
- package/modules/iam.module.d.ts +2 -2
- package/modules/index.d.ts +1 -1
- package/package.json +30 -37
- package/services/action.service.d.ts +9 -9
- package/services/iam-config.service.d.ts +4 -4
- package/services/iam-datasource.service.d.ts +3 -3
- package/services/index.d.ts +6 -6
- package/services/permission-cache.service.d.ts +5 -5
- package/services/permission.service.d.ts +4 -4
- package/services/role.service.d.ts +8 -8
- package/types/index.d.ts +1 -1
- package/cjs/config/event-actions.js +0 -36
- package/cjs/config/iam.constants.js +0 -11
- package/cjs/config/index.js +0 -20
- package/cjs/config/message-keys.js +0 -71
- package/cjs/controllers/action.controller.js +0 -174
- package/cjs/controllers/action.controller.spec.js +0 -79
- package/cjs/controllers/company-action-permission.controller.js +0 -119
- package/cjs/controllers/company-action-permission.controller.spec.js +0 -65
- package/cjs/controllers/index.js +0 -23
- package/cjs/controllers/my-permission.controller.js +0 -147
- package/cjs/controllers/my-permission.controller.spec.js +0 -128
- package/cjs/controllers/role-permission.controller.js +0 -191
- package/cjs/controllers/role-permission.controller.spec.js +0 -140
- package/cjs/controllers/role.controller.js +0 -102
- package/cjs/controllers/role.controller.spec.js +0 -86
- package/cjs/controllers/user-action-permission.controller.js +0 -129
- package/cjs/controllers/user-action-permission.controller.spec.js +0 -68
- package/cjs/docs/iam-swagger.config.js +0 -209
- package/cjs/docs/iam-swagger.config.spec.js +0 -99
- package/cjs/docs/index.js +0 -18
- package/cjs/dtos/action.dto.js +0 -282
- package/cjs/dtos/index.js +0 -21
- package/cjs/dtos/permission.dto.js +0 -637
- package/cjs/dtos/role.dto.js +0 -155
- package/cjs/entities/action.entity.js +0 -138
- package/cjs/entities/index.js +0 -80
- package/cjs/entities/index.spec.js +0 -56
- package/cjs/entities/permission-base.entity.js +0 -107
- package/cjs/entities/permission-with-company.entity.js +0 -100
- package/cjs/entities/role-base.entity.js +0 -80
- package/cjs/entities/role-with-company.entity.js +0 -55
- package/cjs/entities/role.entity.js +0 -25
- package/cjs/entities/user-iam-permission.entity.js +0 -43
- package/cjs/enums/action-type.enum.js +0 -22
- package/cjs/enums/iam-entity-type.enum.js +0 -17
- package/cjs/enums/iam-permission-type.enum.js +0 -17
- package/cjs/enums/index.js +0 -21
- package/cjs/enums/permission-type.enum.js +0 -16
- package/cjs/helpers/company-access.helper.js +0 -23
- package/cjs/helpers/company-access.helper.spec.js +0 -68
- package/cjs/helpers/index.js +0 -19
- package/cjs/helpers/permission-mode.helper.js +0 -49
- package/cjs/helpers/permission-mode.helper.spec.js +0 -54
- package/cjs/index.js +0 -28
- package/cjs/interfaces/action.interface.js +0 -4
- package/cjs/interfaces/iam-module-options.interface.js +0 -4
- package/cjs/interfaces/index.js +0 -20
- package/cjs/interfaces/role.interface.js +0 -7
- package/cjs/modules/iam.module.js +0 -186
- package/cjs/modules/iam.module.spec.js +0 -282
- package/cjs/modules/index.js +0 -18
- package/cjs/services/action.service.js +0 -337
- package/cjs/services/action.service.spec.js +0 -351
- package/cjs/services/iam-config.service.js +0 -87
- package/cjs/services/iam-config.service.spec.js +0 -110
- package/cjs/services/iam-datasource.service.js +0 -129
- package/cjs/services/iam-datasource.service.spec.js +0 -110
- package/cjs/services/index.js +0 -23
- package/cjs/services/permission-cache.service.js +0 -544
- package/cjs/services/permission-cache.service.spec.js +0 -718
- package/cjs/services/permission.service.js +0 -914
- package/cjs/services/permission.service.spec.js +0 -918
- package/cjs/services/role.service.js +0 -224
- package/cjs/services/role.service.spec.js +0 -347
- package/cjs/types/index.js +0 -18
- package/cjs/types/logic-node.type.js +0 -30
- package/fesm/config/event-actions.js +0 -15
- package/fesm/config/iam.constants.js +0 -1
- package/fesm/config/message-keys.js +0 -35
- package/fesm/controllers/action.controller.js +0 -164
- package/fesm/controllers/action.controller.spec.js +0 -75
- package/fesm/controllers/company-action-permission.controller.js +0 -109
- package/fesm/controllers/company-action-permission.controller.spec.js +0 -61
- package/fesm/controllers/my-permission.controller.js +0 -137
- package/fesm/controllers/my-permission.controller.spec.js +0 -124
- package/fesm/controllers/role-permission.controller.js +0 -181
- package/fesm/controllers/role-permission.controller.spec.js +0 -136
- package/fesm/controllers/role.controller.js +0 -92
- package/fesm/controllers/role.controller.spec.js +0 -82
- package/fesm/controllers/user-action-permission.controller.js +0 -119
- package/fesm/controllers/user-action-permission.controller.spec.js +0 -64
- package/fesm/docs/iam-swagger.config.js +0 -199
- package/fesm/docs/iam-swagger.config.spec.js +0 -95
- package/fesm/dtos/action.dto.js +0 -252
- package/fesm/dtos/permission.dto.js +0 -571
- package/fesm/dtos/role.dto.js +0 -134
- package/fesm/entities/action.entity.js +0 -128
- package/fesm/entities/index.spec.js +0 -52
- package/fesm/entities/permission-base.entity.js +0 -100
- package/fesm/entities/permission-with-company.entity.js +0 -90
- package/fesm/entities/role-base.entity.js +0 -70
- package/fesm/entities/role-with-company.entity.js +0 -45
- package/fesm/entities/role.entity.js +0 -15
- package/fesm/entities/user-iam-permission.entity.js +0 -33
- package/fesm/enums/action-type.enum.js +0 -12
- package/fesm/enums/iam-entity-type.enum.js +0 -7
- package/fesm/enums/iam-permission-type.enum.js +0 -7
- package/fesm/enums/permission-type.enum.js +0 -6
- package/fesm/helpers/company-access.helper.js +0 -18
- package/fesm/helpers/company-access.helper.spec.js +0 -64
- package/fesm/helpers/permission-mode.helper.js +0 -49
- package/fesm/helpers/permission-mode.helper.spec.js +0 -50
- package/fesm/interfaces/action.interface.js +0 -3
- package/fesm/interfaces/iam-module-options.interface.js +0 -3
- package/fesm/interfaces/role.interface.js +0 -4
- package/fesm/modules/iam.module.js +0 -176
- package/fesm/modules/iam.module.spec.js +0 -278
- package/fesm/services/action.service.js +0 -327
- package/fesm/services/action.service.spec.js +0 -347
- package/fesm/services/iam-config.service.js +0 -77
- package/fesm/services/iam-config.service.spec.js +0 -106
- package/fesm/services/iam-datasource.service.js +0 -78
- package/fesm/services/iam-datasource.service.spec.js +0 -106
- package/fesm/services/permission-cache.service.js +0 -527
- package/fesm/services/permission-cache.service.spec.js +0 -714
- package/fesm/services/permission.service.js +0 -904
- package/fesm/services/permission.service.spec.js +0 -914
- package/fesm/services/role.service.js +0 -214
- package/fesm/services/role.service.spec.js +0 -343
- package/fesm/types/logic-node.type.js +0 -27
|
@@ -1,904 +0,0 @@
|
|
|
1
|
-
function _define_property(obj, key, value) {
|
|
2
|
-
if (key in obj) {
|
|
3
|
-
Object.defineProperty(obj, key, {
|
|
4
|
-
value: value,
|
|
5
|
-
enumerable: true,
|
|
6
|
-
configurable: true,
|
|
7
|
-
writable: true
|
|
8
|
-
});
|
|
9
|
-
} else {
|
|
10
|
-
obj[key] = value;
|
|
11
|
-
}
|
|
12
|
-
return obj;
|
|
13
|
-
}
|
|
14
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
15
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
16
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
17
|
-
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
18
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
19
|
-
}
|
|
20
|
-
function _ts_metadata(k, v) {
|
|
21
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
22
|
-
}
|
|
23
|
-
function _ts_param(paramIndex, decorator) {
|
|
24
|
-
return function(target, key) {
|
|
25
|
-
decorator(target, key, paramIndex);
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
import { LogAction } from '@flusys/nestjs-shared';
|
|
29
|
-
import { publishDomainEvent } from '@flusys/nestjs-shared/classes';
|
|
30
|
-
import { BadRequestException, ConflictException, Inject, Injectable, Scope } from '@nestjs/common';
|
|
31
|
-
import { In, IsNull } from 'typeorm';
|
|
32
|
-
import { IAM_EVENT_ACTIONS, IAM_EVENT_ENTITIES, IAM_EVENT_MODULE, IAM_MODE_MESSAGES, PERMISSION_OPERATION_MESSAGES } from '../config';
|
|
33
|
-
import { AssignCompanyActionsDto, AssignRoleActionsDto, AssignUserActionsDto, AssignUserRolesDto, PermissionAction } from '../dtos/permission.dto';
|
|
34
|
-
import { Action } from '../entities/action.entity';
|
|
35
|
-
import { UserIamPermissionWithCompany } from '../entities/permission-with-company.entity';
|
|
36
|
-
import { RoleWithCompany } from '../entities/role-with-company.entity';
|
|
37
|
-
import { Role } from '../entities/role.entity';
|
|
38
|
-
import { UserIamPermission } from '../entities/user-iam-permission.entity';
|
|
39
|
-
import { IamEntityType } from '../enums/iam-entity-type.enum';
|
|
40
|
-
import { IamPermissionType } from '../enums/iam-permission-type.enum';
|
|
41
|
-
import { IAMConfigService } from './iam-config.service';
|
|
42
|
-
import { IAMDataSourceService } from './iam-datasource.service';
|
|
43
|
-
import { PermissionCacheService } from './permission-cache.service';
|
|
44
|
-
export class PermissionService {
|
|
45
|
-
// Repository Getters
|
|
46
|
-
async getPermissionRepository() {
|
|
47
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
48
|
-
const entity = enableCompanyFeature ? UserIamPermissionWithCompany : UserIamPermission;
|
|
49
|
-
return this.dataSourceProvider.getRepository(entity);
|
|
50
|
-
}
|
|
51
|
-
async getActionRepository() {
|
|
52
|
-
return this.dataSourceProvider.getRepository(Action);
|
|
53
|
-
}
|
|
54
|
-
async getRoleRepository() {
|
|
55
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
56
|
-
const entity = enableCompanyFeature ? RoleWithCompany : Role;
|
|
57
|
-
return this.dataSourceProvider.getRepository(entity);
|
|
58
|
-
}
|
|
59
|
-
async getActionsMap(actionIds) {
|
|
60
|
-
const actionRepo = await this.getActionRepository();
|
|
61
|
-
const actions = await actionRepo.find({
|
|
62
|
-
where: {
|
|
63
|
-
id: In(actionIds)
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
return new Map(actions.map((a)=>[
|
|
67
|
-
a.id,
|
|
68
|
-
a
|
|
69
|
-
]));
|
|
70
|
-
}
|
|
71
|
-
// User-Action Permissions
|
|
72
|
-
async assignUserActions(dto) {
|
|
73
|
-
if (!this.iamConfigService.isDirectPermissionEnabled()) {
|
|
74
|
-
throw new BadRequestException({
|
|
75
|
-
message: 'Direct permission assignment not available in RBAC-only mode. Use role-based permissions instead.',
|
|
76
|
-
messageKey: IAM_MODE_MESSAGES.DIRECT_MODE_UNAVAILABLE
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
80
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
81
|
-
const branchId = dto.branchId ?? null;
|
|
82
|
-
const companyId = dto.companyId ?? null;
|
|
83
|
-
const { toAdd: itemsToAdd, toRemove: itemsToRemove } = this.splitItemsByAction(dto.items);
|
|
84
|
-
let added = 0;
|
|
85
|
-
let removed = 0;
|
|
86
|
-
if (itemsToAdd.length > 0) {
|
|
87
|
-
const actionIdsToAdd = itemsToAdd.map((item)=>item.id);
|
|
88
|
-
const whereFind = {
|
|
89
|
-
permissionType: IamPermissionType.USER_ACTION,
|
|
90
|
-
sourceType: IamEntityType.USER,
|
|
91
|
-
sourceId: dto.userId,
|
|
92
|
-
targetType: IamEntityType.ACTION,
|
|
93
|
-
targetId: In(actionIdsToAdd)
|
|
94
|
-
};
|
|
95
|
-
if (enableCompanyFeature) {
|
|
96
|
-
if (companyId) whereFind.companyId = companyId;
|
|
97
|
-
if (branchId) whereFind.branchId = branchId;
|
|
98
|
-
}
|
|
99
|
-
const existingPermissions = await permissionRepo.find({
|
|
100
|
-
where: whereFind,
|
|
101
|
-
select: [
|
|
102
|
-
'targetId'
|
|
103
|
-
]
|
|
104
|
-
});
|
|
105
|
-
const existingActionIds = new Set(existingPermissions.map((p)=>p.targetId));
|
|
106
|
-
const newPermissions = itemsToAdd.filter((item)=>!existingActionIds.has(item.id)).map((item)=>({
|
|
107
|
-
permissionType: IamPermissionType.USER_ACTION,
|
|
108
|
-
sourceType: IamEntityType.USER,
|
|
109
|
-
sourceId: dto.userId,
|
|
110
|
-
targetType: IamEntityType.ACTION,
|
|
111
|
-
targetId: item.id,
|
|
112
|
-
companyId: enableCompanyFeature ? companyId : null,
|
|
113
|
-
branchId: enableCompanyFeature ? branchId : null
|
|
114
|
-
}));
|
|
115
|
-
if (newPermissions.length > 0) {
|
|
116
|
-
try {
|
|
117
|
-
await permissionRepo.save(newPermissions);
|
|
118
|
-
added = newPermissions.length;
|
|
119
|
-
} catch (error) {
|
|
120
|
-
if (error?.code === 'ER_DUP_ENTRY' || error?.message?.includes('Duplicate entry')) {
|
|
121
|
-
throw new ConflictException({
|
|
122
|
-
message: 'Some permissions already exist for this user. Please refresh and try again.',
|
|
123
|
-
messageKey: PERMISSION_OPERATION_MESSAGES.ALREADY_EXISTS
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
throw error;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (itemsToRemove.length > 0) {
|
|
131
|
-
const actionIdsToRemove = itemsToRemove.map((item)=>item.id);
|
|
132
|
-
const whereDelete = {
|
|
133
|
-
permissionType: IamPermissionType.USER_ACTION,
|
|
134
|
-
sourceType: IamEntityType.USER,
|
|
135
|
-
sourceId: dto.userId,
|
|
136
|
-
targetType: IamEntityType.ACTION,
|
|
137
|
-
targetId: In(actionIdsToRemove)
|
|
138
|
-
};
|
|
139
|
-
if (enableCompanyFeature) {
|
|
140
|
-
if (companyId) whereDelete.companyId = companyId;
|
|
141
|
-
if (branchId) whereDelete.branchId = branchId;
|
|
142
|
-
}
|
|
143
|
-
const result = await permissionRepo.delete(whereDelete);
|
|
144
|
-
removed = result.affected || 0;
|
|
145
|
-
}
|
|
146
|
-
await this.permissionCacheService.invalidateUser(dto.userId, enableCompanyFeature ? companyId : null, enableCompanyFeature ? [
|
|
147
|
-
branchId
|
|
148
|
-
] : []);
|
|
149
|
-
const result = this.buildOperationResult(dto.items.length, added, removed);
|
|
150
|
-
await this.publishAssignmentEvent(IAM_EVENT_ENTITIES.USER_ACTION, dto.userId, result);
|
|
151
|
-
return result;
|
|
152
|
-
}
|
|
153
|
-
async getUserActions(userId, companyId, branchId) {
|
|
154
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
155
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
156
|
-
const where = {
|
|
157
|
-
permissionType: IamPermissionType.USER_ACTION,
|
|
158
|
-
sourceType: IamEntityType.USER,
|
|
159
|
-
sourceId: userId
|
|
160
|
-
};
|
|
161
|
-
if (enableCompanyFeature) {
|
|
162
|
-
if (companyId) where.companyId = companyId;
|
|
163
|
-
if (branchId) where.branchId = branchId;
|
|
164
|
-
}
|
|
165
|
-
const permissions = await permissionRepo.find({
|
|
166
|
-
where
|
|
167
|
-
});
|
|
168
|
-
if (permissions.length === 0) {
|
|
169
|
-
return [];
|
|
170
|
-
}
|
|
171
|
-
const actionIds = permissions.map((p)=>p.targetId);
|
|
172
|
-
const actionMap = await this.getActionsMap(actionIds);
|
|
173
|
-
return permissions.filter((p)=>actionMap.has(p.targetId)).map((p)=>{
|
|
174
|
-
const action = actionMap.get(p.targetId);
|
|
175
|
-
return {
|
|
176
|
-
id: p.id,
|
|
177
|
-
userId: p.sourceId,
|
|
178
|
-
actionId: action.id,
|
|
179
|
-
actionCode: action.code ?? '',
|
|
180
|
-
actionName: action.name,
|
|
181
|
-
companyId: ('companyId' in p ? p.companyId : null) ?? null,
|
|
182
|
-
branchId: ('branchId' in p ? p.branchId : null) ?? null,
|
|
183
|
-
createdAt: p.createdAt
|
|
184
|
-
};
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
// Role-Action Permissions
|
|
188
|
-
async assignRoleActions(dto) {
|
|
189
|
-
if (!this.iamConfigService.isRbacEnabled()) {
|
|
190
|
-
throw new BadRequestException({
|
|
191
|
-
message: 'Role-based permission assignment not available in DIRECT-only mode. Use direct user permissions instead.',
|
|
192
|
-
messageKey: IAM_MODE_MESSAGES.RBAC_MODE_UNAVAILABLE
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
196
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
197
|
-
let roleCompanyId = null;
|
|
198
|
-
if (enableCompanyFeature) {
|
|
199
|
-
const roleRepo = await this.getRoleRepository();
|
|
200
|
-
const role = await roleRepo.findOne({
|
|
201
|
-
where: {
|
|
202
|
-
id: dto.roleId
|
|
203
|
-
},
|
|
204
|
-
select: [
|
|
205
|
-
'id',
|
|
206
|
-
'companyId'
|
|
207
|
-
]
|
|
208
|
-
});
|
|
209
|
-
roleCompanyId = role?.companyId ?? null;
|
|
210
|
-
}
|
|
211
|
-
const { toAdd: itemsToAdd, toRemove: itemsToRemove } = this.splitItemsByAction(dto.items);
|
|
212
|
-
let added = 0;
|
|
213
|
-
let removed = 0;
|
|
214
|
-
if (itemsToAdd.length > 0) {
|
|
215
|
-
const actionIdsToAdd = itemsToAdd.map((item)=>item.id);
|
|
216
|
-
const existingPermissions = await permissionRepo.find({
|
|
217
|
-
where: {
|
|
218
|
-
permissionType: IamPermissionType.ROLE_ACTION,
|
|
219
|
-
sourceType: IamEntityType.ROLE,
|
|
220
|
-
sourceId: dto.roleId,
|
|
221
|
-
targetType: IamEntityType.ACTION,
|
|
222
|
-
targetId: In(actionIdsToAdd)
|
|
223
|
-
},
|
|
224
|
-
select: [
|
|
225
|
-
'targetId'
|
|
226
|
-
]
|
|
227
|
-
});
|
|
228
|
-
const existingActionIds = new Set(existingPermissions.map((p)=>p.targetId));
|
|
229
|
-
const newPermissions = itemsToAdd.filter((item)=>!existingActionIds.has(item.id)).map((item)=>({
|
|
230
|
-
permissionType: IamPermissionType.ROLE_ACTION,
|
|
231
|
-
sourceType: IamEntityType.ROLE,
|
|
232
|
-
sourceId: dto.roleId,
|
|
233
|
-
targetType: IamEntityType.ACTION,
|
|
234
|
-
targetId: item.id,
|
|
235
|
-
companyId: enableCompanyFeature ? roleCompanyId : null,
|
|
236
|
-
branchId: null
|
|
237
|
-
}));
|
|
238
|
-
if (newPermissions.length > 0) {
|
|
239
|
-
try {
|
|
240
|
-
await permissionRepo.save(newPermissions);
|
|
241
|
-
added = newPermissions.length;
|
|
242
|
-
} catch (error) {
|
|
243
|
-
if (error?.code === 'ER_DUP_ENTRY' || error?.message?.includes('Duplicate entry')) {
|
|
244
|
-
throw new ConflictException({
|
|
245
|
-
message: 'Some role-action permissions already exist. Please refresh and try again.',
|
|
246
|
-
messageKey: PERMISSION_OPERATION_MESSAGES.ALREADY_EXISTS
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
throw error;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
if (itemsToRemove.length > 0) {
|
|
254
|
-
const actionIdsToRemove = itemsToRemove.map((item)=>item.id);
|
|
255
|
-
const result = await permissionRepo.delete({
|
|
256
|
-
permissionType: IamPermissionType.ROLE_ACTION,
|
|
257
|
-
sourceType: IamEntityType.ROLE,
|
|
258
|
-
sourceId: dto.roleId,
|
|
259
|
-
targetType: IamEntityType.ACTION,
|
|
260
|
-
targetId: In(actionIdsToRemove)
|
|
261
|
-
});
|
|
262
|
-
removed = result.affected || 0;
|
|
263
|
-
}
|
|
264
|
-
await this.permissionCacheService.invalidateRoleMembersCache(dto.roleId);
|
|
265
|
-
const result = this.buildOperationResult(dto.items.length, added, removed);
|
|
266
|
-
await this.publishAssignmentEvent(IAM_EVENT_ENTITIES.ROLE_ACTION, dto.roleId, result);
|
|
267
|
-
return result;
|
|
268
|
-
}
|
|
269
|
-
async getRoleActions(roleId) {
|
|
270
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
271
|
-
const permissions = await permissionRepo.find({
|
|
272
|
-
where: {
|
|
273
|
-
permissionType: IamPermissionType.ROLE_ACTION,
|
|
274
|
-
sourceType: IamEntityType.ROLE,
|
|
275
|
-
sourceId: roleId
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
if (permissions.length === 0) {
|
|
279
|
-
return [];
|
|
280
|
-
}
|
|
281
|
-
const actionIds = permissions.map((p)=>p.targetId);
|
|
282
|
-
const actionMap = await this.getActionsMap(actionIds);
|
|
283
|
-
return permissions.filter((p)=>actionMap.has(p.targetId)).map((p)=>{
|
|
284
|
-
const action = actionMap.get(p.targetId);
|
|
285
|
-
return {
|
|
286
|
-
id: p.id,
|
|
287
|
-
roleId: p.sourceId,
|
|
288
|
-
actionId: action.id,
|
|
289
|
-
actionCode: action.code ?? '',
|
|
290
|
-
actionName: action.name,
|
|
291
|
-
createdAt: p.createdAt
|
|
292
|
-
};
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
// Company-Action Permissions (Whitelist)
|
|
296
|
-
/** Assign or remove actions to/from a company (whitelist) */ async assignCompanyActions(dto) {
|
|
297
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
298
|
-
const dataSource = await this.dataSourceProvider.getDataSource();
|
|
299
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
300
|
-
const { toAdd: itemsToAdd, toRemove: itemsToRemove } = this.splitItemsByAction(dto.items);
|
|
301
|
-
let added = 0;
|
|
302
|
-
let removed = 0;
|
|
303
|
-
await dataSource.transaction(async (manager)=>{
|
|
304
|
-
const transactionalPermissionRepo = manager.getRepository(permissionRepo.target);
|
|
305
|
-
if (itemsToAdd.length > 0) {
|
|
306
|
-
const actionIdsToAdd = itemsToAdd.map((item)=>item.id);
|
|
307
|
-
const existingPermissions = await transactionalPermissionRepo.find({
|
|
308
|
-
where: {
|
|
309
|
-
permissionType: IamPermissionType.COMPANY_ACTION,
|
|
310
|
-
sourceType: IamEntityType.COMPANY,
|
|
311
|
-
sourceId: dto.companyId,
|
|
312
|
-
targetType: IamEntityType.ACTION,
|
|
313
|
-
targetId: In(actionIdsToAdd)
|
|
314
|
-
},
|
|
315
|
-
select: [
|
|
316
|
-
'targetId'
|
|
317
|
-
]
|
|
318
|
-
});
|
|
319
|
-
const existingActionIds = new Set(existingPermissions.map((p)=>p.targetId));
|
|
320
|
-
const newActionIds = actionIdsToAdd.filter((id)=>!existingActionIds.has(id));
|
|
321
|
-
if (newActionIds.length > 0) {
|
|
322
|
-
const newPermissions = newActionIds.map((actionId)=>transactionalPermissionRepo.create({
|
|
323
|
-
permissionType: IamPermissionType.COMPANY_ACTION,
|
|
324
|
-
sourceType: IamEntityType.COMPANY,
|
|
325
|
-
sourceId: dto.companyId,
|
|
326
|
-
targetType: IamEntityType.ACTION,
|
|
327
|
-
targetId: actionId
|
|
328
|
-
}));
|
|
329
|
-
await transactionalPermissionRepo.save(newPermissions);
|
|
330
|
-
added = newPermissions.length;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
if (itemsToRemove.length > 0) {
|
|
334
|
-
const actionIdsToRemove = itemsToRemove.map((item)=>item.id);
|
|
335
|
-
const companyResult = await transactionalPermissionRepo.delete({
|
|
336
|
-
permissionType: IamPermissionType.COMPANY_ACTION,
|
|
337
|
-
sourceType: IamEntityType.COMPANY,
|
|
338
|
-
sourceId: dto.companyId,
|
|
339
|
-
targetType: IamEntityType.ACTION,
|
|
340
|
-
targetId: In(actionIdsToRemove)
|
|
341
|
-
});
|
|
342
|
-
removed = companyResult.affected || 0;
|
|
343
|
-
// Cascade: an action no longer on the company whitelist must not remain
|
|
344
|
-
// reachable via role grants or direct user grants scoped to this company.
|
|
345
|
-
const roleEntity = enableCompanyFeature ? RoleWithCompany : Role;
|
|
346
|
-
const roleRepo = manager.getRepository(roleEntity);
|
|
347
|
-
const companyRoles = await roleRepo.find({
|
|
348
|
-
where: {
|
|
349
|
-
companyId: dto.companyId,
|
|
350
|
-
deletedAt: IsNull()
|
|
351
|
-
},
|
|
352
|
-
select: [
|
|
353
|
-
'id'
|
|
354
|
-
]
|
|
355
|
-
});
|
|
356
|
-
if (companyRoles.length > 0) {
|
|
357
|
-
const roleIds = companyRoles.map((role)=>role.id);
|
|
358
|
-
await transactionalPermissionRepo.delete({
|
|
359
|
-
permissionType: IamPermissionType.ROLE_ACTION,
|
|
360
|
-
sourceType: IamEntityType.ROLE,
|
|
361
|
-
sourceId: In(roleIds),
|
|
362
|
-
targetType: IamEntityType.ACTION,
|
|
363
|
-
targetId: In(actionIdsToRemove)
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
if (enableCompanyFeature) {
|
|
367
|
-
await transactionalPermissionRepo.delete({
|
|
368
|
-
permissionType: IamPermissionType.USER_ACTION,
|
|
369
|
-
companyId: dto.companyId,
|
|
370
|
-
targetType: IamEntityType.ACTION,
|
|
371
|
-
targetId: In(actionIdsToRemove)
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
await this.permissionCacheService.invalidateCompanyMembersCache(dto.companyId);
|
|
377
|
-
const result = this.buildOperationResult(dto.items.length, added, removed);
|
|
378
|
-
await this.publishAssignmentEvent(IAM_EVENT_ENTITIES.COMPANY_ACTION, dto.companyId, result);
|
|
379
|
-
return result;
|
|
380
|
-
}
|
|
381
|
-
/** Get all actions assigned to a company (whitelist) */ async getCompanyActions(companyId, isOnlyId = false) {
|
|
382
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
383
|
-
const permissions = await permissionRepo.find({
|
|
384
|
-
where: {
|
|
385
|
-
permissionType: IamPermissionType.COMPANY_ACTION,
|
|
386
|
-
sourceType: IamEntityType.COMPANY,
|
|
387
|
-
sourceId: companyId
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
if (permissions.length === 0) {
|
|
391
|
-
return [];
|
|
392
|
-
}
|
|
393
|
-
const actionIds = permissions.map((p)=>p.targetId);
|
|
394
|
-
if (isOnlyId) return actionIds;
|
|
395
|
-
const actionMap = await this.getActionsMap(actionIds);
|
|
396
|
-
return permissions.filter((p)=>actionMap.has(p.targetId)).map((p)=>{
|
|
397
|
-
const action = actionMap.get(p.targetId);
|
|
398
|
-
return {
|
|
399
|
-
id: p.id,
|
|
400
|
-
companyId: companyId,
|
|
401
|
-
actionId: action.id,
|
|
402
|
-
actionCode: action.code ?? '',
|
|
403
|
-
actionName: action.name,
|
|
404
|
-
createdAt: p.createdAt
|
|
405
|
-
};
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
// User-Role Permissions
|
|
409
|
-
/** Assign user to roles (branch-scoped when company feature is enabled) */ async assignUserRoles(dto) {
|
|
410
|
-
if (!this.iamConfigService.isRbacEnabled()) {
|
|
411
|
-
throw new BadRequestException({
|
|
412
|
-
message: 'Role assignment not available in DIRECT-only mode. Use direct user permissions instead.',
|
|
413
|
-
messageKey: IAM_MODE_MESSAGES.ROLE_ASSIGNMENT_UNAVAILABLE
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
417
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
418
|
-
const branchId = dto.branchId ?? null;
|
|
419
|
-
const companyId = dto.companyId ?? null;
|
|
420
|
-
const { toAdd: itemsToAdd, toRemove: itemsToRemove } = this.splitItemsByAction(dto.items);
|
|
421
|
-
let added = 0;
|
|
422
|
-
let removed = 0;
|
|
423
|
-
if (itemsToAdd.length > 0) {
|
|
424
|
-
const roleIdsToAdd = itemsToAdd.map((item)=>item.id);
|
|
425
|
-
const whereFind = {
|
|
426
|
-
permissionType: IamPermissionType.USER_ROLE,
|
|
427
|
-
sourceType: IamEntityType.USER,
|
|
428
|
-
sourceId: dto.userId,
|
|
429
|
-
targetType: IamEntityType.ROLE,
|
|
430
|
-
targetId: In(roleIdsToAdd)
|
|
431
|
-
};
|
|
432
|
-
if (enableCompanyFeature) {
|
|
433
|
-
if (companyId) whereFind.companyId = companyId;
|
|
434
|
-
if (branchId) whereFind.branchId = branchId;
|
|
435
|
-
}
|
|
436
|
-
const existingPermissions = await permissionRepo.find({
|
|
437
|
-
where: whereFind,
|
|
438
|
-
select: [
|
|
439
|
-
'targetId'
|
|
440
|
-
]
|
|
441
|
-
});
|
|
442
|
-
const existingRoleIds = new Set(existingPermissions.map((p)=>p.targetId));
|
|
443
|
-
const newPermissions = itemsToAdd.filter((item)=>!existingRoleIds.has(item.id)).map((item)=>({
|
|
444
|
-
permissionType: IamPermissionType.USER_ROLE,
|
|
445
|
-
sourceType: IamEntityType.USER,
|
|
446
|
-
sourceId: dto.userId,
|
|
447
|
-
targetType: IamEntityType.ROLE,
|
|
448
|
-
targetId: item.id,
|
|
449
|
-
companyId: enableCompanyFeature ? companyId : null,
|
|
450
|
-
branchId: enableCompanyFeature ? branchId : null
|
|
451
|
-
}));
|
|
452
|
-
if (newPermissions.length > 0) {
|
|
453
|
-
try {
|
|
454
|
-
await permissionRepo.save(newPermissions);
|
|
455
|
-
added = newPermissions.length;
|
|
456
|
-
} catch (error) {
|
|
457
|
-
if (error?.code === 'ER_DUP_ENTRY' || error?.message?.includes('Duplicate entry')) {
|
|
458
|
-
throw new ConflictException({
|
|
459
|
-
message: 'Some user-role permissions already exist. Please refresh and try again.',
|
|
460
|
-
messageKey: PERMISSION_OPERATION_MESSAGES.ALREADY_EXISTS
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
throw error;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
if (itemsToRemove.length > 0) {
|
|
468
|
-
const roleIdsToRemove = itemsToRemove.map((item)=>item.id);
|
|
469
|
-
const whereDelete = {
|
|
470
|
-
permissionType: IamPermissionType.USER_ROLE,
|
|
471
|
-
sourceType: IamEntityType.USER,
|
|
472
|
-
sourceId: dto.userId,
|
|
473
|
-
targetType: IamEntityType.ROLE,
|
|
474
|
-
targetId: In(roleIdsToRemove)
|
|
475
|
-
};
|
|
476
|
-
if (enableCompanyFeature) {
|
|
477
|
-
if (companyId) whereDelete.companyId = companyId;
|
|
478
|
-
if (branchId) whereDelete.branchId = branchId;
|
|
479
|
-
}
|
|
480
|
-
const result = await permissionRepo.delete(whereDelete);
|
|
481
|
-
removed = result.affected || 0;
|
|
482
|
-
}
|
|
483
|
-
await this.permissionCacheService.invalidateUser(dto.userId, enableCompanyFeature ? companyId : null, [
|
|
484
|
-
branchId
|
|
485
|
-
]);
|
|
486
|
-
const result = this.buildOperationResult(dto.items.length, added, removed);
|
|
487
|
-
await this.publishAssignmentEvent(IAM_EVENT_ENTITIES.USER_ROLE, dto.userId, result);
|
|
488
|
-
return result;
|
|
489
|
-
}
|
|
490
|
-
/** Get user's roles (branch-scoped, filtered by companyId and branchId if provided) */ async getUserRoles(userId, branchId, companyId) {
|
|
491
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
492
|
-
const roleRepo = await this.getRoleRepository();
|
|
493
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
494
|
-
const where = {
|
|
495
|
-
permissionType: IamPermissionType.USER_ROLE,
|
|
496
|
-
sourceType: IamEntityType.USER,
|
|
497
|
-
sourceId: userId
|
|
498
|
-
};
|
|
499
|
-
if (enableCompanyFeature) {
|
|
500
|
-
if (companyId) where.companyId = companyId;
|
|
501
|
-
if (branchId) where.branchId = branchId;
|
|
502
|
-
}
|
|
503
|
-
const permissions = await permissionRepo.find({
|
|
504
|
-
where
|
|
505
|
-
});
|
|
506
|
-
if (permissions.length === 0) {
|
|
507
|
-
return [];
|
|
508
|
-
}
|
|
509
|
-
const roleIds = permissions.map((p)=>p.targetId);
|
|
510
|
-
const roleWhere = {
|
|
511
|
-
id: In(roleIds)
|
|
512
|
-
};
|
|
513
|
-
const roles = await roleRepo.find({
|
|
514
|
-
where: roleWhere
|
|
515
|
-
});
|
|
516
|
-
const roleMap = new Map(roles.map((r)=>[
|
|
517
|
-
r.id,
|
|
518
|
-
r
|
|
519
|
-
]));
|
|
520
|
-
return permissions.filter((p)=>roleMap.has(p.targetId)).map((p)=>{
|
|
521
|
-
const role = roleMap.get(p.targetId);
|
|
522
|
-
const permissionEntity = p;
|
|
523
|
-
return {
|
|
524
|
-
id: p.id,
|
|
525
|
-
userId: p.sourceId,
|
|
526
|
-
roleId: role.id,
|
|
527
|
-
roleName: role.name,
|
|
528
|
-
branchId: enableCompanyFeature ? permissionEntity.branchId ?? null : null,
|
|
529
|
-
createdAt: p.createdAt
|
|
530
|
-
};
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
// Effective (Merged) Permissions — self-scoped, company-wide + branch-specific
|
|
534
|
-
/** Get user's effective roles: company-wide (branchId null) merged with branch-specific */ async getUserEffectiveRoles(userId, companyId, branchId) {
|
|
535
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
536
|
-
const roleRepo = await this.getRoleRepository();
|
|
537
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
538
|
-
const baseWhere = {
|
|
539
|
-
permissionType: IamPermissionType.USER_ROLE,
|
|
540
|
-
sourceType: IamEntityType.USER,
|
|
541
|
-
sourceId: userId
|
|
542
|
-
};
|
|
543
|
-
if (enableCompanyFeature && companyId) baseWhere.companyId = companyId;
|
|
544
|
-
const permissions = enableCompanyFeature && branchId ? await permissionRepo.find({
|
|
545
|
-
where: [
|
|
546
|
-
{
|
|
547
|
-
...baseWhere,
|
|
548
|
-
branchId: IsNull()
|
|
549
|
-
},
|
|
550
|
-
{
|
|
551
|
-
...baseWhere,
|
|
552
|
-
branchId
|
|
553
|
-
}
|
|
554
|
-
]
|
|
555
|
-
}) : await permissionRepo.find({
|
|
556
|
-
where: baseWhere
|
|
557
|
-
});
|
|
558
|
-
const validPermissions = permissions.filter((p)=>p.isValid());
|
|
559
|
-
if (validPermissions.length === 0) {
|
|
560
|
-
return [];
|
|
561
|
-
}
|
|
562
|
-
const roleIds = [
|
|
563
|
-
...new Set(validPermissions.map((p)=>p.targetId))
|
|
564
|
-
];
|
|
565
|
-
const roles = await roleRepo.find({
|
|
566
|
-
where: {
|
|
567
|
-
id: In(roleIds)
|
|
568
|
-
}
|
|
569
|
-
});
|
|
570
|
-
const roleMap = new Map(roles.map((r)=>[
|
|
571
|
-
r.id,
|
|
572
|
-
r
|
|
573
|
-
]));
|
|
574
|
-
return validPermissions.filter((p)=>roleMap.has(p.targetId)).map((p)=>{
|
|
575
|
-
const role = roleMap.get(p.targetId);
|
|
576
|
-
return {
|
|
577
|
-
id: p.id,
|
|
578
|
-
userId: p.sourceId,
|
|
579
|
-
roleId: role.id,
|
|
580
|
-
roleName: role.name,
|
|
581
|
-
branchId: enableCompanyFeature ? p.branchId ?? null : null,
|
|
582
|
-
createdAt: p.createdAt
|
|
583
|
-
};
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
/** Get user's effective actions: company-wide (branchId null) merged with branch-specific */ async getUserEffectiveActions(userId, companyId, branchId) {
|
|
587
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
588
|
-
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
589
|
-
const baseWhere = {
|
|
590
|
-
permissionType: IamPermissionType.USER_ACTION,
|
|
591
|
-
sourceType: IamEntityType.USER,
|
|
592
|
-
sourceId: userId
|
|
593
|
-
};
|
|
594
|
-
if (enableCompanyFeature && companyId) baseWhere.companyId = companyId;
|
|
595
|
-
const permissions = enableCompanyFeature && branchId ? await permissionRepo.find({
|
|
596
|
-
where: [
|
|
597
|
-
{
|
|
598
|
-
...baseWhere,
|
|
599
|
-
branchId: IsNull()
|
|
600
|
-
},
|
|
601
|
-
{
|
|
602
|
-
...baseWhere,
|
|
603
|
-
branchId
|
|
604
|
-
}
|
|
605
|
-
]
|
|
606
|
-
}) : await permissionRepo.find({
|
|
607
|
-
where: baseWhere
|
|
608
|
-
});
|
|
609
|
-
const validPermissions = permissions.filter((p)=>p.isValid());
|
|
610
|
-
if (validPermissions.length === 0) {
|
|
611
|
-
return [];
|
|
612
|
-
}
|
|
613
|
-
const actionIds = [
|
|
614
|
-
...new Set(validPermissions.map((p)=>p.targetId))
|
|
615
|
-
];
|
|
616
|
-
const actionMap = await this.getActionsMap(actionIds);
|
|
617
|
-
return validPermissions.filter((p)=>actionMap.has(p.targetId)).map((p)=>{
|
|
618
|
-
const action = actionMap.get(p.targetId);
|
|
619
|
-
return {
|
|
620
|
-
id: p.id,
|
|
621
|
-
userId: p.sourceId,
|
|
622
|
-
actionId: action.id,
|
|
623
|
-
actionCode: action.code ?? '',
|
|
624
|
-
actionName: action.name,
|
|
625
|
-
companyId: ('companyId' in p ? p.companyId : null) ?? null,
|
|
626
|
-
branchId: ('branchId' in p ? p.branchId : null) ?? null,
|
|
627
|
-
createdAt: p.createdAt
|
|
628
|
-
};
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
// My Permissions
|
|
632
|
-
/** Get user's effective permissions (cache-first approach) */ async getMyPermissions(userId, branchId, companyId, parentCodes) {
|
|
633
|
-
return this.permissionCacheService.getMyPermissionsResponse(userId, branchId, companyId, parentCodes);
|
|
634
|
-
}
|
|
635
|
-
// Helper Methods
|
|
636
|
-
/** Split permission items into add and remove arrays */ splitItemsByAction(items) {
|
|
637
|
-
return {
|
|
638
|
-
toAdd: items.filter((item)=>item.action === PermissionAction.ADD),
|
|
639
|
-
toRemove: items.filter((item)=>item.action === PermissionAction.REMOVE)
|
|
640
|
-
};
|
|
641
|
-
}
|
|
642
|
-
async publishAssignmentEvent(entity, targetId, result) {
|
|
643
|
-
await publishDomainEvent({
|
|
644
|
-
module: IAM_EVENT_MODULE,
|
|
645
|
-
entity,
|
|
646
|
-
action: IAM_EVENT_ACTIONS.PERMISSIONS_ASSIGNED,
|
|
647
|
-
ids: [
|
|
648
|
-
targetId
|
|
649
|
-
],
|
|
650
|
-
metadata: {
|
|
651
|
-
added: result.added,
|
|
652
|
-
removed: result.removed,
|
|
653
|
-
total: result.total
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
/** Build standard operation result DTO */ buildOperationResult(_totalItems, added, removed) {
|
|
658
|
-
return {
|
|
659
|
-
added,
|
|
660
|
-
removed,
|
|
661
|
-
total: _totalItems
|
|
662
|
-
};
|
|
663
|
-
}
|
|
664
|
-
async revokeCompanyPermissions(companyId) {
|
|
665
|
-
if (!this.iamConfigService.isCompanyFeatureEnabled()) {
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
669
|
-
const roleRepo = await this.getRoleRepository();
|
|
670
|
-
const dataSource = await this.dataSourceProvider.getDataSource();
|
|
671
|
-
const companyRoles = await roleRepo.find({
|
|
672
|
-
where: {
|
|
673
|
-
companyId,
|
|
674
|
-
deletedAt: IsNull()
|
|
675
|
-
},
|
|
676
|
-
select: [
|
|
677
|
-
'id'
|
|
678
|
-
]
|
|
679
|
-
});
|
|
680
|
-
const roleIds = companyRoles.map((role)=>role.id);
|
|
681
|
-
const affectedUserRows = await permissionRepo.find({
|
|
682
|
-
where: {
|
|
683
|
-
permissionType: In([
|
|
684
|
-
IamPermissionType.USER_ROLE,
|
|
685
|
-
IamPermissionType.USER_ACTION
|
|
686
|
-
]),
|
|
687
|
-
sourceType: IamEntityType.USER,
|
|
688
|
-
companyId
|
|
689
|
-
},
|
|
690
|
-
select: [
|
|
691
|
-
'sourceId'
|
|
692
|
-
]
|
|
693
|
-
});
|
|
694
|
-
const affectedUserIds = [
|
|
695
|
-
...new Set(affectedUserRows.map((row)=>row.sourceId))
|
|
696
|
-
];
|
|
697
|
-
await dataSource.transaction(async (manager)=>{
|
|
698
|
-
const txRepo = manager.getRepository(permissionRepo.target);
|
|
699
|
-
await txRepo.delete({
|
|
700
|
-
permissionType: IamPermissionType.COMPANY_ACTION,
|
|
701
|
-
sourceType: IamEntityType.COMPANY,
|
|
702
|
-
sourceId: companyId
|
|
703
|
-
});
|
|
704
|
-
if (roleIds.length > 0) {
|
|
705
|
-
await txRepo.delete({
|
|
706
|
-
permissionType: IamPermissionType.ROLE_ACTION,
|
|
707
|
-
sourceType: IamEntityType.ROLE,
|
|
708
|
-
sourceId: In(roleIds)
|
|
709
|
-
});
|
|
710
|
-
}
|
|
711
|
-
await txRepo.delete({
|
|
712
|
-
permissionType: In([
|
|
713
|
-
IamPermissionType.USER_ROLE,
|
|
714
|
-
IamPermissionType.USER_ACTION
|
|
715
|
-
]),
|
|
716
|
-
companyId
|
|
717
|
-
});
|
|
718
|
-
if (roleIds.length > 0) {
|
|
719
|
-
const txRoleRepo = manager.getRepository(roleRepo.target);
|
|
720
|
-
await txRoleRepo.delete(roleIds);
|
|
721
|
-
}
|
|
722
|
-
});
|
|
723
|
-
if (affectedUserIds.length > 0) {
|
|
724
|
-
await this.permissionCacheService.invalidateUsers(affectedUserIds, companyId);
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
async revokeBranchPermissions(branchId, companyId) {
|
|
728
|
-
if (!this.iamConfigService.isCompanyFeatureEnabled()) {
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
732
|
-
const where = {
|
|
733
|
-
permissionType: In([
|
|
734
|
-
IamPermissionType.USER_ROLE,
|
|
735
|
-
IamPermissionType.USER_ACTION
|
|
736
|
-
]),
|
|
737
|
-
companyId,
|
|
738
|
-
branchId
|
|
739
|
-
};
|
|
740
|
-
const affectedUserRows = await permissionRepo.find({
|
|
741
|
-
where: {
|
|
742
|
-
...where,
|
|
743
|
-
sourceType: IamEntityType.USER
|
|
744
|
-
},
|
|
745
|
-
select: [
|
|
746
|
-
'sourceId'
|
|
747
|
-
]
|
|
748
|
-
});
|
|
749
|
-
const affectedUserIds = [
|
|
750
|
-
...new Set(affectedUserRows.map((row)=>row.sourceId))
|
|
751
|
-
];
|
|
752
|
-
await permissionRepo.delete(where);
|
|
753
|
-
if (affectedUserIds.length > 0) {
|
|
754
|
-
await this.permissionCacheService.invalidateUsers(affectedUserIds, companyId, [
|
|
755
|
-
branchId
|
|
756
|
-
]);
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
async revokeUserCompanyAccess(userId, companyId) {
|
|
760
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
761
|
-
await permissionRepo.delete({
|
|
762
|
-
permissionType: In([
|
|
763
|
-
IamPermissionType.USER_ROLE,
|
|
764
|
-
IamPermissionType.USER_ACTION
|
|
765
|
-
]),
|
|
766
|
-
sourceType: IamEntityType.USER,
|
|
767
|
-
sourceId: userId,
|
|
768
|
-
companyId
|
|
769
|
-
});
|
|
770
|
-
await this.permissionCacheService.invalidateUser(userId, companyId);
|
|
771
|
-
}
|
|
772
|
-
async revokeUserBranchAccess(userId, branchId, companyId) {
|
|
773
|
-
const permissionRepo = await this.getPermissionRepository();
|
|
774
|
-
const where = {
|
|
775
|
-
permissionType: In([
|
|
776
|
-
IamPermissionType.USER_ROLE,
|
|
777
|
-
IamPermissionType.USER_ACTION
|
|
778
|
-
]),
|
|
779
|
-
sourceType: IamEntityType.USER,
|
|
780
|
-
sourceId: userId,
|
|
781
|
-
branchId,
|
|
782
|
-
companyId
|
|
783
|
-
};
|
|
784
|
-
await permissionRepo.delete(where);
|
|
785
|
-
await this.permissionCacheService.invalidateUser(userId, companyId, [
|
|
786
|
-
branchId
|
|
787
|
-
]);
|
|
788
|
-
}
|
|
789
|
-
// NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
|
|
790
|
-
constructor(permissionCacheService, iamConfigService, dataSourceProvider){
|
|
791
|
-
_define_property(this, "permissionCacheService", void 0);
|
|
792
|
-
_define_property(this, "iamConfigService", void 0);
|
|
793
|
-
_define_property(this, "dataSourceProvider", void 0);
|
|
794
|
-
this.permissionCacheService = permissionCacheService;
|
|
795
|
-
this.iamConfigService = iamConfigService;
|
|
796
|
-
this.dataSourceProvider = dataSourceProvider;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
_ts_decorate([
|
|
800
|
-
LogAction({
|
|
801
|
-
action: 'iam.assignUserActions',
|
|
802
|
-
module: 'iam'
|
|
803
|
-
}),
|
|
804
|
-
_ts_metadata("design:type", Function),
|
|
805
|
-
_ts_metadata("design:paramtypes", [
|
|
806
|
-
typeof AssignUserActionsDto === "undefined" ? Object : AssignUserActionsDto
|
|
807
|
-
]),
|
|
808
|
-
_ts_metadata("design:returntype", Promise)
|
|
809
|
-
], PermissionService.prototype, "assignUserActions", null);
|
|
810
|
-
_ts_decorate([
|
|
811
|
-
LogAction({
|
|
812
|
-
action: 'iam.assignRoleActions',
|
|
813
|
-
module: 'iam'
|
|
814
|
-
}),
|
|
815
|
-
_ts_metadata("design:type", Function),
|
|
816
|
-
_ts_metadata("design:paramtypes", [
|
|
817
|
-
typeof AssignRoleActionsDto === "undefined" ? Object : AssignRoleActionsDto
|
|
818
|
-
]),
|
|
819
|
-
_ts_metadata("design:returntype", Promise)
|
|
820
|
-
], PermissionService.prototype, "assignRoleActions", null);
|
|
821
|
-
_ts_decorate([
|
|
822
|
-
LogAction({
|
|
823
|
-
action: 'iam.assignCompanyActions',
|
|
824
|
-
module: 'iam'
|
|
825
|
-
}),
|
|
826
|
-
_ts_metadata("design:type", Function),
|
|
827
|
-
_ts_metadata("design:paramtypes", [
|
|
828
|
-
typeof AssignCompanyActionsDto === "undefined" ? Object : AssignCompanyActionsDto
|
|
829
|
-
]),
|
|
830
|
-
_ts_metadata("design:returntype", Promise)
|
|
831
|
-
], PermissionService.prototype, "assignCompanyActions", null);
|
|
832
|
-
_ts_decorate([
|
|
833
|
-
LogAction({
|
|
834
|
-
action: 'iam.assignUserRoles',
|
|
835
|
-
module: 'iam'
|
|
836
|
-
}),
|
|
837
|
-
_ts_metadata("design:type", Function),
|
|
838
|
-
_ts_metadata("design:paramtypes", [
|
|
839
|
-
typeof AssignUserRolesDto === "undefined" ? Object : AssignUserRolesDto
|
|
840
|
-
]),
|
|
841
|
-
_ts_metadata("design:returntype", Promise)
|
|
842
|
-
], PermissionService.prototype, "assignUserRoles", null);
|
|
843
|
-
_ts_decorate([
|
|
844
|
-
LogAction({
|
|
845
|
-
action: 'iam.revokeCompanyPermissions',
|
|
846
|
-
module: 'iam'
|
|
847
|
-
}),
|
|
848
|
-
_ts_metadata("design:type", Function),
|
|
849
|
-
_ts_metadata("design:paramtypes", [
|
|
850
|
-
String
|
|
851
|
-
]),
|
|
852
|
-
_ts_metadata("design:returntype", Promise)
|
|
853
|
-
], PermissionService.prototype, "revokeCompanyPermissions", null);
|
|
854
|
-
_ts_decorate([
|
|
855
|
-
LogAction({
|
|
856
|
-
action: 'iam.revokeBranchPermissions',
|
|
857
|
-
module: 'iam'
|
|
858
|
-
}),
|
|
859
|
-
_ts_metadata("design:type", Function),
|
|
860
|
-
_ts_metadata("design:paramtypes", [
|
|
861
|
-
String,
|
|
862
|
-
String
|
|
863
|
-
]),
|
|
864
|
-
_ts_metadata("design:returntype", Promise)
|
|
865
|
-
], PermissionService.prototype, "revokeBranchPermissions", null);
|
|
866
|
-
_ts_decorate([
|
|
867
|
-
LogAction({
|
|
868
|
-
action: 'iam.revokeUserCompanyAccess',
|
|
869
|
-
module: 'iam'
|
|
870
|
-
}),
|
|
871
|
-
_ts_metadata("design:type", Function),
|
|
872
|
-
_ts_metadata("design:paramtypes", [
|
|
873
|
-
String,
|
|
874
|
-
String
|
|
875
|
-
]),
|
|
876
|
-
_ts_metadata("design:returntype", Promise)
|
|
877
|
-
], PermissionService.prototype, "revokeUserCompanyAccess", null);
|
|
878
|
-
_ts_decorate([
|
|
879
|
-
LogAction({
|
|
880
|
-
action: 'iam.revokeUserBranchAccess',
|
|
881
|
-
module: 'iam'
|
|
882
|
-
}),
|
|
883
|
-
_ts_metadata("design:type", Function),
|
|
884
|
-
_ts_metadata("design:paramtypes", [
|
|
885
|
-
String,
|
|
886
|
-
String,
|
|
887
|
-
String
|
|
888
|
-
]),
|
|
889
|
-
_ts_metadata("design:returntype", Promise)
|
|
890
|
-
], PermissionService.prototype, "revokeUserBranchAccess", null);
|
|
891
|
-
PermissionService = _ts_decorate([
|
|
892
|
-
Injectable({
|
|
893
|
-
scope: Scope.REQUEST
|
|
894
|
-
}),
|
|
895
|
-
_ts_param(0, Inject(PermissionCacheService)),
|
|
896
|
-
_ts_param(1, Inject(IAMConfigService)),
|
|
897
|
-
_ts_param(2, Inject(IAMDataSourceService)),
|
|
898
|
-
_ts_metadata("design:type", Function),
|
|
899
|
-
_ts_metadata("design:paramtypes", [
|
|
900
|
-
typeof PermissionCacheService === "undefined" ? Object : PermissionCacheService,
|
|
901
|
-
typeof IAMConfigService === "undefined" ? Object : IAMConfigService,
|
|
902
|
-
typeof IAMDataSourceService === "undefined" ? Object : IAMDataSourceService
|
|
903
|
-
])
|
|
904
|
-
], PermissionService);
|