@elsikora/nestjs-crud-automator 4.1.0 → 4.2.0-dev.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/README.md +10 -0
- package/dist/cjs/decorator/api/authorization/decision.decorator.d.ts +9 -0
- package/dist/cjs/decorator/api/authorization/decision.decorator.js +26 -0
- package/dist/cjs/decorator/api/authorization/decision.decorator.js.map +1 -0
- package/dist/cjs/decorator/api/index.d.ts +1 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interface/class/api/authorization/decision/interface.d.ts +2 -1
- package/dist/esm/decorator/api/authorization/decision.decorator.d.ts +9 -0
- package/dist/esm/decorator/api/authorization/decision.decorator.js +24 -0
- package/dist/esm/decorator/api/authorization/decision.decorator.js.map +1 -0
- package/dist/esm/decorator/api/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interface/class/api/authorization/decision/interface.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -976,6 +976,16 @@ Custom `@ApiMethod(...)` actions pass through unchanged after the namespace. For
|
|
|
976
976
|
|
|
977
977
|
The runtime resolves a `principal`, dispatches to the selected mode, and stores a unified `authorizationDecision` on the request. Hooks mode traces matched rules and resolved permissions; IAM mode traces attachments, documents, statements, boundaries, and final decision type. For out-of-band checks, inject `ApiAuthorizationSimulator` and call `evaluate(...)` with the same controller authorization metadata you use at runtime.
|
|
978
978
|
|
|
979
|
+
Custom handlers can inject that evaluated decision without accepting the raw request. The decorator returns the exact guard-attached object and fails closed with `403 Forbidden` when a securable route did not produce one:
|
|
980
|
+
|
|
981
|
+
```typescript
|
|
982
|
+
public async publish(
|
|
983
|
+
@ApiAuthorizationDecision<PostEntity>() authorizationDecision: IApiAuthorizationDecision<PostEntity>,
|
|
984
|
+
): Promise<PostEntity> {
|
|
985
|
+
return await this.service.publish(authorizationDecision.principal.id);
|
|
986
|
+
}
|
|
987
|
+
```
|
|
988
|
+
|
|
979
989
|
Important IAM details from the current implementation:
|
|
980
990
|
|
|
981
991
|
- `resource.id` and `resource.operatorId` are safe planner-friendly paths for `GET` and `GET_LIST` when declared in `resourceDefinition.fields`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IApiBaseEntity } from '../../../interface/api-base-entity.interface';
|
|
2
|
+
import { TApiAuthorizationRuleTransformPayload } from '../../../type/class/api/authorization/rule/transform-payload.type';
|
|
3
|
+
/**
|
|
4
|
+
* Injects the authorization decision attached to the current HTTP request by the Automator authorization guard.
|
|
5
|
+
* @template E - Authorized entity type.
|
|
6
|
+
* @template R - Authorized route result payload type.
|
|
7
|
+
* @returns {ParameterDecorator} Parameter decorator that fails closed when the request has no authorization decision.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ApiAuthorizationDecision<E extends IApiBaseEntity, R extends TApiAuthorizationRuleTransformPayload<E> = TApiAuthorizationRuleTransformPayload<E>>(): ParameterDecorator;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var common = require('@nestjs/common');
|
|
4
|
+
var resolveFromRequest_utility = require('../../../utility/authorization/decision/resolve-from-request.utility.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Injects the authorization decision attached to the current HTTP request by the Automator authorization guard.
|
|
8
|
+
* @template E - Authorized entity type.
|
|
9
|
+
* @template R - Authorized route result payload type.
|
|
10
|
+
* @returns {ParameterDecorator} Parameter decorator that fails closed when the request has no authorization decision.
|
|
11
|
+
*/
|
|
12
|
+
// Nest's ParameterDecorator cannot carry its factory output type, so these generics bind the factory contract used by each decorator application.
|
|
13
|
+
// eslint-disable-next-line @elsikora/typescript/no-unnecessary-type-parameters
|
|
14
|
+
function ApiAuthorizationDecision() {
|
|
15
|
+
return common.createParamDecorator((_data, context) => {
|
|
16
|
+
const request = context.switchToHttp().getRequest();
|
|
17
|
+
const decision = resolveFromRequest_utility.AuthorizationDecisionResolveFromRequest(request);
|
|
18
|
+
if (!decision) {
|
|
19
|
+
throw new common.ForbiddenException();
|
|
20
|
+
}
|
|
21
|
+
return decision;
|
|
22
|
+
})();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.ApiAuthorizationDecision = ApiAuthorizationDecision;
|
|
26
|
+
//# sourceMappingURL=decision.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision.decorator.js","sources":["../../../../../../src/decorator/api/authorization/decision.decorator.ts"],"sourcesContent":[null],"names":["createParamDecorator","AuthorizationDecisionResolveFromRequest","ForbiddenException"],"mappings":";;;;;AASA;;;;;AAKG;AACH;AACA;SACgB,wBAAwB,GAAA;AACvC,IAAA,OAAOA,2BAAoB,CAA6C,CAAC,KAAgB,EAAE,OAAyB,KAAqC;QACxJ,MAAM,OAAO,GAA8B,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAA6B;AACzG,QAAA,MAAM,QAAQ,GAAgDC,kEAAuC,CAAO,OAAO,CAAC;QAEpH,IAAI,CAAC,QAAQ,EAAE;YACd,MAAM,IAAIC,yBAAkB,EAAE;QAC/B;AAEA,QAAA,OAAO,QAAQ;IAChB,CAAC,CAAC,EAAE;AACL;;;;"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -78,6 +78,7 @@ require('./constant/utility/api/get-default-string-format-properties/customizer-
|
|
|
78
78
|
var constant = require('./constant/utility/dto/constant.js');
|
|
79
79
|
var generate_constant = require('./constant/utility/dto/generate.constant.js');
|
|
80
80
|
var authorizationPolicy_decorator = require('./decorator/api/authorization-policy.decorator.js');
|
|
81
|
+
var decision_decorator = require('./decorator/api/authorization/decision.decorator.js');
|
|
81
82
|
var decorator = require('./decorator/api/controller/decorator.js');
|
|
82
83
|
var observable_decorator = require('./decorator/api/controller/observable.decorator.js');
|
|
83
84
|
var securable_decorator = require('./decorator/api/controller/securable.decorator.js');
|
|
@@ -378,6 +379,7 @@ exports.GET_DEFAULT_STRING_FORMAT_PROPERTIES_API_UTILITY_CONSTANT = constant$1.G
|
|
|
378
379
|
exports.DTO_UTILITY_CONSTANT = constant.DTO_UTILITY_CONSTANT;
|
|
379
380
|
exports.DTO_GENERATE_CONSTANT = generate_constant.DTO_GENERATE_CONSTANT;
|
|
380
381
|
exports.ApiAuthorizationPolicy = authorizationPolicy_decorator.ApiAuthorizationPolicy;
|
|
382
|
+
exports.ApiAuthorizationDecision = decision_decorator.ApiAuthorizationDecision;
|
|
381
383
|
exports.ApiController = decorator.ApiController;
|
|
382
384
|
exports.ApiControllerObservable = observable_decorator.ApiControllerObservable;
|
|
383
385
|
exports.ApiControllerSecurable = securable_decorator.ApiControllerSecurable;
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -5,7 +5,8 @@ import { IApiAuthorizationPrincipal } from '../principal/interface';
|
|
|
5
5
|
import { IApiAuthorizationRule } from '../rule/interface';
|
|
6
6
|
import { IApiAuthorizationScope } from '../scope.interface';
|
|
7
7
|
import { TApiAuthorizationRuleResultTransform } from '../../../../../type/class/api/authorization/rule/result-transform.type';
|
|
8
|
-
|
|
8
|
+
import { TApiAuthorizationRuleTransformPayload } from '../../../../../type/class/api/authorization/rule/transform-payload.type';
|
|
9
|
+
export interface IApiAuthorizationDecision<E extends IApiBaseEntity, R = TApiAuthorizationRuleTransformPayload<E>> {
|
|
9
10
|
action: string;
|
|
10
11
|
appliedRules: Array<IApiAuthorizationRule<E, R>>;
|
|
11
12
|
effect: EApiPolicyEffect;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IApiBaseEntity } from '../../../interface/api-base-entity.interface';
|
|
2
|
+
import { TApiAuthorizationRuleTransformPayload } from '../../../type/class/api/authorization/rule/transform-payload.type';
|
|
3
|
+
/**
|
|
4
|
+
* Injects the authorization decision attached to the current HTTP request by the Automator authorization guard.
|
|
5
|
+
* @template E - Authorized entity type.
|
|
6
|
+
* @template R - Authorized route result payload type.
|
|
7
|
+
* @returns {ParameterDecorator} Parameter decorator that fails closed when the request has no authorization decision.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ApiAuthorizationDecision<E extends IApiBaseEntity, R extends TApiAuthorizationRuleTransformPayload<E> = TApiAuthorizationRuleTransformPayload<E>>(): ParameterDecorator;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createParamDecorator, ForbiddenException } from '@nestjs/common';
|
|
2
|
+
import { AuthorizationDecisionResolveFromRequest } from '../../../utility/authorization/decision/resolve-from-request.utility.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Injects the authorization decision attached to the current HTTP request by the Automator authorization guard.
|
|
6
|
+
* @template E - Authorized entity type.
|
|
7
|
+
* @template R - Authorized route result payload type.
|
|
8
|
+
* @returns {ParameterDecorator} Parameter decorator that fails closed when the request has no authorization decision.
|
|
9
|
+
*/
|
|
10
|
+
// Nest's ParameterDecorator cannot carry its factory output type, so these generics bind the factory contract used by each decorator application.
|
|
11
|
+
// eslint-disable-next-line @elsikora/typescript/no-unnecessary-type-parameters
|
|
12
|
+
function ApiAuthorizationDecision() {
|
|
13
|
+
return createParamDecorator((_data, context) => {
|
|
14
|
+
const request = context.switchToHttp().getRequest();
|
|
15
|
+
const decision = AuthorizationDecisionResolveFromRequest(request);
|
|
16
|
+
if (!decision) {
|
|
17
|
+
throw new ForbiddenException();
|
|
18
|
+
}
|
|
19
|
+
return decision;
|
|
20
|
+
})();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { ApiAuthorizationDecision };
|
|
24
|
+
//# sourceMappingURL=decision.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision.decorator.js","sources":["../../../../../../src/decorator/api/authorization/decision.decorator.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AASA;;;;;AAKG;AACH;AACA;SACgB,wBAAwB,GAAA;AACvC,IAAA,OAAO,oBAAoB,CAA6C,CAAC,KAAgB,EAAE,OAAyB,KAAqC;QACxJ,MAAM,OAAO,GAA8B,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAA6B;AACzG,QAAA,MAAM,QAAQ,GAAgD,uCAAuC,CAAO,OAAO,CAAC;QAEpH,IAAI,CAAC,QAAQ,EAAE;YACd,MAAM,IAAI,kBAAkB,EAAE;QAC/B;AAEA,QAAA,OAAO,QAAQ;IAChB,CAAC,CAAC,EAAE;AACL;;;;"}
|
package/dist/esm/index.js
CHANGED
|
@@ -76,6 +76,7 @@ import './constant/utility/api/get-default-string-format-properties/customizer-m
|
|
|
76
76
|
export { DTO_UTILITY_CONSTANT } from './constant/utility/dto/constant.js';
|
|
77
77
|
export { DTO_GENERATE_CONSTANT } from './constant/utility/dto/generate.constant.js';
|
|
78
78
|
export { ApiAuthorizationPolicy } from './decorator/api/authorization-policy.decorator.js';
|
|
79
|
+
export { ApiAuthorizationDecision } from './decorator/api/authorization/decision.decorator.js';
|
|
79
80
|
export { ApiController } from './decorator/api/controller/decorator.js';
|
|
80
81
|
export { ApiControllerObservable } from './decorator/api/controller/observable.decorator.js';
|
|
81
82
|
export { ApiControllerSecurable } from './decorator/api/controller/securable.decorator.js';
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -5,7 +5,8 @@ import { IApiAuthorizationPrincipal } from '../principal/interface';
|
|
|
5
5
|
import { IApiAuthorizationRule } from '../rule/interface';
|
|
6
6
|
import { IApiAuthorizationScope } from '../scope.interface';
|
|
7
7
|
import { TApiAuthorizationRuleResultTransform } from '../../../../../type/class/api/authorization/rule/result-transform.type';
|
|
8
|
-
|
|
8
|
+
import { TApiAuthorizationRuleTransformPayload } from '../../../../../type/class/api/authorization/rule/transform-payload.type';
|
|
9
|
+
export interface IApiAuthorizationDecision<E extends IApiBaseEntity, R = TApiAuthorizationRuleTransformPayload<E>> {
|
|
9
10
|
action: string;
|
|
10
11
|
appliedRules: Array<IApiAuthorizationRule<E, R>>;
|
|
11
12
|
effect: EApiPolicyEffect;
|