@sapl/nestjs 1.0.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.
Files changed (123) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +539 -0
  3. package/dist/EnforceDropWhileDenied.d.ts +4 -0
  4. package/dist/EnforceDropWhileDenied.d.ts.map +1 -0
  5. package/dist/EnforceDropWhileDenied.js +8 -0
  6. package/dist/EnforceDropWhileDenied.js.map +1 -0
  7. package/dist/EnforceDropWhileDeniedAspect.d.ts +15 -0
  8. package/dist/EnforceDropWhileDeniedAspect.d.ts.map +1 -0
  9. package/dist/EnforceDropWhileDeniedAspect.js +108 -0
  10. package/dist/EnforceDropWhileDeniedAspect.js.map +1 -0
  11. package/dist/EnforceOptions.d.ts +42 -0
  12. package/dist/EnforceOptions.d.ts.map +1 -0
  13. package/dist/EnforceOptions.js +3 -0
  14. package/dist/EnforceOptions.js.map +1 -0
  15. package/dist/EnforceRecoverableIfDenied.d.ts +4 -0
  16. package/dist/EnforceRecoverableIfDenied.d.ts.map +1 -0
  17. package/dist/EnforceRecoverableIfDenied.js +8 -0
  18. package/dist/EnforceRecoverableIfDenied.js.map +1 -0
  19. package/dist/EnforceRecoverableIfDeniedAspect.d.ts +15 -0
  20. package/dist/EnforceRecoverableIfDeniedAspect.d.ts.map +1 -0
  21. package/dist/EnforceRecoverableIfDeniedAspect.js +134 -0
  22. package/dist/EnforceRecoverableIfDeniedAspect.js.map +1 -0
  23. package/dist/EnforceTillDenied.d.ts +4 -0
  24. package/dist/EnforceTillDenied.d.ts.map +1 -0
  25. package/dist/EnforceTillDenied.js +8 -0
  26. package/dist/EnforceTillDenied.js.map +1 -0
  27. package/dist/EnforceTillDeniedAspect.d.ts +15 -0
  28. package/dist/EnforceTillDeniedAspect.d.ts.map +1 -0
  29. package/dist/EnforceTillDeniedAspect.js +119 -0
  30. package/dist/EnforceTillDeniedAspect.js.map +1 -0
  31. package/dist/MethodInvocationContext.d.ts +8 -0
  32. package/dist/MethodInvocationContext.d.ts.map +1 -0
  33. package/dist/MethodInvocationContext.js +3 -0
  34. package/dist/MethodInvocationContext.js.map +1 -0
  35. package/dist/PostEnforce.d.ts +23 -0
  36. package/dist/PostEnforce.d.ts.map +1 -0
  37. package/dist/PostEnforce.js +27 -0
  38. package/dist/PostEnforce.js.map +1 -0
  39. package/dist/PostEnforceAspect.d.ts +15 -0
  40. package/dist/PostEnforceAspect.d.ts.map +1 -0
  41. package/dist/PostEnforceAspect.js +81 -0
  42. package/dist/PostEnforceAspect.js.map +1 -0
  43. package/dist/PreEnforce.d.ts +21 -0
  44. package/dist/PreEnforce.d.ts.map +1 -0
  45. package/dist/PreEnforce.js +25 -0
  46. package/dist/PreEnforce.js.map +1 -0
  47. package/dist/PreEnforceAspect.d.ts +15 -0
  48. package/dist/PreEnforceAspect.d.ts.map +1 -0
  49. package/dist/PreEnforceAspect.js +107 -0
  50. package/dist/PreEnforceAspect.js.map +1 -0
  51. package/dist/StreamingEnforceOptions.d.ts +22 -0
  52. package/dist/StreamingEnforceOptions.d.ts.map +1 -0
  53. package/dist/StreamingEnforceOptions.js +3 -0
  54. package/dist/StreamingEnforceOptions.js.map +1 -0
  55. package/dist/SubscriptionBuilder.d.ts +17 -0
  56. package/dist/SubscriptionBuilder.d.ts.map +1 -0
  57. package/dist/SubscriptionBuilder.js +86 -0
  58. package/dist/SubscriptionBuilder.js.map +1 -0
  59. package/dist/SubscriptionContext.d.ts +48 -0
  60. package/dist/SubscriptionContext.d.ts.map +1 -0
  61. package/dist/SubscriptionContext.js +3 -0
  62. package/dist/SubscriptionContext.js.map +1 -0
  63. package/dist/constraints/ConstraintEnforcementService.d.ts +22 -0
  64. package/dist/constraints/ConstraintEnforcementService.d.ts.map +1 -0
  65. package/dist/constraints/ConstraintEnforcementService.js +209 -0
  66. package/dist/constraints/ConstraintEnforcementService.js.map +1 -0
  67. package/dist/constraints/ConstraintHandlerBundle.d.ts +19 -0
  68. package/dist/constraints/ConstraintHandlerBundle.d.ts.map +1 -0
  69. package/dist/constraints/ConstraintHandlerBundle.js +47 -0
  70. package/dist/constraints/ConstraintHandlerBundle.js.map +1 -0
  71. package/dist/constraints/SaplConstraintHandler.d.ts +3 -0
  72. package/dist/constraints/SaplConstraintHandler.d.ts.map +1 -0
  73. package/dist/constraints/SaplConstraintHandler.js +6 -0
  74. package/dist/constraints/SaplConstraintHandler.js.map +1 -0
  75. package/dist/constraints/StreamingConstraintHandlerBundle.d.ts +18 -0
  76. package/dist/constraints/StreamingConstraintHandlerBundle.d.ts.map +1 -0
  77. package/dist/constraints/StreamingConstraintHandlerBundle.js +34 -0
  78. package/dist/constraints/StreamingConstraintHandlerBundle.js.map +1 -0
  79. package/dist/constraints/api/index.d.ts +35 -0
  80. package/dist/constraints/api/index.d.ts.map +1 -0
  81. package/dist/constraints/api/index.js +11 -0
  82. package/dist/constraints/api/index.js.map +1 -0
  83. package/dist/constraints/providers/ContentFilter.d.ts +3 -0
  84. package/dist/constraints/providers/ContentFilter.d.ts.map +1 -0
  85. package/dist/constraints/providers/ContentFilter.js +224 -0
  86. package/dist/constraints/providers/ContentFilter.js.map +1 -0
  87. package/dist/constraints/providers/ContentFilterPredicateProvider.d.ts +6 -0
  88. package/dist/constraints/providers/ContentFilterPredicateProvider.d.ts.map +1 -0
  89. package/dist/constraints/providers/ContentFilterPredicateProvider.js +26 -0
  90. package/dist/constraints/providers/ContentFilterPredicateProvider.js.map +1 -0
  91. package/dist/constraints/providers/ContentFilteringProvider.d.ts +7 -0
  92. package/dist/constraints/providers/ContentFilteringProvider.d.ts.map +1 -0
  93. package/dist/constraints/providers/ContentFilteringProvider.js +29 -0
  94. package/dist/constraints/providers/ContentFilteringProvider.js.map +1 -0
  95. package/dist/enforcement-utils.d.ts +7 -0
  96. package/dist/enforcement-utils.d.ts.map +1 -0
  97. package/dist/enforcement-utils.js +28 -0
  98. package/dist/enforcement-utils.js.map +1 -0
  99. package/dist/index.d.ts +20 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +37 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/pdp.service.d.ts +17 -0
  104. package/dist/pdp.service.d.ts.map +1 -0
  105. package/dist/pdp.service.js +296 -0
  106. package/dist/pdp.service.js.map +1 -0
  107. package/dist/sapl.constants.d.ts +2 -0
  108. package/dist/sapl.constants.d.ts.map +1 -0
  109. package/dist/sapl.constants.js +5 -0
  110. package/dist/sapl.constants.js.map +1 -0
  111. package/dist/sapl.interfaces.d.ts +25 -0
  112. package/dist/sapl.interfaces.d.ts.map +1 -0
  113. package/dist/sapl.interfaces.js +3 -0
  114. package/dist/sapl.interfaces.js.map +1 -0
  115. package/dist/sapl.module.d.ts +7 -0
  116. package/dist/sapl.module.d.ts.map +1 -0
  117. package/dist/sapl.module.js +91 -0
  118. package/dist/sapl.module.js.map +1 -0
  119. package/dist/types.d.ts +29 -0
  120. package/dist/types.d.ts.map +1 -0
  121. package/dist/types.js +3 -0
  122. package/dist/types.js.map +1 -0
  123. package/package.json +67 -0
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var EnforceDropWhileDeniedAspect_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.EnforceDropWhileDeniedAspect = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const nestjs_aop_1 = require("@toss/nestjs-aop");
16
+ const nestjs_cls_1 = require("nestjs-cls");
17
+ const rxjs_1 = require("rxjs");
18
+ const EnforceDropWhileDenied_1 = require("./EnforceDropWhileDenied");
19
+ const pdp_service_1 = require("./pdp.service");
20
+ const SubscriptionBuilder_1 = require("./SubscriptionBuilder");
21
+ const ConstraintEnforcementService_1 = require("./constraints/ConstraintEnforcementService");
22
+ let EnforceDropWhileDeniedAspect = EnforceDropWhileDeniedAspect_1 = class EnforceDropWhileDeniedAspect {
23
+ constructor(pdpService, cls, constraintService) {
24
+ this.pdpService = pdpService;
25
+ this.cls = cls;
26
+ this.constraintService = constraintService;
27
+ this.logger = new common_1.Logger(EnforceDropWhileDeniedAspect_1.name);
28
+ }
29
+ wrap({ method, metadata, methodName, instance }) {
30
+ const aspect = this;
31
+ const className = instance.constructor.name;
32
+ return (...args) => {
33
+ return new rxjs_1.Observable((subscriber) => {
34
+ let currentBundle = null;
35
+ let sourceSubscription = null;
36
+ let permitted = false;
37
+ const ctx = (0, SubscriptionBuilder_1.buildContext)(aspect.cls, methodName, className, args);
38
+ const subscription = (0, SubscriptionBuilder_1.buildSubscriptionFromContext)(metadata, ctx);
39
+ const decisions$ = aspect.pdpService.decide(subscription);
40
+ const decisionSub = decisions$.subscribe({
41
+ next: (decision) => {
42
+ if (decision.decision === 'PERMIT') {
43
+ try {
44
+ const newBundle = aspect.constraintService.streamingBundleFor(decision);
45
+ newBundle.handleOnDecisionConstraints();
46
+ currentBundle = newBundle;
47
+ }
48
+ catch (error) {
49
+ aspect.logger.warn(`Obligation handling failed: ${error}`);
50
+ permitted = false;
51
+ currentBundle = null;
52
+ return;
53
+ }
54
+ permitted = true;
55
+ if (!sourceSubscription) {
56
+ sourceSubscription = method(...args).subscribe({
57
+ next: (value) => {
58
+ if (!permitted || !currentBundle)
59
+ return;
60
+ try {
61
+ const transformed = currentBundle.handleAllOnNextConstraints(value);
62
+ subscriber.next(transformed);
63
+ }
64
+ catch (error) {
65
+ aspect.logger.warn(`Constraint handling failed on next: ${error}`);
66
+ permitted = false;
67
+ currentBundle = null;
68
+ }
69
+ },
70
+ error: (err) => subscriber.error(err),
71
+ complete: () => {
72
+ currentBundle?.handleOnCompleteConstraints();
73
+ subscriber.complete();
74
+ },
75
+ });
76
+ }
77
+ }
78
+ else {
79
+ permitted = false;
80
+ currentBundle = null;
81
+ try {
82
+ const bestEffort = aspect.constraintService.streamingBestEffortBundleFor(decision);
83
+ bestEffort.handleOnDecisionConstraints();
84
+ }
85
+ catch {
86
+ /* best effort */
87
+ }
88
+ }
89
+ },
90
+ error: (err) => subscriber.error(err),
91
+ });
92
+ return () => {
93
+ currentBundle?.handleOnCancelConstraints();
94
+ decisionSub.unsubscribe();
95
+ sourceSubscription?.unsubscribe();
96
+ };
97
+ });
98
+ };
99
+ }
100
+ };
101
+ exports.EnforceDropWhileDeniedAspect = EnforceDropWhileDeniedAspect;
102
+ exports.EnforceDropWhileDeniedAspect = EnforceDropWhileDeniedAspect = EnforceDropWhileDeniedAspect_1 = __decorate([
103
+ (0, nestjs_aop_1.Aspect)(EnforceDropWhileDenied_1.ENFORCE_DROP_WHILE_DENIED_SYMBOL),
104
+ __metadata("design:paramtypes", [pdp_service_1.PdpService,
105
+ nestjs_cls_1.ClsService,
106
+ ConstraintEnforcementService_1.ConstraintEnforcementService])
107
+ ], EnforceDropWhileDeniedAspect);
108
+ //# sourceMappingURL=EnforceDropWhileDeniedAspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceDropWhileDeniedAspect.js","sourceRoot":"","sources":["../lib/EnforceDropWhileDeniedAspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { SubscriptionContext } from './SubscriptionContext';
2
+ import { AuthorizationDecision } from './types';
3
+ /**
4
+ * A subscription field value: either a literal (sent as-is to the PDP) or a
5
+ * callback that receives the request-time SubscriptionContext and returns
6
+ * the value dynamically.
7
+ *
8
+ * Examples:
9
+ * action: 'read' // literal
10
+ * resource: (ctx) => ({ id: ctx.params.id }) // callback
11
+ * subject: (ctx) => ctx.request.user // callback
12
+ */
13
+ export type SubscriptionField<T = any> = T | ((ctx: SubscriptionContext) => T);
14
+ /**
15
+ * Callback invoked when the PDP denies access. Receives the request-time context
16
+ * and the PDP decision. The return value becomes the HTTP response body (with 200).
17
+ * If not provided, a ForbiddenException (403) is thrown.
18
+ *
19
+ * WARNING: Do not return the raw `decision` object -- it may contain policy internals
20
+ * (obligations, advice) that should not be exposed to clients. Build a safe response
21
+ * from specific fields only, or throw a custom HttpException for non-200 responses.
22
+ */
23
+ export type OnDenyHandler = (ctx: SubscriptionContext, decision: AuthorizationDecision) => any;
24
+ /**
25
+ * The five SAPL authorization subscription fields.
26
+ * All fields are optional -- sensible defaults are derived at runtime.
27
+ */
28
+ export interface SubscriptionOptions {
29
+ subject?: SubscriptionField;
30
+ action?: SubscriptionField;
31
+ resource?: SubscriptionField;
32
+ environment?: SubscriptionField;
33
+ secrets?: SubscriptionField;
34
+ }
35
+ /**
36
+ * Options for @PreEnforce and @PostEnforce decorators.
37
+ * Extends SubscriptionOptions with a deny handler callback.
38
+ */
39
+ export interface EnforceOptions extends SubscriptionOptions {
40
+ onDeny?: OnDenyHandler;
41
+ }
42
+ //# sourceMappingURL=EnforceOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceOptions.d.ts","sourceRoot":"","sources":["../lib/EnforceOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,mBAAmB,KAAK,CAAC,CAAC,CAAC;AAE/E;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,mBAAmB,EAAE,QAAQ,EAAE,qBAAqB,KAAK,GAAG,CAAC;AAE/F;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=EnforceOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceOptions.js","sourceRoot":"","sources":["../lib/EnforceOptions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import { EnforceRecoverableOptions } from './StreamingEnforceOptions';
2
+ export declare const ENFORCE_RECOVERABLE_SYMBOL: unique symbol;
3
+ export declare const EnforceRecoverableIfDenied: (options?: EnforceRecoverableOptions) => MethodDecorator;
4
+ //# sourceMappingURL=EnforceRecoverableIfDenied.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceRecoverableIfDenied.d.ts","sourceRoot":"","sources":["../lib/EnforceRecoverableIfDenied.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,eAAO,MAAM,0BAA0B,eAA+C,CAAC;AAEvF,eAAO,MAAM,0BAA0B,GAAI,UAAS,yBAA8B,oBAC5B,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnforceRecoverableIfDenied = exports.ENFORCE_RECOVERABLE_SYMBOL = void 0;
4
+ const nestjs_aop_1 = require("@toss/nestjs-aop");
5
+ exports.ENFORCE_RECOVERABLE_SYMBOL = Symbol('sapl:enforce-recoverable-if-denied');
6
+ const EnforceRecoverableIfDenied = (options = {}) => (0, nestjs_aop_1.createDecorator)(exports.ENFORCE_RECOVERABLE_SYMBOL, options);
7
+ exports.EnforceRecoverableIfDenied = EnforceRecoverableIfDenied;
8
+ //# sourceMappingURL=EnforceRecoverableIfDenied.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceRecoverableIfDenied.js","sourceRoot":"","sources":["../lib/EnforceRecoverableIfDenied.ts"],"names":[],"mappings":";;;AAAA,iDAAmD;AAGtC,QAAA,0BAA0B,GAAG,MAAM,CAAC,oCAAoC,CAAC,CAAC;AAEhF,MAAM,0BAA0B,GAAG,CAAC,UAAqC,EAAE,EAAE,EAAE,CACpF,IAAA,4BAAe,EAAC,kCAA0B,EAAE,OAAO,CAAC,CAAC;AAD1C,QAAA,0BAA0B,8BACgB"}
@@ -0,0 +1,15 @@
1
+ import { LazyDecorator, WrapParams } from '@toss/nestjs-aop';
2
+ import { ClsService } from 'nestjs-cls';
3
+ import { Observable } from 'rxjs';
4
+ import { EnforceRecoverableOptions } from './StreamingEnforceOptions';
5
+ import { PdpService } from './pdp.service';
6
+ import { ConstraintEnforcementService } from './constraints/ConstraintEnforcementService';
7
+ export declare class EnforceRecoverableIfDeniedAspect implements LazyDecorator<any, EnforceRecoverableOptions> {
8
+ private readonly pdpService;
9
+ private readonly cls;
10
+ private readonly constraintService;
11
+ private readonly logger;
12
+ constructor(pdpService: PdpService, cls: ClsService, constraintService: ConstraintEnforcementService);
13
+ wrap({ method, metadata, methodName, instance }: WrapParams<any, EnforceRecoverableOptions>): (...args: any[]) => Observable<unknown>;
14
+ }
15
+ //# sourceMappingURL=EnforceRecoverableIfDeniedAspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceRecoverableIfDeniedAspect.d.ts","sourceRoot":"","sources":["../lib/EnforceRecoverableIfDeniedAspect.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,UAAU,EAAgB,MAAM,MAAM,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAC;AAG1F,qBACa,gCAAiC,YAAW,aAAa,CAAC,GAAG,EAAE,yBAAyB,CAAC;IAIlG,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IALpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqD;gBAGzD,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,UAAU,EACf,iBAAiB,EAAE,4BAA4B;IAGlE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,UAAU,CAAC,GAAG,EAAE,yBAAyB,CAAC,IAIjF,GAAG,MAAM,GAAG,EAAE;CA8FzB"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var EnforceRecoverableIfDeniedAspect_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.EnforceRecoverableIfDeniedAspect = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const nestjs_aop_1 = require("@toss/nestjs-aop");
16
+ const nestjs_cls_1 = require("nestjs-cls");
17
+ const rxjs_1 = require("rxjs");
18
+ const EnforceRecoverableIfDenied_1 = require("./EnforceRecoverableIfDenied");
19
+ const pdp_service_1 = require("./pdp.service");
20
+ const SubscriptionBuilder_1 = require("./SubscriptionBuilder");
21
+ const ConstraintEnforcementService_1 = require("./constraints/ConstraintEnforcementService");
22
+ let EnforceRecoverableIfDeniedAspect = EnforceRecoverableIfDeniedAspect_1 = class EnforceRecoverableIfDeniedAspect {
23
+ constructor(pdpService, cls, constraintService) {
24
+ this.pdpService = pdpService;
25
+ this.cls = cls;
26
+ this.constraintService = constraintService;
27
+ this.logger = new common_1.Logger(EnforceRecoverableIfDeniedAspect_1.name);
28
+ }
29
+ wrap({ method, metadata, methodName, instance }) {
30
+ const aspect = this;
31
+ const className = instance.constructor.name;
32
+ return (...args) => {
33
+ return new rxjs_1.Observable((subscriber) => {
34
+ let currentBundle = null;
35
+ let sourceSubscription = null;
36
+ let accessState = 'initial';
37
+ const emitter = { next: (v) => subscriber.next(v) };
38
+ const ctx = (0, SubscriptionBuilder_1.buildContext)(aspect.cls, methodName, className, args);
39
+ const subscription = (0, SubscriptionBuilder_1.buildSubscriptionFromContext)(metadata, ctx);
40
+ const decisions$ = aspect.pdpService.decide(subscription);
41
+ const decisionSub = decisions$.subscribe({
42
+ next: (decision) => {
43
+ const previousState = accessState;
44
+ if (decision.decision === 'PERMIT') {
45
+ try {
46
+ const newBundle = aspect.constraintService.streamingBundleFor(decision);
47
+ newBundle.handleOnDecisionConstraints();
48
+ currentBundle = newBundle;
49
+ }
50
+ catch (error) {
51
+ aspect.logger.warn(`Obligation handling failed: ${error}`);
52
+ accessState = 'denied';
53
+ currentBundle = null;
54
+ if (previousState !== 'denied') {
55
+ try {
56
+ metadata.onStreamDeny?.(decision, emitter);
57
+ }
58
+ catch (callbackError) {
59
+ aspect.logger.warn(`onStreamDeny callback failed: ${callbackError}`);
60
+ }
61
+ }
62
+ return;
63
+ }
64
+ accessState = 'permitted';
65
+ if (previousState === 'denied') {
66
+ try {
67
+ metadata.onStreamRecover?.(decision, emitter);
68
+ }
69
+ catch (callbackError) {
70
+ aspect.logger.warn(`onStreamRecover callback failed: ${callbackError}`);
71
+ }
72
+ }
73
+ if (!sourceSubscription) {
74
+ sourceSubscription = method(...args).subscribe({
75
+ next: (value) => {
76
+ if (accessState !== 'permitted' || !currentBundle)
77
+ return;
78
+ try {
79
+ const transformed = currentBundle.handleAllOnNextConstraints(value);
80
+ subscriber.next(transformed);
81
+ }
82
+ catch (error) {
83
+ aspect.logger.warn(`Constraint handling failed on next: ${error}`);
84
+ accessState = 'denied';
85
+ currentBundle = null;
86
+ }
87
+ },
88
+ error: (err) => subscriber.error(err),
89
+ complete: () => {
90
+ currentBundle?.handleOnCompleteConstraints();
91
+ subscriber.complete();
92
+ },
93
+ });
94
+ }
95
+ }
96
+ else {
97
+ accessState = 'denied';
98
+ currentBundle = null;
99
+ try {
100
+ const bestEffort = aspect.constraintService.streamingBestEffortBundleFor(decision);
101
+ bestEffort.handleOnDecisionConstraints();
102
+ }
103
+ catch {
104
+ /* best effort */
105
+ }
106
+ if (previousState !== 'denied') {
107
+ try {
108
+ metadata.onStreamDeny?.(decision, emitter);
109
+ }
110
+ catch (callbackError) {
111
+ aspect.logger.warn(`onStreamDeny callback failed: ${callbackError}`);
112
+ }
113
+ }
114
+ }
115
+ },
116
+ error: (err) => subscriber.error(err),
117
+ });
118
+ return () => {
119
+ currentBundle?.handleOnCancelConstraints();
120
+ decisionSub.unsubscribe();
121
+ sourceSubscription?.unsubscribe();
122
+ };
123
+ });
124
+ };
125
+ }
126
+ };
127
+ exports.EnforceRecoverableIfDeniedAspect = EnforceRecoverableIfDeniedAspect;
128
+ exports.EnforceRecoverableIfDeniedAspect = EnforceRecoverableIfDeniedAspect = EnforceRecoverableIfDeniedAspect_1 = __decorate([
129
+ (0, nestjs_aop_1.Aspect)(EnforceRecoverableIfDenied_1.ENFORCE_RECOVERABLE_SYMBOL),
130
+ __metadata("design:paramtypes", [pdp_service_1.PdpService,
131
+ nestjs_cls_1.ClsService,
132
+ ConstraintEnforcementService_1.ConstraintEnforcementService])
133
+ ], EnforceRecoverableIfDeniedAspect);
134
+ //# sourceMappingURL=EnforceRecoverableIfDeniedAspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceRecoverableIfDeniedAspect.js","sourceRoot":"","sources":["../lib/EnforceRecoverableIfDeniedAspect.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAwC;AACxC,iDAAqE;AACrE,2CAAwC;AACxC,+BAAgD;AAChD,6EAA0E;AAE1E,+CAA2C;AAE3C,+DAAmF;AACnF,6FAA0F;AAInF,IAAM,gCAAgC,wCAAtC,MAAM,gCAAgC;IAG3C,YACmB,UAAsB,EACtB,GAAe,EACf,iBAA+C;QAF/C,eAAU,GAAV,UAAU,CAAY;QACtB,QAAG,GAAH,GAAG,CAAY;QACf,sBAAiB,GAAjB,iBAAiB,CAA8B;QALjD,WAAM,GAAG,IAAI,eAAM,CAAC,kCAAgC,CAAC,IAAI,CAAC,CAAC;IAMzE,CAAC;IAEJ,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAA8C;QACzF,MAAM,MAAM,GAAG,IAAI,CAAC;QACpB,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;QAE5C,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE;YACxB,OAAO,IAAI,iBAAU,CAAC,CAAC,UAAU,EAAE,EAAE;gBACnC,IAAI,aAAa,GAA4C,IAAI,CAAC;gBAClE,IAAI,kBAAkB,GAAwB,IAAI,CAAC;gBACnD,IAAI,WAAW,GAAuC,SAAS,CAAC;gBAChE,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEzD,MAAM,GAAG,GAAG,IAAA,kCAAY,EAAC,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;gBAClE,MAAM,YAAY,GAAG,IAAA,kDAA4B,EAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBACjE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAE1D,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC;oBACvC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;wBACjB,MAAM,aAAa,GAAG,WAAW,CAAC;wBAElC,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;4BACnC,IAAI,CAAC;gCACH,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;gCACxE,SAAS,CAAC,2BAA2B,EAAE,CAAC;gCACxC,aAAa,GAAG,SAAS,CAAC;4BAC5B,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;gCAC3D,WAAW,GAAG,QAAQ,CAAC;gCACvB,aAAa,GAAG,IAAI,CAAC;gCACrB,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;oCAC/B,IAAI,CAAC;wCACH,QAAQ,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oCAC7C,CAAC;oCAAC,OAAO,aAAa,EAAE,CAAC;wCACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,aAAa,EAAE,CAAC,CAAC;oCACvE,CAAC;gCACH,CAAC;gCACD,OAAO;4BACT,CAAC;4BACD,WAAW,GAAG,WAAW,CAAC;4BAE1B,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gCAC/B,IAAI,CAAC;oCACH,QAAQ,CAAC,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gCAChD,CAAC;gCAAC,OAAO,aAAa,EAAE,CAAC;oCACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,aAAa,EAAE,CAAC,CAAC;gCAC1E,CAAC;4BACH,CAAC;4BAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;gCACxB,kBAAkB,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC;oCAC7C,IAAI,EAAE,CAAC,KAAU,EAAE,EAAE;wCACnB,IAAI,WAAW,KAAK,WAAW,IAAI,CAAC,aAAa;4CAAE,OAAO;wCAC1D,IAAI,CAAC;4CACH,MAAM,WAAW,GAAG,aAAa,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;4CACpE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wCAC/B,CAAC;wCAAC,OAAO,KAAK,EAAE,CAAC;4CACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,KAAK,EAAE,CAAC,CAAC;4CACnE,WAAW,GAAG,QAAQ,CAAC;4CACvB,aAAa,GAAG,IAAI,CAAC;wCACvB,CAAC;oCACH,CAAC;oCACD,KAAK,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;oCAC1C,QAAQ,EAAE,GAAG,EAAE;wCACb,aAAa,EAAE,2BAA2B,EAAE,CAAC;wCAC7C,UAAU,CAAC,QAAQ,EAAE,CAAC;oCACxB,CAAC;iCACF,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;6BAAM,CAAC;4BACN,WAAW,GAAG,QAAQ,CAAC;4BACvB,aAAa,GAAG,IAAI,CAAC;4BACrB,IAAI,CAAC;gCACH,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;gCACnF,UAAU,CAAC,2BAA2B,EAAE,CAAC;4BAC3C,CAAC;4BAAC,MAAM,CAAC;gCACP,iBAAiB;4BACnB,CAAC;4BAED,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gCAC/B,IAAI,CAAC;oCACH,QAAQ,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gCAC7C,CAAC;gCAAC,OAAO,aAAa,EAAE,CAAC;oCACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,aAAa,EAAE,CAAC,CAAC;gCACvE,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;oBACD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;iBACtC,CAAC,CAAC;gBAEH,OAAO,GAAG,EAAE;oBACV,aAAa,EAAE,yBAAyB,EAAE,CAAC;oBAC3C,WAAW,CAAC,WAAW,EAAE,CAAC;oBAC1B,kBAAkB,EAAE,WAAW,EAAE,CAAC;gBACpC,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;CAEF,CAAA;AA3GY,4EAAgC;2CAAhC,gCAAgC;IAD5C,IAAA,mBAAM,EAAC,uDAA0B,CAAC;qCAKF,wBAAU;QACjB,uBAAU;QACI,2DAA4B;GANvD,gCAAgC,CA2G5C"}
@@ -0,0 +1,4 @@
1
+ import { EnforceTillDeniedOptions } from './StreamingEnforceOptions';
2
+ export declare const ENFORCE_TILL_DENIED_SYMBOL: unique symbol;
3
+ export declare const EnforceTillDenied: (options?: EnforceTillDeniedOptions) => MethodDecorator;
4
+ //# sourceMappingURL=EnforceTillDenied.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceTillDenied.d.ts","sourceRoot":"","sources":["../lib/EnforceTillDenied.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,eAAO,MAAM,0BAA0B,eAAqC,CAAC;AAE7E,eAAO,MAAM,iBAAiB,GAAI,UAAS,wBAA6B,oBAClB,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnforceTillDenied = exports.ENFORCE_TILL_DENIED_SYMBOL = void 0;
4
+ const nestjs_aop_1 = require("@toss/nestjs-aop");
5
+ exports.ENFORCE_TILL_DENIED_SYMBOL = Symbol('sapl:enforce-till-denied');
6
+ const EnforceTillDenied = (options = {}) => (0, nestjs_aop_1.createDecorator)(exports.ENFORCE_TILL_DENIED_SYMBOL, options);
7
+ exports.EnforceTillDenied = EnforceTillDenied;
8
+ //# sourceMappingURL=EnforceTillDenied.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceTillDenied.js","sourceRoot":"","sources":["../lib/EnforceTillDenied.ts"],"names":[],"mappings":";;;AAAA,iDAAmD;AAGtC,QAAA,0BAA0B,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAEtE,MAAM,iBAAiB,GAAG,CAAC,UAAoC,EAAE,EAAE,EAAE,CAC1E,IAAA,4BAAe,EAAC,kCAA0B,EAAE,OAAO,CAAC,CAAC;AAD1C,QAAA,iBAAiB,qBACyB"}
@@ -0,0 +1,15 @@
1
+ import { LazyDecorator, WrapParams } from '@toss/nestjs-aop';
2
+ import { ClsService } from 'nestjs-cls';
3
+ import { Observable } from 'rxjs';
4
+ import { EnforceTillDeniedOptions } from './StreamingEnforceOptions';
5
+ import { PdpService } from './pdp.service';
6
+ import { ConstraintEnforcementService } from './constraints/ConstraintEnforcementService';
7
+ export declare class EnforceTillDeniedAspect implements LazyDecorator<any, EnforceTillDeniedOptions> {
8
+ private readonly pdpService;
9
+ private readonly cls;
10
+ private readonly constraintService;
11
+ private readonly logger;
12
+ constructor(pdpService: PdpService, cls: ClsService, constraintService: ConstraintEnforcementService);
13
+ wrap({ method, metadata, methodName, instance }: WrapParams<any, EnforceTillDeniedOptions>): (...args: any[]) => Observable<unknown>;
14
+ }
15
+ //# sourceMappingURL=EnforceTillDeniedAspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceTillDeniedAspect.d.ts","sourceRoot":"","sources":["../lib/EnforceTillDeniedAspect.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,UAAU,EAAgB,MAAM,MAAM,CAAC;AAEhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAC;AAG1F,qBACa,uBAAwB,YAAW,aAAa,CAAC,GAAG,EAAE,wBAAwB,CAAC;IAIxF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IALpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;gBAGhD,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,UAAU,EACf,iBAAiB,EAAE,4BAA4B;IAGlE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,UAAU,CAAC,GAAG,EAAE,wBAAwB,CAAC,IAIhF,GAAG,MAAM,GAAG,EAAE;CA6EzB"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var EnforceTillDeniedAspect_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.EnforceTillDeniedAspect = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const nestjs_aop_1 = require("@toss/nestjs-aop");
16
+ const nestjs_cls_1 = require("nestjs-cls");
17
+ const rxjs_1 = require("rxjs");
18
+ const EnforceTillDenied_1 = require("./EnforceTillDenied");
19
+ const pdp_service_1 = require("./pdp.service");
20
+ const SubscriptionBuilder_1 = require("./SubscriptionBuilder");
21
+ const ConstraintEnforcementService_1 = require("./constraints/ConstraintEnforcementService");
22
+ let EnforceTillDeniedAspect = EnforceTillDeniedAspect_1 = class EnforceTillDeniedAspect {
23
+ constructor(pdpService, cls, constraintService) {
24
+ this.pdpService = pdpService;
25
+ this.cls = cls;
26
+ this.constraintService = constraintService;
27
+ this.logger = new common_1.Logger(EnforceTillDeniedAspect_1.name);
28
+ }
29
+ wrap({ method, metadata, methodName, instance }) {
30
+ const aspect = this;
31
+ const className = instance.constructor.name;
32
+ return (...args) => {
33
+ return new rxjs_1.Observable((subscriber) => {
34
+ let currentBundle = null;
35
+ let sourceSubscription = null;
36
+ let permitted = false;
37
+ const emitter = { next: (v) => subscriber.next(v) };
38
+ const ctx = (0, SubscriptionBuilder_1.buildContext)(aspect.cls, methodName, className, args);
39
+ const subscription = (0, SubscriptionBuilder_1.buildSubscriptionFromContext)(metadata, ctx);
40
+ const decisions$ = aspect.pdpService.decide(subscription);
41
+ const decisionSub = decisions$.subscribe({
42
+ next: (decision) => {
43
+ if (decision.decision === 'PERMIT') {
44
+ try {
45
+ const newBundle = aspect.constraintService.streamingBundleFor(decision);
46
+ newBundle.handleOnDecisionConstraints();
47
+ currentBundle = newBundle;
48
+ }
49
+ catch (error) {
50
+ aspect.logger.warn(`Obligation handling failed: ${error}`);
51
+ try {
52
+ metadata.onStreamDeny?.(decision, emitter);
53
+ }
54
+ catch (callbackError) {
55
+ aspect.logger.warn(`onStreamDeny callback failed: ${callbackError}`);
56
+ }
57
+ subscriber.error(new common_1.ForbiddenException('Access denied by policy'));
58
+ return;
59
+ }
60
+ permitted = true;
61
+ if (!sourceSubscription) {
62
+ sourceSubscription = method(...args).subscribe({
63
+ next: (value) => {
64
+ if (!permitted || !currentBundle)
65
+ return;
66
+ try {
67
+ const transformed = currentBundle.handleAllOnNextConstraints(value);
68
+ subscriber.next(transformed);
69
+ }
70
+ catch (error) {
71
+ aspect.logger.warn(`Constraint handling failed on next: ${error}`);
72
+ subscriber.error(new common_1.ForbiddenException('Constraint handling failed'));
73
+ }
74
+ },
75
+ error: (err) => subscriber.error(err),
76
+ complete: () => {
77
+ currentBundle?.handleOnCompleteConstraints();
78
+ subscriber.complete();
79
+ },
80
+ });
81
+ }
82
+ }
83
+ else {
84
+ permitted = false;
85
+ try {
86
+ const bestEffort = aspect.constraintService.streamingBestEffortBundleFor(decision);
87
+ bestEffort.handleOnDecisionConstraints();
88
+ }
89
+ catch {
90
+ /* best effort */
91
+ }
92
+ try {
93
+ metadata.onStreamDeny?.(decision, emitter);
94
+ }
95
+ catch (callbackError) {
96
+ aspect.logger.warn(`onStreamDeny callback failed: ${callbackError}`);
97
+ }
98
+ subscriber.error(new common_1.ForbiddenException('Access denied by policy'));
99
+ }
100
+ },
101
+ error: (err) => subscriber.error(err),
102
+ });
103
+ return () => {
104
+ currentBundle?.handleOnCancelConstraints();
105
+ decisionSub.unsubscribe();
106
+ sourceSubscription?.unsubscribe();
107
+ };
108
+ });
109
+ };
110
+ }
111
+ };
112
+ exports.EnforceTillDeniedAspect = EnforceTillDeniedAspect;
113
+ exports.EnforceTillDeniedAspect = EnforceTillDeniedAspect = EnforceTillDeniedAspect_1 = __decorate([
114
+ (0, nestjs_aop_1.Aspect)(EnforceTillDenied_1.ENFORCE_TILL_DENIED_SYMBOL),
115
+ __metadata("design:paramtypes", [pdp_service_1.PdpService,
116
+ nestjs_cls_1.ClsService,
117
+ ConstraintEnforcementService_1.ConstraintEnforcementService])
118
+ ], EnforceTillDeniedAspect);
119
+ //# sourceMappingURL=EnforceTillDeniedAspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnforceTillDeniedAspect.js","sourceRoot":"","sources":["../lib/EnforceTillDeniedAspect.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,iDAAqE;AACrE,2CAAwC;AACxC,+BAAgD;AAChD,2DAAiE;AAEjE,+CAA2C;AAE3C,+DAAmF;AACnF,6FAA0F;AAInF,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IAGlC,YACmB,UAAsB,EACtB,GAAe,EACf,iBAA+C;QAF/C,eAAU,GAAV,UAAU,CAAY;QACtB,QAAG,GAAH,GAAG,CAAY;QACf,sBAAiB,GAAjB,iBAAiB,CAA8B;QALjD,WAAM,GAAG,IAAI,eAAM,CAAC,yBAAuB,CAAC,IAAI,CAAC,CAAC;IAMhE,CAAC;IAEJ,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAA6C;QACxF,MAAM,MAAM,GAAG,IAAI,CAAC;QACpB,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;QAE5C,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE;YACxB,OAAO,IAAI,iBAAU,CAAC,CAAC,UAAU,EAAE,EAAE;gBACnC,IAAI,aAAa,GAA4C,IAAI,CAAC;gBAClE,IAAI,kBAAkB,GAAwB,IAAI,CAAC;gBACnD,IAAI,SAAS,GAAG,KAAK,CAAC;gBACtB,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEzD,MAAM,GAAG,GAAG,IAAA,kCAAY,EAAC,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;gBAClE,MAAM,YAAY,GAAG,IAAA,kDAA4B,EAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBACjE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAE1D,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC;oBACvC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;wBACjB,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;4BACnC,IAAI,CAAC;gCACH,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;gCACxE,SAAS,CAAC,2BAA2B,EAAE,CAAC;gCACxC,aAAa,GAAG,SAAS,CAAC;4BAC5B,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;gCAC3D,IAAI,CAAC;oCACH,QAAQ,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gCAC7C,CAAC;gCAAC,OAAO,aAAa,EAAE,CAAC;oCACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,aAAa,EAAE,CAAC,CAAC;gCACvE,CAAC;gCACD,UAAU,CAAC,KAAK,CAAC,IAAI,2BAAkB,CAAC,yBAAyB,CAAC,CAAC,CAAC;gCACpE,OAAO;4BACT,CAAC;4BACD,SAAS,GAAG,IAAI,CAAC;4BAEjB,IAAI,CAAC,kBAAkB,EAAE,CAAC;gCACxB,kBAAkB,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC;oCAC7C,IAAI,EAAE,CAAC,KAAU,EAAE,EAAE;wCACnB,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa;4CAAE,OAAO;wCACzC,IAAI,CAAC;4CACH,MAAM,WAAW,GAAG,aAAa,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;4CACpE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wCAC/B,CAAC;wCAAC,OAAO,KAAK,EAAE,CAAC;4CACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,KAAK,EAAE,CAAC,CAAC;4CACnE,UAAU,CAAC,KAAK,CAAC,IAAI,2BAAkB,CAAC,4BAA4B,CAAC,CAAC,CAAC;wCACzE,CAAC;oCACH,CAAC;oCACD,KAAK,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;oCAC1C,QAAQ,EAAE,GAAG,EAAE;wCACb,aAAa,EAAE,2BAA2B,EAAE,CAAC;wCAC7C,UAAU,CAAC,QAAQ,EAAE,CAAC;oCACxB,CAAC;iCACF,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;6BAAM,CAAC;4BACN,SAAS,GAAG,KAAK,CAAC;4BAClB,IAAI,CAAC;gCACH,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;gCACnF,UAAU,CAAC,2BAA2B,EAAE,CAAC;4BAC3C,CAAC;4BAAC,MAAM,CAAC;gCACP,iBAAiB;4BACnB,CAAC;4BACD,IAAI,CAAC;gCACH,QAAQ,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;4BAC7C,CAAC;4BAAC,OAAO,aAAa,EAAE,CAAC;gCACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,aAAa,EAAE,CAAC,CAAC;4BACvE,CAAC;4BACD,UAAU,CAAC,KAAK,CAAC,IAAI,2BAAkB,CAAC,yBAAyB,CAAC,CAAC,CAAC;wBACtE,CAAC;oBACH,CAAC;oBACD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;iBACtC,CAAC,CAAC;gBAEH,OAAO,GAAG,EAAE;oBACV,aAAa,EAAE,yBAAyB,EAAE,CAAC;oBAC3C,WAAW,CAAC,WAAW,EAAE,CAAC;oBAC1B,kBAAkB,EAAE,WAAW,EAAE,CAAC;gBACpC,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;CAEF,CAAA;AA1FY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,mBAAM,EAAC,8CAA0B,CAAC;qCAKF,wBAAU;QACjB,uBAAU;QACI,2DAA4B;GANvD,uBAAuB,CA0FnC"}
@@ -0,0 +1,8 @@
1
+ import { SaplRequest } from './SubscriptionContext';
2
+ export interface MethodInvocationContext {
3
+ request: SaplRequest;
4
+ args: any[];
5
+ methodName: string;
6
+ className: string;
7
+ }
8
+ //# sourceMappingURL=MethodInvocationContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MethodInvocationContext.d.ts","sourceRoot":"","sources":["../lib/MethodInvocationContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MethodInvocationContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MethodInvocationContext.js","sourceRoot":"","sources":["../lib/MethodInvocationContext.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import { EnforceOptions } from './EnforceOptions';
2
+ export declare const POST_ENFORCE_SYMBOL: unique symbol;
3
+ /**
4
+ * Decorator that marks a method for SAPL post-enforcement.
5
+ *
6
+ * Works on any injectable class method (controllers, services, etc.) via
7
+ * AOP aspects. The actual authorization check is performed by
8
+ * PostEnforceAspect, which lets the method execute first, then builds an
9
+ * authorization subscription (including the method's return value), calls
10
+ * the PDP, and either returns the result or denies access.
11
+ *
12
+ * Important: The method executes before authorization is checked. Any side
13
+ * effects (database writes, emails, etc.) will occur regardless of the decision.
14
+ * Use @PreEnforce for methods with side effects that should not execute when
15
+ * access is denied.
16
+ *
17
+ * Example:
18
+ * @PostEnforce({ action: 'read', resource: 'patientRecord' })
19
+ * @Get('patient/:id')
20
+ * async getPatient(@Param('id') id: string) { ... }
21
+ */
22
+ export declare const PostEnforce: (options?: EnforceOptions) => MethodDecorator;
23
+ //# sourceMappingURL=PostEnforce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostEnforce.d.ts","sourceRoot":"","sources":["../lib/PostEnforce.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,mBAAmB,eAA8B,CAAC;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,WAAW,GAAI,UAAS,cAAmB,oBACT,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostEnforce = exports.POST_ENFORCE_SYMBOL = void 0;
4
+ const nestjs_aop_1 = require("@toss/nestjs-aop");
5
+ exports.POST_ENFORCE_SYMBOL = Symbol('sapl:post-enforce');
6
+ /**
7
+ * Decorator that marks a method for SAPL post-enforcement.
8
+ *
9
+ * Works on any injectable class method (controllers, services, etc.) via
10
+ * AOP aspects. The actual authorization check is performed by
11
+ * PostEnforceAspect, which lets the method execute first, then builds an
12
+ * authorization subscription (including the method's return value), calls
13
+ * the PDP, and either returns the result or denies access.
14
+ *
15
+ * Important: The method executes before authorization is checked. Any side
16
+ * effects (database writes, emails, etc.) will occur regardless of the decision.
17
+ * Use @PreEnforce for methods with side effects that should not execute when
18
+ * access is denied.
19
+ *
20
+ * Example:
21
+ * @PostEnforce({ action: 'read', resource: 'patientRecord' })
22
+ * @Get('patient/:id')
23
+ * async getPatient(@Param('id') id: string) { ... }
24
+ */
25
+ const PostEnforce = (options = {}) => (0, nestjs_aop_1.createDecorator)(exports.POST_ENFORCE_SYMBOL, options);
26
+ exports.PostEnforce = PostEnforce;
27
+ //# sourceMappingURL=PostEnforce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostEnforce.js","sourceRoot":"","sources":["../lib/PostEnforce.ts"],"names":[],"mappings":";;;AAAA,iDAAmD;AAGtC,QAAA,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AACI,MAAM,WAAW,GAAG,CAAC,UAA0B,EAAE,EAAE,EAAE,CAC1D,IAAA,4BAAe,EAAC,2BAAmB,EAAE,OAAO,CAAC,CAAC;AADnC,QAAA,WAAW,eACwB"}