@dudousxd/nestjs-authz 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/README.md +279 -0
  3. package/dist/authz.guard.d.ts +48 -0
  4. package/dist/authz.guard.d.ts.map +1 -0
  5. package/dist/authz.guard.js +144 -0
  6. package/dist/authz.guard.js.map +1 -0
  7. package/dist/can-endpoint.controller.d.ts +0 -19
  8. package/dist/can-endpoint.controller.d.ts.map +1 -1
  9. package/dist/can-endpoint.controller.js +18 -9
  10. package/dist/can-endpoint.controller.js.map +1 -1
  11. package/dist/decision-provider.d.ts +25 -16
  12. package/dist/decision-provider.d.ts.map +1 -1
  13. package/dist/decision-provider.js +11 -1
  14. package/dist/decision-provider.js.map +1 -1
  15. package/dist/decisions.d.ts +24 -0
  16. package/dist/decisions.d.ts.map +1 -0
  17. package/dist/decisions.js +87 -0
  18. package/dist/decisions.js.map +1 -0
  19. package/dist/decorator/roles.decorator.d.ts +6 -12
  20. package/dist/decorator/roles.decorator.d.ts.map +1 -1
  21. package/dist/decorator/roles.decorator.js +13 -15
  22. package/dist/decorator/roles.decorator.js.map +1 -1
  23. package/dist/diagnostics.d.ts +15 -5
  24. package/dist/diagnostics.d.ts.map +1 -1
  25. package/dist/diagnostics.js +3 -1
  26. package/dist/diagnostics.js.map +1 -1
  27. package/dist/errors/exceptions.d.ts +0 -8
  28. package/dist/errors/exceptions.d.ts.map +1 -1
  29. package/dist/errors/exceptions.js +0 -14
  30. package/dist/errors/exceptions.js.map +1 -1
  31. package/dist/gate.d.ts +83 -218
  32. package/dist/gate.d.ts.map +1 -1
  33. package/dist/gate.js +209 -611
  34. package/dist/gate.js.map +1 -1
  35. package/dist/helpers.d.ts +46 -0
  36. package/dist/helpers.d.ts.map +1 -0
  37. package/dist/helpers.js +89 -0
  38. package/dist/helpers.js.map +1 -0
  39. package/dist/index.d.ts +28 -21
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +30 -13
  42. package/dist/index.js.map +1 -1
  43. package/dist/links.d.ts +39 -0
  44. package/dist/links.d.ts.map +1 -0
  45. package/dist/links.js +57 -0
  46. package/dist/links.js.map +1 -0
  47. package/dist/module.d.ts +23 -22
  48. package/dist/module.d.ts.map +1 -1
  49. package/dist/module.js +129 -158
  50. package/dist/module.js.map +1 -1
  51. package/dist/official.d.ts +39 -0
  52. package/dist/official.d.ts.map +1 -0
  53. package/dist/official.js +44 -0
  54. package/dist/official.js.map +1 -0
  55. package/dist/policies/authz-policy.d.ts +42 -0
  56. package/dist/policies/authz-policy.d.ts.map +1 -0
  57. package/dist/policies/authz-policy.js +80 -0
  58. package/dist/policies/authz-policy.js.map +1 -0
  59. package/dist/policies/gate.policy.d.ts +18 -0
  60. package/dist/policies/gate.policy.d.ts.map +1 -0
  61. package/dist/policies/gate.policy.js +37 -0
  62. package/dist/policies/gate.policy.js.map +1 -0
  63. package/dist/policies/index.d.ts +5 -0
  64. package/dist/policies/index.d.ts.map +1 -0
  65. package/dist/policies/index.js +5 -0
  66. package/dist/policies/index.js.map +1 -0
  67. package/dist/policies/permission.policy.d.ts +27 -0
  68. package/dist/policies/permission.policy.d.ts.map +1 -0
  69. package/dist/policies/permission.policy.js +61 -0
  70. package/dist/policies/permission.policy.js.map +1 -0
  71. package/dist/policies/role.policy.d.ts +27 -0
  72. package/dist/policies/role.policy.d.ts.map +1 -0
  73. package/dist/policies/role.policy.js +51 -0
  74. package/dist/policies/role.policy.js.map +1 -0
  75. package/dist/policy-index.d.ts +51 -0
  76. package/dist/policy-index.d.ts.map +1 -0
  77. package/dist/policy-index.js +135 -0
  78. package/dist/policy-index.js.map +1 -0
  79. package/dist/rbac.d.ts +92 -0
  80. package/dist/rbac.d.ts.map +1 -0
  81. package/dist/rbac.js +293 -0
  82. package/dist/rbac.js.map +1 -0
  83. package/dist/resource-resolver.d.ts +15 -17
  84. package/dist/resource-resolver.d.ts.map +1 -1
  85. package/dist/resource-resolver.js +8 -8
  86. package/dist/resource-resolver.js.map +1 -1
  87. package/dist/runtime.d.ts +31 -0
  88. package/dist/runtime.d.ts.map +1 -0
  89. package/dist/runtime.js +40 -0
  90. package/dist/runtime.js.map +1 -0
  91. package/dist/tokens.d.ts +4 -8
  92. package/dist/tokens.d.ts.map +1 -1
  93. package/dist/tokens.js +4 -8
  94. package/dist/tokens.js.map +1 -1
  95. package/dist/types.d.ts +52 -171
  96. package/dist/types.d.ts.map +1 -1
  97. package/package.json +19 -10
  98. package/skills/authz-enforcement/SKILL.md +67 -135
  99. package/skills/authz-policies/SKILL.md +43 -117
  100. package/skills/authz-query-scopes/SKILL.md +16 -9
  101. package/skills/authz-rbac-seams/SKILL.md +29 -12
  102. package/skills/authz-setup/SKILL.md +45 -106
  103. package/dist/decorator/can.decorator.d.ts +0 -29
  104. package/dist/decorator/can.decorator.d.ts.map +0 -1
  105. package/dist/decorator/can.decorator.js +0 -23
  106. package/dist/decorator/can.decorator.js.map +0 -1
  107. package/dist/decorator/policy.decorator.d.ts +0 -18
  108. package/dist/decorator/policy.decorator.d.ts.map +0 -1
  109. package/dist/decorator/policy.decorator.js +0 -28
  110. package/dist/decorator/policy.decorator.js.map +0 -1
  111. package/dist/guard/can.guard.d.ts +0 -31
  112. package/dist/guard/can.guard.d.ts.map +0 -1
  113. package/dist/guard/can.guard.js +0 -92
  114. package/dist/guard/can.guard.js.map +0 -1
  115. package/dist/guard/roles.guard.d.ts +0 -21
  116. package/dist/guard/roles.guard.d.ts.map +0 -1
  117. package/dist/guard/roles.guard.js +0 -50
  118. package/dist/guard/roles.guard.js.map +0 -1
  119. package/dist/policy-registry.d.ts +0 -46
  120. package/dist/policy-registry.d.ts.map +0 -1
  121. package/dist/policy-registry.js +0 -101
  122. package/dist/policy-registry.js.map +0 -1
