@flusys/nestjs-iam 3.0.1 → 4.0.0-rc
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/cjs/config/index.js +1 -0
- package/cjs/config/message-keys.js +102 -0
- package/cjs/controllers/action.controller.js +4 -0
- package/cjs/controllers/company-action-permission.controller.js +2 -0
- package/cjs/controllers/my-permission.controller.js +2 -0
- package/cjs/controllers/role-permission.controller.js +5 -2
- package/cjs/controllers/role.controller.js +1 -0
- package/cjs/controllers/user-action-permission.controller.js +4 -2
- package/cjs/dtos/permission.dto.js +8 -0
- package/cjs/helpers/company-access.helper.js +6 -2
- package/cjs/services/action.service.js +9 -2
- package/cjs/services/iam-datasource.service.js +7 -3
- package/cjs/services/permission-cache.service.js +97 -71
- package/cjs/services/permission.service.js +72 -12
- package/cjs/services/role.service.js +1 -1
- package/config/index.d.ts +1 -0
- package/config/message-keys.d.ts +106 -0
- package/dtos/permission.dto.d.ts +1 -0
- package/fesm/config/index.js +1 -0
- package/fesm/config/message-keys.js +64 -0
- package/fesm/controllers/action.controller.js +4 -0
- package/fesm/controllers/company-action-permission.controller.js +2 -0
- package/fesm/controllers/my-permission.controller.js +2 -0
- package/fesm/controllers/role-permission.controller.js +5 -2
- package/fesm/controllers/role.controller.js +1 -0
- package/fesm/controllers/user-action-permission.controller.js +4 -2
- package/fesm/dtos/permission.dto.js +8 -0
- package/fesm/helpers/company-access.helper.js +6 -2
- package/fesm/services/action.service.js +9 -2
- package/fesm/services/iam-datasource.service.js +8 -4
- package/fesm/services/permission-cache.service.js +99 -73
- package/fesm/services/permission.service.js +74 -14
- package/fesm/services/role.service.js +1 -1
- package/helpers/company-access.helper.d.ts +1 -1
- package/package.json +3 -3
- package/services/iam-datasource.service.d.ts +0 -2
- package/services/permission-cache.service.d.ts +1 -2
- package/services/permission.service.d.ts +0 -1
|
@@ -25,9 +25,8 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import { HybridCache } from '@flusys/nestjs-shared';
|
|
29
|
-
import {
|
|
30
|
-
import { Inject, Injectable, Logger } from '@nestjs/common';
|
|
28
|
+
import { HybridCache, LogAction } from '@flusys/nestjs-shared';
|
|
29
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
31
30
|
export class PermissionCacheService {
|
|
32
31
|
// Cache Key Generation
|
|
33
32
|
generateCacheKey(options) {
|
|
@@ -45,38 +44,20 @@ export class PermissionCacheService {
|
|
|
45
44
|
}
|
|
46
45
|
// Cache Operations
|
|
47
46
|
async setPermissions(options, permissions) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
await this.cacheManager.set(key, permissions, this.TTL);
|
|
51
|
-
this.logger.debug(`Cached ${permissions.length} permissions for key: ${key}`);
|
|
52
|
-
} catch (error) {
|
|
53
|
-
const errorMessage = ErrorHandler.getErrorMessage(error);
|
|
54
|
-
this.logger.error(`Failed to cache permissions: ${errorMessage}`);
|
|
55
|
-
// Don't throw - cache failure shouldn't break the operation
|
|
56
|
-
}
|
|
47
|
+
const key = this.generateCacheKey(options);
|
|
48
|
+
await this.cacheManager.set(key, permissions, this.TTL);
|
|
57
49
|
}
|
|
58
50
|
// My-Permissions Cache Operations
|
|
59
51
|
async setMyPermissions(options, data) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
await this.cacheManager.set(key, data, this.TTL);
|
|
63
|
-
this.logger.debug(`Cached my-permissions for key: ${key} (${data.frontendActions.length} frontend, ${data.backendCodes.length} backend)`);
|
|
64
|
-
} catch (error) {
|
|
65
|
-
const errorMessage = ErrorHandler.getErrorMessage(error);
|
|
66
|
-
this.logger.error(`Failed to cache my-permissions: ${errorMessage}`);
|
|
67
|
-
}
|
|
52
|
+
const key = this.generateMyPermissionsCacheKey(options);
|
|
53
|
+
await this.cacheManager.set(key, data, this.TTL);
|
|
68
54
|
}
|
|
69
55
|
async getMyPermissions(options) {
|
|
70
56
|
try {
|
|
71
57
|
const key = this.generateMyPermissionsCacheKey(options);
|
|
72
58
|
const result = await this.cacheManager.get(key);
|
|
73
|
-
if (result) {
|
|
74
|
-
this.logger.debug(`Cache hit for my-permissions: ${key}`);
|
|
75
|
-
}
|
|
76
59
|
return result || null;
|
|
77
|
-
} catch
|
|
78
|
-
const errorMessage = ErrorHandler.getErrorMessage(error);
|
|
79
|
-
this.logger.error(`Failed to get my-permissions from cache: ${errorMessage}`);
|
|
60
|
+
} catch {
|
|
80
61
|
return null;
|
|
81
62
|
}
|
|
82
63
|
}
|
|
@@ -88,14 +69,8 @@ export class PermissionCacheService {
|
|
|
88
69
|
return `${this.ACTION_CODE_PREFIX}:map`;
|
|
89
70
|
}
|
|
90
71
|
async setActionCodeMap(codeToIdMap, tenantId) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
await this.cacheManager.set(key, codeToIdMap, this.ACTION_CODE_TTL);
|
|
94
|
-
this.logger.debug(`Cached ${Object.keys(codeToIdMap).length} action code mappings${tenantId ? ` for tenant ${tenantId}` : ''}`);
|
|
95
|
-
} catch (error) {
|
|
96
|
-
const errorMessage = ErrorHandler.getErrorMessage(error);
|
|
97
|
-
this.logger.error(`Failed to cache action code map: ${errorMessage}`);
|
|
98
|
-
}
|
|
72
|
+
const key = this.generateActionCodeCacheKey(tenantId);
|
|
73
|
+
await this.cacheManager.set(key, codeToIdMap, this.ACTION_CODE_TTL);
|
|
99
74
|
}
|
|
100
75
|
async getActionIdsByCodes(codes, tenantId) {
|
|
101
76
|
try {
|
|
@@ -111,72 +86,47 @@ export class PermissionCacheService {
|
|
|
111
86
|
}
|
|
112
87
|
}
|
|
113
88
|
return Object.keys(result).length > 0 ? result : null;
|
|
114
|
-
} catch
|
|
115
|
-
const errorMessage = ErrorHandler.getErrorMessage(error);
|
|
116
|
-
this.logger.error(`Failed to get action IDs from cache: ${errorMessage}`);
|
|
89
|
+
} catch {
|
|
117
90
|
return null;
|
|
118
91
|
}
|
|
119
92
|
}
|
|
120
93
|
// Cache Invalidation
|
|
121
94
|
async invalidateUser(userId, companyId, branchIds) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
95
|
+
const keysToDelete = [
|
|
96
|
+
`${this.CACHE_PREFIX}:user:${userId}`,
|
|
97
|
+
`${this.MY_PERMISSIONS_PREFIX}:user:${userId}`
|
|
98
|
+
];
|
|
99
|
+
if (companyId) {
|
|
100
|
+
const branches = branchIds?.length ? branchIds : [
|
|
101
|
+
null
|
|
128
102
|
];
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
null
|
|
132
|
-
];
|
|
133
|
-
for (const branchId of branches){
|
|
134
|
-
keysToDelete.push(`${this.CACHE_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`, `${this.MY_PERMISSIONS_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`);
|
|
135
|
-
}
|
|
103
|
+
for (const branchId of branches){
|
|
104
|
+
keysToDelete.push(`${this.CACHE_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`, `${this.MY_PERMISSIONS_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`);
|
|
136
105
|
}
|
|
137
|
-
await Promise.all(keysToDelete.map((key)=>this.cacheManager.del(key)));
|
|
138
|
-
this.logger.debug(`Invalidated ${keysToDelete.length} cache keys for user ${userId}`);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
const errorMessage = ErrorHandler.getErrorMessage(error);
|
|
141
|
-
this.logger.warn(`Failed to invalidate user cache for ${userId}: ${errorMessage}`);
|
|
142
106
|
}
|
|
107
|
+
await Promise.all(keysToDelete.map((key)=>this.cacheManager.del(key)));
|
|
143
108
|
}
|
|
144
109
|
async invalidateUsers(userIds, companyId, branchIds) {
|
|
145
110
|
if (userIds.length === 0) {
|
|
146
111
|
return 0;
|
|
147
112
|
}
|
|
148
113
|
const results = await Promise.allSettled(userIds.map((userId)=>this.invalidateUser(userId, companyId, branchIds)));
|
|
149
|
-
|
|
150
|
-
const failedCount = results.filter((r)=>r.status === 'rejected').length;
|
|
151
|
-
if (failedCount > 0) {
|
|
152
|
-
this.logger.warn(`Failed to invalidate cache for ${failedCount} users`);
|
|
153
|
-
}
|
|
154
|
-
if (successCount > 0) {
|
|
155
|
-
this.logger.log(`Invalidated cache for ${successCount} users`);
|
|
156
|
-
}
|
|
157
|
-
return successCount;
|
|
114
|
+
return results.filter((r)=>r.status === 'fulfilled').length;
|
|
158
115
|
}
|
|
159
|
-
async invalidateRole(
|
|
116
|
+
async invalidateRole(_roleId, userIds, companyId, branchIds) {
|
|
160
117
|
if (userIds.length === 0) {
|
|
161
|
-
this.logger.debug(`No users found for role ${roleId}`);
|
|
162
118
|
return 0;
|
|
163
119
|
}
|
|
164
|
-
|
|
165
|
-
if (count > 0) {
|
|
166
|
-
this.logger.log(`Invalidated cache for ${count} users with role ${roleId}`);
|
|
167
|
-
}
|
|
168
|
-
return count;
|
|
120
|
+
return await this.invalidateUsers(userIds, companyId, branchIds);
|
|
169
121
|
}
|
|
170
122
|
constructor(cacheManager){
|
|
171
123
|
_define_property(this, "cacheManager", void 0);
|
|
172
|
-
_define_property(this, "logger", void 0);
|
|
173
124
|
_define_property(this, "TTL", void 0); // 1 hour
|
|
174
125
|
_define_property(this, "ACTION_CODE_TTL", void 0); // 2 hours for action codes (less frequent changes)
|
|
175
126
|
_define_property(this, "CACHE_PREFIX", void 0);
|
|
176
127
|
_define_property(this, "MY_PERMISSIONS_PREFIX", void 0);
|
|
177
128
|
_define_property(this, "ACTION_CODE_PREFIX", void 0);
|
|
178
129
|
this.cacheManager = cacheManager;
|
|
179
|
-
this.logger = new Logger(PermissionCacheService.name);
|
|
180
130
|
this.TTL = 3600000;
|
|
181
131
|
this.ACTION_CODE_TTL = 7200000;
|
|
182
132
|
this.CACHE_PREFIX = 'permissions';
|
|
@@ -184,6 +134,82 @@ export class PermissionCacheService {
|
|
|
184
134
|
this.ACTION_CODE_PREFIX = 'action-codes';
|
|
185
135
|
}
|
|
186
136
|
}
|
|
137
|
+
_ts_decorate([
|
|
138
|
+
LogAction({
|
|
139
|
+
action: 'permissionCache.setPermissions',
|
|
140
|
+
module: 'iam'
|
|
141
|
+
}),
|
|
142
|
+
_ts_metadata("design:type", Function),
|
|
143
|
+
_ts_metadata("design:paramtypes", [
|
|
144
|
+
typeof PermissionCacheKeyOptions === "undefined" ? Object : PermissionCacheKeyOptions,
|
|
145
|
+
Array
|
|
146
|
+
]),
|
|
147
|
+
_ts_metadata("design:returntype", Promise)
|
|
148
|
+
], PermissionCacheService.prototype, "setPermissions", null);
|
|
149
|
+
_ts_decorate([
|
|
150
|
+
LogAction({
|
|
151
|
+
action: 'permissionCache.setMyPermissions',
|
|
152
|
+
module: 'iam'
|
|
153
|
+
}),
|
|
154
|
+
_ts_metadata("design:type", Function),
|
|
155
|
+
_ts_metadata("design:paramtypes", [
|
|
156
|
+
typeof PermissionCacheKeyOptions === "undefined" ? Object : PermissionCacheKeyOptions,
|
|
157
|
+
typeof CachedMyPermissions === "undefined" ? Object : CachedMyPermissions
|
|
158
|
+
]),
|
|
159
|
+
_ts_metadata("design:returntype", Promise)
|
|
160
|
+
], PermissionCacheService.prototype, "setMyPermissions", null);
|
|
161
|
+
_ts_decorate([
|
|
162
|
+
LogAction({
|
|
163
|
+
action: 'permissionCache.setActionCodeMap',
|
|
164
|
+
module: 'iam'
|
|
165
|
+
}),
|
|
166
|
+
_ts_metadata("design:type", Function),
|
|
167
|
+
_ts_metadata("design:paramtypes", [
|
|
168
|
+
typeof Record === "undefined" ? Object : Record,
|
|
169
|
+
String
|
|
170
|
+
]),
|
|
171
|
+
_ts_metadata("design:returntype", Promise)
|
|
172
|
+
], PermissionCacheService.prototype, "setActionCodeMap", null);
|
|
173
|
+
_ts_decorate([
|
|
174
|
+
LogAction({
|
|
175
|
+
action: 'permissionCache.invalidateUser',
|
|
176
|
+
module: 'iam'
|
|
177
|
+
}),
|
|
178
|
+
_ts_metadata("design:type", Function),
|
|
179
|
+
_ts_metadata("design:paramtypes", [
|
|
180
|
+
String,
|
|
181
|
+
Object,
|
|
182
|
+
Array
|
|
183
|
+
]),
|
|
184
|
+
_ts_metadata("design:returntype", Promise)
|
|
185
|
+
], PermissionCacheService.prototype, "invalidateUser", null);
|
|
186
|
+
_ts_decorate([
|
|
187
|
+
LogAction({
|
|
188
|
+
action: 'permissionCache.invalidateUsers',
|
|
189
|
+
module: 'iam'
|
|
190
|
+
}),
|
|
191
|
+
_ts_metadata("design:type", Function),
|
|
192
|
+
_ts_metadata("design:paramtypes", [
|
|
193
|
+
Array,
|
|
194
|
+
Object,
|
|
195
|
+
Array
|
|
196
|
+
]),
|
|
197
|
+
_ts_metadata("design:returntype", Promise)
|
|
198
|
+
], PermissionCacheService.prototype, "invalidateUsers", null);
|
|
199
|
+
_ts_decorate([
|
|
200
|
+
LogAction({
|
|
201
|
+
action: 'permissionCache.invalidateRole',
|
|
202
|
+
module: 'iam'
|
|
203
|
+
}),
|
|
204
|
+
_ts_metadata("design:type", Function),
|
|
205
|
+
_ts_metadata("design:paramtypes", [
|
|
206
|
+
String,
|
|
207
|
+
Array,
|
|
208
|
+
Object,
|
|
209
|
+
Array
|
|
210
|
+
]),
|
|
211
|
+
_ts_metadata("design:returntype", Promise)
|
|
212
|
+
], PermissionCacheService.prototype, "invalidateRole", null);
|
|
187
213
|
PermissionCacheService = _ts_decorate([
|
|
188
214
|
Injectable(),
|
|
189
215
|
_ts_param(0, Inject('CACHE_INSTANCE')),
|
|
@@ -25,9 +25,11 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import {
|
|
28
|
+
import { IAM_MODE_MESSAGES, PERMISSION_OPERATION_MESSAGES } from '../config';
|
|
29
|
+
import { LogAction } from '@flusys/nestjs-shared';
|
|
30
|
+
import { BadRequestException, ConflictException, Inject, Injectable, Scope } from '@nestjs/common';
|
|
29
31
|
import { In, IsNull } from 'typeorm';
|
|
30
|
-
import { PermissionAction } from '../dtos/permission.dto';
|
|
32
|
+
import { AssignCompanyActionsDto, AssignRoleActionsDto, AssignUserActionsDto, AssignUserRolesDto, PermissionAction } from '../dtos/permission.dto';
|
|
31
33
|
import { Action } from '../entities/action.entity';
|
|
32
34
|
import { UserIamPermissionWithCompany } from '../entities/permission-with-company.entity';
|
|
33
35
|
import { RoleWithCompany } from '../entities/role-with-company.entity';
|
|
@@ -56,7 +58,10 @@ export class PermissionService {
|
|
|
56
58
|
// User-Action Permissions
|
|
57
59
|
async assignUserActions(dto) {
|
|
58
60
|
if (!this.iamConfigService.isDirectPermissionEnabled()) {
|
|
59
|
-
throw new BadRequestException(
|
|
61
|
+
throw new BadRequestException({
|
|
62
|
+
message: 'Direct permission assignment not available in RBAC-only mode. Use role-based permissions instead.',
|
|
63
|
+
messageKey: IAM_MODE_MESSAGES.DIRECT_MODE_UNAVAILABLE
|
|
64
|
+
});
|
|
60
65
|
}
|
|
61
66
|
const permissionRepo = await this.getPermissionRepository();
|
|
62
67
|
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
@@ -101,7 +106,10 @@ export class PermissionService {
|
|
|
101
106
|
added = newPermissions.length;
|
|
102
107
|
} catch (error) {
|
|
103
108
|
if (error?.code === 'ER_DUP_ENTRY' || error?.message?.includes('Duplicate entry')) {
|
|
104
|
-
throw new ConflictException(
|
|
109
|
+
throw new ConflictException({
|
|
110
|
+
message: 'Some permissions already exist for this user. Please refresh and try again.',
|
|
111
|
+
messageKey: PERMISSION_OPERATION_MESSAGES.ALREADY_EXISTS
|
|
112
|
+
});
|
|
105
113
|
}
|
|
106
114
|
throw error;
|
|
107
115
|
}
|
|
@@ -172,7 +180,10 @@ export class PermissionService {
|
|
|
172
180
|
// Role-Action Permissions
|
|
173
181
|
async assignRoleActions(dto) {
|
|
174
182
|
if (!this.iamConfigService.isRbacEnabled()) {
|
|
175
|
-
throw new BadRequestException(
|
|
183
|
+
throw new BadRequestException({
|
|
184
|
+
message: 'Role-based permission assignment not available in DIRECT-only mode. Use direct user permissions instead.',
|
|
185
|
+
messageKey: IAM_MODE_MESSAGES.RBAC_MODE_UNAVAILABLE
|
|
186
|
+
});
|
|
176
187
|
}
|
|
177
188
|
const permissionRepo = await this.getPermissionRepository();
|
|
178
189
|
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
@@ -224,7 +235,10 @@ export class PermissionService {
|
|
|
224
235
|
added = newPermissions.length;
|
|
225
236
|
} catch (error) {
|
|
226
237
|
if (error?.code === 'ER_DUP_ENTRY' || error?.message?.includes('Duplicate entry')) {
|
|
227
|
-
throw new ConflictException(
|
|
238
|
+
throw new ConflictException({
|
|
239
|
+
message: 'Some role-action permissions already exist. Please refresh and try again.',
|
|
240
|
+
messageKey: PERMISSION_OPERATION_MESSAGES.ALREADY_EXISTS
|
|
241
|
+
});
|
|
228
242
|
}
|
|
229
243
|
throw error;
|
|
230
244
|
}
|
|
@@ -378,9 +392,6 @@ export class PermissionService {
|
|
|
378
392
|
});
|
|
379
393
|
removedUserActions = userResult.affected || 0;
|
|
380
394
|
}
|
|
381
|
-
if (removedRoleActions > 0 || removedUserActions > 0) {
|
|
382
|
-
this.logger.log(`Cascade deleted for company ${companyId}: ${removedRoleActions} role actions, ${removedUserActions} user actions`);
|
|
383
|
-
}
|
|
384
395
|
return {
|
|
385
396
|
removedCompanyActions: companyResult.affected || 0,
|
|
386
397
|
removedRoleActions,
|
|
@@ -439,7 +450,10 @@ export class PermissionService {
|
|
|
439
450
|
// User-Role Permissions
|
|
440
451
|
/** Assign user to roles (branch-scoped when company feature is enabled) */ async assignUserRoles(dto) {
|
|
441
452
|
if (!this.iamConfigService.isRbacEnabled()) {
|
|
442
|
-
throw new BadRequestException(
|
|
453
|
+
throw new BadRequestException({
|
|
454
|
+
message: 'Role assignment not available in DIRECT-only mode. Use direct user permissions instead.',
|
|
455
|
+
messageKey: IAM_MODE_MESSAGES.ROLE_ASSIGNMENT_UNAVAILABLE
|
|
456
|
+
});
|
|
443
457
|
}
|
|
444
458
|
const permissionRepo = await this.getPermissionRepository();
|
|
445
459
|
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
@@ -484,7 +498,10 @@ export class PermissionService {
|
|
|
484
498
|
added = newPermissions.length;
|
|
485
499
|
} catch (error) {
|
|
486
500
|
if (error?.code === 'ER_DUP_ENTRY' || error?.message?.includes('Duplicate entry')) {
|
|
487
|
-
throw new ConflictException(
|
|
501
|
+
throw new ConflictException({
|
|
502
|
+
message: 'Some user-role permissions already exist. Please refresh and try again.',
|
|
503
|
+
messageKey: PERMISSION_OPERATION_MESSAGES.ALREADY_EXISTS
|
|
504
|
+
});
|
|
488
505
|
}
|
|
489
506
|
throw error;
|
|
490
507
|
}
|
|
@@ -710,7 +727,8 @@ export class PermissionService {
|
|
|
710
727
|
success: true,
|
|
711
728
|
added,
|
|
712
729
|
removed,
|
|
713
|
-
message: `Successfully processed ${totalItems} items: ${added} added, ${removed} removed${additionalMessage}
|
|
730
|
+
message: `Successfully processed ${totalItems} items: ${added} added, ${removed} removed${additionalMessage}`,
|
|
731
|
+
messageKey: PERMISSION_OPERATION_MESSAGES.PROCESS_SUCCESS
|
|
714
732
|
};
|
|
715
733
|
}
|
|
716
734
|
/** Get role IDs assigned to a user (merges company-wide + branch-specific roles) */ async getUserRoleIds(userId, branchId, companyId) {
|
|
@@ -887,13 +905,55 @@ export class PermissionService {
|
|
|
887
905
|
_define_property(this, "permissionCacheService", void 0);
|
|
888
906
|
_define_property(this, "iamConfigService", void 0);
|
|
889
907
|
_define_property(this, "dataSourceProvider", void 0);
|
|
890
|
-
_define_property(this, "logger", void 0);
|
|
891
908
|
this.permissionCacheService = permissionCacheService;
|
|
892
909
|
this.iamConfigService = iamConfigService;
|
|
893
910
|
this.dataSourceProvider = dataSourceProvider;
|
|
894
|
-
this.logger = new Logger(PermissionService.name);
|
|
895
911
|
}
|
|
896
912
|
}
|
|
913
|
+
_ts_decorate([
|
|
914
|
+
LogAction({
|
|
915
|
+
action: 'iam.assignUserActions',
|
|
916
|
+
module: 'iam'
|
|
917
|
+
}),
|
|
918
|
+
_ts_metadata("design:type", Function),
|
|
919
|
+
_ts_metadata("design:paramtypes", [
|
|
920
|
+
typeof AssignUserActionsDto === "undefined" ? Object : AssignUserActionsDto
|
|
921
|
+
]),
|
|
922
|
+
_ts_metadata("design:returntype", Promise)
|
|
923
|
+
], PermissionService.prototype, "assignUserActions", null);
|
|
924
|
+
_ts_decorate([
|
|
925
|
+
LogAction({
|
|
926
|
+
action: 'iam.assignRoleActions',
|
|
927
|
+
module: 'iam'
|
|
928
|
+
}),
|
|
929
|
+
_ts_metadata("design:type", Function),
|
|
930
|
+
_ts_metadata("design:paramtypes", [
|
|
931
|
+
typeof AssignRoleActionsDto === "undefined" ? Object : AssignRoleActionsDto
|
|
932
|
+
]),
|
|
933
|
+
_ts_metadata("design:returntype", Promise)
|
|
934
|
+
], PermissionService.prototype, "assignRoleActions", null);
|
|
935
|
+
_ts_decorate([
|
|
936
|
+
LogAction({
|
|
937
|
+
action: 'iam.assignCompanyActions',
|
|
938
|
+
module: 'iam'
|
|
939
|
+
}),
|
|
940
|
+
_ts_metadata("design:type", Function),
|
|
941
|
+
_ts_metadata("design:paramtypes", [
|
|
942
|
+
typeof AssignCompanyActionsDto === "undefined" ? Object : AssignCompanyActionsDto
|
|
943
|
+
]),
|
|
944
|
+
_ts_metadata("design:returntype", Promise)
|
|
945
|
+
], PermissionService.prototype, "assignCompanyActions", null);
|
|
946
|
+
_ts_decorate([
|
|
947
|
+
LogAction({
|
|
948
|
+
action: 'iam.assignUserRoles',
|
|
949
|
+
module: 'iam'
|
|
950
|
+
}),
|
|
951
|
+
_ts_metadata("design:type", Function),
|
|
952
|
+
_ts_metadata("design:paramtypes", [
|
|
953
|
+
typeof AssignUserRolesDto === "undefined" ? Object : AssignUserRolesDto
|
|
954
|
+
]),
|
|
955
|
+
_ts_metadata("design:returntype", Promise)
|
|
956
|
+
], PermissionService.prototype, "assignUserRoles", null);
|
|
897
957
|
PermissionService = _ts_decorate([
|
|
898
958
|
Injectable({
|
|
899
959
|
scope: Scope.REQUEST
|
|
@@ -112,7 +112,7 @@ export class RoleService extends RequestScopedApiService {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
constructor(cacheManager, utilsService, iamConfigService, dataSourceProvider){
|
|
115
|
-
super('role', null, cacheManager, utilsService, RoleService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "iamConfigService", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.iamConfigService = iamConfigService, this.dataSourceProvider = dataSourceProvider;
|
|
115
|
+
super('role', null, cacheManager, utilsService, RoleService.name, true, 'iam'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "iamConfigService", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.iamConfigService = iamConfigService, this.dataSourceProvider = dataSourceProvider;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
RoleService = _ts_decorate([
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ILoggedUserInfo } from '@flusys/nestjs-shared';
|
|
2
2
|
import { IAMConfigService } from '../services/iam-config.service';
|
|
3
|
-
export declare function validateCompanyAccess(config: IAMConfigService, companyId: string | undefined, user: ILoggedUserInfo, errorMessage?: string): void;
|
|
3
|
+
export declare function validateCompanyAccess(config: IAMConfigService, companyId: string | undefined, user: ILoggedUserInfo, errorMessage?: string, messageKey?: "auth.company.no.access"): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/nestjs-iam",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-rc",
|
|
4
4
|
"description": "Identity and Access Management (IAM) module for NestJS applications",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "fesm/index.js",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"typeorm": "^0.3.0"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@flusys/nestjs-core": "
|
|
93
|
-
"@flusys/nestjs-shared": "
|
|
92
|
+
"@flusys/nestjs-core": "4.0.0-rc",
|
|
93
|
+
"@flusys/nestjs-shared": "4.0.0-rc"
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
|
|
2
2
|
import { IDatabaseConfig, ITenantDatabaseConfig } from '@flusys/nestjs-core';
|
|
3
|
-
import { Logger } from '@nestjs/common';
|
|
4
3
|
import { Request } from 'express';
|
|
5
4
|
import { DataSource } from 'typeorm';
|
|
6
5
|
import { IAMConfigService } from './iam-config.service';
|
|
7
6
|
export declare class IAMDataSourceService extends MultiTenantDataSourceService {
|
|
8
7
|
private readonly configService;
|
|
9
|
-
protected readonly logger: Logger;
|
|
10
8
|
protected static readonly tenantConnections: Map<string, DataSource>;
|
|
11
9
|
protected static singleDataSource: DataSource | null;
|
|
12
10
|
protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
|
|
@@ -17,7 +17,6 @@ export interface CachedMyPermissions {
|
|
|
17
17
|
}
|
|
18
18
|
export declare class PermissionCacheService {
|
|
19
19
|
private readonly cacheManager;
|
|
20
|
-
private readonly logger;
|
|
21
20
|
private readonly TTL;
|
|
22
21
|
private readonly ACTION_CODE_TTL;
|
|
23
22
|
private readonly CACHE_PREFIX;
|
|
@@ -35,5 +34,5 @@ export declare class PermissionCacheService {
|
|
|
35
34
|
getActionIdsByCodes(codes: string[], tenantId?: string): Promise<Record<string, string> | null>;
|
|
36
35
|
invalidateUser(userId: string, companyId?: string | null, branchIds?: (string | null)[]): Promise<void>;
|
|
37
36
|
invalidateUsers(userIds: string[], companyId?: string | null, branchIds?: (string | null)[]): Promise<number>;
|
|
38
|
-
invalidateRole(
|
|
37
|
+
invalidateRole(_roleId: string, userIds: string[], companyId?: string | null, branchIds?: (string | null)[]): Promise<number>;
|
|
39
38
|
}
|
|
@@ -6,7 +6,6 @@ export declare class PermissionService {
|
|
|
6
6
|
private readonly permissionCacheService;
|
|
7
7
|
private readonly iamConfigService;
|
|
8
8
|
private readonly dataSourceProvider;
|
|
9
|
-
private readonly logger;
|
|
10
9
|
constructor(permissionCacheService: PermissionCacheService, iamConfigService: IAMConfigService, dataSourceProvider: IAMDataSourceService);
|
|
11
10
|
private getPermissionRepository;
|
|
12
11
|
private getActionRepository;
|