@dudousxd/nestjs-authz 0.10.0 → 0.12.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 +21 -0
- package/README.md +1 -1
- package/dist/console.d.ts.map +1 -1
- package/dist/console.js +3 -1
- package/dist/console.js.map +1 -1
- package/dist/dev-tools.d.ts +102 -0
- package/dist/dev-tools.d.ts.map +1 -0
- package/dist/dev-tools.js +403 -0
- package/dist/dev-tools.js.map +1 -0
- package/dist/gate.d.ts +23 -0
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +44 -1
- package/dist/gate.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +2 -0
- package/dist/module.js.map +1 -1
- package/dist/rbac.d.ts +11 -1
- package/dist/rbac.d.ts.map +1 -1
- package/dist/rbac.js +22 -1
- package/dist/rbac.js.map +1 -1
- package/dist/role-provider.d.ts +25 -0
- package/dist/role-provider.d.ts.map +1 -1
- package/dist/role-provider.js.map +1 -1
- package/dist/tenant-override.d.ts +31 -0
- package/dist/tenant-override.d.ts.map +1 -0
- package/dist/tenant-override.js +42 -0
- package/dist/tenant-override.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/skills/authz-rbac-seams/SKILL.md +16 -0
- package/skills/authz-setup/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @dudousxd/nestjs-authz
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#76](https://github.com/DavideCarvalho/nestjs-authz/pull/76) [`d2a9b06`](https://github.com/DavideCarvalho/nestjs-authz/commit/d2a9b06c398b80c68957ae573c1f5bd866a9ff72) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Add MCP dev tools: `AuthzModule` registers `authz_explain_check`, `authz_list_effective_roles` and `authz_list_effective_permissions` in the Aviary dev-tools slot (`Symbol.for('@dudousxd/aviary:dev-tools')`, created when absent). They register without an `authorize`, so the agent dev endpoint's `devTools.authorize` gates them (open outside production, denied in production without it); a hub that cannot gate console-less libs leaves them out. `devTools: { loadSubject, loadResource }` hands checks your models (default: `resolveUser` and `resourceLoaders`); `devTools: false` turns the tools off. New: `gate.explainFor(user, ability, resource?)`, `runInTenantScope(tenantId, fn)`, and `RoleProvider.describeRbac?(user)`, which the RBAC adapters implement; the adapters honour a scope forced by `runInTenantScope` ahead of their `tenant` resolver and the context tenant.
|
|
8
|
+
|
|
9
|
+
- [#76](https://github.com/DavideCarvalho/nestjs-authz/pull/76) [`d2a9b06`](https://github.com/DavideCarvalho/nestjs-authz/commit/d2a9b06c398b80c68957ae573c1f5bd866a9ff72) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Tenancy for nested tenants, tenant families and required tenants (nestjs-context's chain contract, read structurally, so older contexts keep working):
|
|
10
|
+
|
|
11
|
+
- A role or grant assigned at any level of the active tenant chain applies (a clinic role counts inside its units). `tenancy.kinds` picks the levels, and the context's own `kinds` apply when the module sets none.
|
|
12
|
+
- `tenancy.roles` maps the caller's role at every level of the chain.
|
|
13
|
+
- New `tenancy.family` option.
|
|
14
|
+
- New `tenancy.required` option, defaulting to the context's. A check with no tenant throws `TenantRequiredError` (403, `E_TENANT_REQUIRED`) instead of running in the global scope.
|
|
15
|
+
- Console `authorize` helpers, the MCP dev tools, and the new `runWithoutRequiredTenant(fn)` pass `required: false`.
|
|
16
|
+
- `describeRbac` reports the `tenantChain`.
|
|
17
|
+
|
|
18
|
+
## 0.11.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- [#74](https://github.com/DavideCarvalho/nestjs-authz/pull/74) [`35421dc`](https://github.com/DavideCarvalho/nestjs-authz/commit/35421dc5b09bd271d5087d26e8536191ef6ba342) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - **Breaking:** require Node.js 24 or newer (`engines.node` is now `>=24`; it was `>=22`, and `>=20` for `-client` and `-react`). CI tests on Node 24 and 26. No API changes: see the Upgrading page in the docs.
|
|
23
|
+
|
|
3
24
|
## 0.10.0
|
|
4
25
|
|
|
5
26
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ See [`DESIGN.md`](https://github.com/DavideCarvalho/nestjs-authz/blob/main/DESIG
|
|
|
37
37
|
pnpm add @nestjs/authorization @dudousxd/nestjs-authz
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
Requires NestJS 12 and Node
|
|
40
|
+
Requires NestJS 12 and Node 24+. Two optional peers: `@nestjs/authentication` gives the `Gate`
|
|
41
41
|
its ambient user (`AuthenticationContext.user`); `@dudousxd/nestjs-context` gives it one too
|
|
42
42
|
(outside an authentication scope), plus the per-request permission cache and
|
|
43
43
|
tenant-scoped roles.
|
package/dist/console.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,0BAA0B,EAEhC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,gBAAgB,EAKrB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,0BAA0B,EAEhC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,gBAAgB,EAKrB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIvC,gDAAgD;AAChD,MAAM,MAAM,sBAAsB,GAC9B,OAAO,GACP;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAAA;CAAE,GAC5D;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3B,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAChG;AACD,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAE7D,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,MAAM,gBAAgB,GACxB,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,GACzF,sBAAsB,GACtB,CAAC,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAAC,CAAC,GACpD,kBAAkB,GAClB,MAAM,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,YAAY,eAA8C,CAAC;AAQxE;;;;GAIG;AACH,qBACa,gBAAgB;IAIzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAGrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAP5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;gBAGtC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,SAAS,EAGf,QAAQ,CAAC,EAAE,0BAA0B,YAAA;IAGxD,oDAAoD;IAC9C,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtD;;;;OAIG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IActF,4FAA4F;IACtF,KAAK,CACT,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,GACrC,OAAO,CAAC,sBAAsB,CAAC;CAMnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,sBAAsB,CAoB9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,sBAAsB,CAmBhF;AAID;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,sBAAsB,CAexD"}
|
package/dist/console.js
CHANGED
|
@@ -18,6 +18,7 @@ import { Gate } from './gate.js';
|
|
|
18
18
|
import { PermissionPolicy } from './policies/permission.policy.js';
|
|
19
19
|
import { RolePolicy } from './policies/role.policy.js';
|
|
20
20
|
import { AuthzRbac } from './rbac.js';
|
|
21
|
+
import { runWithoutRequiredTenant } from './tenant-override.js';
|
|
21
22
|
/**
|
|
22
23
|
* The token Aviary consoles resolve `authorize: '<gate name>'` through. `AuthzModule`
|
|
23
24
|
* provides it globally.
|
|
@@ -76,7 +77,8 @@ let AuthzConsoleGate = class AuthzConsoleGate {
|
|
|
76
77
|
/** @internal Runs `test` for the call's user and turns the answer into a console result. */
|
|
77
78
|
async check(context, test) {
|
|
78
79
|
const user = await this.userOf(context);
|
|
79
|
-
|
|
80
|
+
// Console access is not a tenant-scoped read: `tenancy.required` never denies it.
|
|
81
|
+
if (await runWithoutRequiredTenant(() => test(user)))
|
|
80
82
|
return true;
|
|
81
83
|
return user === null ? unauthenticated() : false;
|
|
82
84
|
}
|
package/dist/console.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.js","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,4BAA4B,EAE5B,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,MAAM,EACN,UAAU,EACV,MAAM,EACN,QAAQ,GAET,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { type OnModuleDestroy, type OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { Gate } from './gate.js';
|
|
3
|
+
import { AuthzRbac } from './rbac.js';
|
|
4
|
+
import type { AuthzModuleOptions } from './types.js';
|
|
5
|
+
/** The process-wide slot the Aviary dev MCP endpoint serves (`@dudousxd/nestjs-agent-mcp-server`). */
|
|
6
|
+
export declare const DEV_TOOLS_SLOT: unique symbol;
|
|
7
|
+
/** One property of a {@link DevToolInputSchema}. */
|
|
8
|
+
export interface DevToolInputProperty {
|
|
9
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'array';
|
|
10
|
+
description?: string;
|
|
11
|
+
enum?: readonly string[];
|
|
12
|
+
items?: {
|
|
13
|
+
type: 'string';
|
|
14
|
+
};
|
|
15
|
+
minimum?: number;
|
|
16
|
+
maximum?: number;
|
|
17
|
+
}
|
|
18
|
+
/** A dev tool's input: an object of scalar / enum / array-of-string properties. */
|
|
19
|
+
export interface DevToolInputSchema {
|
|
20
|
+
type: 'object';
|
|
21
|
+
properties: Record<string, DevToolInputProperty>;
|
|
22
|
+
required?: string[];
|
|
23
|
+
}
|
|
24
|
+
/** What a tool's `run` receives besides its input. */
|
|
25
|
+
export interface DevToolCall {
|
|
26
|
+
context: unknown;
|
|
27
|
+
caller: {
|
|
28
|
+
id: string;
|
|
29
|
+
via: 'token' | 'session' | 'open';
|
|
30
|
+
};
|
|
31
|
+
limits: {
|
|
32
|
+
maxRows: number;
|
|
33
|
+
maxBytes: number;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** One developer tool, as the dev-tools slot takes it. */
|
|
37
|
+
export interface AuthzDevTool {
|
|
38
|
+
name: string;
|
|
39
|
+
kind: 'read' | 'action';
|
|
40
|
+
description: string;
|
|
41
|
+
input: DevToolInputSchema;
|
|
42
|
+
destructive?: boolean;
|
|
43
|
+
available?(): boolean | Promise<boolean>;
|
|
44
|
+
run(input: Record<string, unknown>, call?: DevToolCall): Promise<unknown>;
|
|
45
|
+
}
|
|
46
|
+
/** A `{ type, id }` reference the tools take for a subject or a resource. */
|
|
47
|
+
export interface AuthzDevToolsRef {
|
|
48
|
+
type: string;
|
|
49
|
+
id: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The `devTools` hooks of `AuthzModule.forRoot()`: load the real models behind the refs a tool
|
|
53
|
+
* asks about, so policies, `superAdmin` and the decision provider see what they see in the app.
|
|
54
|
+
*/
|
|
55
|
+
export interface AuthzDevToolsOptions {
|
|
56
|
+
/**
|
|
57
|
+
* Load the subject (`{ type: 'user', id: '42' }` → your `User`). Default: `resolveUser`, when
|
|
58
|
+
* configured. Without either, checks receive the `{ type, id }` ref itself. Return
|
|
59
|
+
* `undefined`/`null` when it does not exist.
|
|
60
|
+
*/
|
|
61
|
+
loadSubject?: (ref: AuthzDevToolsRef) => unknown | Promise<unknown>;
|
|
62
|
+
/**
|
|
63
|
+
* Load the resource of `authz_explain_check` (`{ type: 'Post', id: '7' }` → your `Post`).
|
|
64
|
+
* Default: the `resourceLoaders` entry of that type. Without either, checks receive the
|
|
65
|
+
* `{ type, id }` ref, which no `@PolicyFor` policy is linked to.
|
|
66
|
+
*/
|
|
67
|
+
loadResource?: (ref: AuthzDevToolsRef) => unknown | Promise<unknown>;
|
|
68
|
+
}
|
|
69
|
+
/** What the tools read, at call time. */
|
|
70
|
+
export interface AuthzDevToolsDeps {
|
|
71
|
+
gate: Gate;
|
|
72
|
+
rbac: AuthzRbac;
|
|
73
|
+
options: () => AuthzModuleOptions;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The authz developer tools (all read-only): explain a check, and a subject's effective roles
|
|
77
|
+
* and permissions.
|
|
78
|
+
*/
|
|
79
|
+
export declare function authzDevTools(deps: AuthzDevToolsDeps): AuthzDevTool[];
|
|
80
|
+
/** Why {@link registerAuthzDevTools} did or did not register. */
|
|
81
|
+
export type DevToolsRegistration = 'registered' | 'unsupported' | 'failed';
|
|
82
|
+
/**
|
|
83
|
+
* Register the authz tools into the dev-tools slot (created when absent), without an
|
|
84
|
+
* `authorize`: the dev endpoint's `devTools.authorize` gates them. A hub that says it cannot gate a
|
|
85
|
+
* lib without a console (`supports('endpoint-authorize')` is false) is left alone. Never throws.
|
|
86
|
+
*/
|
|
87
|
+
export declare function registerAuthzDevTools(deps: AuthzDevToolsDeps): {
|
|
88
|
+
outcome: DevToolsRegistration;
|
|
89
|
+
unregister?: () => void;
|
|
90
|
+
};
|
|
91
|
+
/** Registers the authz dev tools at module init and removes them at module destroy. */
|
|
92
|
+
export declare class AuthzDevTools implements OnModuleInit, OnModuleDestroy {
|
|
93
|
+
private readonly gate;
|
|
94
|
+
private readonly rbac;
|
|
95
|
+
private readonly logger;
|
|
96
|
+
private readonly options;
|
|
97
|
+
private unregister;
|
|
98
|
+
constructor(gate: Gate, rbac: AuthzRbac, options?: AuthzModuleOptions);
|
|
99
|
+
onModuleInit(): void;
|
|
100
|
+
onModuleDestroy(): void;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=dev-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-tools.d.ts","sourceRoot":"","sources":["../src/dev-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,403 @@
|
|
|
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 { Inject, Injectable, Logger, Optional, } from '@nestjs/common';
|
|
14
|
+
import { Gate } from './gate.js';
|
|
15
|
+
import { permissionSatisfied } from './permission-matcher.js';
|
|
16
|
+
import { AuthzRbac } from './rbac.js';
|
|
17
|
+
import { runInTenantScope, runWithoutRequiredTenant } from './tenant-override.js';
|
|
18
|
+
import { AUTHZ_MODULE_OPTIONS } from './tokens.js';
|
|
19
|
+
// ── the dev-tools contract (v1), re-declared: authz never imports the agent's MCP server ──
|
|
20
|
+
/** The process-wide slot the Aviary dev MCP endpoint serves (`@dudousxd/nestjs-agent-mcp-server`). */
|
|
21
|
+
export const DEV_TOOLS_SLOT = Symbol.for('@dudousxd/aviary:dev-tools');
|
|
22
|
+
/** The slot, created when absent (whoever loads first creates it). */
|
|
23
|
+
function devToolsSlot() {
|
|
24
|
+
const holder = globalThis;
|
|
25
|
+
const existing = holder[DEV_TOOLS_SLOT];
|
|
26
|
+
if (existing !== undefined)
|
|
27
|
+
return existing;
|
|
28
|
+
const libs = [];
|
|
29
|
+
const slot = {
|
|
30
|
+
version: 1,
|
|
31
|
+
libs,
|
|
32
|
+
register(lib) {
|
|
33
|
+
if (libs.some((entry) => entry.lib === lib.lib)) {
|
|
34
|
+
throw new Error(`dev tools: the lib "${lib.lib}" is already registered`);
|
|
35
|
+
}
|
|
36
|
+
libs.push(lib);
|
|
37
|
+
return () => {
|
|
38
|
+
const index = libs.indexOf(lib);
|
|
39
|
+
if (index !== -1)
|
|
40
|
+
libs.splice(index, 1);
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
holder[DEV_TOOLS_SLOT] = slot;
|
|
45
|
+
return slot;
|
|
46
|
+
}
|
|
47
|
+
const subjectType = {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: "The subject type (default 'user').",
|
|
50
|
+
};
|
|
51
|
+
const subjectId = {
|
|
52
|
+
type: 'string',
|
|
53
|
+
description: 'The subject id (a user id, a team id…).',
|
|
54
|
+
};
|
|
55
|
+
const tenantId = {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: "Tenant to check in. Omitted: the scope the app's own checks would use in this request. '' forces the global scope.",
|
|
58
|
+
};
|
|
59
|
+
const limit = {
|
|
60
|
+
type: 'integer',
|
|
61
|
+
description: 'How many items to return (default 20, max 100).',
|
|
62
|
+
minimum: 1,
|
|
63
|
+
maximum: 100,
|
|
64
|
+
};
|
|
65
|
+
const page = {
|
|
66
|
+
type: 'integer',
|
|
67
|
+
description: 'Page number, from 1 (the `next` of the previous answer).',
|
|
68
|
+
minimum: 1,
|
|
69
|
+
};
|
|
70
|
+
function intOf(value, fallback, max = Number.MAX_SAFE_INTEGER) {
|
|
71
|
+
return typeof value === 'number' && Number.isFinite(value)
|
|
72
|
+
? Math.max(1, Math.min(max, Math.floor(value)))
|
|
73
|
+
: fallback;
|
|
74
|
+
}
|
|
75
|
+
function str(value) {
|
|
76
|
+
return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined;
|
|
77
|
+
}
|
|
78
|
+
/** One page of `items` in the `{ items, next }` shape every dev-tools list returns. */
|
|
79
|
+
function pageOf(items, input) {
|
|
80
|
+
const size = intOf(input.limit, 20, 100);
|
|
81
|
+
const number = intOf(input.page, 1);
|
|
82
|
+
const start = (number - 1) * size;
|
|
83
|
+
return {
|
|
84
|
+
items: items.slice(start, start + size),
|
|
85
|
+
next: start + size < items.length ? number + 1 : null,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function subjectOf(input) {
|
|
89
|
+
const id = str(input.subjectId);
|
|
90
|
+
if (id === undefined)
|
|
91
|
+
throw new Error('`subjectId` is required');
|
|
92
|
+
return { type: str(input.subjectType) ?? 'user', id };
|
|
93
|
+
}
|
|
94
|
+
/** `tenantId` input → the forced scope (`null` = global), or `undefined` to keep the default. */
|
|
95
|
+
function scopeOf(input) {
|
|
96
|
+
const value = input.tenantId;
|
|
97
|
+
if (value === undefined || value === null)
|
|
98
|
+
return undefined;
|
|
99
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
100
|
+
return String(value);
|
|
101
|
+
if (typeof value !== 'string')
|
|
102
|
+
throw new Error('`tenantId` must be a string');
|
|
103
|
+
const id = value.trim();
|
|
104
|
+
return id === '' ? null : id;
|
|
105
|
+
}
|
|
106
|
+
/** Run `fn` in the forced scope, when there is one, never requiring a tenant. */
|
|
107
|
+
function inScope(scope, fn) {
|
|
108
|
+
// A dev tool call is not a tenant-scoped request: no tenant means the global scope.
|
|
109
|
+
return runWithoutRequiredTenant(() => (scope === undefined ? fn() : runInTenantScope(scope, fn)));
|
|
110
|
+
}
|
|
111
|
+
async function load(hook, ref) {
|
|
112
|
+
if (hook === undefined)
|
|
113
|
+
return { loaded: false, value: ref };
|
|
114
|
+
const value = await hook(ref);
|
|
115
|
+
return value === undefined || value === null
|
|
116
|
+
? { loaded: false, value: ref }
|
|
117
|
+
: { loaded: true, value };
|
|
118
|
+
}
|
|
119
|
+
/** The loaders in effect: the `devTools` hooks, else `resolveUser` / `resourceLoaders`. */
|
|
120
|
+
function hooksOf(options) {
|
|
121
|
+
const own = typeof options.devTools === 'object' && options.devTools !== null ? options.devTools : {};
|
|
122
|
+
const resolveUser = options.resolveUser;
|
|
123
|
+
const loaders = options.resourceLoaders;
|
|
124
|
+
return {
|
|
125
|
+
loadSubject: own.loadSubject ?? (resolveUser ? (ref) => resolveUser(ref) : undefined),
|
|
126
|
+
loadResource: own.loadResource ??
|
|
127
|
+
(loaders
|
|
128
|
+
? (ref) => Object.hasOwn(loaders, ref.type) ? loaders[ref.type]?.(ref.id) : undefined
|
|
129
|
+
: undefined),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const CALLER_NOTE = "Roles that `tenancy.roles` maps from the caller's role inside the context tenant only count for the user making the request; for another subject they are not visible here.";
|
|
133
|
+
const NO_SCOPE_SUPPORT = 'The installed RBAC adapter cannot take `tenantId`: its roles and permissions are read in the scope of this request. Upgrade the adapter.';
|
|
134
|
+
/** The subject's effective roles with their sources, in the forced scope when there is one. */
|
|
135
|
+
async function roleView(rbac, user, scope) {
|
|
136
|
+
const sources = await rbac.roleSourcesOf(user);
|
|
137
|
+
const byRole = new Map();
|
|
138
|
+
const add = (role, source) => byRole.set(role, [...(byRole.get(role) ?? []), source]);
|
|
139
|
+
for (const role of sources.user)
|
|
140
|
+
add(role, 'user');
|
|
141
|
+
if (sources.rbac) {
|
|
142
|
+
for (const role of sources.rbac.roles.store)
|
|
143
|
+
add(role, 'store');
|
|
144
|
+
for (const role of sources.rbac.roles.tenant)
|
|
145
|
+
add(role, 'tenant');
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
for (const role of sources.provider)
|
|
149
|
+
add(role, 'provider');
|
|
150
|
+
}
|
|
151
|
+
const id = scope !== undefined ? scope : (sources.rbac?.tenantId ?? null);
|
|
152
|
+
const from = scope !== undefined ? (scope === null ? 'global' : 'explicit') : id ? 'context' : 'global';
|
|
153
|
+
return {
|
|
154
|
+
roles: [...byRole].map(([role, from]) => ({ role, sources: from })),
|
|
155
|
+
tenant: {
|
|
156
|
+
id,
|
|
157
|
+
from,
|
|
158
|
+
...(sources.rbac?.tenantChain && sources.rbac.tenantChain.length > 1
|
|
159
|
+
? { chain: sources.rbac.tenantChain }
|
|
160
|
+
: {}),
|
|
161
|
+
},
|
|
162
|
+
rbac: sources.rbac,
|
|
163
|
+
...(scope !== undefined && rbac.roles() !== undefined && sources.rbac === undefined
|
|
164
|
+
? { warning: NO_SCOPE_SUPPORT }
|
|
165
|
+
: {}),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The authz developer tools (all read-only): explain a check, and a subject's effective roles
|
|
170
|
+
* and permissions.
|
|
171
|
+
*/
|
|
172
|
+
export function authzDevTools(deps) {
|
|
173
|
+
return [
|
|
174
|
+
{
|
|
175
|
+
name: 'authz_explain_check',
|
|
176
|
+
kind: 'read',
|
|
177
|
+
description: 'Why a subject can or cannot do something: the verdict and its reason (super-admin, ' +
|
|
178
|
+
'decision-provider, policy, permission-provider, gate, anonymous, or unresolved when ' +
|
|
179
|
+
'nothing defines the ability), what the decision provider said, the subject’s effective ' +
|
|
180
|
+
'roles with their sources, and which roles or direct grants (in what the permission ' +
|
|
181
|
+
'provider lists) cover the permission. ' +
|
|
182
|
+
'Read-only: no decision event is published.',
|
|
183
|
+
input: {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: {
|
|
186
|
+
subjectType,
|
|
187
|
+
subjectId,
|
|
188
|
+
permission: {
|
|
189
|
+
type: 'string',
|
|
190
|
+
description: "The permission or ability, e.g. 'posts.update' or 'update'.",
|
|
191
|
+
},
|
|
192
|
+
tenantId,
|
|
193
|
+
resourceType: {
|
|
194
|
+
type: 'string',
|
|
195
|
+
description: "Type of the resource the check is about, e.g. 'Post' (with resourceId).",
|
|
196
|
+
},
|
|
197
|
+
resourceId: { type: 'string', description: 'Id of the resource (with resourceType).' },
|
|
198
|
+
},
|
|
199
|
+
required: ['subjectId', 'permission'],
|
|
200
|
+
},
|
|
201
|
+
async run(input) {
|
|
202
|
+
const ref = subjectOf(input);
|
|
203
|
+
const permission = str(input.permission);
|
|
204
|
+
if (permission === undefined)
|
|
205
|
+
throw new Error('`permission` is required');
|
|
206
|
+
const resourceType = str(input.resourceType);
|
|
207
|
+
const resourceId = str(input.resourceId);
|
|
208
|
+
if ((resourceType === undefined) !== (resourceId === undefined)) {
|
|
209
|
+
throw new Error('`resourceType` and `resourceId` go together: pass both or neither');
|
|
210
|
+
}
|
|
211
|
+
const scope = scopeOf(input);
|
|
212
|
+
const hooks = hooksOf(deps.options());
|
|
213
|
+
const resourceRef = resourceType !== undefined && resourceId !== undefined
|
|
214
|
+
? { type: resourceType, id: resourceId }
|
|
215
|
+
: undefined;
|
|
216
|
+
return inScope(scope, async () => {
|
|
217
|
+
// Loaded in the requested tenant, so tenant-scoped loaders see it.
|
|
218
|
+
const subject = await load(hooks.loadSubject, ref);
|
|
219
|
+
const resource = resourceRef ? await load(hooks.loadResource, resourceRef) : undefined;
|
|
220
|
+
const decision = await deps.gate.explainFor(subject.value, permission, resource?.value);
|
|
221
|
+
const view = await roleView(deps.rbac, subject.value, scope);
|
|
222
|
+
// Coverage from the grants the Gate consults: the permission provider's list when it
|
|
223
|
+
// has one, else the RBAC adapter's view. A role only counts for what that list holds.
|
|
224
|
+
const provider = deps.rbac.permissions();
|
|
225
|
+
const listed = typeof provider?.getPermissions === 'function'
|
|
226
|
+
? new Set((await provider.getPermissions(subject.value)) ?? [])
|
|
227
|
+
: view.rbac
|
|
228
|
+
? new Set(view.rbac.permissions)
|
|
229
|
+
: undefined;
|
|
230
|
+
const grantingRoles = [];
|
|
231
|
+
let directGrants = [];
|
|
232
|
+
if (listed) {
|
|
233
|
+
const viaRoles = new Set();
|
|
234
|
+
for (const { role } of view.roles) {
|
|
235
|
+
const matched = (view.rbac?.rolePermissions[role] ?? []).filter((p) => listed.has(p) && permissionSatisfied([p], permission));
|
|
236
|
+
if (matched.length === 0)
|
|
237
|
+
continue;
|
|
238
|
+
grantingRoles.push({ role, matched: [...new Set(matched)] });
|
|
239
|
+
for (const p of matched)
|
|
240
|
+
viaRoles.add(p);
|
|
241
|
+
}
|
|
242
|
+
directGrants = [...listed].filter((p) => permissionSatisfied([p], permission) && !viaRoles.has(p));
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
...decision,
|
|
246
|
+
subject: ref,
|
|
247
|
+
permission,
|
|
248
|
+
tenant: view.tenant,
|
|
249
|
+
effectiveRoles: view.roles.map((r) => r.role),
|
|
250
|
+
roleSources: Object.fromEntries(view.roles.map((r) => [r.role, r.sources])),
|
|
251
|
+
grantingRoles,
|
|
252
|
+
directGrants,
|
|
253
|
+
subjectLoaded: subject.loaded,
|
|
254
|
+
...(resourceRef
|
|
255
|
+
? { resource: resourceRef, resourceLoaded: resource?.loaded === true }
|
|
256
|
+
: {}),
|
|
257
|
+
...(view.warning ? { warning: view.warning } : {}),
|
|
258
|
+
note: CALLER_NOTE,
|
|
259
|
+
};
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: 'authz_list_effective_roles',
|
|
265
|
+
kind: 'read',
|
|
266
|
+
description: "A subject's effective roles in a tenant, each with where it comes from: the user object " +
|
|
267
|
+
"or resolveRoles ('user'), the RBAC store ('store'), the caller's role inside the context " +
|
|
268
|
+
"tenant mapped by tenancy.roles ('tenant'), or a role provider that does not say ('provider').",
|
|
269
|
+
input: {
|
|
270
|
+
type: 'object',
|
|
271
|
+
properties: { subjectType, subjectId, tenantId },
|
|
272
|
+
required: ['subjectId'],
|
|
273
|
+
},
|
|
274
|
+
async run(input) {
|
|
275
|
+
const ref = subjectOf(input);
|
|
276
|
+
const scope = scopeOf(input);
|
|
277
|
+
const hooks = hooksOf(deps.options());
|
|
278
|
+
return inScope(scope, async () => {
|
|
279
|
+
const subject = await load(hooks.loadSubject, ref);
|
|
280
|
+
const view = await roleView(deps.rbac, subject.value, scope);
|
|
281
|
+
return {
|
|
282
|
+
subject: ref,
|
|
283
|
+
tenant: view.tenant,
|
|
284
|
+
items: view.roles,
|
|
285
|
+
next: null,
|
|
286
|
+
subjectLoaded: subject.loaded,
|
|
287
|
+
...(view.warning ? { warning: view.warning } : {}),
|
|
288
|
+
note: CALLER_NOTE,
|
|
289
|
+
};
|
|
290
|
+
});
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: 'authz_list_effective_permissions',
|
|
295
|
+
kind: 'read',
|
|
296
|
+
description: "A subject's effective permissions in a tenant (role-derived and direct grants), " +
|
|
297
|
+
'wildcards as stored. Paged: { items, next }.',
|
|
298
|
+
input: {
|
|
299
|
+
type: 'object',
|
|
300
|
+
properties: { subjectType, subjectId, tenantId, limit, page },
|
|
301
|
+
required: ['subjectId'],
|
|
302
|
+
},
|
|
303
|
+
async run(input) {
|
|
304
|
+
const ref = subjectOf(input);
|
|
305
|
+
const scope = scopeOf(input);
|
|
306
|
+
const hooks = hooksOf(deps.options());
|
|
307
|
+
return inScope(scope, async () => {
|
|
308
|
+
const subject = await load(hooks.loadSubject, ref);
|
|
309
|
+
const provider = deps.rbac.permissions();
|
|
310
|
+
const view = await roleView(deps.rbac, subject.value, scope);
|
|
311
|
+
if (typeof provider?.getPermissions !== 'function') {
|
|
312
|
+
return {
|
|
313
|
+
subject: ref,
|
|
314
|
+
tenant: view.tenant,
|
|
315
|
+
items: [],
|
|
316
|
+
next: null,
|
|
317
|
+
subjectLoaded: subject.loaded,
|
|
318
|
+
...(view.warning ? { warning: view.warning } : {}),
|
|
319
|
+
note: provider
|
|
320
|
+
? 'The permission provider cannot list permissions (no getPermissions).'
|
|
321
|
+
: 'No permission provider: install an RBAC adapter (AuthzRbacModule).',
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const granted = (await provider.getPermissions(subject.value)) ?? [];
|
|
325
|
+
return {
|
|
326
|
+
subject: ref,
|
|
327
|
+
tenant: view.tenant,
|
|
328
|
+
...pageOf([...new Set(granted)].sort(), input),
|
|
329
|
+
subjectLoaded: subject.loaded,
|
|
330
|
+
...(view.warning ? { warning: view.warning } : {}),
|
|
331
|
+
};
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Register the authz tools into the dev-tools slot (created when absent), without an
|
|
339
|
+
* `authorize`: the dev endpoint's `devTools.authorize` gates them. A hub that says it cannot gate a
|
|
340
|
+
* lib without a console (`supports('endpoint-authorize')` is false) is left alone. Never throws.
|
|
341
|
+
*/
|
|
342
|
+
export function registerAuthzDevTools(deps) {
|
|
343
|
+
try {
|
|
344
|
+
const slot = devToolsSlot();
|
|
345
|
+
if (slot.version !== 1 || typeof slot.register !== 'function') {
|
|
346
|
+
return { outcome: 'unsupported' };
|
|
347
|
+
}
|
|
348
|
+
if (typeof slot.supports === 'function' && !slot.supports('endpoint-authorize')) {
|
|
349
|
+
return { outcome: 'unsupported' };
|
|
350
|
+
}
|
|
351
|
+
const unregister = slot.register({
|
|
352
|
+
lib: 'authz',
|
|
353
|
+
title: 'Authorization (authz)',
|
|
354
|
+
tools: authzDevTools(deps),
|
|
355
|
+
});
|
|
356
|
+
return { outcome: 'registered', unregister };
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return { outcome: 'failed' };
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/** Registers the authz dev tools at module init and removes them at module destroy. */
|
|
363
|
+
let AuthzDevTools = class AuthzDevTools {
|
|
364
|
+
gate;
|
|
365
|
+
rbac;
|
|
366
|
+
logger = new Logger('AuthzDevTools');
|
|
367
|
+
options;
|
|
368
|
+
unregister;
|
|
369
|
+
constructor(gate, rbac, options) {
|
|
370
|
+
this.gate = gate;
|
|
371
|
+
this.rbac = rbac;
|
|
372
|
+
this.options = options ?? {};
|
|
373
|
+
}
|
|
374
|
+
onModuleInit() {
|
|
375
|
+
if (this.options.devTools === false)
|
|
376
|
+
return;
|
|
377
|
+
const { outcome, unregister } = registerAuthzDevTools({
|
|
378
|
+
gate: this.gate,
|
|
379
|
+
rbac: this.rbac,
|
|
380
|
+
options: () => this.options,
|
|
381
|
+
});
|
|
382
|
+
this.unregister = unregister;
|
|
383
|
+
if (outcome === 'unsupported') {
|
|
384
|
+
this.logger.debug('dev tools not registered: the installed dev-tools hub cannot gate libs without a console (needs devTools.authorize support)');
|
|
385
|
+
}
|
|
386
|
+
else if (outcome === 'failed') {
|
|
387
|
+
this.logger.debug('dev tools could not be registered');
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
onModuleDestroy() {
|
|
391
|
+
this.unregister?.();
|
|
392
|
+
this.unregister = undefined;
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
AuthzDevTools = __decorate([
|
|
396
|
+
Injectable(),
|
|
397
|
+
__param(2, Optional()),
|
|
398
|
+
__param(2, Inject(AUTHZ_MODULE_OPTIONS)),
|
|
399
|
+
__metadata("design:paramtypes", [Gate,
|
|
400
|
+
AuthzRbac, Object])
|
|
401
|
+
], AuthzDevTools);
|
|
402
|
+
export { AuthzDevTools };
|
|
403
|
+
//# sourceMappingURL=dev-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-tools.js","sourceRoot":"","sources":["../src/dev-tools.ts"],"names":[],"mappings":"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"}
|