package/dist/rbac.js ADDED
@@ -0,0 +1,293 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { InjectCapability } from '@dudousxd/nestjs-diagnostics/nestjs';
14
+ import { Inject, Injectable, Optional } from '@nestjs/common';
15
+ import { ModuleRef } from '@nestjs/core';
16
+ import { PermissionCache } from './permission-cache.js';
17
+ import { permissionSatisfied } from './permission-matcher.js';
18
+ import { defaultRoleResolver } from './role-provider.js';
19
+ import { AUTHZ_MODULE_OPTIONS, CONTEXT_ACCESSOR, DECISION_PROVIDER, PERMISSION_PROVIDER, ROLE_PROVIDER, } from './tokens.js';
20
+ /**
21
+ * Key of the per-request {@link PermissionCache} on the nestjs-context store. `Symbol.for`
22
+ * so every copy of this module shares it.
23
+ */
24
+ const REQUEST_PERMISSION_CACHE = Symbol.for('@dudousxd/nestjs-authz:request-permission-cache');
25
+ /** Key under which the per-request `resolveUser` results are stashed on the context store. */
26
+ const REQUEST_USERS = Symbol.for('@dudousxd/nestjs-authz:request-users');
27
+ /**
28
+ * Roles and permissions of a user, from the persisted RBAC seams (`ROLE_PROVIDER`,
29
+ * `PERMISSION_PROVIDER`, registered by the TypeORM / MikroORM / Prisma / Drizzle adapters)
30
+ * and from the user object itself (`user.roles` / `user.role`); the optional external
31
+ * decision point (`DECISION_PROVIDER`); and the ambient user for `Gate` calls made without
32
+ * one. Shared by `RolePolicy`, `PermissionPolicy`, `AuthzPolicy` and the `Gate`.
33
+ *
34
+ * Within one request (a nestjs-context store), a user's permissions and provider roles
35
+ * are fetched once, however many checks run, in guards and in handlers alike.
36
+ */
37
+ let AuthzRbac = class AuthzRbac {
38
+ context;
39
+ moduleRef;
40
+ permissionProvider;
41
+ roleProvider;
42
+ decisionProvider;
43
+ roleResolver;
44
+ resolveUser;
45
+ lookups = new Map();
46
+ authentication;
47
+ constructor(options, context, moduleRef, permissionProvider, roleProvider, decisionProvider) {
48
+ this.context = context;
49
+ this.moduleRef = moduleRef;
50
+ this.permissionProvider = permissionProvider;
51
+ this.roleProvider = roleProvider;
52
+ this.decisionProvider = decisionProvider;
53
+ this.roleResolver = options?.resolveRoles ?? defaultRoleResolver;
54
+ this.resolveUser = options?.resolveUser;
55
+ }
56
+ /**
57
+ * Finds `@nestjs/authentication`'s `AuthenticationContext` when that optional peer is
58
+ * installed and its module is imported. The class is the DI token, so the package is
59
+ * loaded only here, and its absence is not an error.
60
+ */
61
+ async onModuleInit() {
62
+ if (!this.moduleRef || this.authentication)
63
+ return;
64
+ let token;
65
+ try {
66
+ const specifier = '@nestjs/authentication';
67
+ token = (await import(specifier))
68
+ .AuthenticationContext;
69
+ }
70
+ catch {
71
+ return;
72
+ }
73
+ if (typeof token !== 'function')
74
+ return;
75
+ try {
76
+ this.authentication = this.moduleRef.get(token, {
77
+ strict: false,
78
+ });
79
+ }
80
+ catch {
81
+ this.authentication = undefined;
82
+ }
83
+ }
84
+ /**
85
+ * A provider registered by any module: the injected one, else a non-strict lookup,
86
+ * memoized, so a global RBAC module or a root-level accessor is found too.
87
+ */
88
+ lookup(token, injected) {
89
+ if (injected)
90
+ return injected;
91
+ const memo = this.lookups.get(token);
92
+ if (memo)
93
+ return memo.value;
94
+ let value;
95
+ try {
96
+ value = this.moduleRef?.get(token, { strict: false });
97
+ }
98
+ catch {
99
+ value = undefined;
100
+ }
101
+ this.lookups.set(token, { value });
102
+ return value;
103
+ }
104
+ /** @internal The nestjs-context accessor, when one is registered. */
105
+ contextAccessor() {
106
+ return this.lookup(CONTEXT_ACCESSOR, this.context);
107
+ }
108
+ /** The persisted permission seam, when an RBAC adapter registered one. */
109
+ permissions() {
110
+ return this.lookup(PERMISSION_PROVIDER, this.permissionProvider);
111
+ }
112
+ /** The persisted role seam, when an RBAC adapter registered one. */
113
+ roles() {
114
+ return this.lookup(ROLE_PROVIDER, this.roleProvider);
115
+ }
116
+ /** The external decision point (Cerbos, OPA, …), when one is registered. */
117
+ decisions() {
118
+ return this.lookup(DECISION_PROVIDER, this.decisionProvider);
119
+ }
120
+ /**
121
+ * The user for a `Gate` call made without one:
122
+ *
123
+ * 1. `@nestjs/authentication`'s `AuthenticationContext.user`, when that optional peer is
124
+ * installed and its scope is active (a call it handles, or `AuthenticationContext.run()`):
125
+ * its answer is final, so a `null` there is a guest;
126
+ * 2. else, with no authentication scope at all, nestjs-context's user ref, hydrated by
127
+ * `resolveUser` when configured (once per `type:id` per request);
128
+ * 3. else `null` (a guest).
129
+ */
130
+ async currentUser() {
131
+ const authenticated = this.authenticatedUser();
132
+ if (authenticated !== undefined)
133
+ return authenticated;
134
+ const context = this.contextAccessor();
135
+ if (!context)
136
+ return null;
137
+ const ref = context.userRef();
138
+ if (ref === undefined)
139
+ return null;
140
+ const resolveUser = this.resolveUser;
141
+ if (!resolveUser)
142
+ return ref;
143
+ const hydrate = async () => (await resolveUser(ref)) ?? null;
144
+ const store = this.requestStore();
145
+ if (!store)
146
+ return hydrate();
147
+ let users = store[REQUEST_USERS];
148
+ if (!(users instanceof Map)) {
149
+ users = new Map();
150
+ store[REQUEST_USERS] = users;
151
+ }
152
+ const key = `${ref.type}:${typeof ref.id}:${ref.id}`;
153
+ const cached = users.get(key);
154
+ if (cached)
155
+ return cached;
156
+ const pending = hydrate();
157
+ users.set(key, pending);
158
+ pending.catch(() => users.delete(key));
159
+ return pending;
160
+ }
161
+ /**
162
+ * `AuthenticationContext.user` (`null` for an anonymous call) when its scope is active;
163
+ * `undefined` without the package or outside its scope. A version that hides the scope is
164
+ * read as before: a user is an answer, `null` is not.
165
+ */
166
+ authenticatedUser() {
167
+ const authentication = this.authentication;
168
+ if (!authentication)
169
+ return undefined;
170
+ try {
171
+ const scope = authentication.scope;
172
+ if (scope && typeof scope === 'object' && 'current' in scope) {
173
+ return scope.current === undefined ? undefined : (authentication.user ?? null);
174
+ }
175
+ return authentication.user ?? undefined;
176
+ }
177
+ catch {
178
+ return undefined;
179
+ }
180
+ }
181
+ /** The nestjs-context store for the current request, or `undefined` when there is none. */
182
+ requestStore() {
183
+ const context = this.contextAccessor();
184
+ if (!context || typeof context.get !== 'function')
185
+ return undefined;
186
+ let store;
187
+ try {
188
+ store = context.get();
189
+ }
190
+ catch {
191
+ store = undefined;
192
+ }
193
+ return store;
194
+ }
195
+ /**
196
+ * The per-request {@link PermissionCache} on the nestjs-context store, so every check
197
+ * in one request shares a single `getPermissions` and `getRoles` fetch per user.
198
+ * `undefined` without a store.
199
+ */
200
+ requestCache() {
201
+ const store = this.requestStore();
202
+ if (!store)
203
+ return undefined;
204
+ const existing = store[REQUEST_PERMISSION_CACHE];
205
+ if (existing instanceof PermissionCache)
206
+ return existing;
207
+ const cache = new PermissionCache();
208
+ store[REQUEST_PERMISSION_CACHE] = cache;
209
+ return cache;
210
+ }
211
+ /**
212
+ * The user's role names: the role resolver's (the user object) and the role provider's,
213
+ * the latter fetched through `cache` (the request's, by default).
214
+ */
215
+ async rolesOf(user, cache = this.requestCache()) {
216
+ const out = new Set();
217
+ if (user == null)
218
+ return out;
219
+ const fromResolver = await this.roleResolver(user);
220
+ if (Array.isArray(fromResolver)) {
221
+ for (const r of fromResolver)
222
+ if (typeof r === 'string')
223
+ out.add(r);
224
+ }
225
+ const provider = this.roles();
226
+ if (provider) {
227
+ const fromProvider = await (cache ? cache.getRoles(provider, user) : provider.getRoles(user));
228
+ if (Array.isArray(fromProvider)) {
229
+ for (const r of fromProvider)
230
+ if (typeof r === 'string')
231
+ out.add(r);
232
+ }
233
+ }
234
+ return out;
235
+ }
236
+ /** True when the user holds any of `roles`. A guest holds none. */
237
+ async hasAnyRole(user, roles, cache) {
238
+ if (user == null || roles.length === 0)
239
+ return false;
240
+ const held = await this.rolesOf(user, cache ?? this.requestCache());
241
+ return roles.some((r) => held.has(r));
242
+ }
243
+ /** True when the user holds every one of `roles`. */
244
+ async hasAllRoles(user, roles) {
245
+ if (user == null || roles.length === 0)
246
+ return false;
247
+ const held = await this.rolesOf(user);
248
+ return roles.every((r) => held.has(r));
249
+ }
250
+ /**
251
+ * True when the permission seam grants `permission` to `user`. With `getPermissions`,
252
+ * wildcard grants apply (`posts.*` satisfies `posts.update`, `*` anything), fetched
253
+ * once per `cache` (the request's, by default). A set the provider marks
254
+ * `exhaustivePermissions` answers on its own; otherwise a miss still asks the
255
+ * exact-match `hasPermission`. A guest, or no seam, is never granted.
256
+ */
257
+ async grants(user, permission, resource, cache = this.requestCache()) {
258
+ if (user == null)
259
+ return false;
260
+ const provider = this.permissions();
261
+ if (!provider)
262
+ return false;
263
+ if (typeof provider.getPermissions === 'function') {
264
+ const satisfied = cache
265
+ ? await cache.satisfies(provider, user, permission)
266
+ : await (async () => {
267
+ const granted = await provider.getPermissions?.(user);
268
+ return granted == null ? undefined : permissionSatisfied(granted, permission);
269
+ })();
270
+ if (satisfied === true)
271
+ return true;
272
+ if (satisfied === false && provider.exhaustivePermissions === true)
273
+ return false;
274
+ }
275
+ return (await provider.hasPermission(user, permission, resource)) === true;
276
+ }
277
+ };
278
+ AuthzRbac = __decorate([
279
+ Injectable(),
280
+ __param(0, Optional()),
281
+ __param(0, Inject(AUTHZ_MODULE_OPTIONS)),
282
+ __param(1, InjectCapability('context', 'accessor')),
283
+ __param(2, Optional()),
284
+ __param(3, Optional()),
285
+ __param(3, Inject(PERMISSION_PROVIDER)),
286
+ __param(4, Optional()),
287
+ __param(4, Inject(ROLE_PROVIDER)),
288
+ __param(5, Optional()),
289
+ __param(5, Inject(DECISION_PROVIDER)),
290
+ __metadata("design:paramtypes", [Object, Object, ModuleRef, Object, Object, Object])
291
+ ], AuthzRbac);
292
+ export { AuthzRbac };
293
+ //# sourceMappingURL=rbac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.js","sourceRoot":"","sources":["../src/rbac.ts"],"names":[],"mappings":"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"}
@@ -1,29 +1,27 @@
1
1
  import type { ExecutionContext, Type } from '@nestjs/common';
