@flusys/nestjs-iam 3.0.0 → 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/README.md +1 -1
- 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
package/README.md
CHANGED
package/cjs/config/index.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
5
|
_export_star(require("./iam.constants"), exports);
|
|
6
|
+
_export_star(require("./message-keys"), exports);
|
|
6
7
|
function _export_star(from, to) {
|
|
7
8
|
Object.keys(from).forEach(function(k) {
|
|
8
9
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// ==================== IAM MODULE MESSAGE KEYS ====================
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
function _export(target, all) {
|
|
7
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
_export(exports, {
|
|
13
|
+
get ACTION_MESSAGES () {
|
|
14
|
+
return ACTION_MESSAGES;
|
|
15
|
+
},
|
|
16
|
+
get COMPANY_ACTION_PERMISSION_MESSAGES () {
|
|
17
|
+
return COMPANY_ACTION_PERMISSION_MESSAGES;
|
|
18
|
+
},
|
|
19
|
+
get IAM_MODE_MESSAGES () {
|
|
20
|
+
return IAM_MODE_MESSAGES;
|
|
21
|
+
},
|
|
22
|
+
get IAM_MODULE_MESSAGES () {
|
|
23
|
+
return IAM_MODULE_MESSAGES;
|
|
24
|
+
},
|
|
25
|
+
get MY_PERMISSION_MESSAGES () {
|
|
26
|
+
return MY_PERMISSION_MESSAGES;
|
|
27
|
+
},
|
|
28
|
+
get PERMISSION_OPERATION_MESSAGES () {
|
|
29
|
+
return PERMISSION_OPERATION_MESSAGES;
|
|
30
|
+
},
|
|
31
|
+
get ROLE_MESSAGES () {
|
|
32
|
+
return ROLE_MESSAGES;
|
|
33
|
+
},
|
|
34
|
+
get ROLE_PERMISSION_MESSAGES () {
|
|
35
|
+
return ROLE_PERMISSION_MESSAGES;
|
|
36
|
+
},
|
|
37
|
+
get USER_ACTION_PERMISSION_MESSAGES () {
|
|
38
|
+
return USER_ACTION_PERMISSION_MESSAGES;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const ACTION_MESSAGES = {
|
|
42
|
+
CREATE_SUCCESS: 'action.create.success',
|
|
43
|
+
CREATE_MANY_SUCCESS: 'action.create.many.success',
|
|
44
|
+
GET_SUCCESS: 'action.get.success',
|
|
45
|
+
GET_ALL_SUCCESS: 'action.get.all.success',
|
|
46
|
+
UPDATE_SUCCESS: 'action.update.success',
|
|
47
|
+
UPDATE_MANY_SUCCESS: 'action.update.many.success',
|
|
48
|
+
DELETE_SUCCESS: 'action.delete.success',
|
|
49
|
+
RESTORE_SUCCESS: 'action.restore.success',
|
|
50
|
+
NOT_FOUND: 'action.not.found'
|
|
51
|
+
};
|
|
52
|
+
const ROLE_MESSAGES = {
|
|
53
|
+
CREATE_SUCCESS: 'role.create.success',
|
|
54
|
+
CREATE_MANY_SUCCESS: 'role.create.many.success',
|
|
55
|
+
GET_SUCCESS: 'role.get.success',
|
|
56
|
+
GET_ALL_SUCCESS: 'role.get.all.success',
|
|
57
|
+
UPDATE_SUCCESS: 'role.update.success',
|
|
58
|
+
UPDATE_MANY_SUCCESS: 'role.update.many.success',
|
|
59
|
+
DELETE_SUCCESS: 'role.delete.success',
|
|
60
|
+
RESTORE_SUCCESS: 'role.restore.success',
|
|
61
|
+
NOT_FOUND: 'role.not.found'
|
|
62
|
+
};
|
|
63
|
+
const ROLE_PERMISSION_MESSAGES = {
|
|
64
|
+
GET_SUCCESS: 'role.permission.get.success',
|
|
65
|
+
ASSIGN_SUCCESS: 'role.permission.assign.success',
|
|
66
|
+
ACTIONS_SUCCESS: 'role.permission.actions.success',
|
|
67
|
+
USERS_SUCCESS: 'role.permission.users.success',
|
|
68
|
+
USER_ROLES_SUCCESS: 'role.permission.user.roles.success'
|
|
69
|
+
};
|
|
70
|
+
const USER_ACTION_PERMISSION_MESSAGES = {
|
|
71
|
+
GET_SUCCESS: 'user.action.permission.get.success',
|
|
72
|
+
ASSIGN_SUCCESS: 'user.action.permission.assign.success',
|
|
73
|
+
REVOKE_SUCCESS: 'user.action.permission.revoke.success'
|
|
74
|
+
};
|
|
75
|
+
const COMPANY_ACTION_PERMISSION_MESSAGES = {
|
|
76
|
+
GET_SUCCESS: 'company.action.permission.get.success',
|
|
77
|
+
ASSIGN_SUCCESS: 'company.action.permission.assign.success',
|
|
78
|
+
REVOKE_SUCCESS: 'company.action.permission.revoke.success'
|
|
79
|
+
};
|
|
80
|
+
const MY_PERMISSION_MESSAGES = {
|
|
81
|
+
GET_SUCCESS: 'my.permission.get.success'
|
|
82
|
+
};
|
|
83
|
+
const IAM_MODE_MESSAGES = {
|
|
84
|
+
DIRECT_MODE_UNAVAILABLE: 'iam.direct.mode.unavailable',
|
|
85
|
+
RBAC_MODE_UNAVAILABLE: 'iam.rbac.mode.unavailable',
|
|
86
|
+
ROLE_ASSIGNMENT_UNAVAILABLE: 'iam.role.assignment.unavailable'
|
|
87
|
+
};
|
|
88
|
+
const PERMISSION_OPERATION_MESSAGES = {
|
|
89
|
+
PROCESS_SUCCESS: 'permission.process.success',
|
|
90
|
+
ALREADY_EXISTS: 'permission.already.exists',
|
|
91
|
+
USER_REQUIRED: 'permission.user.required'
|
|
92
|
+
};
|
|
93
|
+
const IAM_MODULE_MESSAGES = {
|
|
94
|
+
ACTION: ACTION_MESSAGES,
|
|
95
|
+
ROLE: ROLE_MESSAGES,
|
|
96
|
+
ROLE_PERMISSION: ROLE_PERMISSION_MESSAGES,
|
|
97
|
+
USER_ACTION_PERMISSION: USER_ACTION_PERMISSION_MESSAGES,
|
|
98
|
+
COMPANY_ACTION_PERMISSION: COMPANY_ACTION_PERMISSION_MESSAGES,
|
|
99
|
+
MY_PERMISSION: MY_PERMISSION_MESSAGES,
|
|
100
|
+
IAM_MODE: IAM_MODE_MESSAGES,
|
|
101
|
+
PERMISSION_OPERATION: PERMISSION_OPERATION_MESSAGES
|
|
102
|
+
};
|
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "ActionController", {
|
|
|
10
10
|
});
|
|
11
11
|
const _guards = require("@flusys/nestjs-shared/guards");
|
|
12
12
|
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
13
|
+
const _config = require("../config");
|
|
13
14
|
const _common = require("@nestjs/common");
|
|
14
15
|
const _swagger = require("@nestjs/swagger");
|
|
15
16
|
const _actiondto = require("../dtos/action.dto");
|
|
@@ -42,6 +43,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
let ActionController = class ActionController extends (0, _nestjsshared.createApiController)(_actiondto.CreateActionDto, _actiondto.UpdateActionDto, _actiondto.ActionResponseDto, {
|
|
46
|
+
entityName: 'action',
|
|
45
47
|
security: {
|
|
46
48
|
insert: {
|
|
47
49
|
level: 'permission',
|
|
@@ -92,6 +94,7 @@ let ActionController = class ActionController extends (0, _nestjsshared.createAp
|
|
|
92
94
|
return {
|
|
93
95
|
success: true,
|
|
94
96
|
message: 'Actions retrieved successfully',
|
|
97
|
+
messageKey: _config.ACTION_MESSAGES.GET_ALL_SUCCESS,
|
|
95
98
|
data: actions
|
|
96
99
|
};
|
|
97
100
|
}
|
|
@@ -100,6 +103,7 @@ let ActionController = class ActionController extends (0, _nestjsshared.createAp
|
|
|
100
103
|
return {
|
|
101
104
|
success: true,
|
|
102
105
|
message: 'Action tree retrieved successfully',
|
|
106
|
+
messageKey: _config.ACTION_MESSAGES.GET_ALL_SUCCESS,
|
|
103
107
|
data: tree
|
|
104
108
|
};
|
|
105
109
|
}
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "CompanyActionPermissionController", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
12
|
+
const _config = require("../config");
|
|
12
13
|
const _common = require("@nestjs/common");
|
|
13
14
|
const _swagger = require("@nestjs/swagger");
|
|
14
15
|
const _permissiondto = require("../dtos/permission.dto");
|
|
@@ -49,6 +50,7 @@ let CompanyActionPermissionController = class CompanyActionPermissionController
|
|
|
49
50
|
return {
|
|
50
51
|
success: true,
|
|
51
52
|
message: 'Company actions retrieved successfully',
|
|
53
|
+
messageKey: _config.COMPANY_ACTION_PERMISSION_MESSAGES.GET_SUCCESS,
|
|
52
54
|
data: actions
|
|
53
55
|
};
|
|
54
56
|
}
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "MyPermissionController", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
12
|
+
const _config = require("../config");
|
|
12
13
|
const _common = require("@nestjs/common");
|
|
13
14
|
const _swagger = require("@nestjs/swagger");
|
|
14
15
|
const _permissiondto = require("../dtos/permission.dto");
|
|
@@ -46,6 +47,7 @@ let MyPermissionController = class MyPermissionController {
|
|
|
46
47
|
return {
|
|
47
48
|
success: true,
|
|
48
49
|
message: 'Permissions loaded successfully',
|
|
50
|
+
messageKey: _config.MY_PERMISSION_MESSAGES.GET_SUCCESS,
|
|
49
51
|
data
|
|
50
52
|
};
|
|
51
53
|
}
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "RolePermissionController", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
12
|
+
const _config = require("../config");
|
|
12
13
|
const _common = require("@nestjs/common");
|
|
13
14
|
const _swagger = require("@nestjs/swagger");
|
|
14
15
|
const _permissiondto = require("../dtos/permission.dto");
|
|
@@ -51,19 +52,21 @@ let RolePermissionController = class RolePermissionController {
|
|
|
51
52
|
return {
|
|
52
53
|
success: true,
|
|
53
54
|
message: 'Role actions retrieved successfully',
|
|
55
|
+
messageKey: _config.ROLE_PERMISSION_MESSAGES.ACTIONS_SUCCESS,
|
|
54
56
|
data: actions
|
|
55
57
|
};
|
|
56
58
|
}
|
|
57
59
|
async assignUserRoles(dto, user) {
|
|
58
|
-
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user
|
|
60
|
+
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user);
|
|
59
61
|
return this.permissionService.assignUserRoles(dto);
|
|
60
62
|
}
|
|
61
63
|
async getUserRoles(dto, user) {
|
|
62
|
-
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user
|
|
64
|
+
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user);
|
|
63
65
|
const roles = await this.permissionService.getUserRoles(dto.userId, dto.branchId, dto.companyId);
|
|
64
66
|
return {
|
|
65
67
|
success: true,
|
|
66
68
|
message: 'User roles retrieved successfully',
|
|
69
|
+
messageKey: _config.ROLE_PERMISSION_MESSAGES.USER_ROLES_SUCCESS,
|
|
67
70
|
data: roles
|
|
68
71
|
};
|
|
69
72
|
}
|
|
@@ -41,6 +41,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
let RoleController = class RoleController extends (0, _nestjsshared.createApiController)(_roledto.CreateRoleDto, _roledto.UpdateRoleDto, _roledto.RoleResponseDto, {
|
|
44
|
+
entityName: 'role',
|
|
44
45
|
security: {
|
|
45
46
|
insert: {
|
|
46
47
|
level: 'permission',
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "UserActionPermissionController", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
12
|
+
const _config = require("../config");
|
|
12
13
|
const _common = require("@nestjs/common");
|
|
13
14
|
const _swagger = require("@nestjs/swagger");
|
|
14
15
|
const _permissiondto = require("../dtos/permission.dto");
|
|
@@ -44,15 +45,16 @@ function _ts_param(paramIndex, decorator) {
|
|
|
44
45
|
}
|
|
45
46
|
let UserActionPermissionController = class UserActionPermissionController {
|
|
46
47
|
async assignUserActions(dto, user) {
|
|
47
|
-
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user
|
|
48
|
+
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user);
|
|
48
49
|
return this.permissionService.assignUserActions(dto);
|
|
49
50
|
}
|
|
50
51
|
async getUserActions(dto, user) {
|
|
51
|
-
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user
|
|
52
|
+
(0, _helpers.validateCompanyAccess)(this.config, dto.companyId, user);
|
|
52
53
|
const actions = await this.permissionService.getUserActions(dto.userId, dto.branchId, dto.companyId);
|
|
53
54
|
return {
|
|
54
55
|
success: true,
|
|
55
56
|
message: 'User actions retrieved successfully',
|
|
57
|
+
messageKey: _config.USER_ACTION_PERMISSION_MESSAGES.GET_SUCCESS,
|
|
56
58
|
data: actions
|
|
57
59
|
};
|
|
58
60
|
}
|
|
@@ -616,6 +616,7 @@ let PermissionOperationResultDto = class PermissionOperationResultDto {
|
|
|
616
616
|
_define_property(this, "added", void 0);
|
|
617
617
|
_define_property(this, "removed", void 0);
|
|
618
618
|
_define_property(this, "message", void 0);
|
|
619
|
+
_define_property(this, "messageKey", void 0);
|
|
619
620
|
}
|
|
620
621
|
};
|
|
621
622
|
_ts_decorate([
|
|
@@ -642,3 +643,10 @@ _ts_decorate([
|
|
|
642
643
|
}),
|
|
643
644
|
_ts_metadata("design:type", String)
|
|
644
645
|
], PermissionOperationResultDto.prototype, "message", void 0);
|
|
646
|
+
_ts_decorate([
|
|
647
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
648
|
+
description: 'Translation key for localization',
|
|
649
|
+
example: 'permission.process.success'
|
|
650
|
+
}),
|
|
651
|
+
_ts_metadata("design:type", String)
|
|
652
|
+
], PermissionOperationResultDto.prototype, "messageKey", void 0);
|
|
@@ -9,11 +9,15 @@ Object.defineProperty(exports, "validateCompanyAccess", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _common = require("@nestjs/common");
|
|
12
|
-
|
|
12
|
+
const _constants = require("@flusys/nestjs-shared/constants");
|
|
13
|
+
function validateCompanyAccess(config, companyId, user, errorMessage = 'You do not have access to this company', messageKey = _constants.AUTH_MESSAGES.COMPANY_NO_ACCESS) {
|
|
13
14
|
if (!config.isCompanyFeatureEnabled() || !companyId) {
|
|
14
15
|
return;
|
|
15
16
|
}
|
|
16
17
|
if (user.companyId !== companyId) {
|
|
17
|
-
throw new _common.ForbiddenException(
|
|
18
|
+
throw new _common.ForbiddenException({
|
|
19
|
+
message: errorMessage,
|
|
20
|
+
messageKey
|
|
21
|
+
});
|
|
18
22
|
}
|
|
19
23
|
}
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "ActionService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
|
+
const _config = require("../config");
|
|
12
13
|
const _modules = require("@flusys/nestjs-shared/modules");
|
|
13
14
|
const _common = require("@nestjs/common");
|
|
14
15
|
const _typeorm = require("typeorm");
|
|
@@ -105,7 +106,13 @@ let ActionService = class ActionService extends _classes.RequestScopedApiService
|
|
|
105
106
|
}
|
|
106
107
|
requireUser(user, methodName) {
|
|
107
108
|
if (!user) {
|
|
108
|
-
throw new _common.BadRequestException(
|
|
109
|
+
throw new _common.BadRequestException({
|
|
110
|
+
message: `User is required for ${methodName}`,
|
|
111
|
+
messageKey: _config.PERMISSION_OPERATION_MESSAGES.USER_REQUIRED,
|
|
112
|
+
messageParams: {
|
|
113
|
+
method: methodName
|
|
114
|
+
}
|
|
115
|
+
});
|
|
109
116
|
}
|
|
110
117
|
}
|
|
111
118
|
/** Get actions available for permission assignment (filtered by company whitelist) */ async getActionsForPermission(user) {
|
|
@@ -177,7 +184,7 @@ let ActionService = class ActionService extends _classes.RequestScopedApiService
|
|
|
177
184
|
return rootNodes;
|
|
178
185
|
}
|
|
179
186
|
constructor(cacheManager, utilsService, iamConfigService, dataSourceProvider, permissionService){
|
|
180
|
-
super('action', null, cacheManager, utilsService, ActionService.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), _define_property(this, "permissionService", void 0), // Custom Methods
|
|
187
|
+
super('action', null, cacheManager, utilsService, ActionService.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), _define_property(this, "permissionService", void 0), // Custom Methods
|
|
181
188
|
_define_property(this, "actionSelectFields", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.iamConfigService = iamConfigService, this.dataSourceProvider = dataSourceProvider, this.permissionService = permissionService, this.actionSelectFields = [
|
|
182
189
|
'id',
|
|
183
190
|
'code',
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "IAMDataSourceService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _modules = require("@flusys/nestjs-shared/modules");
|
|
12
|
+
const _constants = require("@flusys/nestjs-shared/constants");
|
|
12
13
|
const _common = require("@nestjs/common");
|
|
13
14
|
const _core = require("@nestjs/core");
|
|
14
15
|
const _express = require("express");
|
|
@@ -109,7 +110,7 @@ let IAMDataSourceService = class IAMDataSourceService extends _modules.MultiTena
|
|
|
109
110
|
// Overrides
|
|
110
111
|
async createDataSourceFromConfig(config) {
|
|
111
112
|
const entities = await this.getIAMEntities();
|
|
112
|
-
return super.createDataSourceFromConfig(config, entities);
|
|
113
|
+
return await super.createDataSourceFromConfig(config, entities);
|
|
113
114
|
}
|
|
114
115
|
async getSingleDataSource() {
|
|
115
116
|
if (!IAMDataSourceService.singleDataSource) {
|
|
@@ -119,7 +120,10 @@ let IAMDataSourceService = class IAMDataSourceService extends _modules.MultiTena
|
|
|
119
120
|
const lockPromise = (async ()=>{
|
|
120
121
|
const config = this.getDefaultDatabaseConfig();
|
|
121
122
|
if (!config) {
|
|
122
|
-
throw new
|
|
123
|
+
throw new _common.InternalServerErrorException({
|
|
124
|
+
message: 'Default database config is not available',
|
|
125
|
+
messageKey: _constants.SYSTEM_MESSAGES.DATABASE_CONFIG_NOT_AVAILABLE
|
|
126
|
+
});
|
|
123
127
|
}
|
|
124
128
|
const ds = await this.createDataSourceFromConfig(config);
|
|
125
129
|
IAMDataSourceService.singleDataSource = ds;
|
|
@@ -159,7 +163,7 @@ let IAMDataSourceService = class IAMDataSourceService extends _modules.MultiTena
|
|
|
159
163
|
}
|
|
160
164
|
}
|
|
161
165
|
constructor(configService, request){
|
|
162
|
-
super(IAMDataSourceService.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0),
|
|
166
|
+
super(IAMDataSourceService.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0), this.configService = configService;
|
|
163
167
|
}
|
|
164
168
|
};
|
|
165
169
|
// Override parent's static properties to have IAM-specific cache
|
|
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "PermissionCacheService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
12
|
-
const _utils = require("@flusys/nestjs-shared/utils");
|
|
13
12
|
const _common = require("@nestjs/common");
|
|
14
13
|
function _define_property(obj, key, value) {
|
|
15
14
|
if (key in obj) {
|
|
@@ -55,38 +54,20 @@ let PermissionCacheService = class PermissionCacheService {
|
|
|
55
54
|
}
|
|
56
55
|
// Cache Operations
|
|
57
56
|
async setPermissions(options, permissions) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
await this.cacheManager.set(key, permissions, this.TTL);
|
|
61
|
-
this.logger.debug(`Cached ${permissions.length} permissions for key: ${key}`);
|
|
62
|
-
} catch (error) {
|
|
63
|
-
const errorMessage = _utils.ErrorHandler.getErrorMessage(error);
|
|
64
|
-
this.logger.error(`Failed to cache permissions: ${errorMessage}`);
|
|
65
|
-
// Don't throw - cache failure shouldn't break the operation
|
|
66
|
-
}
|
|
57
|
+
const key = this.generateCacheKey(options);
|
|
58
|
+
await this.cacheManager.set(key, permissions, this.TTL);
|
|
67
59
|
}
|
|
68
60
|
// My-Permissions Cache Operations
|
|
69
61
|
async setMyPermissions(options, data) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
await this.cacheManager.set(key, data, this.TTL);
|
|
73
|
-
this.logger.debug(`Cached my-permissions for key: ${key} (${data.frontendActions.length} frontend, ${data.backendCodes.length} backend)`);
|
|
74
|
-
} catch (error) {
|
|
75
|
-
const errorMessage = _utils.ErrorHandler.getErrorMessage(error);
|
|
76
|
-
this.logger.error(`Failed to cache my-permissions: ${errorMessage}`);
|
|
77
|
-
}
|
|
62
|
+
const key = this.generateMyPermissionsCacheKey(options);
|
|
63
|
+
await this.cacheManager.set(key, data, this.TTL);
|
|
78
64
|
}
|
|
79
65
|
async getMyPermissions(options) {
|
|
80
66
|
try {
|
|
81
67
|
const key = this.generateMyPermissionsCacheKey(options);
|
|
82
68
|
const result = await this.cacheManager.get(key);
|
|
83
|
-
if (result) {
|
|
84
|
-
this.logger.debug(`Cache hit for my-permissions: ${key}`);
|
|
85
|
-
}
|
|
86
69
|
return result || null;
|
|
87
|
-
} catch
|
|
88
|
-
const errorMessage = _utils.ErrorHandler.getErrorMessage(error);
|
|
89
|
-
this.logger.error(`Failed to get my-permissions from cache: ${errorMessage}`);
|
|
70
|
+
} catch {
|
|
90
71
|
return null;
|
|
91
72
|
}
|
|
92
73
|
}
|
|
@@ -98,14 +79,8 @@ let PermissionCacheService = class PermissionCacheService {
|
|
|
98
79
|
return `${this.ACTION_CODE_PREFIX}:map`;
|
|
99
80
|
}
|
|
100
81
|
async setActionCodeMap(codeToIdMap, tenantId) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
await this.cacheManager.set(key, codeToIdMap, this.ACTION_CODE_TTL);
|
|
104
|
-
this.logger.debug(`Cached ${Object.keys(codeToIdMap).length} action code mappings${tenantId ? ` for tenant ${tenantId}` : ''}`);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
const errorMessage = _utils.ErrorHandler.getErrorMessage(error);
|
|
107
|
-
this.logger.error(`Failed to cache action code map: ${errorMessage}`);
|
|
108
|
-
}
|
|
82
|
+
const key = this.generateActionCodeCacheKey(tenantId);
|
|
83
|
+
await this.cacheManager.set(key, codeToIdMap, this.ACTION_CODE_TTL);
|
|
109
84
|
}
|
|
110
85
|
async getActionIdsByCodes(codes, tenantId) {
|
|
111
86
|
try {
|
|
@@ -121,72 +96,47 @@ let PermissionCacheService = class PermissionCacheService {
|
|
|
121
96
|
}
|
|
122
97
|
}
|
|
123
98
|
return Object.keys(result).length > 0 ? result : null;
|
|
124
|
-
} catch
|
|
125
|
-
const errorMessage = _utils.ErrorHandler.getErrorMessage(error);
|
|
126
|
-
this.logger.error(`Failed to get action IDs from cache: ${errorMessage}`);
|
|
99
|
+
} catch {
|
|
127
100
|
return null;
|
|
128
101
|
}
|
|
129
102
|
}
|
|
130
103
|
// Cache Invalidation
|
|
131
104
|
async invalidateUser(userId, companyId, branchIds) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
105
|
+
const keysToDelete = [
|
|
106
|
+
`${this.CACHE_PREFIX}:user:${userId}`,
|
|
107
|
+
`${this.MY_PERMISSIONS_PREFIX}:user:${userId}`
|
|
108
|
+
];
|
|
109
|
+
if (companyId) {
|
|
110
|
+
const branches = branchIds?.length ? branchIds : [
|
|
111
|
+
null
|
|
138
112
|
];
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
null
|
|
142
|
-
];
|
|
143
|
-
for (const branchId of branches){
|
|
144
|
-
keysToDelete.push(`${this.CACHE_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`, `${this.MY_PERMISSIONS_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`);
|
|
145
|
-
}
|
|
113
|
+
for (const branchId of branches){
|
|
114
|
+
keysToDelete.push(`${this.CACHE_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`, `${this.MY_PERMISSIONS_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`);
|
|
146
115
|
}
|
|
147
|
-
await Promise.all(keysToDelete.map((key)=>this.cacheManager.del(key)));
|
|
148
|
-
this.logger.debug(`Invalidated ${keysToDelete.length} cache keys for user ${userId}`);
|
|
149
|
-
} catch (error) {
|
|
150
|
-
const errorMessage = _utils.ErrorHandler.getErrorMessage(error);
|
|
151
|
-
this.logger.warn(`Failed to invalidate user cache for ${userId}: ${errorMessage}`);
|
|
152
116
|
}
|
|
117
|
+
await Promise.all(keysToDelete.map((key)=>this.cacheManager.del(key)));
|
|
153
118
|
}
|
|
154
119
|
async invalidateUsers(userIds, companyId, branchIds) {
|
|
155
120
|
if (userIds.length === 0) {
|
|
156
121
|
return 0;
|
|
157
122
|
}
|
|
158
123
|
const results = await Promise.allSettled(userIds.map((userId)=>this.invalidateUser(userId, companyId, branchIds)));
|
|
159
|
-
|
|
160
|
-
const failedCount = results.filter((r)=>r.status === 'rejected').length;
|
|
161
|
-
if (failedCount > 0) {
|
|
162
|
-
this.logger.warn(`Failed to invalidate cache for ${failedCount} users`);
|
|
163
|
-
}
|
|
164
|
-
if (successCount > 0) {
|
|
165
|
-
this.logger.log(`Invalidated cache for ${successCount} users`);
|
|
166
|
-
}
|
|
167
|
-
return successCount;
|
|
124
|
+
return results.filter((r)=>r.status === 'fulfilled').length;
|
|
168
125
|
}
|
|
169
|
-
async invalidateRole(
|
|
126
|
+
async invalidateRole(_roleId, userIds, companyId, branchIds) {
|
|
170
127
|
if (userIds.length === 0) {
|
|
171
|
-
this.logger.debug(`No users found for role ${roleId}`);
|
|
172
128
|
return 0;
|
|
173
129
|
}
|
|
174
|
-
|
|
175
|
-
if (count > 0) {
|
|
176
|
-
this.logger.log(`Invalidated cache for ${count} users with role ${roleId}`);
|
|
177
|
-
}
|
|
178
|
-
return count;
|
|
130
|
+
return await this.invalidateUsers(userIds, companyId, branchIds);
|
|
179
131
|
}
|
|
180
132
|
constructor(cacheManager){
|
|
181
133
|
_define_property(this, "cacheManager", void 0);
|
|
182
|
-
_define_property(this, "logger", void 0);
|
|
183
134
|
_define_property(this, "TTL", void 0); // 1 hour
|
|
184
135
|
_define_property(this, "ACTION_CODE_TTL", void 0); // 2 hours for action codes (less frequent changes)
|
|
185
136
|
_define_property(this, "CACHE_PREFIX", void 0);
|
|
186
137
|
_define_property(this, "MY_PERMISSIONS_PREFIX", void 0);
|
|
187
138
|
_define_property(this, "ACTION_CODE_PREFIX", void 0);
|
|
188
139
|
this.cacheManager = cacheManager;
|
|
189
|
-
this.logger = new _common.Logger(PermissionCacheService.name);
|
|
190
140
|
this.TTL = 3600000;
|
|
191
141
|
this.ACTION_CODE_TTL = 7200000;
|
|
192
142
|
this.CACHE_PREFIX = 'permissions';
|
|
@@ -194,6 +144,82 @@ let PermissionCacheService = class PermissionCacheService {
|
|
|
194
144
|
this.ACTION_CODE_PREFIX = 'action-codes';
|
|
195
145
|
}
|
|
196
146
|
};
|
|
147
|
+
_ts_decorate([
|
|
148
|
+
(0, _nestjsshared.LogAction)({
|
|
149
|
+
action: 'permissionCache.setPermissions',
|
|
150
|
+
module: 'iam'
|
|
151
|
+
}),
|
|
152
|
+
_ts_metadata("design:type", Function),
|
|
153
|
+
_ts_metadata("design:paramtypes", [
|
|
154
|
+
typeof PermissionCacheKeyOptions === "undefined" ? Object : PermissionCacheKeyOptions,
|
|
155
|
+
Array
|
|
156
|
+
]),
|
|
157
|
+
_ts_metadata("design:returntype", Promise)
|
|
158
|
+
], PermissionCacheService.prototype, "setPermissions", null);
|
|
159
|
+
_ts_decorate([
|
|
160
|
+
(0, _nestjsshared.LogAction)({
|
|
161
|
+
action: 'permissionCache.setMyPermissions',
|
|
162
|
+
module: 'iam'
|
|
163
|
+
}),
|
|
164
|
+
_ts_metadata("design:type", Function),
|
|
165
|
+
_ts_metadata("design:paramtypes", [
|
|
166
|
+
typeof PermissionCacheKeyOptions === "undefined" ? Object : PermissionCacheKeyOptions,
|
|
167
|
+
typeof CachedMyPermissions === "undefined" ? Object : CachedMyPermissions
|
|
168
|
+
]),
|
|
169
|
+
_ts_metadata("design:returntype", Promise)
|
|
170
|
+
], PermissionCacheService.prototype, "setMyPermissions", null);
|
|
171
|
+
_ts_decorate([
|
|
172
|
+
(0, _nestjsshared.LogAction)({
|
|
173
|
+
action: 'permissionCache.setActionCodeMap',
|
|
174
|
+
module: 'iam'
|
|
175
|
+
}),
|
|
176
|
+
_ts_metadata("design:type", Function),
|
|
177
|
+
_ts_metadata("design:paramtypes", [
|
|
178
|
+
typeof Record === "undefined" ? Object : Record,
|
|
179
|
+
String
|
|
180
|
+
]),
|
|
181
|
+
_ts_metadata("design:returntype", Promise)
|
|
182
|
+
], PermissionCacheService.prototype, "setActionCodeMap", null);
|
|
183
|
+
_ts_decorate([
|
|
184
|
+
(0, _nestjsshared.LogAction)({
|
|
185
|
+
action: 'permissionCache.invalidateUser',
|
|
186
|
+
module: 'iam'
|
|
187
|
+
}),
|
|
188
|
+
_ts_metadata("design:type", Function),
|
|
189
|
+
_ts_metadata("design:paramtypes", [
|
|
190
|
+
String,
|
|
191
|
+
Object,
|
|
192
|
+
Array
|
|
193
|
+
]),
|
|
194
|
+
_ts_metadata("design:returntype", Promise)
|
|
195
|
+
], PermissionCacheService.prototype, "invalidateUser", null);
|
|
196
|
+
_ts_decorate([
|
|
197
|
+
(0, _nestjsshared.LogAction)({
|
|
198
|
+
action: 'permissionCache.invalidateUsers',
|
|
199
|
+
module: 'iam'
|
|
200
|
+
}),
|
|
201
|
+
_ts_metadata("design:type", Function),
|
|
202
|
+
_ts_metadata("design:paramtypes", [
|
|
203
|
+
Array,
|
|
204
|
+
Object,
|
|
205
|
+
Array
|
|
206
|
+
]),
|
|
207
|
+
_ts_metadata("design:returntype", Promise)
|
|
208
|
+
], PermissionCacheService.prototype, "invalidateUsers", null);
|
|
209
|
+
_ts_decorate([
|
|
210
|
+
(0, _nestjsshared.LogAction)({
|
|
211
|
+
action: 'permissionCache.invalidateRole',
|
|
212
|
+
module: 'iam'
|
|
213
|
+
}),
|
|
214
|
+
_ts_metadata("design:type", Function),
|
|
215
|
+
_ts_metadata("design:paramtypes", [
|
|
216
|
+
String,
|
|
217
|
+
Array,
|
|
218
|
+
Object,
|
|
219
|
+
Array
|
|
220
|
+
]),
|
|
221
|
+
_ts_metadata("design:returntype", Promise)
|
|
222
|
+
], PermissionCacheService.prototype, "invalidateRole", null);
|
|
197
223
|
PermissionCacheService = _ts_decorate([
|
|
198
224
|
(0, _common.Injectable)(),
|
|
199
225
|
_ts_param(0, (0, _common.Inject)('CACHE_INSTANCE')),
|