@flusys/nestjs-iam 0.1.0-alpha.1 → 0.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +665 -0
- package/cjs/config/iam.constants.js +11 -0
- package/cjs/config/index.js +18 -0
- package/cjs/controllers/action.controller.js +117 -0
- package/cjs/controllers/company-action-permission.controller.js +110 -0
- package/cjs/controllers/index.js +23 -0
- package/cjs/controllers/my-permission.controller.js +90 -0
- package/cjs/controllers/role-permission.controller.js +160 -0
- package/cjs/controllers/role.controller.js +58 -0
- package/cjs/controllers/user-action-permission.controller.js +110 -0
- package/cjs/docs/iam-swagger.config.js +202 -0
- package/cjs/docs/index.js +18 -0
- package/cjs/dtos/action.dto.js +347 -0
- package/cjs/dtos/index.js +21 -0
- package/cjs/dtos/permission.dto.js +554 -0
- package/cjs/dtos/role.dto.js +238 -0
- package/cjs/entities/action-base.entity.js +135 -0
- package/cjs/entities/action.entity.js +28 -0
- package/cjs/entities/index.js +81 -0
- package/cjs/entities/permission-base.entity.js +156 -0
- package/cjs/entities/permission-with-company.entity.js +99 -0
- package/cjs/entities/role-base.entity.js +86 -0
- package/cjs/entities/role-with-company.entity.js +55 -0
- package/cjs/entities/role.entity.js +25 -0
- package/cjs/entities/user-iam-permission.entity.js +57 -0
- package/cjs/enums/action-type.enum.js +22 -0
- package/cjs/enums/index.js +19 -0
- package/cjs/enums/permission-type.enum.js +16 -0
- package/cjs/helpers/index.js +19 -0
- package/cjs/helpers/permission-evaluator.helper.js +175 -0
- package/cjs/helpers/permission-mode.helper.js +49 -0
- package/cjs/index.js +28 -79
- package/cjs/interfaces/action.interface.js +4 -0
- package/cjs/interfaces/iam-module-async-options.interface.js +4 -0
- package/cjs/interfaces/iam-module-options.interface.js +18 -0
- package/cjs/interfaces/index.js +21 -0
- package/cjs/interfaces/role.interface.js +7 -0
- package/cjs/modules/iam.module.js +237 -0
- package/cjs/modules/index.js +18 -0
- package/cjs/services/action.service.js +253 -0
- package/cjs/services/iam-config.service.js +107 -0
- package/cjs/services/iam-datasource.provider.js +205 -0
- package/cjs/services/index.js +23 -0
- package/cjs/services/permission-cache.service.js +308 -0
- package/cjs/services/permission.service.js +1020 -0
- package/cjs/services/role.service.js +181 -0
- package/cjs/types/index.js +18 -0
- package/cjs/types/logic-node.type.js +54 -0
- package/fesm/config/iam.constants.js +1 -0
- package/fesm/config/index.js +1 -0
- package/fesm/controllers/action.controller.js +107 -0
- package/fesm/controllers/company-action-permission.controller.js +100 -0
- package/fesm/controllers/index.js +7 -0
- package/fesm/controllers/my-permission.controller.js +80 -0
- package/fesm/controllers/role-permission.controller.js +150 -0
- package/fesm/controllers/role.controller.js +48 -0
- package/fesm/controllers/user-action-permission.controller.js +100 -0
- package/fesm/docs/iam-swagger.config.js +192 -0
- package/fesm/docs/index.js +1 -0
- package/fesm/dtos/action.dto.js +317 -0
- package/fesm/dtos/index.js +4 -0
- package/fesm/dtos/permission.dto.js +490 -0
- package/fesm/dtos/role.dto.js +214 -0
- package/fesm/entities/action-base.entity.js +128 -0
- package/fesm/entities/action.entity.js +18 -0
- package/fesm/entities/index.js +56 -0
- package/fesm/entities/permission-base.entity.js +138 -0
- package/fesm/entities/permission-with-company.entity.js +89 -0
- package/fesm/entities/role-base.entity.js +79 -0
- package/fesm/entities/role-with-company.entity.js +45 -0
- package/fesm/entities/role.entity.js +15 -0
- package/fesm/entities/user-iam-permission.entity.js +38 -0
- package/fesm/enums/action-type.enum.js +12 -0
- package/fesm/enums/index.js +2 -0
- package/fesm/enums/permission-type.enum.js +6 -0
- package/fesm/helpers/index.js +2 -0
- package/fesm/helpers/permission-evaluator.helper.js +165 -0
- package/fesm/helpers/permission-mode.helper.js +49 -0
- package/fesm/index.js +11 -79
- package/fesm/interfaces/action.interface.js +3 -0
- package/fesm/interfaces/iam-module-async-options.interface.js +3 -0
- package/fesm/interfaces/iam-module-options.interface.js +1 -0
- package/fesm/interfaces/index.js +4 -0
- package/fesm/interfaces/role.interface.js +4 -0
- package/fesm/modules/iam.module.js +227 -0
- package/fesm/modules/index.js +1 -0
- package/fesm/services/action.service.js +243 -0
- package/fesm/services/iam-config.service.js +97 -0
- package/fesm/services/iam-datasource.provider.js +154 -0
- package/fesm/services/index.js +6 -0
- package/fesm/services/permission-cache.service.js +298 -0
- package/fesm/services/permission.service.js +1010 -0
- package/fesm/services/role.service.js +171 -0
- package/fesm/types/index.js +1 -0
- package/fesm/types/logic-node.type.js +36 -0
- package/package.json +25 -25
- package/cjs/config-index.js +0 -1
- package/cjs/controllers-index.js +0 -1
- package/cjs/docs-index.js +0 -79
- package/cjs/dtos-index.js +0 -1
- package/cjs/entities-index.js +0 -1
- package/cjs/enums-index.js +0 -1
- package/cjs/helpers-index.js +0 -1
- package/cjs/interfaces-index.js +0 -1
- package/cjs/modules-index.js +0 -1
- package/cjs/services-index.js +0 -1
- package/cjs/types-index.js +0 -1
- package/fesm/config-index.js +0 -1
- package/fesm/controllers-index.js +0 -1
- package/fesm/docs-index.js +0 -79
- package/fesm/dtos-index.js +0 -1
- package/fesm/entities-index.js +0 -1
- package/fesm/enums-index.js +0 -1
- package/fesm/helpers-index.js +0 -1
- package/fesm/interfaces-index.js +0 -0
- package/fesm/modules-index.js +0 -1
- package/fesm/services-index.js +0 -1
- package/fesm/types-index.js +0 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "IAMModule", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return IAMModule;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _modules = require("@flusys/nestjs-shared/modules");
|
|
12
|
+
const _common = require("@nestjs/common");
|
|
13
|
+
const _typeorm = require("@nestjs/typeorm");
|
|
14
|
+
const _iamconstants = require("../config/iam.constants");
|
|
15
|
+
const _controllers = require("../controllers");
|
|
16
|
+
const _entities = require("../entities");
|
|
17
|
+
const _permissiontypeenum = require("../enums/permission-type.enum");
|
|
18
|
+
const _helpers = require("../helpers");
|
|
19
|
+
const _services = require("../services");
|
|
20
|
+
const _iamconfigservice = require("../services/iam-config.service");
|
|
21
|
+
const _iamdatasourceprovider = require("../services/iam-datasource.provider");
|
|
22
|
+
const _permissioncacheservice = require("../services/permission-cache.service");
|
|
23
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
24
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
25
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
26
|
+
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;
|
|
27
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
28
|
+
}
|
|
29
|
+
let IAMModule = class IAMModule {
|
|
30
|
+
static getControllers(permissionMode, enableCompanyFeature) {
|
|
31
|
+
const baseControllers = [
|
|
32
|
+
_controllers.ActionController,
|
|
33
|
+
_controllers.MyPermissionController
|
|
34
|
+
];
|
|
35
|
+
// Direct permission mode - user actions only
|
|
36
|
+
if (permissionMode === _permissiontypeenum.IAMPermissionMode.DIRECT) {
|
|
37
|
+
baseControllers.push(_controllers.UserActionPermissionController);
|
|
38
|
+
}
|
|
39
|
+
// RBAC mode - role actions and user roles only
|
|
40
|
+
if (permissionMode === _permissiontypeenum.IAMPermissionMode.RBAC) {
|
|
41
|
+
baseControllers.push(_controllers.RoleController);
|
|
42
|
+
baseControllers.push(_controllers.RolePermissionController);
|
|
43
|
+
}
|
|
44
|
+
// FULL mode - all permission controllers
|
|
45
|
+
if (permissionMode === _permissiontypeenum.IAMPermissionMode.FULL) {
|
|
46
|
+
baseControllers.push(_controllers.RoleController);
|
|
47
|
+
baseControllers.push(_controllers.UserActionPermissionController);
|
|
48
|
+
baseControllers.push(_controllers.RolePermissionController);
|
|
49
|
+
}
|
|
50
|
+
// Company action permissions - only if company feature enabled
|
|
51
|
+
if (enableCompanyFeature) {
|
|
52
|
+
baseControllers.push(_controllers.CompanyActionPermissionController);
|
|
53
|
+
}
|
|
54
|
+
return baseControllers;
|
|
55
|
+
}
|
|
56
|
+
static getEntities(permissionMode, enableCompanyFeature) {
|
|
57
|
+
// Core entities
|
|
58
|
+
const entities = [];
|
|
59
|
+
// Action entity - always included
|
|
60
|
+
entities.push(_entities.Action);
|
|
61
|
+
// Permission entity is always needed
|
|
62
|
+
if (enableCompanyFeature) {
|
|
63
|
+
entities.push(_entities.UserIamPermissionWithCompany);
|
|
64
|
+
} else {
|
|
65
|
+
entities.push(_entities.UserIamPermission);
|
|
66
|
+
}
|
|
67
|
+
// Role entity - Only for RBAC or FULL mode
|
|
68
|
+
if (permissionMode === _permissiontypeenum.IAMPermissionMode.RBAC || permissionMode === _permissiontypeenum.IAMPermissionMode.FULL) {
|
|
69
|
+
if (enableCompanyFeature) {
|
|
70
|
+
entities.push(_entities.RoleWithCompany);
|
|
71
|
+
} else {
|
|
72
|
+
entities.push(_entities.Role);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return entities;
|
|
76
|
+
}
|
|
77
|
+
static getServices(permissionMode) {
|
|
78
|
+
const services = [
|
|
79
|
+
_services.ActionService,
|
|
80
|
+
_services.PermissionService,
|
|
81
|
+
_permissioncacheservice.PermissionCacheService,
|
|
82
|
+
_helpers.PermissionEvaluatorHelper
|
|
83
|
+
];
|
|
84
|
+
// RoleService - Only for RBAC or FULL mode
|
|
85
|
+
if (permissionMode === _permissiontypeenum.IAMPermissionMode.RBAC || permissionMode === _permissiontypeenum.IAMPermissionMode.FULL) {
|
|
86
|
+
services.push(_services.RoleService);
|
|
87
|
+
}
|
|
88
|
+
return services;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create repository providers that use IAMDataSourceProvider
|
|
92
|
+
* This replaces TypeOrmModule.forFeature() functionality
|
|
93
|
+
*/ static getRepositoryProviders(permissionMode, enableCompanyFeature) {
|
|
94
|
+
const entities = this.getEntities(permissionMode, enableCompanyFeature);
|
|
95
|
+
return entities.map((entity)=>({
|
|
96
|
+
provide: (0, _typeorm.getRepositoryToken)(entity),
|
|
97
|
+
scope: _common.Scope.REQUEST,
|
|
98
|
+
useFactory: async (dataSourceProvider)=>{
|
|
99
|
+
return await dataSourceProvider.getRepository(entity);
|
|
100
|
+
},
|
|
101
|
+
inject: [
|
|
102
|
+
_iamdatasourceprovider.IAMDataSourceProvider
|
|
103
|
+
]
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
static forRoot(options = {}) {
|
|
107
|
+
const { global = false, includeController = false } = options;
|
|
108
|
+
const databaseMode = options.bootstrapAppConfig?.databaseMode;
|
|
109
|
+
const enableCompanyFeature = options.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
110
|
+
// Read permissionMode from bootstrap config using helper
|
|
111
|
+
const permissionMode = _helpers.PermissionModeHelper.fromString(options.bootstrapAppConfig?.permissionMode);
|
|
112
|
+
const isMultiTenant = databaseMode === 'multi-tenant';
|
|
113
|
+
const entities = this.getEntities(permissionMode, enableCompanyFeature);
|
|
114
|
+
const controllers = includeController ? this.getControllers(permissionMode, enableCompanyFeature) : [];
|
|
115
|
+
const providers = [
|
|
116
|
+
{
|
|
117
|
+
provide: _iamconstants.IAM_MODULE_OPTIONS,
|
|
118
|
+
useValue: options
|
|
119
|
+
},
|
|
120
|
+
_iamconfigservice.IAMConfigService,
|
|
121
|
+
_iamdatasourceprovider.IAMDataSourceProvider,
|
|
122
|
+
...this.getServices(permissionMode)
|
|
123
|
+
];
|
|
124
|
+
const imports = [
|
|
125
|
+
_modules.CacheModule,
|
|
126
|
+
_modules.UtilsModule
|
|
127
|
+
];
|
|
128
|
+
const module = {
|
|
129
|
+
module: IAMModule,
|
|
130
|
+
imports,
|
|
131
|
+
controllers,
|
|
132
|
+
providers,
|
|
133
|
+
exports: [
|
|
134
|
+
_iamconfigservice.IAMConfigService,
|
|
135
|
+
_iamdatasourceprovider.IAMDataSourceProvider,
|
|
136
|
+
_services.ActionService,
|
|
137
|
+
_services.PermissionService,
|
|
138
|
+
_permissioncacheservice.PermissionCacheService,
|
|
139
|
+
_helpers.PermissionEvaluatorHelper,
|
|
140
|
+
...permissionMode === _permissiontypeenum.IAMPermissionMode.RBAC || permissionMode === _permissiontypeenum.IAMPermissionMode.FULL ? [
|
|
141
|
+
_services.RoleService
|
|
142
|
+
] : []
|
|
143
|
+
]
|
|
144
|
+
};
|
|
145
|
+
if (global) {
|
|
146
|
+
return {
|
|
147
|
+
...module,
|
|
148
|
+
global: true
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return module;
|
|
152
|
+
}
|
|
153
|
+
static forRootAsync(asyncOptions) {
|
|
154
|
+
const { global = false, includeController = false, imports: externalImports = [] } = asyncOptions;
|
|
155
|
+
const databaseMode = asyncOptions.bootstrapAppConfig?.databaseMode;
|
|
156
|
+
const enableCompanyFeature = asyncOptions.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
157
|
+
// Read permissionMode from bootstrap config using helper
|
|
158
|
+
const permissionMode = _helpers.PermissionModeHelper.fromString(asyncOptions.bootstrapAppConfig?.permissionMode);
|
|
159
|
+
const isMultiTenant = databaseMode === 'multi-tenant';
|
|
160
|
+
const entities = this.getEntities(permissionMode, enableCompanyFeature);
|
|
161
|
+
const controllers = includeController ? this.getControllers(permissionMode, enableCompanyFeature) : [];
|
|
162
|
+
const asyncProviders = this.createAsyncProviders(asyncOptions);
|
|
163
|
+
const providers = [
|
|
164
|
+
...asyncProviders,
|
|
165
|
+
_iamconfigservice.IAMConfigService,
|
|
166
|
+
_iamdatasourceprovider.IAMDataSourceProvider,
|
|
167
|
+
...this.getServices(permissionMode)
|
|
168
|
+
];
|
|
169
|
+
const imports = [
|
|
170
|
+
...externalImports,
|
|
171
|
+
_modules.CacheModule,
|
|
172
|
+
_modules.UtilsModule
|
|
173
|
+
];
|
|
174
|
+
const module = {
|
|
175
|
+
module: IAMModule,
|
|
176
|
+
imports,
|
|
177
|
+
controllers,
|
|
178
|
+
providers,
|
|
179
|
+
exports: [
|
|
180
|
+
_iamconfigservice.IAMConfigService,
|
|
181
|
+
_iamdatasourceprovider.IAMDataSourceProvider,
|
|
182
|
+
_services.ActionService,
|
|
183
|
+
_services.PermissionService,
|
|
184
|
+
_permissioncacheservice.PermissionCacheService,
|
|
185
|
+
_helpers.PermissionEvaluatorHelper,
|
|
186
|
+
...permissionMode === _permissiontypeenum.IAMPermissionMode.RBAC || permissionMode === _permissiontypeenum.IAMPermissionMode.FULL ? [
|
|
187
|
+
_services.RoleService
|
|
188
|
+
] : []
|
|
189
|
+
]
|
|
190
|
+
};
|
|
191
|
+
if (global) {
|
|
192
|
+
return {
|
|
193
|
+
...module,
|
|
194
|
+
global: true
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return module;
|
|
198
|
+
}
|
|
199
|
+
static createAsyncProviders(options) {
|
|
200
|
+
if (options.useExisting || options.useFactory) {
|
|
201
|
+
return [
|
|
202
|
+
this.createAsyncOptionsProvider(options)
|
|
203
|
+
];
|
|
204
|
+
}
|
|
205
|
+
const useClass = options.useClass;
|
|
206
|
+
return [
|
|
207
|
+
this.createAsyncOptionsProvider(options),
|
|
208
|
+
{
|
|
209
|
+
provide: useClass,
|
|
210
|
+
useClass
|
|
211
|
+
}
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
static createAsyncOptionsProvider(options) {
|
|
215
|
+
if (options.useFactory) {
|
|
216
|
+
return {
|
|
217
|
+
provide: _iamconstants.IAM_MODULE_OPTIONS,
|
|
218
|
+
useFactory: options.useFactory,
|
|
219
|
+
inject: options.inject || []
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const inject = [
|
|
223
|
+
options.useClass || options.useExisting
|
|
224
|
+
];
|
|
225
|
+
return {
|
|
226
|
+
provide: _iamconstants.IAM_MODULE_OPTIONS,
|
|
227
|
+
useFactory: async (optionsFactory)=>optionsFactory.createIAMOptions(),
|
|
228
|
+
inject
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
static forFeature(options = {}) {
|
|
232
|
+
return this.forRoot(options);
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
IAMModule = _ts_decorate([
|
|
236
|
+
(0, _common.Module)({})
|
|
237
|
+
], IAMModule);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./iam.module"), exports);
|
|
6
|
+
function _export_star(from, to) {
|
|
7
|
+
Object.keys(from).forEach(function(k) {
|
|
8
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
9
|
+
Object.defineProperty(to, k, {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function() {
|
|
12
|
+
return from[k];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return from;
|
|
18
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ActionService", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return ActionService;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
|
+
const _modules = require("@flusys/nestjs-shared/modules");
|
|
13
|
+
const _common = require("@nestjs/common");
|
|
14
|
+
const _typeorm = require("typeorm");
|
|
15
|
+
const _actionentity = require("../entities/action.entity");
|
|
16
|
+
const _iamconfigservice = require("./iam-config.service");
|
|
17
|
+
const _iamdatasourceprovider = require("./iam-datasource.provider");
|
|
18
|
+
const _permissionservice = require("./permission.service");
|
|
19
|
+
function _define_property(obj, key, value) {
|
|
20
|
+
if (key in obj) {
|
|
21
|
+
Object.defineProperty(obj, key, {
|
|
22
|
+
value: value,
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true
|
|
26
|
+
});
|
|
27
|
+
} else {
|
|
28
|
+
obj[key] = value;
|
|
29
|
+
}
|
|
30
|
+
return obj;
|
|
31
|
+
}
|
|
32
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
33
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
34
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
35
|
+
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;
|
|
36
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
37
|
+
}
|
|
38
|
+
function _ts_metadata(k, v) {
|
|
39
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
40
|
+
}
|
|
41
|
+
function _ts_param(paramIndex, decorator) {
|
|
42
|
+
return function(target, key) {
|
|
43
|
+
decorator(target, key, paramIndex);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
let ActionService = class ActionService extends _classes.RequestScopedApiService {
|
|
47
|
+
/**
|
|
48
|
+
* Resolve entity class for this service
|
|
49
|
+
* @returns Action entity class
|
|
50
|
+
*/ resolveEntity() {
|
|
51
|
+
return _actionentity.Action;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get DataSource provider for this service
|
|
55
|
+
* @returns IAMDataSourceProvider instance
|
|
56
|
+
*/ getDataSourceProvider() {
|
|
57
|
+
return this.dataSourceProvider;
|
|
58
|
+
}
|
|
59
|
+
// ==================== Entity Conversion ====================
|
|
60
|
+
async convertSingleDtoToEntity(dto, _user) {
|
|
61
|
+
if (!('id' in dto) || !dto.id) {
|
|
62
|
+
return dto;
|
|
63
|
+
}
|
|
64
|
+
const existingAction = await this.repository.findOne({
|
|
65
|
+
where: {
|
|
66
|
+
id: dto.id
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
if (!existingAction) {
|
|
70
|
+
throw new _common.NotFoundException(`Action with ID ${dto.id} not found`);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
...existingAction,
|
|
74
|
+
...dto
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async getSelectQuery(query, _user, select) {
|
|
78
|
+
if (!select || !select.length) {
|
|
79
|
+
select = [
|
|
80
|
+
'id',
|
|
81
|
+
'name',
|
|
82
|
+
'code',
|
|
83
|
+
'description',
|
|
84
|
+
'actionType',
|
|
85
|
+
'permissionLogic',
|
|
86
|
+
'isActive',
|
|
87
|
+
'parentId',
|
|
88
|
+
'serial',
|
|
89
|
+
'createdAt'
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
const selectFields = select.map((field)=>`${this.entityName}.${field}`);
|
|
93
|
+
query.select(selectFields);
|
|
94
|
+
return {
|
|
95
|
+
query,
|
|
96
|
+
isRaw: false
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
async getGlobalSearchQuery(query, search, _user) {
|
|
100
|
+
query.andWhere('(action.name LIKE :search OR action.code LIKE :search OR action.description LIKE :search)', {
|
|
101
|
+
search: `%${search}%`
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
query,
|
|
105
|
+
isRaw: false
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Override: Convert entity to response DTO
|
|
110
|
+
*/ convertEntityToResponseDto(entity, _isRaw) {
|
|
111
|
+
return {
|
|
112
|
+
id: entity.id,
|
|
113
|
+
readOnly: entity.readOnly,
|
|
114
|
+
name: entity.name,
|
|
115
|
+
description: entity.description,
|
|
116
|
+
code: entity.code,
|
|
117
|
+
actionType: entity.actionType,
|
|
118
|
+
permissionLogic: entity.permissionLogic,
|
|
119
|
+
serial: entity.serial,
|
|
120
|
+
isActive: entity.isActive,
|
|
121
|
+
parentId: entity.parentId,
|
|
122
|
+
metadata: entity.metadata,
|
|
123
|
+
createdAt: entity.createdAt,
|
|
124
|
+
updatedAt: entity.updatedAt,
|
|
125
|
+
deletedAt: entity.deletedAt,
|
|
126
|
+
createdById: entity.createdById,
|
|
127
|
+
updatedById: entity.updatedById,
|
|
128
|
+
deletedById: entity.deletedById
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get actions available for permission assignment (filtered by company whitelist)
|
|
133
|
+
*
|
|
134
|
+
* @param user - Logged in user info
|
|
135
|
+
* @returns Array of actions with id, code, and name fields
|
|
136
|
+
*/ async getActionsForPermission(user) {
|
|
137
|
+
await this.ensureRepositoryInitialized();
|
|
138
|
+
if (!user) {
|
|
139
|
+
throw new Error('User is required for getActionsForPermission');
|
|
140
|
+
}
|
|
141
|
+
const selectFields = [
|
|
142
|
+
'id',
|
|
143
|
+
'code',
|
|
144
|
+
'name',
|
|
145
|
+
'description',
|
|
146
|
+
'actionType',
|
|
147
|
+
'permissionLogic',
|
|
148
|
+
'isActive',
|
|
149
|
+
'parentId',
|
|
150
|
+
'serial'
|
|
151
|
+
];
|
|
152
|
+
const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
|
|
153
|
+
if (enableCompanyFeature && user.companyId) {
|
|
154
|
+
const companyActionIds = await this.permissionService.getCompanyActionIds(user.companyId);
|
|
155
|
+
if (companyActionIds.length === 0) {
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
const actions = await this.repository.find({
|
|
159
|
+
where: {
|
|
160
|
+
id: (0, _typeorm.In)(companyActionIds)
|
|
161
|
+
},
|
|
162
|
+
select: selectFields
|
|
163
|
+
});
|
|
164
|
+
return actions.map((action)=>this.convertEntityToResponseDto(action, false));
|
|
165
|
+
}
|
|
166
|
+
const actions = await this.repository.find({
|
|
167
|
+
select: selectFields
|
|
168
|
+
});
|
|
169
|
+
return actions.map((action)=>this.convertEntityToResponseDto(action, false));
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get actions in hierarchical tree structure
|
|
173
|
+
*
|
|
174
|
+
* @param user - Logged in user info for company filtering
|
|
175
|
+
* @param search - Optional search term (name or code)
|
|
176
|
+
* @param isActive - Optional filter by active status
|
|
177
|
+
* @param withDeleted - Include deleted actions (default: false)
|
|
178
|
+
* @returns Array of root actions with nested children
|
|
179
|
+
*/ async getActionTree(user, search, isActive, withDeleted = false) {
|
|
180
|
+
await this.ensureRepositoryInitialized();
|
|
181
|
+
if (!user) {
|
|
182
|
+
throw new Error('User is required for getActionTree');
|
|
183
|
+
}
|
|
184
|
+
const query = this.repository.createQueryBuilder('action');
|
|
185
|
+
if (!withDeleted) {
|
|
186
|
+
query.andWhere('action.deletedAt IS NULL');
|
|
187
|
+
}
|
|
188
|
+
if (isActive !== undefined) {
|
|
189
|
+
query.andWhere('action.isActive = :isActive', {
|
|
190
|
+
isActive
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (search?.trim()) {
|
|
194
|
+
query.andWhere('(action.name LIKE :search OR action.code LIKE :search)', {
|
|
195
|
+
search: `%${search.trim()}%`
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const actions = await query.orderBy('action.serial', 'ASC').getMany();
|
|
199
|
+
return this.buildActionTree(actions);
|
|
200
|
+
}
|
|
201
|
+
buildActionTree(actions) {
|
|
202
|
+
if (!actions?.length) {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
const map = new Map();
|
|
206
|
+
const rootNodes = [];
|
|
207
|
+
for (const action of actions){
|
|
208
|
+
const treeNode = {
|
|
209
|
+
...this.convertEntityToResponseDto(action, false),
|
|
210
|
+
children: []
|
|
211
|
+
};
|
|
212
|
+
map.set(action.id, treeNode);
|
|
213
|
+
}
|
|
214
|
+
for (const action of actions){
|
|
215
|
+
const node = map.get(action.id);
|
|
216
|
+
if (!node) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (action.parentId && map.has(action.parentId)) {
|
|
220
|
+
const parent = map.get(action.parentId);
|
|
221
|
+
if (parent?.children) {
|
|
222
|
+
parent.children.push(node);
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
rootNodes.push(node);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return rootNodes;
|
|
229
|
+
}
|
|
230
|
+
// NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
|
|
231
|
+
constructor(cacheManager, utilsService, iamConfigService, dataSourceProvider, permissionService){
|
|
232
|
+
// Repository will be set asynchronously by RequestScopedApiService
|
|
233
|
+
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), _define_property(this, "logger", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.iamConfigService = iamConfigService, this.dataSourceProvider = dataSourceProvider, this.permissionService = permissionService, this.logger = new _common.Logger(ActionService.name);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
ActionService = _ts_decorate([
|
|
237
|
+
(0, _common.Injectable)({
|
|
238
|
+
scope: _common.Scope.REQUEST
|
|
239
|
+
}),
|
|
240
|
+
_ts_param(0, (0, _common.Inject)('CACHE_INSTANCE')),
|
|
241
|
+
_ts_param(1, (0, _common.Inject)(_modules.UtilsService)),
|
|
242
|
+
_ts_param(2, (0, _common.Inject)(_iamconfigservice.IAMConfigService)),
|
|
243
|
+
_ts_param(3, (0, _common.Inject)(_iamdatasourceprovider.IAMDataSourceProvider)),
|
|
244
|
+
_ts_param(4, (0, _common.Inject)(_permissionservice.PermissionService)),
|
|
245
|
+
_ts_metadata("design:type", Function),
|
|
246
|
+
_ts_metadata("design:paramtypes", [
|
|
247
|
+
typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
|
|
248
|
+
typeof _modules.UtilsService === "undefined" ? Object : _modules.UtilsService,
|
|
249
|
+
typeof _iamconfigservice.IAMConfigService === "undefined" ? Object : _iamconfigservice.IAMConfigService,
|
|
250
|
+
typeof _iamdatasourceprovider.IAMDataSourceProvider === "undefined" ? Object : _iamdatasourceprovider.IAMDataSourceProvider,
|
|
251
|
+
typeof _permissionservice.PermissionService === "undefined" ? Object : _permissionservice.PermissionService
|
|
252
|
+
])
|
|
253
|
+
], ActionService);
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "IAMConfigService", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return IAMConfigService;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _common = require("@nestjs/common");
|
|
12
|
+
const _iamconstants = require("../config/iam.constants");
|
|
13
|
+
const _permissiontypeenum = require("../enums/permission-type.enum");
|
|
14
|
+
const _helpers = require("../helpers");
|
|
15
|
+
const _iammoduleoptionsinterface = require("../interfaces/iam-module-options.interface");
|
|
16
|
+
function _define_property(obj, key, value) {
|
|
17
|
+
if (key in obj) {
|
|
18
|
+
Object.defineProperty(obj, key, {
|
|
19
|
+
value: value,
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true
|
|
23
|
+
});
|
|
24
|
+
} else {
|
|
25
|
+
obj[key] = value;
|
|
26
|
+
}
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
30
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
31
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
32
|
+
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;
|
|
33
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
34
|
+
}
|
|
35
|
+
function _ts_metadata(k, v) {
|
|
36
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
37
|
+
}
|
|
38
|
+
function _ts_param(paramIndex, decorator) {
|
|
39
|
+
return function(target, key) {
|
|
40
|
+
decorator(target, key, paramIndex);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
let IAMConfigService = class IAMConfigService {
|
|
44
|
+
// ==================== Database Mode ====================
|
|
45
|
+
/**
|
|
46
|
+
* Get database mode (single or multi-tenant)
|
|
47
|
+
*/ getDatabaseMode() {
|
|
48
|
+
return this.options.bootstrapAppConfig?.databaseMode ?? 'single';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check if running in multi-tenant mode
|
|
52
|
+
*/ isMultiTenant() {
|
|
53
|
+
return this.getDatabaseMode() === 'multi-tenant';
|
|
54
|
+
}
|
|
55
|
+
// ==================== Company Feature ====================
|
|
56
|
+
/**
|
|
57
|
+
* Get enable company feature flag
|
|
58
|
+
*/ getEnableCompanyFeature() {
|
|
59
|
+
return this.options.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if company feature is enabled (alias for getEnableCompanyFeature)
|
|
63
|
+
*/ isCompanyFeatureEnabled() {
|
|
64
|
+
return this.getEnableCompanyFeature();
|
|
65
|
+
}
|
|
66
|
+
// ==================== Permission Mode ====================
|
|
67
|
+
/**
|
|
68
|
+
* Get permission mode from bootstrap config
|
|
69
|
+
*
|
|
70
|
+
* **Note:** Reads from bootstrapAppConfig (not runtime config)
|
|
71
|
+
* because permissionMode affects entity/controller registration.
|
|
72
|
+
*/ getPermissionMode() {
|
|
73
|
+
return _helpers.PermissionModeHelper.fromString(this.options.bootstrapAppConfig?.permissionMode);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if RBAC (role-based) permissions are enabled
|
|
77
|
+
*/ isRbacEnabled() {
|
|
78
|
+
const mode = this.getPermissionMode();
|
|
79
|
+
return mode === _permissiontypeenum.IAMPermissionMode.RBAC || mode === _permissiontypeenum.IAMPermissionMode.FULL;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if direct (user-level) permissions are enabled
|
|
83
|
+
*/ isDirectPermissionEnabled() {
|
|
84
|
+
const mode = this.getPermissionMode();
|
|
85
|
+
return mode === _permissiontypeenum.IAMPermissionMode.DIRECT || mode === _permissiontypeenum.IAMPermissionMode.FULL;
|
|
86
|
+
}
|
|
87
|
+
// ==================== Options ====================
|
|
88
|
+
getOptions() {
|
|
89
|
+
return this.options;
|
|
90
|
+
}
|
|
91
|
+
constructor(injectedOptions){
|
|
92
|
+
_define_property(this, "options", void 0);
|
|
93
|
+
this.options = injectedOptions ?? {
|
|
94
|
+
global: false,
|
|
95
|
+
includeController: false
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
IAMConfigService = _ts_decorate([
|
|
100
|
+
(0, _common.Injectable)(),
|
|
101
|
+
_ts_param(0, (0, _common.Optional)()),
|
|
102
|
+
_ts_param(0, (0, _common.Inject)(_iamconstants.IAM_MODULE_OPTIONS)),
|
|
103
|
+
_ts_metadata("design:type", Function),
|
|
104
|
+
_ts_metadata("design:paramtypes", [
|
|
105
|
+
typeof _iammoduleoptionsinterface.IAMModuleOptions === "undefined" ? Object : _iammoduleoptionsinterface.IAMModuleOptions
|
|
106
|
+
])
|
|
107
|
+
], IAMConfigService);
|