@dudousxd/nestjs-authz-inertia 0.1.3 → 0.2.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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @dudousxd/nestjs-authz-inertia
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#67](https://github.com/DavideCarvalho/nestjs-authz/pull/67) [`32e967f`](https://github.com/DavideCarvalho/nestjs-authz/commit/32e967ffbcd68a97e8effc77af9c16bbbafdc918) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Share the class-level abilities of every official `@Policy()` (linked with `@PolicyFor` or not,
8
+ keyed `<resource>.<method>`), checked through the official `AuthorizationService` for the user
9
+ the official guard reads. `resolveClassAbilities` / `createAuthzShare` take a `PolicyIndex`
10
+ (was `PolicyRegistry`) and accept `gate.forUser(user)`. The denial filter also redirects the
11
+ official guard's 401 to `loginUrl`; without nestjs-context a 403 now goes to `forbiddenUrl`.
12
+ Requires `@dudousxd/nestjs-authz` 0.9, NestJS 12 and Node 22+.
13
+
14
+ **Removed:** the `@dudousxd/nestjs-authz-inertia/client` subpath, which only re-exported the
15
+ client package. Import `AbilityStore`, `createCan`, `hydrateFromInertiaProps` and
16
+ `hydrateResource` from `@dudousxd/nestjs-authz-client` directly.
17
+
18
+ ### Patch Changes
19
+
20
+ - [#67](https://github.com/DavideCarvalho/nestjs-authz/pull/67) [`32e967f`](https://github.com/DavideCarvalho/nestjs-authz/commit/32e967ffbcd68a97e8effc77af9c16bbbafdc918) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Fix packages that could be published without files their `exports` point to. `tsc` builds no longer use a `.tsbuildinfo` that can outlive `dist/` and skip emitting files. A new `check:exports` step (also `prepack`) fails the release if any `exports`/`main`/`types` path is missing.
21
+
22
+ - Updated dependencies [[`32e967f`](https://github.com/DavideCarvalho/nestjs-authz/commit/32e967ffbcd68a97e8effc77af9c16bbbafdc918)]:
23
+ - @dudousxd/nestjs-authz-client@0.2.2
24
+
3
25
  ## 0.1.3
4
26
 
5
27
  ### Patch Changes
package/README.md CHANGED
@@ -17,8 +17,10 @@ Authorization decisions reach the front end through three tiers. Prefer the earl
17
17
 
18
18
  ### Tier 1 — Shared props (no request)
19
19
 
20
- Every Inertia render carries the current user's **class-level abilities** (all ad-hoc
21
- gates + class-level `@Policy` methods like `create`/`viewAny`) under `props.auth.can`:
20
+ Every Inertia render carries the user's **class-level abilities** (all ad-hoc gates + the
21
+ abilities of every official `@Policy()` that take no record, like `create`/`viewAny`) under
22
+ `props.auth.can`. The user is the one the official guard reads (`getUser`, default
23
+ `request.user`), and each check runs through the official `AuthorizationService`:
22
24
 
23
25
  ```jsonc
24
26
  { "auth": { "can": { "post.create": true, "access-admin": false } } }
@@ -32,7 +34,8 @@ interceptor shares the map on every Inertia request:
32
34
  ```ts
33
35
  @Module({
34
36
  imports: [
35
- AuthzModule.forRoot({ policies: [PostPolicy] }),
37
+ AuthorizationModule.forRoot(),
38
+ AuthzModule.forRoot(),
36
39
  InertiaModule.forRoot({ /* ... */ }),
37
40
  AuthzInertiaModule.forRoot(), // shares props.auth.can automatically
38
41
  ],
@@ -45,12 +48,13 @@ export class AppModule {}
45
48
 
46
49
  ```ts
47
50
  InertiaModule.forRoot({
48
- share: createAuthzShare(gate, policyRegistry),
51
+ share: createAuthzShare(gate.forUser(user), policyIndex),
49
52
  })
50
53
  ```
51
54
 
52
55
  Both resolve abilities by direct in-process `gate.allows(...)` calls — no HTTP round-trip.
53
- The ability name defaults to `"<resourceLower>.<method>"` (e.g. `post.create`); pass
56
+ The ability name defaults to `"<resourceLower>.<method>"` (e.g. `post.create`), where the
57
+ resource is the class linked with `@PolicyFor(Post)`, else the policy name without `Policy`; pass
54
58
  `abilityNamer: (_, m) => m` for bare method names, or a custom `propKey`.
55
59
 
56
60
  ### Tier 2 — Per-resource `can` map (no request)
@@ -60,7 +64,7 @@ map onto the resource in your controller:
60
64
 
61
65
  ```ts
62
66
  const post = await this.posts.find(id);
63
- const can = await authorizeResource(this.gate, post, ['update', 'delete']);
67
+ const can = await authorizeResource(this.gate.forUser(user), post, ['update', 'delete']);
64
68
  return this.inertia.render('Post/Show', { post: { ...post, can } });
65
69
  // → { post: { id, title, can: { update: true, delete: false } } }
66
70
  ```
@@ -77,12 +81,13 @@ AuthzModule.forRoot({ canEndpoint: true }) // POST /authz/can → { allowed }
77
81
  // or a custom path: canEndpoint: 'api/authz/can'
78
82
  ```
79
83
 
80
- It runs `gate.allows(ability, resource?)` for the current context user and returns
84
+ It runs `gate.allows(ability, resource?)` for the caller (read the way the official guard
85
+ reads it) and returns
81
86
  `{ allowed }`. Off by default. This is the path the codegen-emitted `can()` targets.
82
87
 
83
88
  > **Class-level by default; per-instance with a loader.** Out of the box the endpoint resolves
84
89
  > **class-level abilities and ad-hoc gates** only — the `{ type, id }` shim it receives never
85
- > matches a `@Policy` by constructor, so a **resource-bound** ability that misses the cache and
90
+ > matches a policy linked with `@PolicyFor` by constructor, so a **resource-bound** ability that misses the cache and
86
91
  > falls through to `/authz/can` will **deny**. To make per-instance decisions resolve at tier 3,
87
92
  > register `resourceLoaders` keyed by the resource `type`:
88
93
  >
@@ -93,18 +98,18 @@ It runs `gate.allows(ability, resource?)` for the current context user and retur
93
98
  > })
94
99
  > ```
95
100
  >
96
- > The endpoint then loads the real entity before authorizing, so the instance `@Policy` matches
101
+ > The endpoint then loads the real entity before authorizing, so the linked policy matches
97
102
  > and decides correctly (a loader returning nullish → deny / not found). Prefer hydrating via
98
103
  > tiers 1-2 (shared props / `authorizeResource`) when you can; use `resourceLoaders` for the
99
104
  > abilities that genuinely need a tier-3 round-trip.
100
105
 
101
106
  ## Client store (framework-neutral)
102
107
 
103
- `@dudousxd/nestjs-authz-inertia/client` is a tiny in-memory store + resolver with no
104
- framework dependency — `-react` and the codegen client reuse it.
108
+ The store lives in `@dudousxd/nestjs-authz-client`: a tiny in-memory store + resolver with no
109
+ framework dependency — `-react` and the codegen client reuse it. Install it next to this package.
105
110
 
106
111
  ```ts
107
- import { AbilityStore, hydrateFromInertiaProps, hydrateResource, createCan } from '@dudousxd/nestjs-authz-inertia/client';
112
+ import { AbilityStore, hydrateFromInertiaProps, hydrateResource, createCan } from '@dudousxd/nestjs-authz-client';
108
113
 
109
114
  const store = new AbilityStore();
110
115
  hydrateFromInertiaProps(store, page.props); // tier 1: props.auth.can
@@ -1,4 +1,4 @@
1
- import type { Gate, Resource } from '@dudousxd/nestjs-authz';
1
+ import type { BoundGate, Gate, Resource } from '@dudousxd/nestjs-authz';
2
2
  import type { CanMap } from './resolve-abilities.js';
3
3
  /**
4
4
  * Resolve a per-INSTANCE `can` map for one resource, with NO HTTP round-trip:
@@ -18,7 +18,7 @@ import type { CanMap } from './resolve-abilities.js';
18
18
  *
19
19
  * @returns e.g. `{ update: true, delete: false }`
20
20
  */
21
- export declare function authorizeResource(gate: Gate, resource: Resource, abilities: string[]): Promise<CanMap>;
21
+ export declare function authorizeResource(gate: Gate | BoundGate, resource: Resource, abilities: string[]): Promise<CanMap>;
22
22
  /**
23
23
  * Like {@link authorizeResource}, but resolves for an explicit user via
24
24
  * `gate.forUser(user)` instead of the current context user. Useful outside a
@@ -1 +1 @@
1
- {"version":3,"file":"authorize-resource.d.ts","sourceRoot":"","sources":["../src/authorize-resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,CAWjB"}
1
+ {"version":3,"file":"authorize-resource.d.ts","sourceRoot":"","sources":["../src/authorize-resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,CAWjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorize-resource.js","sourceRoot":"","sources":["../src/authorize-resource.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAU,EACV,QAAkB,EAClB,SAAmB;IAEnB,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,IAAU,EACV,IAAa,EACb,QAAkB,EAClB,SAAmB;IAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"authorize-resource.js","sourceRoot":"","sources":["../src/authorize-resource.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAsB,EACtB,QAAkB,EAClB,SAAmB;IAEnB,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,IAAU,EACV,IAAa,EACb,QAAkB,EAClB,SAAmB;IAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { type ContextAccessor } from '@dudousxd/nestjs-authz';
2
- import { type ArgumentsHost, type ExceptionFilter, ForbiddenException } from '@nestjs/common';
2
+ import { type ArgumentsHost, type ExceptionFilter, ForbiddenException, UnauthorizedException } from '@nestjs/common';
3
3
  import type { AuthzInertiaOptions } from './types.js';
4
4
  /**
5
5
  * Default redirect target for an UNAUTHENTICATED Inertia denial.
@@ -32,7 +32,7 @@ export declare class AuthzDenialFilter implements ExceptionFilter {
32
32
  private readonly options;
33
33
  private readonly context?;
34
34
  constructor(options?: AuthzInertiaOptions, context?: ContextAccessor | undefined);
35
- catch(exception: ForbiddenException, host: ArgumentsHost): void;
35
+ catch(exception: ForbiddenException | UnauthorizedException, host: ArgumentsHost): void;
36
36
  /**
37
37
  * Pick the redirect target from auth-state. An undefined `userRef()` (or no
38
38
  * context accessor at all) is treated as unauthenticated.
@@ -1 +1 @@
1
- {"version":3,"file":"authz-denial.filter.d.ts","sourceRoot":"","sources":["../src/authz-denial.filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,eAAe,EACpB,kBAAkB,EAGnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAsB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E;;GAEG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBACa,iBAAkB,YAAW,eAAe;IAIrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAGxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAHR,OAAO,GAAE,mBAAwB,EAGjC,OAAO,CAAC,EAAE,eAAe,YAAA;IAG5C,KAAK,CAAC,SAAS,EAAE,kBAAkB,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IA2B/D;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CAO9B"}
1
+ {"version":3,"file":"authz-denial.filter.d.ts","sourceRoot":"","sources":["../src/authz-denial.filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,eAAe,EACpB,kBAAkB,EAIlB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAsB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E;;GAEG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBACa,iBAAkB,YAAW,eAAe;IAIrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAGxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAHR,OAAO,GAAE,mBAAwB,EAGjC,OAAO,CAAC,EAAE,eAAe,YAAA;IAG5C,KAAK,CAAC,SAAS,EAAE,kBAAkB,GAAG,qBAAqB,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IA2BvF;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CAY9B"}
@@ -11,7 +11,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
13
  import { CONTEXT_ACCESSOR } from '@dudousxd/nestjs-authz';
14
- import { Catch, ForbiddenException, Inject, Optional, } from '@nestjs/common';
14
+ import { Catch, ForbiddenException, Inject, Optional, UnauthorizedException, } from '@nestjs/common';
15
15
  import { AUTHZ_INERTIA_OPTIONS } from './tokens.js';
16
16
  /**
17
17
  * Default redirect target for an UNAUTHENTICATED Inertia denial.
@@ -65,23 +65,27 @@ let AuthzDenialFilter = class AuthzDenialFilter {
65
65
  denial.handler(exception, host);
66
66
  return;
67
67
  }
68
- const target = this.resolveRedirectTarget(denial);
68
+ const target = this.resolveRedirectTarget(denial, exception);
69
69
  sendRedirect(res, 303, target);
70
70
  }
71
71
  /**
72
72
  * Pick the redirect target from auth-state. An undefined `userRef()` (or no
73
73
  * context accessor at all) is treated as unauthenticated.
74
74
  */
75
- resolveRedirectTarget(denial) {
75
+ resolveRedirectTarget(denial, exception) {
76
76
  const loginUrl = denial.loginUrl ?? DEFAULT_LOGIN_URL;
77
77
  const forbiddenUrl = denial.forbiddenUrl ?? DEFAULT_FORBIDDEN_URL;
78
- const authenticated = this.context?.userRef() !== undefined;
78
+ // The official guard answers a guest with a 401 and a signed-in user with a 403. A
79
+ // 403 for a guest (a `byId()` miss, a custom guard) still goes to the login page when
80
+ // nestjs-context says nobody is signed in.
81
+ const authenticated = !(exception instanceof UnauthorizedException) &&
82
+ (this.context === undefined || this.context.userRef() !== undefined);
79
83
  const target = authenticated ? forbiddenUrl : loginUrl;
80
84
  return toSafePath(target, authenticated ? DEFAULT_FORBIDDEN_URL : DEFAULT_LOGIN_URL);
81
85
  }
82
86
  };
83
87
  AuthzDenialFilter = __decorate([
84
- Catch(ForbiddenException),
88
+ Catch(ForbiddenException, UnauthorizedException),
85
89
  __param(0, Optional()),
86
90
  __param(0, Inject(AUTHZ_INERTIA_OPTIONS)),
87
91
  __param(1, Optional()),
@@ -1 +1 @@
1
- {"version":3,"file":"authz-denial.filter.js","sourceRoot":"","sources":["../src/authz-denial.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,gBAAgB,EAAwB,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAEL,KAAK,EAEL,kBAAkB,EAClB,MAAM,EACN,QAAQ,GACT,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAIT;IAGA;IANnB,YAGmB,UAA+B,EAAE,EAGjC,OAAyB;QAHzB,YAAO,GAAP,OAAO,CAA0B;QAGjC,YAAO,GAAP,OAAO,CAAkB;IACzC,CAAC;IAEJ,KAAK,CAAC,SAA6B,EAAE,IAAmB;QACtD,MAAM,MAAM,GAAuB,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QAE7D,0EAA0E;QAC1E,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;YAC1D,MAAM,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAW,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAW,CAAC;QAExC,wEAAwE;QACxE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YACjC,MAAM,SAAS,CAAC;QAClB,CAAC;QAED,yEAAyE;QACzE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAClD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAAC,MAA0B;QACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,iBAAiB,CAAC;QACtD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,qBAAqB,CAAC;QAClE,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,SAAS,CAAC;QAC5D,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;QACvD,OAAO,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACvF,CAAC;CACF,CAAA;AAhDY,iBAAiB;IAD7B,KAAK,CAAC,kBAAkB,CAAC;IAGrB,WAAA,QAAQ,EAAE,CAAA;IACV,WAAA,MAAM,CAAC,qBAAqB,CAAC,CAAA;IAE7B,WAAA,QAAQ,EAAE,CAAA;IACV,WAAA,MAAM,CAAC,gBAAgB,CAAC,CAAA;;GANhB,iBAAiB,CAgD7B;;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,MAAc,EAAE,QAAgB;IAClD,IAAI,CAAC;QACH,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,GAAY,EAAE,IAAY;IAC3C,MAAM,CAAC,GAAG,GAGT,CAAC;IACF,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,GAAW;IACtC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAC7D,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,0EAA0E,GAAG,EAAE,CAChF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,sEAAsE,GAAG,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,IAAI,KAAK,CACb,kFAAkF,GAAG,GAAG,CACzF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;YAC7B,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpD,OAAO,GAAG,CAAC;YACb,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,qEAAqE,GAAG,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAY,EAAE,MAAc,EAAE,GAAW;IAC7D,MAAM,CAAC,GAAG,GAOT,CAAC;IAEF,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACnC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;SAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACxC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QACtC,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;SAAM,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1C,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QAChC,CAAC,CAAC,GAAG,EAAE,CAAC;IACV,CAAC;SAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACxC,CAAC,CAAC,IAAI,EAAE,CAAC;IACX,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"authz-denial.filter.js","sourceRoot":"","sources":["../src/authz-denial.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,gBAAgB,EAAwB,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAEL,KAAK,EAEL,kBAAkB,EAElB,MAAM,EACN,QAAQ,EACR,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAIT;IAGA;IANnB,YAGmB,UAA+B,EAAE,EAGjC,OAAyB;QAHzB,YAAO,GAAP,OAAO,CAA0B;QAGjC,YAAO,GAAP,OAAO,CAAkB;IACzC,CAAC;IAEJ,KAAK,CAAC,SAAqD,EAAE,IAAmB;QAC9E,MAAM,MAAM,GAAuB,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QAE7D,0EAA0E;QAC1E,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;YAC1D,MAAM,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAW,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAW,CAAC;QAExC,wEAAwE;QACxE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YACjC,MAAM,SAAS,CAAC;QAClB,CAAC;QAED,yEAAyE;QACzE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7D,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAAC,MAA0B,EAAE,SAAwB;QAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,iBAAiB,CAAC;QACtD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,qBAAqB,CAAC;QAClE,mFAAmF;QACnF,sFAAsF;QACtF,2CAA2C;QAC3C,MAAM,aAAa,GACjB,CAAC,CAAC,SAAS,YAAY,qBAAqB,CAAC;YAC7C,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,SAAS,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;QACvD,OAAO,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACvF,CAAC;CACF,CAAA;AArDY,iBAAiB;IAD7B,KAAK,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;IAG5C,WAAA,QAAQ,EAAE,CAAA;IACV,WAAA,MAAM,CAAC,qBAAqB,CAAC,CAAA;IAE7B,WAAA,QAAQ,EAAE,CAAA;IACV,WAAA,MAAM,CAAC,gBAAgB,CAAC,CAAA;;GANhB,iBAAiB,CAqD7B;;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,MAAc,EAAE,QAAgB;IAClD,IAAI,CAAC;QACH,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,GAAY,EAAE,IAAY;IAC3C,MAAM,CAAC,GAAG,GAGT,CAAC;IACF,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,GAAW;IACtC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAC7D,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,0EAA0E,GAAG,EAAE,CAChF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,sEAAsE,GAAG,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,IAAI,KAAK,CACb,kFAAkF,GAAG,GAAG,CACzF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;YAC7B,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpD,OAAO,GAAG,CAAC;YACb,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,qEAAqE,GAAG,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAY,EAAE,MAAc,EAAE,GAAW;IAC7D,MAAM,CAAC,GAAG,GAOT,CAAC;IAEF,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACnC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;SAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACxC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QACtC,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;SAAM,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1C,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QAChC,CAAC,CAAC,GAAG,EAAE,CAAC;IACV,CAAC;SAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACxC,CAAC,CAAC,IAAI,EAAE,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import { Gate, PolicyRegistry } from '@dudousxd/nestjs-authz';
1
+ import { Gate, PolicyIndex } from '@dudousxd/nestjs-authz';
2
2
  import { type CallHandler, type ExecutionContext, type NestInterceptor } from '@nestjs/common';
3
3
  import type { Observable } from 'rxjs';
4
4
  import type { AuthzInertiaOptions } from './types.js';
@@ -15,7 +15,7 @@ export declare class AuthzInertiaInterceptor implements NestInterceptor {
15
15
  private readonly policies;
16
16
  private readonly options;
17
17
  private readonly propKey;
18
- constructor(gate: Gate, policies: PolicyRegistry, options?: AuthzInertiaOptions);
18
+ constructor(gate: Gate, policies: PolicyIndex, options?: AuthzInertiaOptions);
19
19
  intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
20
20
  }
21
21
  //# sourceMappingURL=authz-inertia.interceptor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authz-inertia.interceptor.d.ts","sourceRoot":"","sources":["../src/authz-inertia.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAGrB,KAAK,eAAe,EAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAKvC,OAAO,KAAK,EAAE,mBAAmB,EAAsB,MAAM,YAAY,CAAC;AAE1E;;;;;;;GAOG;AACH,qBACa,uBAAwB,YAAW,eAAe;IAI3D,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAGzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAGd,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,cAAc,EAGxB,OAAO,GAAE,mBAAwB;IAKpD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;CAuB7E"}
1
+ {"version":3,"file":"authz-inertia.interceptor.d.ts","sourceRoot":"","sources":["../src/authz-inertia.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAiB,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAGrB,KAAK,eAAe,EAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAKvC,OAAO,KAAK,EAAE,mBAAmB,EAAsB,MAAM,YAAY,CAAC;AAE1E;;;;;;;GAOG;AACH,qBACa,uBAAwB,YAAW,eAAe;IAI3D,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAGzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAGd,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,WAAW,EAGrB,OAAO,GAAE,mBAAwB;IAKpD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;CAyB7E"}
@@ -10,7 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
- import { Gate, PolicyRegistry } from '@dudousxd/nestjs-authz';
13
+ import { Gate, PolicyIndex, currentUserOf } from '@dudousxd/nestjs-authz';
14
14
  import { Inject, Injectable, Optional, } from '@nestjs/common';
15
15
  import { from, switchMap } from 'rxjs';
16
16
  import { resolveClassAbilities } from './resolve-abilities.js';
@@ -42,7 +42,7 @@ let AuthzInertiaInterceptor = class AuthzInertiaInterceptor {
42
42
  const inertia = req?.inertia;
43
43
  if (!inertia || typeof inertia.share !== 'function')
44
44
  return next.handle();
45
- return from(resolveClassAbilities(this.gate, this.policies, {
45
+ return from(currentUserOf(context).then((user) => resolveClassAbilities(this.gate.forUser(user), this.policies, {
46
46
  ...(this.options.abilities !== undefined ? { abilities: this.options.abilities } : {}),
47
47
  ...(this.options.abilityNamer !== undefined
48
48
  ? { abilityNamer: this.options.abilityNamer }
@@ -50,7 +50,7 @@ let AuthzInertiaInterceptor = class AuthzInertiaInterceptor {
50
50
  ...(this.options.includeBareMethodNames !== undefined
51
51
  ? { includeBareMethodNames: this.options.includeBareMethodNames }
52
52
  : {}),
53
- })).pipe(switchMap((can) => {
53
+ }))).pipe(switchMap((can) => {
54
54
  inertia.share({ [this.propKey]: { can } });
55
55
  return next.handle();
56
56
  }));
@@ -61,7 +61,7 @@ AuthzInertiaInterceptor = __decorate([
61
61
  __param(2, Optional()),
62
62
  __param(2, Inject(AUTHZ_INERTIA_OPTIONS)),
63
63
  __metadata("design:paramtypes", [Gate,
64
- PolicyRegistry, Object])
64
+ PolicyIndex, Object])
65
65
  ], AuthzInertiaInterceptor);
66
66
  export { AuthzInertiaInterceptor };
67
67
  //# sourceMappingURL=authz-inertia.interceptor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authz-inertia.interceptor.js","sourceRoot":"","sources":["../src/authz-inertia.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAGL,MAAM,EACN,UAAU,EAEV,QAAQ,GACT,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD;;;;;;;GAOG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAIf;IACA;IAGA;IAPF,OAAO,CAAS;IAEjC,YACmB,IAAU,EACV,QAAwB,EAGxB,UAA+B,EAAE;QAJjC,SAAI,GAAJ,IAAI,CAAM;QACV,aAAQ,GAAR,QAAQ,CAAgB;QAGxB,YAAO,GAAP,OAAO,CAA0B;QAElD,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,gBAAgB,CAAC;IACtD,CAAC;IAED,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,IAAI,OAAO,CAAC,OAAO,EAAE,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvD,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAsB,CAAC;QACpE,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,CAAC;QAC7B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QAE1E,OAAO,IAAI,CACT,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;YAC9C,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtF,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS;gBACzC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;gBAC7C,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,KAAK,SAAS;gBACnD,CAAC,CAAC,EAAE,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE;gBACjE,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CACH,CAAC,IAAI,CACJ,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;YAChB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AApCY,uBAAuB;IADnC,UAAU,EAAE;IAOR,WAAA,QAAQ,EAAE,CAAA;IACV,WAAA,MAAM,CAAC,qBAAqB,CAAC,CAAA;qCAHP,IAAI;QACA,cAAc;GALhC,uBAAuB,CAoCnC"}
1
+ {"version":3,"file":"authz-inertia.interceptor.js","sourceRoot":"","sources":["../src/authz-inertia.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAGL,MAAM,EACN,UAAU,EAEV,QAAQ,GACT,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD;;;;;;;GAOG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAIf;IACA;IAGA;IAPF,OAAO,CAAS;IAEjC,YACmB,IAAU,EACV,QAAqB,EAGrB,UAA+B,EAAE;QAJjC,SAAI,GAAJ,IAAI,CAAM;QACV,aAAQ,GAAR,QAAQ,CAAa;QAGrB,YAAO,GAAP,OAAO,CAA0B;QAElD,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,gBAAgB,CAAC;IACtD,CAAC;IAED,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,IAAI,OAAO,CAAC,OAAO,EAAE,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvD,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAsB,CAAC;QACpE,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,CAAC;QAC7B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QAE1E,OAAO,IAAI,CACT,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACnC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE;YAC5D,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtF,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS;gBACzC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;gBAC7C,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,KAAK,SAAS;gBACnD,CAAC,CAAC,EAAE,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE;gBACjE,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CACH,CACF,CAAC,IAAI,CACJ,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;YAChB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAtCY,uBAAuB;IADnC,UAAU,EAAE;IAOR,WAAA,QAAQ,EAAE,CAAA;IACV,WAAA,MAAM,CAAC,qBAAqB,CAAC,CAAA;qCAHP,IAAI;QACA,WAAW;GAL7B,uBAAuB,CAsCnC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.1.3";
1
+ export declare const VERSION = "0.2.0";
2
2
  export { AuthzInertiaModule } from './module.js';
3
3
  export { AuthzInertiaInterceptor } from './authz-inertia.interceptor.js';
4
4
  export { AuthzDenialFilter, DEFAULT_LOGIN_URL, DEFAULT_FORBIDDEN_URL, } from './authz-denial.filter.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = '0.1.3';
1
+ export const VERSION = '0.2.0';
2
2
  export { AuthzInertiaModule } from './module.js';
3
3
  export { AuthzInertiaInterceptor } from './authz-inertia.interceptor.js';
4
4
  export { AuthzDenialFilter, DEFAULT_LOGIN_URL, DEFAULT_FORBIDDEN_URL, } from './authz-denial.filter.js';
@@ -1,4 +1,4 @@
1
- import type { Gate, PolicyRegistry } from '@dudousxd/nestjs-authz';
1
+ import type { BoundGate, Gate, PolicyIndex } from '@dudousxd/nestjs-authz';
2
2
  import type { CanMap } from '@dudousxd/nestjs-authz-client';
3
3
  /**
4
4
  * A flat record of `ability -> verdict`, e.g. `{ 'posts.create': true }`.
@@ -7,10 +7,10 @@ import type { CanMap } from '@dudousxd/nestjs-authz-client';
7
7
  */
8
8
  export type { CanMap };
9
9
  /**
10
- * How an ability name is built from a policy's resource class + method name when
11
- * enumerating class-level policy abilities. Default: `"<ResourceName>.<method>"`
12
- * lower-cased on the resource (e.g. `Post` + `create` → `posts.create`... no — see
13
- * below). Kept overridable so an app can match the naming its `@Can` decorators use.
10
+ * How an ability key is built from a policy's resource name and method name when
11
+ * listing class-level abilities. The resource name is the class linked with
12
+ * `@PolicyFor(Resource)`, else the policy class name without `Policy` (`PostPolicy` →
13
+ * `Post`).
14
14
  */
15
15
  export type AbilityNamer = (resourceName: string, method: string) => string;
16
16
  /**
@@ -38,21 +38,16 @@ export interface ResolveAbilitiesOptions {
38
38
  includeBareMethodNames?: boolean;
39
39
  }
40
40
  /**
41
- * Resolve the current user's CLASS-LEVEL abilities into a flat `{ ability: boolean }`
42
- * map, with NO per-request HTTP round-trip — each entry is a direct `gate.allows`
43
- * call against the in-process Gate.
41
+ * Resolve a user's CLASS-LEVEL abilities into a flat `{ ability: boolean }` map, with no
42
+ * HTTP round-trip. Pass `gate.forUser(user)`; a bare `Gate` checks its ambient user.
44
43
  *
45
44
  * Sources, in order:
46
- * 1. Ad-hoc gates registered via `gate.define(...)` (model-less, e.g. `access-admin`).
47
- * 2. Class-level `@Policy` methods (those taking no resource instance — heuristically
48
- * arity `<= 1`, e.g. `create(user)`/`viewAny(user)`), dispatched against the resource
49
- * CLASS so no instance is loaded. Instance methods like `update(user, post)` are NOT
50
- * enumerated (see {@link PolicyRegistry.classAbilities}) — dispatching them against the
51
- * class would write a bogus class-level verdict.
45
+ * 1. Ad-hoc gates registered with `gate.define(...)`.
46
+ * 2. The abilities of every official `@Policy()` that take no argument after the user
47
+ * (`create(user)`, `viewAny(user)`), checked through the official
48
+ * `AuthorizationService` (so each policy's `before()` applies). Abilities that take a
49
+ * record (`update(user, post)`) are per-instance: share them with `authorizeResource`.
52
50
  * 3. Any extra `options.abilities` names.
53
- *
54
- * Gates are checked by name; policy methods are checked by passing the resource
55
- * class as the dispatch target (Gate resolves the class-level policy method).
56
51
  */
57
- export declare function resolveClassAbilities(gate: Gate, policies: PolicyRegistry, options?: ResolveAbilitiesOptions): Promise<CanMap>;
52
+ export declare function resolveClassAbilities(gate: Gate | BoundGate, policies: PolicyIndex, options?: ResolveAbilitiesOptions): Promise<CanMap>;
58
53
  //# sourceMappingURL=resolve-abilities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-abilities.d.ts","sourceRoot":"","sources":["../src/resolve-abilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAY,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAE5D;;;;GAIG;AACH,YAAY,EAAE,MAAM,EAAE,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YACS,CAAC;AAE5C,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
1
+ {"version":3,"file":"resolve-abilities.d.ts","sourceRoot":"","sources":["../src/resolve-abilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAG5D;;;;GAIG;AACH,YAAY,EAAE,MAAM,EAAE,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YACS,CAAC;AAE5C,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,MAAM,CAAC,CA0BjB"}
@@ -5,37 +5,29 @@
5
5
  */
6
6
  export const defaultAbilityNamer = (resourceName, method) => `${resourceName.toLowerCase()}.${method}`;
7
7
  /**
8
- * Resolve the current user's CLASS-LEVEL abilities into a flat `{ ability: boolean }`
9
- * map, with NO per-request HTTP round-trip — each entry is a direct `gate.allows`
10
- * call against the in-process Gate.
8
+ * Resolve a user's CLASS-LEVEL abilities into a flat `{ ability: boolean }` map, with no
9
+ * HTTP round-trip. Pass `gate.forUser(user)`; a bare `Gate` checks its ambient user.
11
10
  *
12
11
  * Sources, in order:
13
- * 1. Ad-hoc gates registered via `gate.define(...)` (model-less, e.g. `access-admin`).
14
- * 2. Class-level `@Policy` methods (those taking no resource instance — heuristically
15
- * arity `<= 1`, e.g. `create(user)`/`viewAny(user)`), dispatched against the resource
16
- * CLASS so no instance is loaded. Instance methods like `update(user, post)` are NOT
17
- * enumerated (see {@link PolicyRegistry.classAbilities}) — dispatching them against the
18
- * class would write a bogus class-level verdict.
12
+ * 1. Ad-hoc gates registered with `gate.define(...)`.
13
+ * 2. The abilities of every official `@Policy()` that take no argument after the user
14
+ * (`create(user)`, `viewAny(user)`), checked through the official
15
+ * `AuthorizationService` (so each policy's `before()` applies). Abilities that take a
16
+ * record (`update(user, post)`) are per-instance: share them with `authorizeResource`.
19
17
  * 3. Any extra `options.abilities` names.
20
- *
21
- * Gates are checked by name; policy methods are checked by passing the resource
22
- * class as the dispatch target (Gate resolves the class-level policy method).
23
18
  */
24
19
  export async function resolveClassAbilities(gate, policies, options = {}) {
25
20
  const namer = options.abilityNamer ?? defaultAbilityNamer;
26
21
  const out = {};
27
- // 1. Ad-hoc gates (model-less). Resolve by ability name only.
28
- const gateNames = new Set([...gate.gateNames(), ...(options.abilities ?? [])]);
29
- for (const ability of gateNames) {
30
- out[ability] = await safeAllows(gate, ability);
22
+ const names = new Set([...gateNamesOf(gate), ...(options.abilities ?? [])]);
23
+ for (const ability of names) {
24
+ out[ability] = await safely(() => gate.allows(ability));
31
25
  }
32
- // 2. Class-level policy methods, dispatched against the resource CLASS.
33
- for (const { resource, abilities } of policies.classAbilities()) {
34
- const resourceName = resource.name ?? 'Resource';
26
+ for (const { policy, resource, abilities } of policies.classAbilities()) {
27
+ const resourceName = resource?.name ?? policy.name.replace(/Policy$/, '');
35
28
  for (const method of abilities) {
36
29
  const key = namer(resourceName, method);
37
- // Gate.allows accepts a Type (class) as the resource for class-level abilities.
38
- out[key] = await safeAllows(gate, method, resource);
30
+ out[key] = await safely(() => gate.allows.call(gate, policy, method));
39
31
  if (options.includeBareMethodNames && out[method] === undefined) {
40
32
  out[method] = out[key];
41
33
  }
@@ -43,13 +35,15 @@ export async function resolveClassAbilities(gate, policies, options = {}) {
43
35
  }
44
36
  return out;
45
37
  }
46
- /**
47
- * `gate.allows` may throw (unresolved/ambiguous ability). For prop sharing we
48
- * fail closed (deny) rather than crash the render.
49
- */
50
- async function safeAllows(gate, ability, resource) {
38
+ /** The ad-hoc gate names, from a `Gate` or the `Gate` behind a `BoundGate`. */
39
+ function gateNamesOf(gate) {
40
+ const owner = gate.gate ?? gate;
41
+ return typeof owner.gateNames === 'function' ? owner.gateNames() : [];
42
+ }
43
+ /** A check that throws (unresolved ability, unregistered policy) shares `false`. */
44
+ async function safely(check) {
51
45
  try {
52
- return await gate.allows(ability, resource);
46
+ return await check();
53
47
  }
54
48
  catch {
55
49
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-abilities.js","sourceRoot":"","sources":["../src/resolve-abilities.ts"],"names":[],"mappings":"AAkBA;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,CACxE,GAAG,YAAY,CAAC,WAAW,EAAE,IAAI,MAAM,EAAE,CAAC;AAqB5C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAU,EACV,QAAwB,EACxB,UAAmC,EAAE;IAErC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,IAAI,mBAAmB,CAAC;IAC1D,MAAM,GAAG,GAAW,EAAE,CAAC;IAEvB,8DAA8D;IAC9D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACvF,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,wEAAwE;IACxE,KAAK,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC;QAChE,MAAM,YAAY,GAAI,QAA8B,CAAC,IAAI,IAAI,UAAU,CAAC;QACxE,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACxC,gFAAgF;YAChF,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAA+B,CAAC,CAAC;YAC3E,IAAI,OAAO,CAAC,sBAAsB,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBAChE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,UAAU,CAAC,IAAU,EAAE,OAAe,EAAE,QAAmB;IACxE,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"resolve-abilities.js","sourceRoot":"","sources":["../src/resolve-abilities.ts"],"names":[],"mappings":"AAmBA;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,CACxE,GAAG,YAAY,CAAC,WAAW,EAAE,IAAI,MAAM,EAAE,CAAC;AAqB5C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAsB,EACtB,QAAqB,EACrB,UAAmC,EAAE;IAErC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,IAAI,mBAAmB,CAAC;IAC1D,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACpF,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;QAC5B,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC;QACxE,MAAM,YAAY,GAAG,QAAQ,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC1E,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACxC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAC1B,IAAI,CAAC,MAA4D,CAAC,IAAI,CACrE,IAAI,EACJ,MAAM,EACN,MAAM,CACP,CACF,CAAC;YACF,IAAI,OAAO,CAAC,sBAAsB,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBAChE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+EAA+E;AAC/E,SAAS,WAAW,CAAC,IAAsB;IACzC,MAAM,KAAK,GAAI,IAAmC,CAAC,IAAI,IAAK,IAAa,CAAC;IAC1E,OAAO,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,oFAAoF;AACpF,KAAK,UAAU,MAAM,CAAC,KAA6B;IACjD,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/dist/share.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Gate, PolicyRegistry } from '@dudousxd/nestjs-authz';
1
+ import type { BoundGate, Gate, PolicyIndex } from '@dudousxd/nestjs-authz';
2
2
  import { type ResolveAbilitiesOptions } from './resolve-abilities.js';
3
3
  /** Default prop namespace: `props.auth.can`. */
4
4
  export declare const DEFAULT_PROP_KEY = "auth";
@@ -24,5 +24,5 @@ export interface CreateAuthzShareOptions extends ResolveAbilitiesOptions {
24
24
  * render and merges the result into every page's shared props. The client store's
25
25
  * `hydrateFromInertiaProps` then reads `props.auth.can`.
26
26
  */
27
- export declare function createAuthzShare(gate: Gate, policies: PolicyRegistry, options?: CreateAuthzShareOptions): () => Promise<Record<string, unknown>>;
27
+ export declare function createAuthzShare(gate: Gate | BoundGate, policies: PolicyIndex, options?: CreateAuthzShareOptions): () => Promise<Record<string, unknown>>;
28
28
  //# sourceMappingURL=share.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,KAAK,uBAAuB,EAAyB,MAAM,wBAAwB,CAAC;AAE7F,gDAAgD;AAChD,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACtE,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,uBAA4B,GACpC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMxC"}
1
+ {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,KAAK,uBAAuB,EAAyB,MAAM,wBAAwB,CAAC;AAE7F,gDAAgD;AAChD,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACtE,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,uBAA4B,GACpC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMxC"}
package/dist/share.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AACA,OAAO,EAAgC,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE7F,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAOvC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAU,EACV,QAAwB,EACxB,UAAmC,EAAE;IAErC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACpD,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AACA,OAAO,EAAgC,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE7F,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAOvC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAsB,EACtB,QAAqB,EACrB,UAAmC,EAAE;IAErC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACpD,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type { ArgumentsHost, ForbiddenException } from '@nestjs/common';
1
+ import type { ArgumentsHost, ForbiddenException, UnauthorizedException } from '@nestjs/common';
2
2
  import type { AbilityNamer, CanMap } from './resolve-abilities.js';
3
3
  /**
4
4
  * Configures the {@link AuthzDenialFilter}: how authorization denials
5
- * (`@Roles`/`@Can` → `ForbiddenException`) render on Inertia requests. Non-Inertia
5
+ * (the official guard's `UnauthorizedException` / `ForbiddenException`) render on Inertia requests. Non-Inertia
6
6
  * (REST) requests are unaffected — they keep the normal 403 JSON.
7
7
  */
8
8
  export interface AuthzDenialOptions {
@@ -14,7 +14,7 @@ export interface AuthzDenialOptions {
14
14
  */
15
15
  enabled?: boolean;
16
16
  /**
17
- * Redirect target for an UNAUTHENTICATED denial (no `CONTEXT_ACCESSOR` user).
17
+ * Redirect target for an UNAUTHENTICATED denial (a 401, or a 403 while nestjs-context has no user).
18
18
  *
19
19
  * Default: `'/login'`.
20
20
  */
@@ -31,7 +31,7 @@ export interface AuthzDenialOptions {
31
31
  * `ForbiddenException` and the `ArgumentsHost`. When provided, it replaces the
32
32
  * default redirect behavior for Inertia requests.
33
33
  */
34
- handler?: (exception: ForbiddenException, host: ArgumentsHost) => void;
34
+ handler?: (exception: ForbiddenException | UnauthorizedException, host: ArgumentsHost) => void;
35
35
  }
36
36
  /**
37
37
  * Minimal structural mirror of the request object carrying `req.inertia`, set by
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CACxE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAChD;AAED,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,kBAAkB,GAAG,qBAAqB,EAAE,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAChG;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAChD;AAED,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-authz-inertia",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Inertia.js integration for @dudousxd/nestjs-authz — share a user's abilities as props so client `can()` checks need no network request.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -8,6 +8,19 @@
8
8
  "url": "git+https://github.com/DavideCarvalho/nestjs-authz.git",
9
9
  "directory": "packages/inertia"
10
10
  },
11
+ "homepage": "https://davidecarvalho.github.io/aviary/docs/authz",
12
+ "bugs": {
13
+ "url": "https://github.com/DavideCarvalho/nestjs-authz/issues"
14
+ },
15
+ "keywords": [
16
+ "nestjs",
17
+ "authorization",
18
+ "authz",
19
+ "inertia",
20
+ "inertia.js",
21
+ "abilities",
22
+ "can"
23
+ ],
11
24
  "author": "Davi Carvalho <davi@goflip.ai>",
12
25
  "type": "module",
13
26
  "main": "./dist/index.js",
@@ -17,11 +30,6 @@
17
30
  "types": "./dist/index.d.ts",
18
31
  "import": "./dist/index.js",
19
32
  "default": "./dist/index.js"
20
- },
21
- "./client": {
22
- "types": "./dist/client.d.ts",
23
- "import": "./dist/client.js",
24
- "default": "./dist/client.js"
25
33
  }
26
34
  },
27
35
  "files": [
@@ -30,14 +38,15 @@
30
38
  "CHANGELOG.md"
31
39
  ],
32
40
  "dependencies": {
33
- "@dudousxd/nestjs-authz-client": "^0.2.1"
41
+ "@dudousxd/nestjs-authz-client": "^0.2.2"
34
42
  },
35
43
  "peerDependencies": {
36
- "@dudousxd/nestjs-authz": ">=0.2.0",
44
+ "@dudousxd/nestjs-authz": ">=0.9.0 <0.10.0",
37
45
  "@dudousxd/nestjs-context": ">=0.1.0",
38
46
  "@dudousxd/nestjs-inertia": ">=1.0.0",
39
- "@nestjs/common": ">=10.0.0",
40
- "@nestjs/core": ">=10.0.0",
47
+ "@nestjs/authorization": "^0.1.3",
48
+ "@nestjs/common": "^12.0.0",
49
+ "@nestjs/core": "^12.0.0",
41
50
  "reflect-metadata": ">=0.1.13"
42
51
  },
43
52
  "peerDependenciesMeta": {
@@ -46,31 +55,23 @@
46
55
  }
47
56
  },
48
57
  "devDependencies": {
49
- "@dudousxd/nestjs-inertia": "^1.5.0",
50
- "@nestjs/common": "^12.0.1",
51
- "@nestjs/core": "^12.0.1",
52
- "@nestjs/testing": "^12.0.1",
53
- "@types/node": "^20.0.0",
54
- "reflect-metadata": "^0.2.2",
55
- "rxjs": "^7.8.1",
56
- "typescript": "^5.4.0",
57
- "vitest": "^3.0.0",
58
- "@dudousxd/nestjs-authz": "^0.6.5"
58
+ "@dudousxd/nestjs-inertia": "1.8.2",
59
+ "@nestjs/authorization": "0.1.3",
60
+ "@nestjs/common": "12.0.1",
61
+ "@nestjs/core": "12.0.1",
62
+ "@nestjs/testing": "12.0.1",
63
+ "@types/node": "22.20.5",
64
+ "reflect-metadata": "0.2.2",
65
+ "rxjs": "7.8.2",
66
+ "typescript": "5.9.3",
67
+ "vitest": "3.2.7",
68
+ "@dudousxd/nestjs-authz": "^0.9.1"
59
69
  },
60
70
  "engines": {
61
- "node": ">=20"
71
+ "node": ">=22"
62
72
  },
63
- "keywords": [
64
- "nestjs",
65
- "authorization",
66
- "authz",
67
- "inertia",
68
- "inertia.js",
69
- "abilities",
70
- "can"
71
- ],
72
73
  "scripts": {
73
- "build": "tsc -p tsconfig.json",
74
+ "build": "tsc -p tsconfig.json --incremental false",
74
75
  "test": "vitest run --passWithNoTests",
75
76
  "test:watch": "vitest",
76
77
  "typecheck": "tsc -p tsconfig.json --noEmit"
package/dist/client.d.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * Re-export of the framework-neutral ability store, now canonicalized in
3
- * {@link @dudousxd/nestjs-authz-client}. Kept here so the long-standing
4
- * `@dudousxd/nestjs-authz-inertia/client` entry point continues to work.
5
- *
6
- * @module client
7
- */
8
- export { AbilityStore, createCan, hydrateFromInertiaProps, hydrateResource, } from '@dudousxd/nestjs-authz-client';
9
- export type { CanMap, ResourceRef, HydratableProps, FallbackMode, AbilityStoreOptions, CanResolver, } from '@dudousxd/nestjs-authz-client';
10
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EACZ,SAAS,EACT,uBAAuB,EACvB,eAAe,GAChB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,MAAM,EACN,WAAW,EACX,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,WAAW,GACZ,MAAM,+BAA+B,CAAC"}
package/dist/client.js DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * Re-export of the framework-neutral ability store, now canonicalized in
3
- * {@link @dudousxd/nestjs-authz-client}. Kept here so the long-standing
4
- * `@dudousxd/nestjs-authz-inertia/client` entry point continues to work.
5
- *
6
- * @module client
7
- */
8
- export { AbilityStore, createCan, hydrateFromInertiaProps, hydrateResource, } from '@dudousxd/nestjs-authz-client';
9
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EACZ,SAAS,EACT,uBAAuB,EACvB,eAAe,GAChB,MAAM,+BAA+B,CAAC"}