@klerick/acl-json-api-nestjs 0.1.0
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/CHANGELOG.md +15 -0
- package/README.md +3556 -0
- package/package.json +41 -0
- package/src/index.d.ts +8 -0
- package/src/index.js +15 -0
- package/src/index.js.map +1 -0
- package/src/lib/constants/index.d.ts +14 -0
- package/src/lib/constants/index.js +18 -0
- package/src/lib/constants/index.js.map +1 -0
- package/src/lib/decorators/acl-controller.decorator.d.ts +4 -0
- package/src/lib/decorators/acl-controller.decorator.js +19 -0
- package/src/lib/decorators/acl-controller.decorator.js.map +1 -0
- package/src/lib/decorators/index.d.ts +1 -0
- package/src/lib/decorators/index.js +6 -0
- package/src/lib/decorators/index.js.map +1 -0
- package/src/lib/factories/ability-proxy.factory.d.ts +17 -0
- package/src/lib/factories/ability-proxy.factory.js +100 -0
- package/src/lib/factories/ability-proxy.factory.js.map +1 -0
- package/src/lib/factories/ability.factory.d.ts +49 -0
- package/src/lib/factories/ability.factory.js +235 -0
- package/src/lib/factories/ability.factory.js.map +1 -0
- package/src/lib/factories/index.d.ts +2 -0
- package/src/lib/factories/index.js +6 -0
- package/src/lib/factories/index.js.map +1 -0
- package/src/lib/guards/acl.guard.d.ts +21 -0
- package/src/lib/guards/acl.guard.js +68 -0
- package/src/lib/guards/acl.guard.js.map +1 -0
- package/src/lib/guards/index.d.ts +1 -0
- package/src/lib/guards/index.js +5 -0
- package/src/lib/guards/index.js.map +1 -0
- package/src/lib/nestjs-acl-permissions.module.d.ts +9 -0
- package/src/lib/nestjs-acl-permissions.module.js +56 -0
- package/src/lib/nestjs-acl-permissions.module.js.map +1 -0
- package/src/lib/services/acl-authorization.service.d.ts +10 -0
- package/src/lib/services/acl-authorization.service.js +100 -0
- package/src/lib/services/acl-authorization.service.js.map +1 -0
- package/src/lib/services/index.d.ts +2 -0
- package/src/lib/services/index.js +6 -0
- package/src/lib/services/index.js.map +1 -0
- package/src/lib/services/rule-materializer.service.d.ts +73 -0
- package/src/lib/services/rule-materializer.service.js +251 -0
- package/src/lib/services/rule-materializer.service.js.map +1 -0
- package/src/lib/types/acl-context.types.d.ts +14 -0
- package/src/lib/types/acl-context.types.js +3 -0
- package/src/lib/types/acl-context.types.js.map +1 -0
- package/src/lib/types/acl-options.types.d.ts +97 -0
- package/src/lib/types/acl-options.types.js +3 -0
- package/src/lib/types/acl-options.types.js.map +1 -0
- package/src/lib/types/acl-rules.types.d.ts +201 -0
- package/src/lib/types/acl-rules.types.js +27 -0
- package/src/lib/types/acl-rules.types.js.map +1 -0
- package/src/lib/types/decorator-options.types.d.ts +64 -0
- package/src/lib/types/decorator-options.types.js +3 -0
- package/src/lib/types/decorator-options.types.js.map +1 -0
- package/src/lib/types/index.d.ts +4 -0
- package/src/lib/types/index.js +8 -0
- package/src/lib/types/index.js.map +1 -0
- package/src/lib/utils/index.d.ts +10 -0
- package/src/lib/utils/index.js +53 -0
- package/src/lib/utils/index.js.map +1 -0
- package/src/lib/utils/orm-proxy/extract-field-paths.d.ts +73 -0
- package/src/lib/utils/orm-proxy/extract-field-paths.js +155 -0
- package/src/lib/utils/orm-proxy/extract-field-paths.js.map +1 -0
- package/src/lib/utils/orm-proxy/handle-acl-query-error.d.ts +19 -0
- package/src/lib/utils/orm-proxy/handle-acl-query-error.js +53 -0
- package/src/lib/utils/orm-proxy/handle-acl-query-error.js.map +1 -0
- package/src/lib/utils/orm-proxy/index.d.ts +9 -0
- package/src/lib/utils/orm-proxy/index.js +24 -0
- package/src/lib/utils/orm-proxy/index.js.map +1 -0
- package/src/lib/utils/orm-proxy/merge-query-with-acl-data.d.ts +27 -0
- package/src/lib/utils/orm-proxy/merge-query-with-acl-data.js +78 -0
- package/src/lib/utils/orm-proxy/merge-query-with-acl-data.js.map +1 -0
- package/src/lib/utils/orm-proxy/prepare-acl-query.d.ts +11 -0
- package/src/lib/utils/orm-proxy/prepare-acl-query.js +35 -0
- package/src/lib/utils/orm-proxy/prepare-acl-query.js.map +1 -0
- package/src/lib/utils/orm-proxy/process-item-field-restrictions.d.ts +24 -0
- package/src/lib/utils/orm-proxy/process-item-field-restrictions.js +42 -0
- package/src/lib/utils/orm-proxy/process-item-field-restrictions.js.map +1 -0
- package/src/lib/utils/orm-proxy/remove-acl-added-fields.d.ts +31 -0
- package/src/lib/utils/orm-proxy/remove-acl-added-fields.js +104 -0
- package/src/lib/utils/orm-proxy/remove-acl-added-fields.js.map +1 -0
- package/src/lib/utils/orm-proxy/unset-deep.d.ts +13 -0
- package/src/lib/utils/orm-proxy/unset-deep.js +41 -0
- package/src/lib/utils/orm-proxy/unset-deep.js.map +1 -0
- package/src/lib/utils/orm-proxy/validate-no-current-in-rules.d.ts +19 -0
- package/src/lib/utils/orm-proxy/validate-no-current-in-rules.js +33 -0
- package/src/lib/utils/orm-proxy/validate-no-current-in-rules.js.map +1 -0
- package/src/lib/utils/orm-proxy/validate-rules-for-orm.d.ts +16 -0
- package/src/lib/utils/orm-proxy/validate-rules-for-orm.js +35 -0
- package/src/lib/utils/orm-proxy/validate-rules-for-orm.js.map +1 -0
- package/src/lib/wrappers/index.d.ts +9 -0
- package/src/lib/wrappers/index.js +32 -0
- package/src/lib/wrappers/index.js.map +1 -0
- package/src/lib/wrappers/logger-init.d.ts +2 -0
- package/src/lib/wrappers/logger-init.js +9 -0
- package/src/lib/wrappers/logger-init.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/get-proxy-orm.d.ts +4 -0
- package/src/lib/wrappers/wrapper-json-method-controller/get-proxy-orm.js +47 -0
- package/src/lib/wrappers/wrapper-json-method-controller/get-proxy-orm.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/index.d.ts +3 -0
- package/src/lib/wrappers/wrapper-json-method-controller/index.js +21 -0
- package/src/lib/wrappers/wrapper-json-method-controller/index.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/delete-one-proxy.d.ts +3 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/delete-one-proxy.js +51 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/delete-one-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/delete-relationship-proxy.d.ts +4 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/delete-relationship-proxy.js +59 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/delete-relationship-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-all-proxy.d.ts +13 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-all-proxy.js +67 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-all-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-one-proxy.d.ts +12 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-one-proxy.js +50 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-one-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-relationship-proxy.d.ts +4 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-relationship-proxy.js +50 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/get-relationship-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/index.d.ts +9 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/index.js +13 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/index.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/patch-one-proxy.d.ts +3 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/patch-one-proxy.js +132 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/patch-one-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/patch-relationship-proxy.d.ts +4 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/patch-relationship-proxy.js +68 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/patch-relationship-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/post-one-proxy.d.ts +3 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/post-one-proxy.js +73 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/post-one-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/post-relationship-proxy.d.ts +4 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/post-relationship-proxy.js +66 -0
- package/src/lib/wrappers/wrapper-json-method-controller/method-proxy/post-relationship-proxy.js.map +1 -0
- package/src/lib/wrappers/wrapper-json-method-controller/on-module-init.d.ts +2 -0
- package/src/lib/wrappers/wrapper-json-method-controller/on-module-init.js +16 -0
- package/src/lib/wrappers/wrapper-json-method-controller/on-module-init.js.map +1 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var AclGuard_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.AclGuard = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const core_1 = require("@nestjs/core");
|
|
8
|
+
const services_1 = require("../services");
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
/**
|
|
11
|
+
* Guard for ACL permission checking
|
|
12
|
+
*
|
|
13
|
+
* Thin wrapper that delegates all logic to AclAuthorizationService
|
|
14
|
+
*
|
|
15
|
+
* Applied automatically by @AclController decorator
|
|
16
|
+
*
|
|
17
|
+
* Lifecycle: Guards run BEFORE interceptors and pipes
|
|
18
|
+
*
|
|
19
|
+
* Benefits:
|
|
20
|
+
* - Fails fast (before handler execution)
|
|
21
|
+
* - Semantic correctness (Guard = authorization)
|
|
22
|
+
* - Supports onNoRules policy (deny/allow/warn)
|
|
23
|
+
*/
|
|
24
|
+
let AclGuard = AclGuard_1 = class AclGuard {
|
|
25
|
+
moduleRef;
|
|
26
|
+
reflector;
|
|
27
|
+
logger = new common_1.Logger(AclGuard_1.name);
|
|
28
|
+
async canActivate(executionContext) {
|
|
29
|
+
const controller = executionContext.getClass();
|
|
30
|
+
const handler = executionContext.getHandler();
|
|
31
|
+
const controllerName = controller.name;
|
|
32
|
+
const methodName = handler.name;
|
|
33
|
+
const metadata = this.reflector.get(constants_1.ACL_CONTROLLER_METADATA, controller);
|
|
34
|
+
if (!metadata) {
|
|
35
|
+
this.logger.debug(`No @AclController metadata found on ${controllerName}, allowing access`);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
// If ACL is disabled for this controller
|
|
39
|
+
if (metadata.enabled === false) {
|
|
40
|
+
this.logger.debug(`ACL disabled for controller ${controllerName}, allowing access`);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// Check if ACL is enabled for this specific method
|
|
44
|
+
const isMethodEnabled = metadata.methods[methodName];
|
|
45
|
+
// If method configuration is explicitly false, allow access
|
|
46
|
+
if (isMethodEnabled === false) {
|
|
47
|
+
this.logger.debug(`ACL disabled for method ${controllerName}.${methodName}, allowing access`);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
// Delegate all logic to authorization service
|
|
51
|
+
return this.moduleRef.get(services_1.AclAuthorizationService, {
|
|
52
|
+
strict: false,
|
|
53
|
+
}).authorize(controllerName, methodName, metadata);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.AclGuard = AclGuard;
|
|
57
|
+
tslib_1.__decorate([
|
|
58
|
+
(0, common_1.Inject)(core_1.ModuleRef),
|
|
59
|
+
tslib_1.__metadata("design:type", core_1.ModuleRef)
|
|
60
|
+
], AclGuard.prototype, "moduleRef", void 0);
|
|
61
|
+
tslib_1.__decorate([
|
|
62
|
+
(0, common_1.Inject)(core_1.Reflector),
|
|
63
|
+
tslib_1.__metadata("design:type", core_1.Reflector)
|
|
64
|
+
], AclGuard.prototype, "reflector", void 0);
|
|
65
|
+
exports.AclGuard = AclGuard = AclGuard_1 = tslib_1.__decorate([
|
|
66
|
+
(0, common_1.Injectable)()
|
|
67
|
+
], AclGuard);
|
|
68
|
+
//# sourceMappingURL=acl.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acl.guard.js","sourceRoot":"","sources":["../../../../../../../libs/acl-permissions/nestjs-acl-permissions/src/lib/guards/acl.guard.ts"],"names":[],"mappings":";;;;;AAAA,2CAA2F;AAC3F,uCAAoD;AACpD,0CAAsD;AAEtD,4CAAuD;AAEvD;;;;;;;;;;;;;GAaG;AAEI,IAAM,QAAQ,gBAAd,MAAM,QAAQ;IACiB,SAAS,CAAa;IACtB,SAAS,CAAa;IAEzC,MAAM,GAAG,IAAI,eAAM,CAAC,UAAQ,CAAC,IAAI,CAAC,CAAC;IAEpD,KAAK,CAAC,WAAW,CAAC,gBAAkC;QAElD,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC;QACvC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CACjC,mCAAuB,EACvB,UAAU,CACX,CAAC;QAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,uCAAuC,cAAc,mBAAmB,CACzE,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,yCAAyC;QACzC,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,+BAA+B,cAAc,mBAAmB,CACjE,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mDAAmD;QACnD,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAErD,4DAA4D;QAC5D,IAAI,eAAe,KAAK,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,2BAA2B,cAAc,IAAI,UAAU,mBAAmB,CAC3E,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,8CAA8C;QAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kCAAuB,EAAE;YACjD,MAAM,EAAE,KAAK;SACd,CAAC,CAAC,SAAS,CAAC,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;CACF,CAAA;AAjDY,4BAAQ;AACiB;IAAnC,IAAA,eAAM,EAAC,gBAAS,CAAC;sCAA8B,gBAAS;2CAAC;AACtB;IAAnC,IAAA,eAAM,EAAC,gBAAS,CAAC;sCAA8B,gBAAS;2CAAC;mBAF/C,QAAQ;IADpB,IAAA,mBAAU,GAAE;GACA,QAAQ,CAiDpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './acl.guard';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/acl-permissions/nestjs-acl-permissions/src/lib/guards/index.ts"],"names":[],"mappings":";;;AAAA,sDAA4B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DynamicModule, OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import type { AclModuleOptions } from './types';
|
|
3
|
+
export declare class AclPermissionsModule implements OnModuleInit {
|
|
4
|
+
private readonly moduleRef;
|
|
5
|
+
private readonly options;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
static forRoot(options: AclModuleOptions): DynamicModule;
|
|
8
|
+
onModuleInit(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var AclPermissionsModule_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.AclPermissionsModule = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const core_1 = require("@nestjs/core");
|
|
8
|
+
const constants_1 = require("./constants");
|
|
9
|
+
const services_1 = require("./services");
|
|
10
|
+
const guards_1 = require("./guards");
|
|
11
|
+
const factories_1 = require("./factories");
|
|
12
|
+
let AclPermissionsModule = AclPermissionsModule_1 = class AclPermissionsModule {
|
|
13
|
+
moduleRef;
|
|
14
|
+
options;
|
|
15
|
+
logger = new common_1.Logger(AclPermissionsModule_1.name);
|
|
16
|
+
static forRoot(options) {
|
|
17
|
+
return {
|
|
18
|
+
module: AclPermissionsModule_1,
|
|
19
|
+
providers: [
|
|
20
|
+
{
|
|
21
|
+
provide: constants_1.ACL_MODULE_OPTIONS,
|
|
22
|
+
useValue: options,
|
|
23
|
+
},
|
|
24
|
+
guards_1.AclGuard,
|
|
25
|
+
services_1.AclAuthorizationService,
|
|
26
|
+
services_1.RuleMaterializer,
|
|
27
|
+
factories_1.AbilityFactoryProvider,
|
|
28
|
+
factories_1.AbilityProvider,
|
|
29
|
+
],
|
|
30
|
+
exports: [guards_1.AclGuard, services_1.AclAuthorizationService, factories_1.AbilityProvider],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
onModuleInit() {
|
|
34
|
+
try {
|
|
35
|
+
this.moduleRef.get(this.options.rulesLoader, { strict: false });
|
|
36
|
+
this.moduleRef.get(this.options.contextStore, { strict: false });
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
this.logger.warn(`RulesLoader or ContextStore not found, ACL will not work`);
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
exports.AclPermissionsModule = AclPermissionsModule;
|
|
45
|
+
tslib_1.__decorate([
|
|
46
|
+
(0, common_1.Inject)(core_1.ModuleRef),
|
|
47
|
+
tslib_1.__metadata("design:type", core_1.ModuleRef)
|
|
48
|
+
], AclPermissionsModule.prototype, "moduleRef", void 0);
|
|
49
|
+
tslib_1.__decorate([
|
|
50
|
+
(0, common_1.Inject)(constants_1.ACL_MODULE_OPTIONS),
|
|
51
|
+
tslib_1.__metadata("design:type", Object)
|
|
52
|
+
], AclPermissionsModule.prototype, "options", void 0);
|
|
53
|
+
exports.AclPermissionsModule = AclPermissionsModule = AclPermissionsModule_1 = tslib_1.__decorate([
|
|
54
|
+
(0, common_1.Module)({})
|
|
55
|
+
], AclPermissionsModule);
|
|
56
|
+
//# sourceMappingURL=nestjs-acl-permissions.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs-acl-permissions.module.js","sourceRoot":"","sources":["../../../../../../libs/acl-permissions/nestjs-acl-permissions/src/lib/nestjs-acl-permissions.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAMwB;AACxB,uCAAyC;AACzC,2CAAiD;AAEjD,yCAAuE;AACvE,qCAAoC;AACpC,2CAAsE;AAG/D,IAAM,oBAAoB,4BAA1B,MAAM,oBAAoB;IACK,SAAS,CAAa;IACb,OAAO,CAAoB;IACvD,MAAM,GAAG,IAAI,eAAM,CAAC,sBAAoB,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,OAAO,CAAC,OAAyB;QACtC,OAAO;YACL,MAAM,EAAE,sBAAoB;YAC5B,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,8BAAkB;oBAC3B,QAAQ,EAAE,OAAO;iBAClB;gBACD,iBAAQ;gBACR,kCAAuB;gBACvB,2BAAgB;gBAChB,kCAAsB;gBACtB,2BAAe;aAChB;YACD,OAAO,EAAE,CAAC,iBAAQ,EAAE,kCAAuB,EAAE,2BAAe,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED,YAAY;QACV,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,0DAA0D,CAC3D,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF,CAAA;AAjCY,oDAAoB;AACK;IAAnC,IAAA,eAAM,EAAC,gBAAS,CAAC;sCAA8B,gBAAS;uDAAC;AACb;IAA5C,IAAA,eAAM,EAAC,8BAAkB,CAAC;;qDAA6C;+BAF7D,oBAAoB;IADhC,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,oBAAoB,CAiChC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AclControllerMetadata } from '../types';
|
|
2
|
+
export declare class AclAuthorizationService {
|
|
3
|
+
private readonly moduleRef;
|
|
4
|
+
private readonly options;
|
|
5
|
+
private readonly abilityFactory;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
authorize(controllerName: string, action: string, metaData: AclControllerMetadata): Promise<boolean>;
|
|
8
|
+
private getDefaultRulesForAction;
|
|
9
|
+
private getSubjectFromInput;
|
|
10
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var AclAuthorizationService_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.AclAuthorizationService = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const core_1 = require("@nestjs/core");
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
10
|
+
const factories_1 = require("../factories");
|
|
11
|
+
let AclAuthorizationService = AclAuthorizationService_1 = class AclAuthorizationService {
|
|
12
|
+
moduleRef;
|
|
13
|
+
options;
|
|
14
|
+
abilityFactory;
|
|
15
|
+
logger = new common_1.Logger(AclAuthorizationService_1.name);
|
|
16
|
+
async authorize(controllerName, action, metaData) {
|
|
17
|
+
const { subject: subjectForRules } = metaData;
|
|
18
|
+
const actionOptions = (0, utils_1.getActionOptions)(this.options, metaData.methods[action]);
|
|
19
|
+
const subject = this.getSubjectFromInput(subjectForRules);
|
|
20
|
+
const rulesLoader = this.moduleRef.get(this.options.rulesLoader, { strict: false });
|
|
21
|
+
const [rules, context, helpers] = await Promise.all([
|
|
22
|
+
rulesLoader.loadRules(subjectForRules, action),
|
|
23
|
+
rulesLoader.getContext(),
|
|
24
|
+
rulesLoader.getHelpers(),
|
|
25
|
+
]);
|
|
26
|
+
const resultRules = Array.isArray(rules) && rules.length > 0
|
|
27
|
+
? rules
|
|
28
|
+
: this.getDefaultRulesForAction(controllerName, action, subject, actionOptions);
|
|
29
|
+
const ability = this.abilityFactory(subject, action, resultRules, context, helpers);
|
|
30
|
+
if (!ability.can(action, subject)) {
|
|
31
|
+
this.logger.debug(`Access denied for ${controllerName}.${action} (action: ${action}, subject: ${subject})`);
|
|
32
|
+
throw new common_1.ForbiddenException([
|
|
33
|
+
{
|
|
34
|
+
code: 'forbidden',
|
|
35
|
+
message: `not allow "${action}"`,
|
|
36
|
+
path: ['action'],
|
|
37
|
+
},
|
|
38
|
+
], {
|
|
39
|
+
description: `Access denied for ${action} on ${subject}`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const contextStore = this.moduleRef.get(this.options.contextStore, {
|
|
43
|
+
strict: false,
|
|
44
|
+
});
|
|
45
|
+
contextStore.set(constants_1.ACL_CONTEXT_KEY, ability);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
getDefaultRulesForAction(controllerName, action, subject, actionOptions) {
|
|
49
|
+
if (actionOptions.defaultRules && actionOptions.defaultRules.length > 0) {
|
|
50
|
+
this.logger.debug(`No rules for ${controllerName}.${action}, applying defaultRules`);
|
|
51
|
+
return actionOptions.defaultRules;
|
|
52
|
+
}
|
|
53
|
+
const policy = actionOptions.onNoRules || 'deny';
|
|
54
|
+
if (policy === 'deny') {
|
|
55
|
+
this.logger.error(`No ACL rules defined for ${controllerName}.${action}, denying access (onNoRules: '${policy}')`);
|
|
56
|
+
throw new common_1.ForbiddenException([
|
|
57
|
+
{
|
|
58
|
+
code: 'forbidden',
|
|
59
|
+
message: `not allow access`,
|
|
60
|
+
path: [],
|
|
61
|
+
},
|
|
62
|
+
], {
|
|
63
|
+
description: `No ACL rules defined for ${controllerName}.${action}`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
this.logger.warn(`No ACL rules defined for ${controllerName}.${action}, allowing access with permissive rule (onNoRules: '${policy}')`);
|
|
67
|
+
return [
|
|
68
|
+
{
|
|
69
|
+
action,
|
|
70
|
+
subject,
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
getSubjectFromInput(subject) {
|
|
75
|
+
if (typeof subject === 'string') {
|
|
76
|
+
return subject;
|
|
77
|
+
}
|
|
78
|
+
if (typeof subject === 'function' && subject.name) {
|
|
79
|
+
return subject.name;
|
|
80
|
+
}
|
|
81
|
+
throw new Error('Entity shouldbe class or string');
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
exports.AclAuthorizationService = AclAuthorizationService;
|
|
85
|
+
tslib_1.__decorate([
|
|
86
|
+
(0, common_1.Inject)(core_1.ModuleRef),
|
|
87
|
+
tslib_1.__metadata("design:type", core_1.ModuleRef)
|
|
88
|
+
], AclAuthorizationService.prototype, "moduleRef", void 0);
|
|
89
|
+
tslib_1.__decorate([
|
|
90
|
+
(0, common_1.Inject)(constants_1.ACL_MODULE_OPTIONS),
|
|
91
|
+
tslib_1.__metadata("design:type", Object)
|
|
92
|
+
], AclAuthorizationService.prototype, "options", void 0);
|
|
93
|
+
tslib_1.__decorate([
|
|
94
|
+
(0, common_1.Inject)(factories_1.ABILITY_FACTORY),
|
|
95
|
+
tslib_1.__metadata("design:type", Function)
|
|
96
|
+
], AclAuthorizationService.prototype, "abilityFactory", void 0);
|
|
97
|
+
exports.AclAuthorizationService = AclAuthorizationService = AclAuthorizationService_1 = tslib_1.__decorate([
|
|
98
|
+
(0, common_1.Injectable)()
|
|
99
|
+
], AclAuthorizationService);
|
|
100
|
+
//# sourceMappingURL=acl-authorization.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acl-authorization.service.js","sourceRoot":"","sources":["../../../../../../../libs/acl-permissions/nestjs-acl-permissions/src/lib/services/acl-authorization.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./acl-authorization.service"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./rule-materializer.service"), exports);
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/acl-permissions/nestjs-acl-permissions/src/lib/services/index.ts"],"names":[],"mappings":";;;AAAA,sEAA4C;AAC5C,sEAA2C"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Logger } from '@nestjs/common';
|
|
2
|
+
import { AbilityTuple, MongoQuery, RawRuleFrom } from '@casl/ability';
|
|
3
|
+
import type { AclInputData } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Service for materializing ACL rules by interpolating template variables
|
|
6
|
+
*
|
|
7
|
+
* Converts rules with templates like { userId: '${@input.userId}' }
|
|
8
|
+
* into materialized rules with actual values like { userId: 123 }
|
|
9
|
+
*
|
|
10
|
+
* Uses Tagged Template Literals via Function for safe and efficient evaluation
|
|
11
|
+
*/
|
|
12
|
+
export declare class RuleMaterializer {
|
|
13
|
+
readonly logger: Logger;
|
|
14
|
+
private readonly QUOTE_PLACEHOLDER;
|
|
15
|
+
private readonly options;
|
|
16
|
+
private get strictMode();
|
|
17
|
+
/**
|
|
18
|
+
* Materializes ACL rules by replacing template variables with actual values
|
|
19
|
+
*
|
|
20
|
+
* @param rules - Array of rules with template strings
|
|
21
|
+
* @param context - Variables from getContext()
|
|
22
|
+
* @param helpers - Helper functions from getHelpers()
|
|
23
|
+
* @param input - External input data (available as @input in templates)
|
|
24
|
+
* @returns Materialized rules with interpolated values
|
|
25
|
+
*
|
|
26
|
+
* TODO: Support old/current values in addition to new input
|
|
27
|
+
* For patchOne operations, we need access to both:
|
|
28
|
+
* - @input.* - new values from request
|
|
29
|
+
* - @input.__current.* - old values from database
|
|
30
|
+
* This enables rules like "allow removing only self from array"
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const rules = [{ conditions: { userId: '${@input.id}' } }];
|
|
35
|
+
* const context = { currentUserId: 123 };
|
|
36
|
+
* const helpers = {};
|
|
37
|
+
* const input = { id: 456 };
|
|
38
|
+
*
|
|
39
|
+
* const materialized = materializer.materialize(rules, context, helpers, input);
|
|
40
|
+
* // Result: [{ conditions: { userId: 456 } }]
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
materialize<A extends AbilityTuple = AbilityTuple, C extends MongoQuery = MongoQuery>(rules: RawRuleFrom<A, C>[], context: Record<string, any>, helpers: Record<string, Function>, input?: AclInputData): RawRuleFrom<A, C>[];
|
|
44
|
+
/**
|
|
45
|
+
* Escapes special characters for use in template literal
|
|
46
|
+
*/
|
|
47
|
+
private escapeForTemplateLiteral;
|
|
48
|
+
/**
|
|
49
|
+
* Evaluates JSON template using Tagged Template Literals
|
|
50
|
+
*
|
|
51
|
+
* Uses a tagged function that correctly formats different types:
|
|
52
|
+
* - strings → wrapped in quotes
|
|
53
|
+
* - arrays → JSON.stringify
|
|
54
|
+
* - numbers/booleans → as-is
|
|
55
|
+
*/
|
|
56
|
+
private evaluateTaggedTemplate;
|
|
57
|
+
/**
|
|
58
|
+
* Creates tagged template function that formats placeholders by type
|
|
59
|
+
*
|
|
60
|
+
* IMPORTANT: Values are already inside JSON string quotes from stringify
|
|
61
|
+
* We need to REMOVE the quotes and insert raw JSON values
|
|
62
|
+
*/
|
|
63
|
+
private createTaggedFunction;
|
|
64
|
+
/**
|
|
65
|
+
* Creates strict Proxy that throws error on undefined property access
|
|
66
|
+
* Used in strict mode to catch template errors early
|
|
67
|
+
*/
|
|
68
|
+
private createStrictProxy;
|
|
69
|
+
/**
|
|
70
|
+
* Handles interpolation errors based on strict mode
|
|
71
|
+
*/
|
|
72
|
+
private handleError;
|
|
73
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var RuleMaterializer_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.RuleMaterializer = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
/**
|
|
10
|
+
* Service for materializing ACL rules by interpolating template variables
|
|
11
|
+
*
|
|
12
|
+
* Converts rules with templates like { userId: '${@input.userId}' }
|
|
13
|
+
* into materialized rules with actual values like { userId: 123 }
|
|
14
|
+
*
|
|
15
|
+
* Uses Tagged Template Literals via Function for safe and efficient evaluation
|
|
16
|
+
*/
|
|
17
|
+
let RuleMaterializer = RuleMaterializer_1 = class RuleMaterializer {
|
|
18
|
+
logger = new common_1.Logger(RuleMaterializer_1.name);
|
|
19
|
+
// Temporary placeholder to distinguish quotes inside strings from quotes around placeholders
|
|
20
|
+
// Example: {"name":"John"} has quotes inside, but {"name":"${userName}"} has placeholder quotes
|
|
21
|
+
QUOTE_PLACEHOLDER = '\u0000QUOTE\u0000';
|
|
22
|
+
options;
|
|
23
|
+
get strictMode() {
|
|
24
|
+
return !this.options ? true : !!this.options.strictInterpolation;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Materializes ACL rules by replacing template variables with actual values
|
|
28
|
+
*
|
|
29
|
+
* @param rules - Array of rules with template strings
|
|
30
|
+
* @param context - Variables from getContext()
|
|
31
|
+
* @param helpers - Helper functions from getHelpers()
|
|
32
|
+
* @param input - External input data (available as @input in templates)
|
|
33
|
+
* @returns Materialized rules with interpolated values
|
|
34
|
+
*
|
|
35
|
+
* TODO: Support old/current values in addition to new input
|
|
36
|
+
* For patchOne operations, we need access to both:
|
|
37
|
+
* - @input.* - new values from request
|
|
38
|
+
* - @input.__current.* - old values from database
|
|
39
|
+
* This enables rules like "allow removing only self from array"
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const rules = [{ conditions: { userId: '${@input.id}' } }];
|
|
44
|
+
* const context = { currentUserId: 123 };
|
|
45
|
+
* const helpers = {};
|
|
46
|
+
* const input = { id: 456 };
|
|
47
|
+
*
|
|
48
|
+
* const materialized = materializer.materialize(rules, context, helpers, input);
|
|
49
|
+
* // Result: [{ conditions: { userId: 456 } }]
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
materialize(rules, context, helpers, input) {
|
|
53
|
+
// In strict mode, wrap input in Proxy to catch undefined property access
|
|
54
|
+
const inputData = input || {};
|
|
55
|
+
const wrappedInput = this.strictMode
|
|
56
|
+
? this.createStrictProxy(inputData, types_1.ACL_INPUT_VAR)
|
|
57
|
+
: inputData;
|
|
58
|
+
// Build scope with context, helpers, and input (without @)
|
|
59
|
+
const scope = {
|
|
60
|
+
...context,
|
|
61
|
+
...helpers,
|
|
62
|
+
[types_1.ACL_INPUT_VAR]: wrappedInput, // 'input' not '@input'
|
|
63
|
+
};
|
|
64
|
+
try {
|
|
65
|
+
// Convert rules to JSON string
|
|
66
|
+
let jsonStr = JSON.stringify(rules, (k, v) => k === 'subject' && typeof v === 'function' ? v.name : v);
|
|
67
|
+
// Replace @input with input (@ is not valid in JS variable names)
|
|
68
|
+
jsonStr = jsonStr.replaceAll(types_1.ACL_INPUT_TEMPLATE, types_1.ACL_INPUT_VAR);
|
|
69
|
+
// Replace \" with ' inside ${...} template expressions
|
|
70
|
+
// JSON.stringify escapes quotes as \" but inside template expressions we need '
|
|
71
|
+
// Example: ${checkStatus(user.status, \"active\")} → ${checkStatus(user.status, 'active')}
|
|
72
|
+
jsonStr = jsonStr.replace(/\$\{([^}]+)\}/g, (match, expr) => {
|
|
73
|
+
const fixedExpr = expr.replace(/\\"/g, "'");
|
|
74
|
+
return `\${${fixedExpr}}`;
|
|
75
|
+
});
|
|
76
|
+
// Replace remaining \" with placeholder (outside of ${...})
|
|
77
|
+
// This helps distinguish quotes around placeholders from quotes inside string values
|
|
78
|
+
jsonStr = jsonStr.replace(/\\"/g, this.QUOTE_PLACEHOLDER);
|
|
79
|
+
// Escape backticks for template literal
|
|
80
|
+
jsonStr = this.escapeForTemplateLiteral(jsonStr);
|
|
81
|
+
this.logger.debug(`JSON template prepared: ${jsonStr.substring(0, 200)}...`);
|
|
82
|
+
// Evaluate using tagged template
|
|
83
|
+
const result = this.evaluateTaggedTemplate(jsonStr, scope);
|
|
84
|
+
// Parse back to object
|
|
85
|
+
const materialized = JSON.parse(result);
|
|
86
|
+
this.logger.debug(`Materialized ${rules.length} rule(s) successfully`);
|
|
87
|
+
return materialized;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
91
|
+
this.handleError(errorMessage, scope);
|
|
92
|
+
throw error; // Re-throw after logging
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Escapes special characters for use in template literal
|
|
97
|
+
*/
|
|
98
|
+
escapeForTemplateLiteral(str) {
|
|
99
|
+
return (str
|
|
100
|
+
// Escape backticks only
|
|
101
|
+
// Don't escape $ because we WANT ${...} to work as template expressions
|
|
102
|
+
.replace(/`/g, '\\`'));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Evaluates JSON template using Tagged Template Literals
|
|
106
|
+
*
|
|
107
|
+
* Uses a tagged function that correctly formats different types:
|
|
108
|
+
* - strings → wrapped in quotes
|
|
109
|
+
* - arrays → JSON.stringify
|
|
110
|
+
* - numbers/booleans → as-is
|
|
111
|
+
*/
|
|
112
|
+
evaluateTaggedTemplate(jsonTemplate, scope) {
|
|
113
|
+
const scopeKeys = Object.keys(scope);
|
|
114
|
+
const scopeValues = Object.values(scope);
|
|
115
|
+
// Tagged template function that handles type formatting
|
|
116
|
+
const taggedFunc = this.createTaggedFunction();
|
|
117
|
+
// Create function: taggedFunc`${userId}${groupIds}...`
|
|
118
|
+
// Example: new Function('tag', 'userId', 'groupIds', 'return tag`...${userId}...${groupIds}...`')
|
|
119
|
+
const functionBody = `return tag\`${jsonTemplate}\`;`;
|
|
120
|
+
// Debug logging
|
|
121
|
+
if (functionBody.length > 500) {
|
|
122
|
+
this.logger.debug(`Function body (first 500 chars): ${functionBody.substring(0, 500)}`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this.logger.debug(`Function body: ${functionBody}`);
|
|
126
|
+
}
|
|
127
|
+
const evalFn = new Function('tag', ...scopeKeys, functionBody);
|
|
128
|
+
// Execute with tagged function and scope values
|
|
129
|
+
const result = evalFn(taggedFunc, ...scopeValues);
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Creates tagged template function that formats placeholders by type
|
|
134
|
+
*
|
|
135
|
+
* IMPORTANT: Values are already inside JSON string quotes from stringify
|
|
136
|
+
* We need to REMOVE the quotes and insert raw JSON values
|
|
137
|
+
*/
|
|
138
|
+
createTaggedFunction() {
|
|
139
|
+
return (literals, ...placeholders) => {
|
|
140
|
+
let result = '';
|
|
141
|
+
const placeholdersLength = placeholders.length;
|
|
142
|
+
for (let i = 0; i < placeholdersLength; i++) {
|
|
143
|
+
let literal = literals[i];
|
|
144
|
+
// Restore placeholder back to \"
|
|
145
|
+
literal = literal.replace(new RegExp(this.QUOTE_PLACEHOLDER, 'g'), '\\"');
|
|
146
|
+
// Check if literal ends with opening quote: "
|
|
147
|
+
// If so, we need to remove it and the closing quote from next literal
|
|
148
|
+
const endsWithQuote = literal.endsWith('"');
|
|
149
|
+
if (endsWithQuote) {
|
|
150
|
+
literal = literal.slice(0, -1); // Remove trailing "
|
|
151
|
+
}
|
|
152
|
+
result += literal;
|
|
153
|
+
const value = placeholders[i];
|
|
154
|
+
// Format value based on type
|
|
155
|
+
if (value === null) {
|
|
156
|
+
result += 'null';
|
|
157
|
+
}
|
|
158
|
+
else if (value === undefined) {
|
|
159
|
+
result += 'null'; // JSON doesn't have undefined
|
|
160
|
+
}
|
|
161
|
+
else if (typeof value === 'string') {
|
|
162
|
+
// Escape quotes and special characters for JSON string
|
|
163
|
+
const escaped = value
|
|
164
|
+
.replace(/\\/g, '\\\\')
|
|
165
|
+
.replace(/"/g, '\\"')
|
|
166
|
+
.replace(/\n/g, '\\n')
|
|
167
|
+
.replace(/\r/g, '\\r')
|
|
168
|
+
.replace(/\t/g, '\\t');
|
|
169
|
+
result += `"${escaped}"`;
|
|
170
|
+
}
|
|
171
|
+
else if (typeof value === 'number' || typeof value === 'boolean') {
|
|
172
|
+
result += String(value);
|
|
173
|
+
}
|
|
174
|
+
else if (Array.isArray(value)) {
|
|
175
|
+
result += JSON.stringify(value);
|
|
176
|
+
}
|
|
177
|
+
else if (value instanceof Date) {
|
|
178
|
+
result += `"${value.toISOString()}"`;
|
|
179
|
+
}
|
|
180
|
+
else if (typeof value === 'object') {
|
|
181
|
+
result += JSON.stringify(value);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// Fallback
|
|
185
|
+
result += JSON.stringify(value);
|
|
186
|
+
}
|
|
187
|
+
// Handle closing quote if we removed opening quote
|
|
188
|
+
if (endsWithQuote && i + 1 < literals.length) {
|
|
189
|
+
const nextLiteral = literals[i + 1];
|
|
190
|
+
if (nextLiteral.startsWith('"')) {
|
|
191
|
+
// Skip the closing quote
|
|
192
|
+
literals = Object.assign([], literals, {
|
|
193
|
+
[i + 1]: nextLiteral.slice(1),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Add final literal (restore placeholder here too)
|
|
199
|
+
let finalLiteral = literals[literals.length - 1];
|
|
200
|
+
finalLiteral = finalLiteral.replace(new RegExp(this.QUOTE_PLACEHOLDER, 'g'), '\\"');
|
|
201
|
+
result += finalLiteral;
|
|
202
|
+
return result;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Creates strict Proxy that throws error on undefined property access
|
|
207
|
+
* Used in strict mode to catch template errors early
|
|
208
|
+
*/
|
|
209
|
+
createStrictProxy(obj, name) {
|
|
210
|
+
return new Proxy(obj, {
|
|
211
|
+
get: (target, prop) => {
|
|
212
|
+
// Allow symbol properties (like Symbol.toStringTag, Symbol.iterator, etc.)
|
|
213
|
+
if (typeof prop === 'symbol') {
|
|
214
|
+
return target[prop];
|
|
215
|
+
}
|
|
216
|
+
// Check if property exists
|
|
217
|
+
if (!(prop in target)) {
|
|
218
|
+
throw new ReferenceError(`Property '${name}.${String(prop)}' is not defined in strict mode`);
|
|
219
|
+
}
|
|
220
|
+
const value = target[prop];
|
|
221
|
+
// If value is an object, wrap it in Proxy too (for nested access)
|
|
222
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
223
|
+
return this.createStrictProxy(value, `${name}.${String(prop)}`);
|
|
224
|
+
}
|
|
225
|
+
return value;
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Handles interpolation errors based on strict mode
|
|
231
|
+
*/
|
|
232
|
+
handleError(errorMessage, scope) {
|
|
233
|
+
const scopeInfo = `Available variables: ${Object.keys(scope).join(', ')}`;
|
|
234
|
+
const fullMessage = `Failed to materialize rules: ${errorMessage}. ${scopeInfo}`;
|
|
235
|
+
if (this.strictMode) {
|
|
236
|
+
this.logger.error(fullMessage);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
this.logger.warn(fullMessage);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
exports.RuleMaterializer = RuleMaterializer;
|
|
244
|
+
tslib_1.__decorate([
|
|
245
|
+
(0, common_1.Inject)(constants_1.ACL_MODULE_OPTIONS),
|
|
246
|
+
tslib_1.__metadata("design:type", Object)
|
|
247
|
+
], RuleMaterializer.prototype, "options", void 0);
|
|
248
|
+
exports.RuleMaterializer = RuleMaterializer = RuleMaterializer_1 = tslib_1.__decorate([
|
|
249
|
+
(0, common_1.Injectable)()
|
|
250
|
+
], RuleMaterializer);
|
|
251
|
+
//# sourceMappingURL=rule-materializer.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-materializer.service.js","sourceRoot":"","sources":["../../../../../../../libs/acl-permissions/nestjs-acl-permissions/src/lib/services/rule-materializer.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for context storage (e.g., ClsService from nestjs-cls)
|
|
3
|
+
* Allows passing rules and data through the request pipeline
|
|
4
|
+
*/
|
|
5
|
+
export interface AclContextStore {
|
|
6
|
+
/**
|
|
7
|
+
* Set value in context
|
|
8
|
+
*/
|
|
9
|
+
set<T = any>(key: any, value: T): void;
|
|
10
|
+
/**
|
|
11
|
+
* Get value from context
|
|
12
|
+
*/
|
|
13
|
+
get<T = any>(key: any): T | undefined;
|
|
14
|
+
}
|