2
+ /** Per-call hints `byId(Resource, { param })` passes to the resolver. */
3
+ export interface ResourceResolveHints {
4
+ /** The route param holding the id, when `byId` named one. */
5
+ param?: string;
6
+ }
2
7
  /**
3
- * Resolves a resource instance for a `@Can(ability, Resource)` route so the guard
4
- * can pass it to the policy method. Apps register an implementation (typically
5
- * ORM-backed) via `AuthzModule.forRoot({ ... })` or as a provider bound to the
6
- * {@link RESOURCE_RESOLVER} token.
7
- *
8
- * Class-level abilities (no resource class on `@Can`) never call the resolver.
8
+ * Loads the resource a `byId(Resource)` argument resolver hands to the policy
9
+ * (`@Can(PostPolicy, 'update', byId(Post))`). Register one, typically ORM-backed, with
10
+ * `AuthzModule.forRoot({ resourceResolver })`. Return `undefined` for "not found":
11
+ * `byId` then refuses the call with a 403 before the policy runs.
9
12
  */
10
13
  export interface ResourceResolver {
11
- /**
12
- * Load the resource instance for `resource` in the given request context.
13
- * Return `undefined` to signal "not found" — the guard treats a missing
14
- * resource as a denial.
15
- */
16
- resolve(resource: Type<unknown>, ctx: ExecutionContext): Promise<object | undefined> | object | undefined;
14
+ resolve(resource: Type<unknown>, ctx: ExecutionContext, hints?: ResourceResolveHints): Promise<object | undefined> | object | undefined;
17
15
  }
