@apipass/cerbos-pep 0.0.69 → 0.0.71

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 ADDED
@@ -0,0 +1,123 @@
1
+ # @apipass/cerbos-pep
2
+
3
+ [English](#english) | [Português](#português)
4
+
5
+ ---
6
+
7
+ ## English
8
+
9
+ ### Description
10
+ `@apipass/cerbos-pep` is a NestJS utility designed to simplify integration with [Cerbos](https://cerbos.dev/), an open-source authorization layer. This package provides a PEP (Policy Enforcement Point) through a NestJS Interceptor that automatically validates permissions against a Cerbos PDP (Policy Decision Point).
11
+
12
+ ### How it works
13
+ The interceptor intercepts incoming HTTP requests, extracts principal information (role and account id) from the request headers (`role` and `account_id`), and checks if the principal is allowed to perform specific actions on a resource defined via the `@CerbosPermission` decorator.
14
+
15
+ ### Usage Example
16
+
17
+ #### 1. Import CerbosModule
18
+ Register the `CerbosModule` in your `AppModule`:
19
+
20
+ ```typescript
21
+ import { CerbosModule } from '@apipass/cerbos-pep';
22
+
23
+ @Module({
24
+ imports: [
25
+ CerbosModule.register({
26
+ url: process.env.CERBOS_PDP_URL ?? 'http://127.0.0.1:3592', // Cerbos PDP URL
27
+ }),
28
+ ],
29
+ })
30
+ export class AppModule {}
31
+ ```
32
+
33
+ #### 2. Apply the Interceptor
34
+ You can apply the `CerbosInterceptor` globally, at the controller level, or per-route:
35
+
36
+ ```typescript
37
+ import { CerbosInterceptor } from '@apipass/cerbos-pep';
38
+ import { UseInterceptors } from '@nestjs/common';
39
+
40
+ @UseInterceptors(CerbosInterceptor)
41
+ @Controller('orders')
42
+ export class OrdersController {}
43
+ ```
44
+
45
+ #### 3. Define Permissions
46
+ Use the `@CerbosPermission` decorator to protect your routes:
47
+
48
+ ```typescript
49
+ import { CerbosPermission } from '@apipass/cerbos-pep';
50
+
51
+ @Get(':id')
52
+ @CerbosPermission({
53
+ resource: {
54
+ kind: 'order',
55
+ },
56
+ actions: ['read'],
57
+ })
58
+ async getOrder(@Param('id') id: string) {
59
+ return this.ordersService.findOne(id);
60
+ }
61
+ ```
62
+
63
+ **Note:** The interceptor expects `role` and `account_id` headers to be present in the request.
64
+
65
+ ---
66
+
67
+ ## Português
68
+
69
+ ### Descrição
70
+ O `@apipass/cerbos-pep` é um utilitário para NestJS projetado para simplificar a integração com o [Cerbos](https://cerbos.dev/), uma camada de autorização de código aberto. Este pacote fornece um PEP (Policy Enforcement Point) por meio de um Interceptor do NestJS que valida automaticamente as permissões em um Cerbos PDP (Policy Decision Point).
71
+
72
+ ### Como funciona
73
+ O interceptor intercepta as requisições HTTP, extrai as informações do principal (role e id da conta) dos cabeçalhos da requisição (`role` e `account_id`) e verifica se o principal tem permissão para realizar ações específicas em um recurso definido através do decorador `@CerbosPermission`.
74
+
75
+ ### Exemplo de Utilização
76
+
77
+ #### 1. Importar o CerbosModule
78
+ Registre o `CerbosModule` no seu `AppModule`:
79
+
80
+ ```typescript
81
+ import { CerbosModule } from '@apipass/cerbos-pep';
82
+
83
+ @Module({
84
+ imports: [
85
+ CerbosModule.register({
86
+ url: 'http://localhost:3592', // URL do Cerbos PDP
87
+ }),
88
+ ],
89
+ })
90
+ export class AppModule {}
91
+ ```
92
+
93
+ #### 2. Aplicar o Interceptor
94
+ Você pode aplicar o `CerbosInterceptor` globalmente, no nível do controller ou por rota:
95
+
96
+ ```typescript
97
+ import { CerbosInterceptor } from '@apipass/cerbos-pep';
98
+ import { UseInterceptors } from '@nestjs/common';
99
+
100
+ @UseInterceptors(CerbosInterceptor)
101
+ @Controller('orders')
102
+ export class OrdersController {}
103
+ ```
104
+
105
+ #### 3. Definir Permissões
106
+ Use o decorador `@CerbosPermission` para proteger suas rotas:
107
+
108
+ ```typescript
109
+ import { CerbosPermission } from '@apipass/cerbos-pep';
110
+
111
+ @Get(':id')
112
+ @CerbosPermission({
113
+ resource: {
114
+ kind: 'order',
115
+ },
116
+ actions: ['read'],
117
+ })
118
+ async getOrder(@Param('id') id: string) {
119
+ return this.ordersService.findOne(id);
120
+ }
121
+ ```
122
+
123
+ **Nota:** O interceptor espera que os headers `role` e `account_id` estejam presentes na requisição.
@@ -0,0 +1,8 @@
1
+ import { AuthorizationPort } from '../ports/authorization.port';
2
+ import { GetQueryPlanParams } from '../get-query-plan';
3
+ import { CerbosService } from "../cerbos.service";
4
+ export declare class CerbosAuthorizationAdapter implements AuthorizationPort {
5
+ private readonly cerbosService;
6
+ constructor(cerbosService: CerbosService);
7
+ getQueryPlan(params: GetQueryPlanParams): Promise<any>;
8
+ }
@@ -0,0 +1,28 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CerbosAuthorizationAdapter = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const cerbos_service_1 = require("../cerbos.service");
15
+ let CerbosAuthorizationAdapter = class CerbosAuthorizationAdapter {
16
+ constructor(cerbosService) {
17
+ this.cerbosService = cerbosService;
18
+ }
19
+ async getQueryPlan(params) {
20
+ return this.cerbosService.getQueryPlan(params);
21
+ }
22
+ };
23
+ exports.CerbosAuthorizationAdapter = CerbosAuthorizationAdapter;
24
+ exports.CerbosAuthorizationAdapter = CerbosAuthorizationAdapter = __decorate([
25
+ (0, common_1.Injectable)(),
26
+ __metadata("design:paramtypes", [cerbos_service_1.CerbosService])
27
+ ], CerbosAuthorizationAdapter);
28
+ //# sourceMappingURL=cerbos-authorization.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cerbos-authorization.adapter.js","sourceRoot":"","sources":["../../src/adapters/cerbos-authorization.adapter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA2C;AAG3C,sDAAkD;AAG3C,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IACnC,YACqB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAC9C,CAAC;IAEJ,KAAK,CAAC,YAAY,CAAC,MAA0B;QACzC,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;IAClD,CAAC;CACJ,CAAA;AARY,gEAA0B;qCAA1B,0BAA0B;IADtC,IAAA,mBAAU,GAAE;qCAG2B,8BAAa;GAFxC,0BAA0B,CAQtC"}
@@ -0,0 +1,7 @@
1
+ export interface AuthorizationContext {
2
+ role: string;
3
+ accountId: string;
4
+ }
5
+ export declare class HttpAuthorizationContextExtractor {
6
+ extract(req: any): AuthorizationContext;
7
+ }
@@ -0,0 +1,25 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.HttpAuthorizationContextExtractor = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ let HttpAuthorizationContextExtractor = class HttpAuthorizationContextExtractor {
12
+ extract(req) {
13
+ const role = req.headers.role?.toLowerCase();
14
+ const accountId = req.headers.account_id;
15
+ if (!role || !accountId) {
16
+ throw new common_1.ForbiddenException('Missing authorization headers');
17
+ }
18
+ return { role, accountId };
19
+ }
20
+ };
21
+ exports.HttpAuthorizationContextExtractor = HttpAuthorizationContextExtractor;
22
+ exports.HttpAuthorizationContextExtractor = HttpAuthorizationContextExtractor = __decorate([
23
+ (0, common_1.Injectable)()
24
+ ], HttpAuthorizationContextExtractor);
25
+ //# sourceMappingURL=authorizatio-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorizatio-context.js","sourceRoot":"","sources":["../src/authorizatio-context.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA8D;AAQvD,IAAM,iCAAiC,GAAvC,MAAM,iCAAiC;IAC1C,OAAO,CAAC,GAAQ;QACZ,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,CAAA;QAC5C,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAA;QAExC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,2BAAkB,CAAC,+BAA+B,CAAC,CAAA;QACjE,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC9B,CAAC;CACJ,CAAA;AAXY,8EAAiC;4CAAjC,iCAAiC;IAD7C,IAAA,mBAAU,GAAE;GACA,iCAAiC,CAW7C"}
@@ -0,0 +1,19 @@
1
+ import { AuthorizationContext } from "./authorizatio-context";
2
+ import { CerbosPermission } from "./cerbos.decorator";
3
+ export declare class CerbosRequestFactory {
4
+ static fromHttp(permission: CerbosPermission, ctx: AuthorizationContext, handlerName: string): {
5
+ principal: {
6
+ id: string;
7
+ roles: string[];
8
+ attributes: {
9
+ accountId: string;
10
+ };
11
+ };
12
+ resource: {
13
+ kind: string;
14
+ id: string;
15
+ attributes: {};
16
+ };
17
+ actions: string[];
18
+ };
19
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CerbosRequestFactory = void 0;
4
+ class CerbosRequestFactory {
5
+ static fromHttp(permission, ctx, handlerName) {
6
+ return {
7
+ principal: {
8
+ id: ctx.role,
9
+ roles: [ctx.role],
10
+ attributes: { accountId: ctx.accountId }
11
+ },
12
+ resource: {
13
+ kind: permission.resource.kind,
14
+ id: permission.resource.id ?? handlerName,
15
+ attributes: {}
16
+ },
17
+ actions: permission.actions
18
+ };
19
+ }
20
+ }
21
+ exports.CerbosRequestFactory = CerbosRequestFactory;
22
+ //# sourceMappingURL=cerbos-request-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cerbos-request-factory.js","sourceRoot":"","sources":["../src/cerbos-request-factory.ts"],"names":[],"mappings":";;;AAGA,MAAa,oBAAoB;IAC7B,MAAM,CAAC,QAAQ,CAAC,UAA4B,EAAE,GAAyB,EAAE,WAAmB;QACxF,OAAO;YACH,SAAS,EAAE;gBACP,EAAE,EAAE,GAAG,CAAC,IAAI;gBACZ,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;gBACjB,UAAU,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE;aAC3C;YACD,QAAQ,EAAE;gBACN,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,IAAI;gBAC9B,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAI,WAAW;gBACzC,UAAU,EAAE,EAAE;aACjB;YACD,OAAO,EAAE,UAAU,CAAC,OAAO;SAC9B,CAAA;IACL,CAAC;CACJ;AAhBD,oDAgBC"}
@@ -1,5 +1,11 @@
1
1
  export declare const CERBOS_METADATA_KEY = "cerbos:permission";
2
+ export declare const CerbosMode: {
3
+ readonly CHECK: "CHECK";
4
+ readonly QUERY_PLAN: "QUERY_PLAN";
5
+ };
6
+ export type CerbosMode = typeof CerbosMode[keyof typeof CerbosMode];
2
7
  export interface CerbosPermission {
8
+ mode?: CerbosMode;
3
9
  resource: {
4
10
  kind: string;
5
11
  id?: string;
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CerbosPermission = exports.CERBOS_METADATA_KEY = void 0;
3
+ exports.CerbosPermission = exports.CerbosMode = exports.CERBOS_METADATA_KEY = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
5
  exports.CERBOS_METADATA_KEY = 'cerbos:permission';
6
+ exports.CerbosMode = {
7
+ CHECK: 'CHECK',
8
+ QUERY_PLAN: 'QUERY_PLAN',
9
+ };
6
10
  const CerbosPermission = (permission) => (0, common_1.SetMetadata)(exports.CERBOS_METADATA_KEY, permission);
7
11
  exports.CerbosPermission = CerbosPermission;
8
12
  //# sourceMappingURL=cerbos.decorator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cerbos.decorator.js","sourceRoot":"","sources":["../src/cerbos.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA4C;AAE/B,QAAA,mBAAmB,GAAG,mBAAmB,CAAA;AAU/C,MAAM,gBAAgB,GAAG,CAAC,UAA4B,EAAE,EAAE,CAC/D,IAAA,oBAAW,EAAC,2BAAmB,EAAE,UAAU,CAAC,CAAA;AADjC,QAAA,gBAAgB,oBACiB"}
1
+ {"version":3,"file":"cerbos.decorator.js","sourceRoot":"","sources":["../src/cerbos.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA4C;AAE/B,QAAA,mBAAmB,GAAG,mBAAmB,CAAA;AACzC,QAAA,UAAU,GAAG;IACxB,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,YAAY;CAChB,CAAA;AAYH,MAAM,gBAAgB,GAAG,CAAC,UAA4B,EAAE,EAAE,CAC/D,IAAA,oBAAW,EAAC,2BAAmB,EAAE,UAAU,CAAC,CAAA;AADjC,QAAA,gBAAgB,oBACiB"}
@@ -1,12 +1,11 @@
1
1
  import { type NestInterceptor, type ExecutionContext, type CallHandler } from '@nestjs/common';
2
2
  import { Reflector } from '@nestjs/core';
3
- import { type Observable } from 'rxjs';
4
- import type { CerbosModuleOptions } from './cerbos.module';
3
+ import { CerbosService } from './cerbos.service';
4
+ import { HttpAuthorizationContextExtractor } from "./authorizatio-context";
5
5
  export declare class CerbosInterceptor implements NestInterceptor {
6
6
  private readonly reflector;
7
- private readonly config;
8
- private cerbosInstance;
9
- constructor(reflector: Reflector, config: CerbosModuleOptions);
10
- private getCerbos;
11
- intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>>;
7
+ private readonly cerbosService;
8
+ private readonly extractor;
9
+ constructor(reflector: Reflector, cerbosService: CerbosService, extractor: HttpAuthorizationContextExtractor);
10
+ intercept(context: ExecutionContext, next: CallHandler): Promise<import("rxjs").Observable<any>>;
12
11
  }
@@ -8,65 +8,40 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
- var __param = (this && this.__param) || function (paramIndex, decorator) {
12
- return function (target, key) { decorator(target, key, paramIndex); }
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.CerbosInterceptor = void 0;
16
13
  const common_1 = require("@nestjs/common");
17
14
  const core_1 = require("@nestjs/core");
18
15
  const cerbos_decorator_1 = require("./cerbos.decorator");
16
+ const cerbos_service_1 = require("./cerbos.service");
17
+ const cerbos_request_factory_1 = require("./cerbos-request-factory");
18
+ const authorizatio_context_1 = require("./authorizatio-context");
19
19
  let CerbosInterceptor = class CerbosInterceptor {
20
- constructor(reflector, config) {
20
+ constructor(reflector, cerbosService, extractor) {
21
21
  this.reflector = reflector;
22
- this.config = config;
23
- this.cerbosInstance = null;
24
- }
25
- async getCerbos() {
26
- if (!this.cerbosInstance) {
27
- const { HTTP: Cerbos } = (await import('@cerbos/http'));
28
- this.cerbosInstance = new Cerbos(this.config.url);
29
- }
30
- return this.cerbosInstance;
22
+ this.cerbosService = cerbosService;
23
+ this.extractor = extractor;
31
24
  }
32
25
  async intercept(context, next) {
33
26
  const permission = this.reflector.getAllAndOverride(cerbos_decorator_1.CERBOS_METADATA_KEY, [context.getHandler(), context.getClass()]);
34
27
  if (!permission) {
35
28
  return next.handle();
36
29
  }
37
- const ctx = context.switchToHttp();
38
- const request = ctx.getRequest();
39
- const role = request.headers.role?.toLowerCase();
40
- const accountId = request.headers.account_id;
41
- if (!role || !accountId) {
42
- throw new common_1.ForbiddenException('Missing authorization headers');
30
+ if (permission.mode === cerbos_decorator_1.CerbosMode.QUERY_PLAN) {
31
+ return next.handle();
43
32
  }
44
- const cerbosRequest = {
45
- principal: {
46
- id: role,
47
- roles: [role],
48
- attributes: { accountId }
49
- },
50
- resource: {
51
- kind: permission.resource.kind,
52
- id: permission.resource.id ?? context.getHandler().name,
53
- attributes: {}
54
- },
55
- actions: permission.actions
56
- };
33
+ const request = context.switchToHttp().getRequest();
34
+ const authContext = this.extractor.extract(request);
35
+ const cerbosRequest = cerbos_request_factory_1.CerbosRequestFactory.fromHttp(permission, authContext, context.getHandler().name);
57
36
  try {
58
- const cerbos = await this.getCerbos();
59
- const result = await cerbos.checkResource(cerbosRequest);
37
+ const result = await this.cerbosService.getCheckResource(cerbosRequest);
60
38
  const allowed = permission.actions.every((action) => result.isAllowed(action));
61
- console.log('cerbos result: ', allowed);
62
39
  if (!allowed) {
63
40
  throw new common_1.ForbiddenException('Access denied by Cerbos');
64
41
  }
65
42
  }
66
43
  catch (error) {
67
- if (error instanceof common_1.ForbiddenException)
68
- throw error;
69
- throw new common_1.ForbiddenException('Error checking permissions');
44
+ throw new common_1.ForbiddenException(`Error - ${error}`);
70
45
  }
71
46
  return next.handle();
72
47
  }
@@ -74,7 +49,8 @@ let CerbosInterceptor = class CerbosInterceptor {
74
49
  exports.CerbosInterceptor = CerbosInterceptor;
75
50
  exports.CerbosInterceptor = CerbosInterceptor = __decorate([
76
51
  (0, common_1.Injectable)(),
77
- __param(1, (0, common_1.Inject)('CERBOS_PDP_URL')),
78
- __metadata("design:paramtypes", [core_1.Reflector, Object])
52
+ __metadata("design:paramtypes", [core_1.Reflector,
53
+ cerbos_service_1.CerbosService,
54
+ authorizatio_context_1.HttpAuthorizationContextExtractor])
79
55
  ], CerbosInterceptor);
80
56
  //# sourceMappingURL=cerbos.interceptor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cerbos.interceptor.js","sourceRoot":"","sources":["../src/cerbos.interceptor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cerbos.interceptor.js","sourceRoot":"","sources":["../src/cerbos.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMuB;AACvB,uCAAwC;AACxC,yDAAyF;AACzF,qDAAgD;AAChD,qEAA8D;AAC9D,iEAAyE;AAKlE,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAC5B,YACqB,SAAoB,EACpB,aAA4B,EAC5B,SAA4C;QAF5C,cAAS,GAAT,SAAS,CAAW;QACpB,kBAAa,GAAb,aAAa,CAAe;QAC5B,cAAS,GAAT,SAAS,CAAmC;IAC9D,CAAC;IAEJ,KAAK,CAAC,SAAS,CAAC,OAAyB,EAAE,IAAiB;QAC1D,MAAM,UAAU,GAAqB,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACjE,sCAAmB,EACnB,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC7C,CAAA;QAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAA;QACtB,CAAC;QAED,IAAI,UAAU,CAAC,IAAI,KAAK,6BAAU,CAAC,UAAU,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,MAAM,EAAE,CAAA;QACtB,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAA;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAEnD,MAAM,aAAa,GAAG,6CAAoB,CAAC,QAAQ,CAC/C,UAAU,EACV,WAAW,EACX,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,CAC5B,CAAA;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAyB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAA;YAC7F,MAAM,OAAO,GAAY,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CACzD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAC3B,CAAA;YACD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,2BAAkB,CAAC,yBAAyB,CAAC,CAAA;YACzD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,2BAAkB,CAAC,WAAW,KAAK,EAAE,CAAC,CAAA;QAClD,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAA;IACtB,CAAC;CAEF,CAAA;AA5CY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;qCAGqB,gBAAS;QACL,8BAAa;QACjB,wDAAiC;GAJtD,iBAAiB,CA4C7B"}
@@ -10,6 +10,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.CerbosModule = void 0;
11
11
  const common_1 = require("@nestjs/common");
12
12
  const cerbos_interceptor_1 = require("./cerbos.interceptor");
13
+ const cerbos_service_1 = require("./cerbos.service");
14
+ const cerbos_authorization_adapter_1 = require("./adapters/cerbos-authorization.adapter");
15
+ const authorization_port_1 = require("./ports/authorization.port");
13
16
  let CerbosModule = CerbosModule_1 = class CerbosModule {
14
17
  static register(options) {
15
18
  return {
@@ -19,9 +22,18 @@ let CerbosModule = CerbosModule_1 = class CerbosModule {
19
22
  provide: 'CERBOS_PDP_URL',
20
23
  useValue: options,
21
24
  },
25
+ cerbos_service_1.CerbosService,
22
26
  cerbos_interceptor_1.CerbosInterceptor,
27
+ {
28
+ provide: authorization_port_1.AUTHORIZATION_PORT,
29
+ useClass: cerbos_authorization_adapter_1.CerbosAuthorizationAdapter,
30
+ }
23
31
  ],
24
- exports: [cerbos_interceptor_1.CerbosInterceptor, 'CERBOS_PDP_URL'],
32
+ exports: [cerbos_service_1.CerbosService,
33
+ cerbos_interceptor_1.CerbosInterceptor,
34
+ 'CERBOS_PDP_URL',
35
+ authorization_port_1.AUTHORIZATION_PORT,
36
+ cerbos_interceptor_1.CerbosInterceptor],
25
37
  };
26
38
  }
27
39
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cerbos.module.js","sourceRoot":"","sources":["../src/cerbos.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAC/D,6DAAyD;AAQlD,IAAM,YAAY,oBAAlB,MAAM,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,OAA4B;QAC1C,OAAO;YACL,MAAM,EAAE,cAAY;YACpB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,gBAAgB;oBACzB,QAAQ,EAAE,OAAO;iBAClB;gBACD,sCAAiB;aAClB;YACD,OAAO,EAAE,CAAC,sCAAiB,EAAE,gBAAgB,CAAC;SAC/C,CAAC;IACJ,CAAC;CACF,CAAA;AAdY,oCAAY;uBAAZ,YAAY;IAFxB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,YAAY,CAcxB"}
1
+ {"version":3,"file":"cerbos.module.js","sourceRoot":"","sources":["../src/cerbos.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAC/D,6DAAyD;AACzD,qDAAiD;AACjD,0FAAqF;AACrF,mEAAgE;AAQzD,IAAM,YAAY,oBAAlB,MAAM,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,OAA4B;QAC1C,OAAO;YACL,MAAM,EAAE,cAAY;YACpB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,gBAAgB;oBACzB,QAAQ,EAAE,OAAO;iBAClB;gBACD,8BAAa;gBACb,sCAAiB;gBACjB;oBACE,OAAO,EAAE,uCAAkB;oBAC3B,QAAQ,EAAE,yDAA0B;iBACrC;aACF;YACD,OAAO,EAAE,CAAC,8BAAa;gBACrB,sCAAiB;gBACjB,gBAAgB;gBAChB,uCAAkB;gBAClB,sCAAiB,CAAC;SACrB,CAAC;IACJ,CAAC;CACF,CAAA;AAvBY,oCAAY;uBAAZ,YAAY;IAFxB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,YAAY,CAuBxB"}
@@ -0,0 +1,11 @@
1
+ import type { CerbosModuleOptions } from './cerbos.module';
2
+ import type { CheckResourceRequest, CheckResourcesResult } from '@cerbos/core' with { 'resolution-mode': 'import' };
3
+ import { GetQueryPlanParams } from "./get-query-plan";
4
+ export declare class CerbosService {
5
+ private readonly config;
6
+ private cerbos;
7
+ constructor(config: CerbosModuleOptions);
8
+ private getCerbos;
9
+ getCheckResource(request: CheckResourceRequest): Promise<CheckResourcesResult>;
10
+ getQueryPlan(params: GetQueryPlanParams): Promise<any>;
11
+ }
@@ -0,0 +1,54 @@
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 __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CerbosService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ let CerbosService = class CerbosService {
18
+ constructor(config) {
19
+ this.config = config;
20
+ }
21
+ async getCerbos() {
22
+ if (!this.cerbos) {
23
+ const { HTTP: Cerbos } = (await import('@cerbos/http'));
24
+ this.cerbos = new Cerbos(this.config.url);
25
+ }
26
+ return this.cerbos;
27
+ }
28
+ async getCheckResource(request) {
29
+ const cerbos = await this.getCerbos();
30
+ return cerbos.checkResource(request);
31
+ }
32
+ async getQueryPlan(params) {
33
+ const cerbos = await this.getCerbos();
34
+ const { principal, resourceKind, action } = params;
35
+ return cerbos.planResources({
36
+ principal: {
37
+ id: principal.id,
38
+ roles: principal.roles,
39
+ attributes: principal.attributes
40
+ },
41
+ resource: {
42
+ kind: resourceKind
43
+ },
44
+ action
45
+ });
46
+ }
47
+ };
48
+ exports.CerbosService = CerbosService;
49
+ exports.CerbosService = CerbosService = __decorate([
50
+ (0, common_1.Injectable)(),
51
+ __param(0, (0, common_1.Inject)('CERBOS_PDP_URL')),
52
+ __metadata("design:paramtypes", [Object])
53
+ ], CerbosService);
54
+ //# sourceMappingURL=cerbos.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cerbos.service.js","sourceRoot":"","sources":["../src/cerbos.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAoD;AAQ7C,IAAM,aAAa,GAAnB,MAAM,aAAa;IAGxB,YAAuD,MAA2B;QAA3B,WAAM,GAAN,MAAM,CAAqB;IAC/E,CAAC;IAEI,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,CAAgC,CAAC;YACvF,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,OAA6B;QAClD,MAAM,MAAM,GAAS,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK,CAAC,YAAY,CAAE,MAA0B;QACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;QAErC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;QAElD,OAAO,MAAM,CAAC,aAAa,CAAC;YAC1B,SAAS,EAAE;gBACT,EAAE,EAAE,SAAS,CAAC,EAAE;gBAChB,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,UAAU,EAAE,SAAS,CAAC,UAAU;aACjC;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,YAAY;aACnB;YACD,MAAM;SACP,CAAC,CAAA;IACJ,CAAC;CAEF,CAAA;AArCY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;IAIE,WAAA,IAAA,eAAM,EAAC,gBAAgB,CAAC,CAAA;;GAH1B,aAAa,CAqCzB"}
@@ -0,0 +1,10 @@
1
+ export interface Principal {
2
+ id: string;
3
+ roles: string[];
4
+ attributes: Record<string, any>;
5
+ }
6
+ export interface GetQueryPlanParams {
7
+ principal: Principal;
8
+ resourceKind: string;
9
+ action: string;
10
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=get-query-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-query-plan.js","sourceRoot":"","sources":["../src/get-query-plan.ts"],"names":[],"mappings":""}
package/lib/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './cerbos.decorator';
2
2
  export * from './cerbos.interceptor';
3
3
  export * from './cerbos.module';
4
+ export * from './ports/authorization.port';
package/lib/index.js CHANGED
@@ -17,4 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./cerbos.decorator"), exports);
18
18
  __exportStar(require("./cerbos.interceptor"), exports);
19
19
  __exportStar(require("./cerbos.module"), exports);
20
+ __exportStar(require("./ports/authorization.port"), exports);
20
21
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAkC;AAClC,uDAAoC;AACpC,kDAA+B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAkC;AAClC,uDAAoC;AACpC,kDAA+B;AAC/B,6DAA0C"}
@@ -0,0 +1,13 @@
1
+ export declare const AUTHORIZATION_PORT: unique symbol;
2
+ export interface AuthorizationPort {
3
+ getQueryPlan(params: GetQueryPlanParams): Promise<unknown>;
4
+ }
5
+ export interface GetQueryPlanParams {
6
+ principal: {
7
+ id: string;
8
+ roles: string[];
9
+ attributes: Record<string, any>;
10
+ };
11
+ resourceKind: string;
12
+ action: string;
13
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AUTHORIZATION_PORT = void 0;
4
+ exports.AUTHORIZATION_PORT = Symbol('AuthorizationPort');
5
+ //# sourceMappingURL=authorization.port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization.port.js","sourceRoot":"","sources":["../../src/ports/authorization.port.ts"],"names":[],"mappings":";;;AAAa,QAAA,kBAAkB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@apipass/cerbos-pep",
3
- "version": "0.0.69",
3
+ "version": "0.0.71",
4
4
  "description": "Cerbos PEP utility for NestJS",
5
- "author": "Junie",
5
+ "author": "raul@apipass.com.br",
6
6
  "license": "ISC",
7
7
  "main": "lib/index.js",
8
8
  "typings": "lib/index.d.ts",
@@ -28,5 +28,5 @@
28
28
  "@nestjs/common": "10.4.15",
29
29
  "@nestjs/core": "10.4.15"
30
30
  },
31
- "gitHead": "6f891b90de3603538170f842c4909b5b677f14e2"
31
+ "gitHead": "cbcf6439e0d49368a46d698ef3384af079df587f"
32
32
  }