@flusys/nestjs-iam 7.1.0 → 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,49 +0,0 @@
|
|
|
1
|
-
import { IAMPermissionMode } from '../enums/permission-type.enum';
|
|
2
|
-
/**
|
|
3
|
-
* Helper for converting permission mode strings to enum values
|
|
4
|
-
*
|
|
5
|
-
* **Purpose:** Centralize the conversion logic from IBootstrapAppConfig.permissionMode
|
|
6
|
-
* (string) to IAMPermissionMode enum to prevent duplication and sync issues.
|
|
7
|
-
*
|
|
8
|
-
* **Used by:**
|
|
9
|
-
* - iam.module.ts (forRoot, forRootAsync)
|
|
10
|
-
* - iam-config.service.ts (getPermissionMode)
|
|
11
|
-
* - main.ts (Swagger setup)
|
|
12
|
-
*/ export class PermissionModeHelper {
|
|
13
|
-
/**
|
|
14
|
-
* Convert permission mode string to enum value
|
|
15
|
-
*
|
|
16
|
-
* @param modeStr - Permission mode string ('FULL', 'RBAC', 'DIRECT')
|
|
17
|
-
* @returns IAMPermissionMode enum value
|
|
18
|
-
* @default IAMPermissionMode.FULL if invalid/missing
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* const mode = PermissionModeHelper.fromString('RBAC');
|
|
23
|
-
* // Returns: IAMPermissionMode.RBAC
|
|
24
|
-
*
|
|
25
|
-
* const mode = PermissionModeHelper.fromString(undefined);
|
|
26
|
-
* // Returns: IAMPermissionMode.FULL (default)
|
|
27
|
-
* ```
|
|
28
|
-
*/ static fromString(modeStr) {
|
|
29
|
-
if (!modeStr) {
|
|
30
|
-
return IAMPermissionMode.FULL;
|
|
31
|
-
}
|
|
32
|
-
const mode = IAMPermissionMode[modeStr];
|
|
33
|
-
return mode ?? IAMPermissionMode.FULL;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Convert enum value to string (for serialization/logging)
|
|
37
|
-
*
|
|
38
|
-
* @param mode - IAMPermissionMode enum value
|
|
39
|
-
* @returns String representation
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```typescript
|
|
43
|
-
* const str = PermissionModeHelper.toString(IAMPermissionMode.RBAC);
|
|
44
|
-
* // Returns: 'RBAC'
|
|
45
|
-
* ```
|
|
46
|
-
*/ static toString(mode) {
|
|
47
|
-
return IAMPermissionMode[mode];
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { IAMPermissionMode } from '../enums/permission-type.enum';
|
|
2
|
-
import { PermissionModeHelper } from './permission-mode.helper';
|
|
3
|
-
describe('PermissionModeHelper', ()=>{
|
|
4
|
-
describe('fromString', ()=>{
|
|
5
|
-
it('converts "RBAC" to IAMPermissionMode.RBAC', ()=>{
|
|
6
|
-
expect(PermissionModeHelper.fromString('RBAC')).toBe(IAMPermissionMode.RBAC);
|
|
7
|
-
});
|
|
8
|
-
it('converts "DIRECT" to IAMPermissionMode.DIRECT', ()=>{
|
|
9
|
-
expect(PermissionModeHelper.fromString('DIRECT')).toBe(IAMPermissionMode.DIRECT);
|
|
10
|
-
});
|
|
11
|
-
it('converts "FULL" to IAMPermissionMode.FULL', ()=>{
|
|
12
|
-
expect(PermissionModeHelper.fromString('FULL')).toBe(IAMPermissionMode.FULL);
|
|
13
|
-
});
|
|
14
|
-
it('defaults to FULL when the string is undefined', ()=>{
|
|
15
|
-
expect(PermissionModeHelper.fromString(undefined)).toBe(IAMPermissionMode.FULL);
|
|
16
|
-
});
|
|
17
|
-
it('defaults to FULL when the string is empty', ()=>{
|
|
18
|
-
expect(PermissionModeHelper.fromString('')).toBe(IAMPermissionMode.FULL);
|
|
19
|
-
});
|
|
20
|
-
it('defaults to FULL when the string is not a known mode', ()=>{
|
|
21
|
-
expect(PermissionModeHelper.fromString('INVALID_MODE')).toBe(IAMPermissionMode.FULL);
|
|
22
|
-
});
|
|
23
|
-
it('is case-sensitive and falls back to FULL for lowercase input', ()=>{
|
|
24
|
-
expect(PermissionModeHelper.fromString('rbac')).toBe(IAMPermissionMode.FULL);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
describe('toString', ()=>{
|
|
28
|
-
it('converts IAMPermissionMode.RBAC to "RBAC"', ()=>{
|
|
29
|
-
expect(PermissionModeHelper.toString(IAMPermissionMode.RBAC)).toBe('RBAC');
|
|
30
|
-
});
|
|
31
|
-
it('converts IAMPermissionMode.DIRECT to "DIRECT"', ()=>{
|
|
32
|
-
expect(PermissionModeHelper.toString(IAMPermissionMode.DIRECT)).toBe('DIRECT');
|
|
33
|
-
});
|
|
34
|
-
it('converts IAMPermissionMode.FULL to "FULL"', ()=>{
|
|
35
|
-
expect(PermissionModeHelper.toString(IAMPermissionMode.FULL)).toBe('FULL');
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
describe('round trip', ()=>{
|
|
39
|
-
it('fromString(toString(mode)) returns the original mode for every enum value', ()=>{
|
|
40
|
-
const modes = [
|
|
41
|
-
IAMPermissionMode.RBAC,
|
|
42
|
-
IAMPermissionMode.DIRECT,
|
|
43
|
-
IAMPermissionMode.FULL
|
|
44
|
-
];
|
|
45
|
-
for (const mode of modes){
|
|
46
|
-
expect(PermissionModeHelper.fromString(PermissionModeHelper.toString(mode))).toBe(mode);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
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;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
}
|
|
7
|
-
import { PERMISSION_GUARD_CONFIG, PERMISSIONS_CACHE_PREFIX } from '@flusys/nestjs-shared';
|
|
8
|
-
import { CacheModule, UtilsModule, createModuleEventsProvider } from '@flusys/nestjs-shared/modules';
|
|
9
|
-
import { Module } from '@nestjs/common';
|
|
10
|
-
import { IAM_MODULE_OPTIONS } from '../config/iam.constants';
|
|
11
|
-
import { ActionController, CompanyActionPermissionController, MyPermissionController, RoleController, RolePermissionController, UserActionPermissionController } from '../controllers';
|
|
12
|
-
import { IAMPermissionMode } from '../enums/permission-type.enum';
|
|
13
|
-
import { PermissionModeHelper } from '../helpers';
|
|
14
|
-
import { ActionService, PermissionService, RoleService } from '../services';
|
|
15
|
-
import { IAMConfigService } from '../services/iam-config.service';
|
|
16
|
-
import { IAMDataSourceService } from '../services/iam-datasource.service';
|
|
17
|
-
import { PermissionCacheService } from '../services/permission-cache.service';
|
|
18
|
-
export class IAMModule {
|
|
19
|
-
static getControllers(permissionMode, enableCompanyFeature) {
|
|
20
|
-
const baseControllers = [
|
|
21
|
-
ActionController,
|
|
22
|
-
MyPermissionController
|
|
23
|
-
];
|
|
24
|
-
// Direct permission mode - user actions only
|
|
25
|
-
if (permissionMode === IAMPermissionMode.DIRECT) {
|
|
26
|
-
baseControllers.push(UserActionPermissionController);
|
|
27
|
-
}
|
|
28
|
-
// RBAC mode - role actions and user roles only
|
|
29
|
-
if (permissionMode === IAMPermissionMode.RBAC) {
|
|
30
|
-
baseControllers.push(RoleController);
|
|
31
|
-
baseControllers.push(RolePermissionController);
|
|
32
|
-
}
|
|
33
|
-
// FULL mode - all permission controllers
|
|
34
|
-
if (permissionMode === IAMPermissionMode.FULL) {
|
|
35
|
-
baseControllers.push(RoleController);
|
|
36
|
-
baseControllers.push(UserActionPermissionController);
|
|
37
|
-
baseControllers.push(RolePermissionController);
|
|
38
|
-
}
|
|
39
|
-
// Company action permissions - only if company feature enabled
|
|
40
|
-
if (enableCompanyFeature) {
|
|
41
|
-
baseControllers.push(CompanyActionPermissionController);
|
|
42
|
-
}
|
|
43
|
-
return baseControllers;
|
|
44
|
-
}
|
|
45
|
-
static getServices(permissionMode) {
|
|
46
|
-
const services = [
|
|
47
|
-
ActionService,
|
|
48
|
-
PermissionService,
|
|
49
|
-
PermissionCacheService
|
|
50
|
-
];
|
|
51
|
-
// RoleService - Only for RBAC or FULL mode
|
|
52
|
-
if (permissionMode === IAMPermissionMode.RBAC || permissionMode === IAMPermissionMode.FULL) {
|
|
53
|
-
services.push(RoleService);
|
|
54
|
-
}
|
|
55
|
-
return services;
|
|
56
|
-
}
|
|
57
|
-
static getPermissionGuardConfigProvider(enableCompanyFeature) {
|
|
58
|
-
return {
|
|
59
|
-
provide: PERMISSION_GUARD_CONFIG,
|
|
60
|
-
useValue: {
|
|
61
|
-
enableCompanyFeature,
|
|
62
|
-
userPermissionKeyFormat: `${PERMISSIONS_CACHE_PREFIX}:user:{userId}`,
|
|
63
|
-
companyPermissionKeyFormat: `${PERMISSIONS_CACHE_PREFIX}:company:{companyId}:branch:{branchId}:user:{userId}`
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
static getExports(permissionMode) {
|
|
68
|
-
const baseExports = [
|
|
69
|
-
IAMConfigService,
|
|
70
|
-
IAMDataSourceService,
|
|
71
|
-
ActionService,
|
|
72
|
-
PermissionService,
|
|
73
|
-
PermissionCacheService,
|
|
74
|
-
PERMISSION_GUARD_CONFIG
|
|
75
|
-
];
|
|
76
|
-
if (permissionMode === IAMPermissionMode.RBAC || permissionMode === IAMPermissionMode.FULL) {
|
|
77
|
-
baseExports.push(RoleService);
|
|
78
|
-
}
|
|
79
|
-
return baseExports;
|
|
80
|
-
}
|
|
81
|
-
static forRoot(options = {}) {
|
|
82
|
-
const { global = false, includeController = false } = options;
|
|
83
|
-
const enableCompanyFeature = options.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
84
|
-
const permissionMode = PermissionModeHelper.fromString(options.bootstrapAppConfig?.permissionMode);
|
|
85
|
-
const controllers = includeController ? this.getControllers(permissionMode, enableCompanyFeature) : [];
|
|
86
|
-
const providers = [
|
|
87
|
-
{
|
|
88
|
-
provide: IAM_MODULE_OPTIONS,
|
|
89
|
-
useValue: options
|
|
90
|
-
},
|
|
91
|
-
IAMConfigService,
|
|
92
|
-
IAMDataSourceService,
|
|
93
|
-
...this.getServices(permissionMode),
|
|
94
|
-
this.getPermissionGuardConfigProvider(enableCompanyFeature),
|
|
95
|
-
createModuleEventsProvider('iam', IAM_MODULE_OPTIONS)
|
|
96
|
-
];
|
|
97
|
-
const module = {
|
|
98
|
-
module: IAMModule,
|
|
99
|
-
imports: [
|
|
100
|
-
CacheModule,
|
|
101
|
-
UtilsModule
|
|
102
|
-
],
|
|
103
|
-
controllers,
|
|
104
|
-
providers,
|
|
105
|
-
exports: this.getExports(permissionMode)
|
|
106
|
-
};
|
|
107
|
-
return global ? {
|
|
108
|
-
...module,
|
|
109
|
-
global: true
|
|
110
|
-
} : module;
|
|
111
|
-
}
|
|
112
|
-
static forRootAsync(asyncOptions) {
|
|
113
|
-
const { global = false, includeController = false, imports: externalImports = [] } = asyncOptions;
|
|
114
|
-
const enableCompanyFeature = asyncOptions.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
115
|
-
const permissionMode = PermissionModeHelper.fromString(asyncOptions.bootstrapAppConfig?.permissionMode);
|
|
116
|
-
const controllers = includeController ? this.getControllers(permissionMode, enableCompanyFeature) : [];
|
|
117
|
-
const providers = [
|
|
118
|
-
...this.createAsyncProviders(asyncOptions),
|
|
119
|
-
IAMConfigService,
|
|
120
|
-
IAMDataSourceService,
|
|
121
|
-
...this.getServices(permissionMode),
|
|
122
|
-
this.getPermissionGuardConfigProvider(enableCompanyFeature),
|
|
123
|
-
createModuleEventsProvider('iam', IAM_MODULE_OPTIONS)
|
|
124
|
-
];
|
|
125
|
-
const module = {
|
|
126
|
-
module: IAMModule,
|
|
127
|
-
imports: [
|
|
128
|
-
...externalImports,
|
|
129
|
-
CacheModule,
|
|
130
|
-
UtilsModule
|
|
131
|
-
],
|
|
132
|
-
controllers,
|
|
133
|
-
providers,
|
|
134
|
-
exports: this.getExports(permissionMode)
|
|
135
|
-
};
|
|
136
|
-
return global ? {
|
|
137
|
-
...module,
|
|
138
|
-
global: true
|
|
139
|
-
} : module;
|
|
140
|
-
}
|
|
141
|
-
static createAsyncProviders(options) {
|
|
142
|
-
if (options.useExisting || options.useFactory) {
|
|
143
|
-
return [
|
|
144
|
-
this.createAsyncOptionsProvider(options)
|
|
145
|
-
];
|
|
146
|
-
}
|
|
147
|
-
const useClass = options.useClass;
|
|
148
|
-
return [
|
|
149
|
-
this.createAsyncOptionsProvider(options),
|
|
150
|
-
{
|
|
151
|
-
provide: useClass,
|
|
152
|
-
useClass
|
|
153
|
-
}
|
|
154
|
-
];
|
|
155
|
-
}
|
|
156
|
-
static createAsyncOptionsProvider(options) {
|
|
157
|
-
if (options.useFactory) {
|
|
158
|
-
return {
|
|
159
|
-
provide: IAM_MODULE_OPTIONS,
|
|
160
|
-
useFactory: options.useFactory,
|
|
161
|
-
inject: options.inject || []
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
const inject = [
|
|
165
|
-
options.useClass || options.useExisting
|
|
166
|
-
];
|
|
167
|
-
return {
|
|
168
|
-
provide: IAM_MODULE_OPTIONS,
|
|
169
|
-
useFactory: async (optionsFactory)=>optionsFactory.createIAMOptions(),
|
|
170
|
-
inject
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
IAMModule = _ts_decorate([
|
|
175
|
-
Module({})
|
|
176
|
-
], IAMModule);
|
|
@@ -1,278 +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
|
-
import { PERMISSION_GUARD_CONFIG } from '@flusys/nestjs-shared';
|
|
15
|
-
import { IAMModule } from './iam.module';
|
|
16
|
-
import { IAM_MODULE_OPTIONS } from '../config/iam.constants';
|
|
17
|
-
import { ActionController, CompanyActionPermissionController, MyPermissionController, RoleController, RolePermissionController, UserActionPermissionController } from '../controllers';
|
|
18
|
-
import { ActionService, PermissionService, RoleService } from '../services';
|
|
19
|
-
import { IAMConfigService } from '../services/iam-config.service';
|
|
20
|
-
import { IAMDataSourceService } from '../services/iam-datasource.service';
|
|
21
|
-
import { PermissionCacheService } from '../services/permission-cache.service';
|
|
22
|
-
function providerTokens(providers) {
|
|
23
|
-
return providers.map((p)=>typeof p === 'function' ? p : p.provide);
|
|
24
|
-
}
|
|
25
|
-
describe('IAMModule', ()=>{
|
|
26
|
-
describe('forRoot - controller/service registration matrix', ()=>{
|
|
27
|
-
it('should register no controllers by default (includeController defaults to false)', ()=>{
|
|
28
|
-
const dynamicModule = IAMModule.forRoot();
|
|
29
|
-
expect(dynamicModule.controllers).toEqual([]);
|
|
30
|
-
});
|
|
31
|
-
it('DIRECT mode: registers only UserActionPermissionController beyond the base set', ()=>{
|
|
32
|
-
const dynamicModule = IAMModule.forRoot({
|
|
33
|
-
includeController: true,
|
|
34
|
-
bootstrapAppConfig: {
|
|
35
|
-
permissionMode: 'DIRECT'
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
expect(dynamicModule.controllers).toEqual([
|
|
39
|
-
ActionController,
|
|
40
|
-
MyPermissionController,
|
|
41
|
-
UserActionPermissionController
|
|
42
|
-
]);
|
|
43
|
-
expect(providerTokens(dynamicModule.providers)).not.toContain(RoleService);
|
|
44
|
-
});
|
|
45
|
-
it('RBAC mode: registers RoleController + RolePermissionController but not UserActionPermissionController', ()=>{
|
|
46
|
-
const dynamicModule = IAMModule.forRoot({
|
|
47
|
-
includeController: true,
|
|
48
|
-
bootstrapAppConfig: {
|
|
49
|
-
permissionMode: 'RBAC'
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
expect(dynamicModule.controllers).toEqual([
|
|
53
|
-
ActionController,
|
|
54
|
-
MyPermissionController,
|
|
55
|
-
RoleController,
|
|
56
|
-
RolePermissionController
|
|
57
|
-
]);
|
|
58
|
-
expect(providerTokens(dynamicModule.providers)).toContain(RoleService);
|
|
59
|
-
});
|
|
60
|
-
it('FULL mode: registers every permission controller', ()=>{
|
|
61
|
-
const dynamicModule = IAMModule.forRoot({
|
|
62
|
-
includeController: true,
|
|
63
|
-
bootstrapAppConfig: {
|
|
64
|
-
permissionMode: 'FULL'
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
expect(dynamicModule.controllers).toEqual([
|
|
68
|
-
ActionController,
|
|
69
|
-
MyPermissionController,
|
|
70
|
-
RoleController,
|
|
71
|
-
UserActionPermissionController,
|
|
72
|
-
RolePermissionController
|
|
73
|
-
]);
|
|
74
|
-
});
|
|
75
|
-
it('defaults to FULL mode when permissionMode is omitted', ()=>{
|
|
76
|
-
const dynamicModule = IAMModule.forRoot({
|
|
77
|
-
includeController: true
|
|
78
|
-
});
|
|
79
|
-
expect(dynamicModule.controllers).toEqual(expect.arrayContaining([
|
|
80
|
-
RoleController,
|
|
81
|
-
UserActionPermissionController,
|
|
82
|
-
RolePermissionController
|
|
83
|
-
]));
|
|
84
|
-
});
|
|
85
|
-
it('defaults to FULL mode when permissionMode is an unrecognized string', ()=>{
|
|
86
|
-
const dynamicModule = IAMModule.forRoot({
|
|
87
|
-
includeController: true,
|
|
88
|
-
bootstrapAppConfig: {
|
|
89
|
-
permissionMode: 'BOGUS'
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
expect(dynamicModule.controllers).toEqual(expect.arrayContaining([
|
|
93
|
-
RoleController,
|
|
94
|
-
UserActionPermissionController,
|
|
95
|
-
RolePermissionController
|
|
96
|
-
]));
|
|
97
|
-
});
|
|
98
|
-
it('adds CompanyActionPermissionController only when enableCompanyFeature is true', ()=>{
|
|
99
|
-
const withCompany = IAMModule.forRoot({
|
|
100
|
-
includeController: true,
|
|
101
|
-
bootstrapAppConfig: {
|
|
102
|
-
enableCompanyFeature: true
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
const withoutCompany = IAMModule.forRoot({
|
|
106
|
-
includeController: true,
|
|
107
|
-
bootstrapAppConfig: {
|
|
108
|
-
enableCompanyFeature: false
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
expect(withCompany.controllers).toContain(CompanyActionPermissionController);
|
|
112
|
-
expect(withoutCompany.controllers).not.toContain(CompanyActionPermissionController);
|
|
113
|
-
});
|
|
114
|
-
it('excludes RoleService for DIRECT mode but includes it for RBAC/FULL', ()=>{
|
|
115
|
-
const direct = IAMModule.forRoot({
|
|
116
|
-
bootstrapAppConfig: {
|
|
117
|
-
permissionMode: 'DIRECT'
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
const rbac = IAMModule.forRoot({
|
|
121
|
-
bootstrapAppConfig: {
|
|
122
|
-
permissionMode: 'RBAC'
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
const full = IAMModule.forRoot({
|
|
126
|
-
bootstrapAppConfig: {
|
|
127
|
-
permissionMode: 'FULL'
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
expect(providerTokens(direct.providers)).not.toContain(RoleService);
|
|
131
|
-
expect(providerTokens(rbac.providers)).toContain(RoleService);
|
|
132
|
-
expect(providerTokens(full.providers)).toContain(RoleService);
|
|
133
|
-
expect(providerTokens(direct.exports)).not.toContain(RoleService);
|
|
134
|
-
expect(providerTokens(rbac.exports)).toContain(RoleService);
|
|
135
|
-
});
|
|
136
|
-
it('always registers the base providers/exports (ActionService, PermissionService, PermissionCacheService)', ()=>{
|
|
137
|
-
const dynamicModule = IAMModule.forRoot();
|
|
138
|
-
expect(providerTokens(dynamicModule.providers)).toEqual(expect.arrayContaining([
|
|
139
|
-
IAMConfigService,
|
|
140
|
-
IAMDataSourceService,
|
|
141
|
-
ActionService,
|
|
142
|
-
PermissionService,
|
|
143
|
-
PermissionCacheService
|
|
144
|
-
]));
|
|
145
|
-
expect(dynamicModule.exports).toEqual(expect.arrayContaining([
|
|
146
|
-
IAMConfigService,
|
|
147
|
-
IAMDataSourceService,
|
|
148
|
-
ActionService,
|
|
149
|
-
PermissionService,
|
|
150
|
-
PermissionCacheService,
|
|
151
|
-
PERMISSION_GUARD_CONFIG
|
|
152
|
-
]));
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
describe('forRoot - options/global handling', ()=>{
|
|
156
|
-
it('should not set `global` on the returned module when global is false/omitted', ()=>{
|
|
157
|
-
const dynamicModule = IAMModule.forRoot();
|
|
158
|
-
expect(dynamicModule.global).toBeUndefined();
|
|
159
|
-
});
|
|
160
|
-
it('should set global: true when requested', ()=>{
|
|
161
|
-
const dynamicModule = IAMModule.forRoot({
|
|
162
|
-
global: true
|
|
163
|
-
});
|
|
164
|
-
expect(dynamicModule.global).toBe(true);
|
|
165
|
-
});
|
|
166
|
-
it('should register IAM_MODULE_OPTIONS with the given options', ()=>{
|
|
167
|
-
const options = {
|
|
168
|
-
includeController: true
|
|
169
|
-
};
|
|
170
|
-
const dynamicModule = IAMModule.forRoot(options);
|
|
171
|
-
const provider = dynamicModule.providers.find((p)=>p.provide === IAM_MODULE_OPTIONS);
|
|
172
|
-
expect(provider.useValue).toBe(options);
|
|
173
|
-
});
|
|
174
|
-
it('should build a company-aware PERMISSION_GUARD_CONFIG provider', ()=>{
|
|
175
|
-
const dynamicModule = IAMModule.forRoot({
|
|
176
|
-
bootstrapAppConfig: {
|
|
177
|
-
enableCompanyFeature: true
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
const provider = dynamicModule.providers.find((p)=>p.provide === PERMISSION_GUARD_CONFIG);
|
|
181
|
-
expect(provider.useValue.enableCompanyFeature).toBe(true);
|
|
182
|
-
expect(provider.useValue.userPermissionKeyFormat).toContain('{userId}');
|
|
183
|
-
expect(provider.useValue.companyPermissionKeyFormat).toContain('{companyId}');
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
describe('forRootAsync', ()=>{
|
|
187
|
-
it('mirrors the controller/service registration matrix of forRoot', ()=>{
|
|
188
|
-
const dynamicModule = IAMModule.forRootAsync({
|
|
189
|
-
includeController: true,
|
|
190
|
-
bootstrapAppConfig: {
|
|
191
|
-
permissionMode: 'DIRECT'
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
expect(dynamicModule.controllers).toEqual([
|
|
195
|
-
ActionController,
|
|
196
|
-
MyPermissionController,
|
|
197
|
-
UserActionPermissionController
|
|
198
|
-
]);
|
|
199
|
-
});
|
|
200
|
-
it('should forward external imports alongside CacheModule/UtilsModule', ()=>{
|
|
201
|
-
let FakeImportedModule = class FakeImportedModule {
|
|
202
|
-
};
|
|
203
|
-
const dynamicModule = IAMModule.forRootAsync({
|
|
204
|
-
imports: [
|
|
205
|
-
FakeImportedModule
|
|
206
|
-
]
|
|
207
|
-
});
|
|
208
|
-
expect(dynamicModule.imports).toEqual(expect.arrayContaining([
|
|
209
|
-
FakeImportedModule
|
|
210
|
-
]));
|
|
211
|
-
});
|
|
212
|
-
it('useFactory: registers a single options provider using the given inject tokens', async ()=>{
|
|
213
|
-
const useFactory = jest.fn().mockResolvedValue({
|
|
214
|
-
foo: 'bar'
|
|
215
|
-
});
|
|
216
|
-
const dynamicModule = IAMModule.forRootAsync({
|
|
217
|
-
useFactory,
|
|
218
|
-
inject: [
|
|
219
|
-
'SOME_TOKEN'
|
|
220
|
-
]
|
|
221
|
-
});
|
|
222
|
-
const optionsProviders = dynamicModule.providers.filter((p)=>p.provide === IAM_MODULE_OPTIONS);
|
|
223
|
-
expect(optionsProviders).toHaveLength(1);
|
|
224
|
-
const provider = optionsProviders[0];
|
|
225
|
-
expect(provider.useFactory).toBe(useFactory);
|
|
226
|
-
expect(provider.inject).toEqual([
|
|
227
|
-
'SOME_TOKEN'
|
|
228
|
-
]);
|
|
229
|
-
});
|
|
230
|
-
it('useClass: registers both the class provider and an options provider that calls createIAMOptions()', async ()=>{
|
|
231
|
-
let MyOptionsFactory = class MyOptionsFactory {
|
|
232
|
-
constructor(){
|
|
233
|
-
_define_property(this, "createIAMOptions", jest.fn().mockResolvedValue({
|
|
234
|
-
foo: 'from-class'
|
|
235
|
-
}));
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
const dynamicModule = IAMModule.forRootAsync({
|
|
239
|
-
useClass: MyOptionsFactory
|
|
240
|
-
});
|
|
241
|
-
const classProvider = dynamicModule.providers.find((p)=>p.provide === MyOptionsFactory);
|
|
242
|
-
expect(classProvider.useClass).toBe(MyOptionsFactory);
|
|
243
|
-
const optionsProvider = dynamicModule.providers.find((p)=>p.provide === IAM_MODULE_OPTIONS);
|
|
244
|
-
expect(optionsProvider.inject).toEqual([
|
|
245
|
-
MyOptionsFactory
|
|
246
|
-
]);
|
|
247
|
-
const instance = new MyOptionsFactory();
|
|
248
|
-
const resolved = await optionsProvider.useFactory(instance);
|
|
249
|
-
expect(instance.createIAMOptions).toHaveBeenCalled();
|
|
250
|
-
expect(resolved).toEqual({
|
|
251
|
-
foo: 'from-class'
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
it('useExisting: registers a single options provider injecting the existing factory', async ()=>{
|
|
255
|
-
let MyOptionsFactory = class MyOptionsFactory {
|
|
256
|
-
constructor(){
|
|
257
|
-
_define_property(this, "createIAMOptions", jest.fn().mockResolvedValue({
|
|
258
|
-
foo: 'from-existing'
|
|
259
|
-
}));
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
const dynamicModule = IAMModule.forRootAsync({
|
|
263
|
-
useExisting: MyOptionsFactory
|
|
264
|
-
});
|
|
265
|
-
const optionsProviders = dynamicModule.providers.filter((p)=>p.provide === IAM_MODULE_OPTIONS);
|
|
266
|
-
expect(optionsProviders).toHaveLength(1);
|
|
267
|
-
const provider = optionsProviders[0];
|
|
268
|
-
expect(provider.inject).toEqual([
|
|
269
|
-
MyOptionsFactory
|
|
270
|
-
]);
|
|
271
|
-
const instance = new MyOptionsFactory();
|
|
272
|
-
const resolved = await provider.useFactory(instance);
|
|
273
|
-
expect(resolved).toEqual({
|
|
274
|
-
foo: 'from-existing'
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
});
|