18
16
  /**
19
- * Default resolver: reads the route `:id` param and produces a lightweight
20
- * `{ id }` shim of the requested resource class. This keeps the guard usable
21
- * out-of-the-box (e.g. ownership checks on `resource.id`) without an ORM, while
22
- * apps that need real entities register their own {@link ResourceResolver}.
17
+ * Default resolver: reads the route `:id` param and produces a lightweight `{ id }`
18
+ * object whose prototype is the resource class's, enough for ownership checks on
19
+ * `resource.id` without an ORM. Register your own {@link ResourceResolver} to load
20
+ * real entities.
23
21
  */
24
22
  export declare class IdParamResourceResolver implements ResourceResolver {
25
23
  private readonly param;
26
24
  constructor(param?: string);
27
- resolve(resource: Type<unknown>, ctx: ExecutionContext): object | undefined;
25
+ resolve(resource: Type<unknown>, ctx: ExecutionContext, hints?: ResourceResolveHints): object | undefined;
28
26
  }
29
27
  //# sourceMappingURL=resource-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource-resolver.d.ts","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,OAAO,CACL,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,EACvB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;CACrD;AAED;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,gBAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,GAAE,MAAa;IAEjD,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS;CAU5E"}
1
+ {"version":3,"file":"resource-resolver.d.ts","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7D,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CACL,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,EACvB,GAAG,EAAE,gBAAgB,EACrB,KAAK,CAAC,EAAE,oBAAoB,GAC3B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;CACrD;AAED;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,gBAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,GAAE,MAAa;IAEjD,OAAO,CACL,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,EACvB,GAAG,EAAE,gBAAgB,EACrB,KAAK,CAAC,EAAE,oBAAoB,GAC3B,MAAM,GAAG,SAAS;CAStB"}
@@ -1,21 +1,21 @@
1
1
  /**
2
- * Default resolver: reads the route `:id` param and produces a lightweight
3
- * `{ id }` shim of the requested resource class. This keeps the guard usable
4
- * out-of-the-box (e.g. ownership checks on `resource.id`) without an ORM, while
5
- * apps that need real entities register their own {@link ResourceResolver}.
2
+ * Default resolver: reads the route `:id` param and produces a lightweight `{ id }`
3
+ * object whose prototype is the resource class's, enough for ownership checks on
4
+ * `resource.id` without an ORM. Register your own {@link ResourceResolver} to load
5
+ * real entities.
6
6
  */
7
7
  export class IdParamResourceResolver {
8
8
  param;
9
9
  constructor(param = 'id') {
10
10
  this.param = param;
11
11
  }
12
- resolve(resource, ctx) {
12
+ resolve(resource, ctx, hints) {
13
+ if (ctx.getType() !== 'http')
14
+ return undefined;
13
15
  const req = ctx.switchToHttp().getRequest();
14
- const id = req?.params?.[this.param];
16
+ const id = req?.params?.[hints?.param ?? this.param];
15
17
  if (id === undefined)
16
18
  return undefined;
17
- // Construct a shaped instance so `instance.constructor === resource`, which
18
- // is how PolicyRegistry maps an instance back to its policy.
19
19
  const instance = Object.create(resource.prototype);
20
20
  instance.id = id;
21
21
  return instance;
@@ -1 +1 @@
1
- {"version":3,"file":"resource-resolver.js","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IACL;IAA7B,YAA6B,QAAgB,IAAI;QAApB,UAAK,GAAL,KAAK,CAAe;IAAG,CAAC;IAErD,OAAO,CAAC,QAAuB,EAAE,GAAqB;QACpD,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAwC,CAAC;QAClF,MAAM,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACvC,4EAA4E;QAC5E,6DAA6D;QAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAA4B,CAAC;QAC9E,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"resource-resolver.js","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IACL;IAA7B,YAA6B,QAAgB,IAAI;QAApB,UAAK,GAAL,KAAK,CAAe;IAAG,CAAC;IAErD,OAAO,CACL,QAAuB,EACvB,GAAqB,EACrB,KAA4B;QAE5B,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC;QAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAwC,CAAC;QAClF,MAAM,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAA4B,CAAC;QAC9E,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ import type { ExecutionContext } from '@nestjs/common';
2
+ import type { DecisionProvider } from './decision-provider.js';
3
+ import { type ResourceResolver } from './resource-resolver.js';
4
+ import type { SuperAdminHook } from './types.js';
5
+ /**
6
+ * What `@Can()` argument resolvers and policy base classes need from the app but
7
+ * cannot inject: the official resolvers run with only the `ExecutionContext`, and a
8
+ * policy base class cannot add constructor parameters to its subclasses. `AuthzModule`
9
+ * fills this in when it boots. One application per process is the expected case; with
10
+ * several, the last one to boot wins.
11
+ */
12
+ interface AuthzRuntime {
13
+ resourceResolver: ResourceResolver;
14
+ superAdmin: SuperAdminHook | undefined;
15
+ /** The external decision point, looked up lazily (an adapter may register it late). */
16
+ decisionProvider: () => DecisionProvider | undefined;
17
+ getUser: (context: ExecutionContext) => unknown;
18
+ }
19
+ /** @internal Called by `AuthzModule` at boot, and by the testing helpers. */
20
+ export declare function configureAuthzRuntime(patch: Partial<AuthzRuntime>): void;
21
+ /** @internal Restore the defaults (tests). */
22
+ export declare function resetAuthzRuntime(): void;
23
+ /** @internal */
24
+ export declare function authzRuntime(): Readonly<AuthzRuntime>;
25
+ /**
26
+ * The user the official guard sees for this call: the `getUser` given to
27
+ * `AuthorizationModule.forRoot()`, else the official `defaultGetUser`. `null` for a guest.
28
+ */
29
+ export declare function currentUserOf(context: ExecutionContext): Promise<unknown>;
30
+ export {};
31
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;GAMG;AACH,UAAU,YAAY;IACpB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,UAAU,EAAE,cAAc,GAAG,SAAS,CAAC;IACvC,uFAAuF;IACvF,gBAAgB,EAAE,MAAM,gBAAgB,GAAG,SAAS,CAAC;IACrD,OAAO,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC;CACjD;AAWD,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAKxE;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED,gBAAgB;AAChB,wBAAgB,YAAY,IAAI,QAAQ,CAAC,YAAY,CAAC,CAErD;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAG/E"}
@@ -0,0 +1,40 @@
1
+ import { defaultGetUser } from '@nestjs/authorization';
2
+ import { IdParamResourceResolver } from './resource-resolver.js';
3
+ const noDecisionProvider = () => undefined;
4
+ const runtime = {
5
+ resourceResolver: new IdParamResourceResolver(),
6
+ superAdmin: undefined,
7
+ decisionProvider: noDecisionProvider,
8
+ getUser: defaultGetUser,
9
+ };
10
+ /** @internal Called by `AuthzModule` at boot, and by the testing helpers. */
11
+ export function configureAuthzRuntime(patch) {
12
+ if (patch.resourceResolver)
13
+ runtime.resourceResolver = patch.resourceResolver;
14
+ if ('superAdmin' in patch)
15
+ runtime.superAdmin = patch.superAdmin;
16
+ if (patch.decisionProvider)
17
+ runtime.decisionProvider = patch.decisionProvider;
18
+ if (patch.getUser)
19
+ runtime.getUser = patch.getUser;
20
+ }
21
+ /** @internal Restore the defaults (tests). */
22
+ export function resetAuthzRuntime() {
23
+ runtime.resourceResolver = new IdParamResourceResolver();
24
+ runtime.superAdmin = undefined;
25
+ runtime.decisionProvider = noDecisionProvider;
26
+ runtime.getUser = defaultGetUser;
27
+ }
28
+ /** @internal */
29
+ export function authzRuntime() {
30
+ return runtime;
31
+ }
32
+ /**
33
+ * The user the official guard sees for this call: the `getUser` given to
34
+ * `AuthorizationModule.forRoot()`, else the official `defaultGetUser`. `null` for a guest.
35
+ */
36
+ export async function currentUserOf(context) {
37
+ const user = await runtime.getUser(context);
38
+ return user === undefined || user === false ? null : user;
39
+ }
40
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,uBAAuB,EAAyB,MAAM,wBAAwB,CAAC;AAkBxF,MAAM,kBAAkB,GAAG,GAAiC,EAAE,CAAC,SAAS,CAAC;AAEzE,MAAM,OAAO,GAAiB;IAC5B,gBAAgB,EAAE,IAAI,uBAAuB,EAAE;IAC/C,UAAU,EAAE,SAAS;IACrB,gBAAgB,EAAE,kBAAkB;IACpC,OAAO,EAAE,cAAc;CACxB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CAAC,KAA4B;IAChE,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC9E,IAAI,YAAY,IAAI,KAAK;QAAE,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACjE,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC9E,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;AACrD,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CAAC,gBAAgB,GAAG,IAAI,uBAAuB,EAAE,CAAC;IACzD,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,gBAAgB,GAAG,kBAAkB,CAAC;IAC9C,OAAO,CAAC,OAAO,GAAG,cAAc,CAAC;AACnC,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAyB;IAC3D,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC"}
package/dist/tokens.d.ts CHANGED
@@ -17,12 +17,8 @@ export declare const RESOURCE_RESOLVER: symbol;
17
17
  * or empty, the endpoint behaves exactly as before (class-level / ad-hoc only).
18
18
  */
19
19
  export declare const RESOURCE_HYDRATOR: symbol;
20
- /** Metadata key for `@Policy(Resource)` — stores the resource class on the policy. */
21
- export declare const POLICY_RESOURCE_METADATA = "nestjs-authz:policy-resource";
22
- /** Metadata key for `@Can(ability, Resource?)` — stores the ability descriptor on a route. */
23
- export declare const CAN_METADATA = "nestjs-authz:can";
24
- /** Metadata key for `@Roles(...roles)` — stores the allowed role names on a route. */
25
- export declare const ROLES_METADATA = "nestjs-authz:roles";
20
+ /** Metadata key of the `@PolicyFor(Resource)` link on a policy class. */
21
+ export { POLICY_RESOURCE_METADATA } from './links.js';
26
22
  /**
27
23
  * Cross-lib injection token for an optional {@link PermissionProvider} — the seam the
28
24
  * RBAC adapter (`@dudousxd/nestjs-authz-typeorm`) registers so that a model-less,
@@ -31,8 +27,8 @@ export declare const ROLES_METADATA = "nestjs-authz:roles";
31
27
  *
32
28
  * `Symbol.for(key)` uses the global symbol registry so an RBAC package registering
33
29
  * this same key resolves to the SAME symbol instance without importing core internals.
34
- * The token is consulted with `@Optional()` — when absent, the Gate behaves exactly
35
- * as before (backward-compatible: unknown abilities still throw).
30
+ * The token is consulted with `@Optional()` — when absent, an unknown string ability
31
+ * still throws.
36
32
  */
37
33
  export declare const PERMISSION_PROVIDER: symbol;
38
34
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,QAAiC,CAAC;AAEnE,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E,sFAAsF;AACtF,eAAO,MAAM,wBAAwB,iCAAiC,CAAC;AAEvE,8FAA8F;AAC9F,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAE/C,sFAAsF;AACtF,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,QAA6C,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,QAAoC,CAAC"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,QAAiC,CAAC;AAEnE,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E,yEAAyE;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,QAA6C,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,QAAoC,CAAC"}
package/dist/tokens.js CHANGED
@@ -18,12 +18,8 @@ export const RESOURCE_RESOLVER = capability('authz', 'resource-resolver');
18
18
  * or empty, the endpoint behaves exactly as before (class-level / ad-hoc only).
19
19
  */
20
20
  export const RESOURCE_HYDRATOR = capability('authz', 'resource-hydrator');
21
- /** Metadata key for `@Policy(Resource)` — stores the resource class on the policy. */
22
- export const POLICY_RESOURCE_METADATA = 'nestjs-authz:policy-resource';
23
- /** Metadata key for `@Can(ability, Resource?)` — stores the ability descriptor on a route. */
24
- export const CAN_METADATA = 'nestjs-authz:can';
25
- /** Metadata key for `@Roles(...roles)` — stores the allowed role names on a route. */
26
- export const ROLES_METADATA = 'nestjs-authz:roles';
21
+ /** Metadata key of the `@PolicyFor(Resource)` link on a policy class. */
22
+ export { POLICY_RESOURCE_METADATA } from './links.js';
27
23
  /**
28
24
  * Cross-lib injection token for an optional {@link PermissionProvider} — the seam the
29
25
  * RBAC adapter (`@dudousxd/nestjs-authz-typeorm`) registers so that a model-less,
@@ -32,8 +28,8 @@ export const ROLES_METADATA = 'nestjs-authz:roles';
32
28
  *
33
29
  * `Symbol.for(key)` uses the global symbol registry so an RBAC package registering
34
30
  * this same key resolves to the SAME symbol instance without importing core internals.
35
- * The token is consulted with `@Optional()` — when absent, the Gate behaves exactly
36
- * as before (backward-compatible: unknown abilities still throw).
31
+ * The token is consulted with `@Optional()` — when absent, an unknown string ability
32
+ * still throws.
37
33
  */
38
34
  export const PERMISSION_PROVIDER = capability('authz', 'permission-provider');
39
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAEnE,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E,sFAAsF;AACtF,MAAM,CAAC,MAAM,wBAAwB,GAAG,8BAA8B,CAAC;AAEvE,8FAA8F;AAC9F,MAAM,CAAC,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAE/C,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC"}
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAEnE,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E,yEAAyE;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC"}