@dudousxd/nestjs-authz-prisma 0.5.1 → 0.7.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,57 @@
1
1
  # @dudousxd/nestjs-authz-prisma
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Back on the 0.x line. The 1.x and 2.x versions were published by accident: a release-tooling peer cascade bumped this package to a major, not an API decision. 0.7.0 contains everything those versions shipped (console `authorize` support, tenancy, Node 24+ `engines`) with no other change. Upgrade from 1.x/2.x to 0.7.0; those versions are deprecated.
8
+
9
+ ## 2.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - [#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.
14
+
15
+ ## 1.1.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [#73](https://github.com/DavideCarvalho/nestjs-authz/pull/73) [`9fd6787`](https://github.com/DavideCarvalho/nestjs-authz/commit/9fd6787307361b8552236a833d969fa041a46bca) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Fix the `$queryRaw` permission fast path: it is now called on the client instead of detached from it. A real `PrismaClient` threw on the unbound call, so every permission check silently fell back to the three-query path.
20
+
21
+ ## 1.1.0
22
+
23
+ ### Minor Changes
24
+
25
+ - [#72](https://github.com/DavideCarvalho/nestjs-authz/pull/72) [`58a5d72`](https://github.com/DavideCarvalho/nestjs-authz/commit/58a5d72d2964a7cfae9cbfe8506526c8518ba30a) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Tenancy for the RBAC modules, following the `@dudousxd/nestjs-context` tenancy switch.
26
+
27
+ - New `tenancy` option (`'inherit' | false | { enabled?, kinds?, nullRows?, roles? }`, default `'inherit'`). With context tenancy on, permission and role checks are scoped to the request's tenant from `Context.setTenant`. A request with no tenant, inside `Context.allTenants()`, or outside a request sees global assignments only. `kinds` limits the tenant kinds this module honours. With tenancy off nothing changes.
28
+ - `tenancy.roles` maps the caller's role inside the tenant (`tenant.role`) to authz roles that apply in that tenant only, e.g. `{ owner: 'org_admin' }`.
29
+ - New `tenant` resolver option, `(user) => tenantId | null | undefined`: an explicit tenant that wins over the context.
30
+ - MikroORM and Prisma can now store tenant-scoped role assignments like Drizzle and TypeORM: `assignRole`, `removeRole` and `setUserRoles` take `{ tenantId }`, and the read methods take a tenant scope. MikroORM: build the entities with `createAuthzEntitySchemas({}, { tenantScoped: true })`. Prisma: add `tenantId String @default("")` to `UserRole` and its `@@id`, then pass `tenantScoped: true`. Without that, every assignment stays global.
31
+
32
+ ## 1.0.0
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies [[`750a6b3`](https://github.com/DavideCarvalho/nestjs-authz/commit/750a6b3f80deea3803dec8df5f9f8cf67a046ac1)]:
37
+ - @dudousxd/nestjs-authz@0.10.0
38
+
39
+ ## 0.6.0
40
+
41
+ ### Minor Changes
42
+
43
+ - [#67](https://github.com/DavideCarvalho/nestjs-authz/pull/67) [`32e967f`](https://github.com/DavideCarvalho/nestjs-authz/commit/32e967ffbcd68a97e8effc77af9c16bbbafdc918) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Run on `@dudousxd/nestjs-authz` 0.9 and `@nestjs/authorization`: persisted roles and
44
+ permissions now guard routes through the official guard as the core's `RolePolicy` /
45
+ `PermissionPolicy` (`@Roles('editor')`, `@Permission('posts.publish')`), and the guard and the
46
+ handler's `Gate` calls share one permission and role fetch per request. The store API
47
+ (role sources, admin management, tenant-scoped roles where supported) and `AuthzRbacModule`
48
+ are unchanged. A persisted permission named like a policy ability no longer bypasses that
49
+ policy (see the core changeset). Requires NestJS 12, `@nestjs/authorization` ^0.1.3 and Node 22+.
50
+
51
+ ### Patch Changes
52
+
53
+ - [#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.
54
+
3
55
  ## 0.5.1
4
56
 
5
57
  ### Patch Changes
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @dudousxd/nestjs-authz-prisma
2
2
 
3
3
  Prisma RBAC persistence for [`@dudousxd/nestjs-authz`](https://github.com/DavideCarvalho/nestjs-authz) —
4
- roles, permissions, and a Gate seam, with **zero connection ownership** (your app owns the
4
+ roles and permissions for the official `@nestjs/authorization` policies, with **zero connection ownership** (your app owns the
5
5
  `PrismaClient`; this package never opens a connection and never imports `@prisma/client`).
6
6
 
7
7
  This is the Prisma sibling of `@dudousxd/nestjs-authz-typeorm`: identical store surface and
@@ -10,7 +10,7 @@ This is the Prisma sibling of `@dudousxd/nestjs-authz-typeorm`: identical store
10
10
  ## Install
11
11
 
12
12
  ```bash
13
- pnpm add @dudousxd/nestjs-authz-prisma @dudousxd/nestjs-authz
13
+ pnpm add @dudousxd/nestjs-authz-prisma @dudousxd/nestjs-authz @nestjs/authorization
14
14
  ```
15
15
 
16
16
  No `@prisma/client` is required by this package — it depends only on the structural
@@ -92,16 +92,30 @@ AuthzRbacModule.forRootAsync({
92
92
  });
93
93
  ```
94
94
 
95
- Once wired, the Gate consults persisted RBAC:
95
+ Once wired, persisted roles and permissions guard routes through the official
96
+ `@nestjs/authorization` guard, as the core's `RolePolicy` / `PermissionPolicy`:
96
97
 
97
98
  ```ts
98
- await store.givePermissionToRole('editor', 'posts.publish');
99
+ await store.givePermissionToRole('editor', 'posts.*');
99
100
  await store.assignRole({ type: 'user', id: 7 }, 'editor');
100
101
 
101
- gate.forUser(user).allows('posts.publish'); // true (PERMISSION_PROVIDER seam, wildcards supported)
102
- gate.forUser(user).hasRole('editor'); // true (ROLE_PROVIDER seam)
102
+ @Permission('posts.publish') // posts.* grants it
103
+ @Can(PermissionPolicy, 'has', permission('posts.publish')) // the same, spelled out
104
+ @Roles('editor') // @Can(RolePolicy, 'has', roles('editor'))
103
105
  ```
104
106
 
107
+ and in services, through the `Gate`:
108
+
109
+ ```ts
110
+ gate.forUser(user).allows('posts.publish'); // true (PERMISSION_PROVIDER seam)
111
+ gate.forUser(user).allows(PermissionPolicy, 'has', 'posts.publish');
112
+ gate.forUser(user).hasRole('editor'); // true (ROLE_PROVIDER seam)
113
+ ```
114
+
115
+ The user is the one the official guard reads (`AuthorizationModule.forRoot({ getUser })`,
116
+ default `request.user`), mapped to a store ref with `userRefFrom` (default `{ type, id }` or
117
+ `{ id }`).
118
+
105
119
  ## Role sources (manual vs SSO/SCIM)
106
120
 
107
121
  Every role assignment records a `source`. It defaults to `'manual'`, so existing calls and existing
@@ -171,10 +185,70 @@ await store.listRoleAssignments({ user: { type: 'user', id: 7 } });
171
185
  await store.removeUser({ type: 'user', id: 7 });
172
186
  ```
173
187
 
174
- This adapter has no tenant-scoped assignments, so every row has `tenantId: null`:
175
- `listRoleAssignments({ tenantId: null })` lists everything and a tenant id string matches
176
- nothing. Without `roleSources: true` every row is `'manual'`, so filtering by another
177
- `source` matches nothing.
188
+ `tenantId` filters: omitted = every tenant, `null` = global assignments only, a string = that
189
+ tenant's scoped assignments only. Without `tenantScoped: true` (below) every row has
190
+ `tenantId: null`, so a tenant id string matches nothing. Without `roleSources: true` every row
191
+ is `'manual'`, so filtering by another `source` matches nothing.
192
+
193
+ ## Tenant-scoped roles
194
+
195
+ Tenant-scoped assignments are opt-in. Add the column to `UserRole` and its `@@id`, then run
196
+ `prisma migrate dev` (existing rows get `''`, a global assignment):
197
+
198
+ ```prisma
199
+ model UserRole {
200
+ userType String
201
+ userId String
202
+ roleId String
203
+ tenantId String @default("")
204
+
205
+ @@id([userType, userId, roleId, tenantId])
206
+ @@index([userType, userId])
207
+ @@map("authz_user_role")
208
+ }
209
+ ```
210
+
211
+ Then turn it on: `new PrismaAuthzStore(prisma, { tenantScoped: true })`, or
212
+ `AuthzRbacModule.forRoot({ client: prisma, tenantScoped: true })`.
213
+
214
+ ```ts
215
+ await store.assignRole(user, 'editor', { tenantId: 'acme' }); // only inside acme
216
+ await store.assignRole(user, 'viewer'); // everywhere
217
+ await store.getRolesForUser(user, { tenantId: 'acme' }); // ['editor', 'viewer']
218
+ await store.getRolesForUser(user); // ['viewer']
219
+ ```
220
+
221
+ `removeRole` and `setUserRoles` take the same `{ tenantId }` (omitted = the global
222
+ assignments). Without `tenantScoped`, every assignment is global and reads ignore the tenant.
223
+ `assignRole` and `setUserRoles` with a `tenantId` throw; `removeRole` with one does nothing,
224
+ since there is no tenant assignment to remove.
225
+
226
+ ## Tenancy
227
+
228
+ The RBAC module reads the tenant only when tenancy is on: turn it on with
229
+ `ContextModule.forRoot({ tenancy: { enabled: true } })` in `@dudousxd/nestjs-context`. Checks
230
+ are then scoped to the request's tenant from `Context.setTenant(...)`.
231
+ A request with no tenant, or inside `Context.allTenants()`, sees global assignments only.
232
+
233
+ ```ts
234
+ AuthzRbacModule.forRoot({
235
+ client: prisma,
236
+ tenantScoped: true,
237
+ tenancy: {
238
+ kinds: ['organization'], // optional: tenant kinds this module honours
239
+ roles: { owner: 'org_admin', member: 'org_member' }, // optional: tenant.role → authz roles in that tenant
240
+ },
241
+ tenant: (user) => (user as { orgId?: string }).orgId, // optional: an explicit tenant wins over the context
242
+ });
243
+ ```
244
+
245
+ `tenancy` defaults to `'inherit'` (follow the context switch); `false` keeps this module out.
246
+ Roles mapped with `roles` apply only inside that tenant and only to the context's current user.
247
+ The `tenant` resolver returns a tenant id, `null` for the global scope, or `undefined` to fall
248
+ back to the context.
249
+
250
+ With tenancy on and without `tenantScoped`, every assignment is global, so only `roles` and the
251
+ `tenant` resolver change what a check sees.
178
252
 
179
253
  ## License
180
254
 
@@ -2,6 +2,7 @@ import type { UserRef } from '@dudousxd/nestjs-authz/store-kit';
2
2
  import { type DynamicModule } from '@nestjs/common';
3
3
  import { PrismaAuthzStore } from './prisma-authz.store.js';
4
4
  import { type PrismaAuthzClientLike } from './prisma-client.js';
5
+ import { type AuthzTenancyOption, type TenantResolver } from './tenancy.js';
5
6
  /** Injection token holding the {@link PrismaAuthzStore} the RBAC module manages. */
6
7
  export declare const AUTHZ_RBAC_STORE: unique symbol;
7
8
  /** Injection token holding the resolved {@link AuthzRbacModuleOptions}. */
@@ -30,11 +31,27 @@ export interface AuthzRbacModuleOptions {
30
31
  * `source` column on `UserRole`. Only used when the module builds the store from `client`.
31
32
  */
32
33
  roleSources?: boolean;
34
+ /**
35
+ * Tenant-scoped role assignments (see {@link PrismaAuthzStoreOptions.tenantScoped}); requires
36
+ * the `tenantId` column on `UserRole`. Only used when the module builds the store from `client`.
37
+ */
38
+ tenantScoped?: boolean;
33
39
  /**
34
40
  * Derive a {@link UserRef} from the Gate's current user. Defaults to
35
41
  * {@link defaultUserRefMapper} (`{ type, id }` or `{ id }`).
36
42
  */
37
43
  userRefFrom?: UserRefMapper;
44
+ /**
45
+ * Tenancy, from `@dudousxd/nestjs-context`. `'inherit'` (default) follows `ContextModule`'s
46
+ * `tenancy.enabled`; with it on, checks are scoped to the context tenant. The object form adds
47
+ * `kinds` and `roles` (map the caller's `tenant.role` to authz roles in that tenant).
48
+ */
49
+ tenancy?: AuthzTenancyOption;
50
+ /**
51
+ * Explicit tenant for a check, from the user being checked. Wins over the context: return a
52
+ * tenant id, `null` for the global scope, or `undefined` to fall back to the context.
53
+ */
54
+ tenant?: TenantResolver;
38
55
  }
39
56
  export interface AuthzRbacModuleAsyncOptions {
40
57
  imports?: unknown[];
@@ -1 +1 @@
1
- {"version":3,"file":"authz-rbac.module.d.ts","sourceRoot":"","sources":["../src/authz-rbac.module.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EACL,KAAK,aAAa,EAQnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAiB,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE/E,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,eAAoD,CAAC;AAClF,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,eAAsD,CAAC;AAEtF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,oFAAoF;IACpF,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;CAC9F;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAOvE;AAsFD;;;;;;GAMG;AACH,qBACa,eAAe;IAC1B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,aAAa;IAa9D,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,2BAA2B,GAAG,aAAa;IAsBxE,OAAO,CAAC,MAAM,CAAC,eAAe;CAS/B"}
1
+ {"version":3,"file":"authz-rbac.module.d.ts","sourceRoot":"","sources":["../src/authz-rbac.module.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EACL,KAAK,aAAa,EAQnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAiB,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACL,KAAK,kBAAkB,EAIvB,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AAEtB,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,eAAoD,CAAC;AAClF,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,eAAsD,CAAC;AAEtF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,oFAAoF;IACpF,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;CAC9F;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAOvE;AA0ID;;;;;;GAMG;AACH,qBACa,eAAe;IAC1B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,aAAa;IAa9D,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,2BAA2B,GAAG,aAAa;IAsBxE,OAAO,CAAC,MAAM,CAAC,eAAe;CAS/B"}
@@ -11,9 +11,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
13
  var AuthzRbacModule_1;
14
- import { PERMISSION_PROVIDER, ROLE_PROVIDER, } from '@dudousxd/nestjs-authz';
14
+ import { CONTEXT_ACCESSOR, PERMISSION_PROVIDER, ROLE_PROVIDER, } from '@dudousxd/nestjs-authz';
15
15
  import { Inject, Injectable, Module, Optional, } from '@nestjs/common';
16
+ import { ModuleRef } from '@nestjs/core';
16
17
  import { PrismaAuthzStore } from './prisma-authz.store.js';
18
+ import { rbacTenant, } from './tenancy.js';
17
19
  /** Injection token holding the {@link PrismaAuthzStore} the RBAC module manages. */
18
20
  export const AUTHZ_RBAC_STORE = Symbol.for('@dudousxd/nestjs-authz-prisma:store');
19
21
  /** Injection token holding the resolved {@link AuthzRbacModuleOptions}. */
@@ -35,7 +37,10 @@ function resolveStore(options) {
35
37
  if (options.store)
36
38
  return options.store;
37
39
  if (options.client) {
38
- return new PrismaAuthzStore(options.client, options.roleSources ? { roleSources: true } : {});
40
+ return new PrismaAuthzStore(options.client, {
41
+ ...(options.roleSources ? { roleSources: true } : {}),
42
+ ...(options.tenantScoped ? { tenantScoped: true } : {}),
43
+ });
39
44
  }
40
45
  throw new Error('AuthzRbacModule (prisma): provide either `store` or `client` in the options.');
41
46
  }
@@ -46,13 +51,27 @@ function resolveStore(options) {
46
51
  */
47
52
  let RbacPermissionProvider = class RbacPermissionProvider {
48
53
  options;
54
+ context;
55
+ moduleRef;
49
56
  // `getPermissions` lists every grant `hasPermission` can find, for any resource.
50
57
  exhaustivePermissions = true;
51
58
  store;
52
- constructor(options) {
59
+ contextCache = { resolved: false, value: undefined };
60
+ constructor(options, context, moduleRef) {
53
61
  this.options = options;
62
+ this.context = context;
63
+ this.moduleRef = moduleRef;
54
64
  this.store = resolveStore(options);
55
65
  }
66
+ tenant(user, ref) {
67
+ return rbacTenant(this.options, user, ref, this.context, this.moduleRef, this.contextCache, false);
68
+ }
69
+ /** The permissions `tenancy.roles` grants through the caller's role in the tenant. */
70
+ async tenantRolePermissions(roles) {
71
+ if (roles.length === 0)
72
+ return [];
73
+ return Object.values(await this.store.getRolePermissions(roles)).flat();
74
+ }
56
75
  // The core `PermissionProvider` interface passes an optional `resource` (3rd
57
76
  // arg); it is intentionally ignored here. RBAC grants are model-less,
58
77
  // named-ability grants (the Laravel/spatie `Gate::before` grant), so the
@@ -62,7 +81,10 @@ let RbacPermissionProvider = class RbacPermissionProvider {
62
81
  const ref = map(user);
63
82
  if (ref === undefined)
64
83
  return undefined;
65
- return this.store.userHasPermission(ref, permission);
84
+ const tenant = this.tenant(user, ref);
85
+ if (await this.store.userHasPermission(ref, permission, tenant.scope))
86
+ return true;
87
+ return (await this.tenantRolePermissions(tenant.roles)).includes(permission);
66
88
  }
67
89
  // Expose the user's full granted permission set so the core can apply
68
90
  // Laravel/spatie-style wildcard matching (a granted `posts.*` satisfies a check
@@ -72,13 +94,20 @@ let RbacPermissionProvider = class RbacPermissionProvider {
72
94
  const ref = map(user);
73
95
  if (ref === undefined)
74
96
  return undefined;
75
- return this.store.getPermissionsForUser(ref);
97
+ const tenant = this.tenant(user, ref);
98
+ const own = await this.store.getPermissionsForUser(ref, tenant.scope);
99
+ if (tenant.roles.length === 0)
100
+ return own;
101
+ return [...new Set([...own, ...(await this.tenantRolePermissions(tenant.roles))])];
76
102
  }
77
103
  };
78
104
  RbacPermissionProvider = __decorate([
79
105
  Injectable(),
80
106
  __param(0, Inject(AUTHZ_RBAC_OPTIONS)),
81
- __metadata("design:paramtypes", [Object])
107
+ __param(1, Optional()),
108
+ __param(1, Inject(CONTEXT_ACCESSOR)),
109
+ __param(2, Optional()),
110
+ __metadata("design:paramtypes", [Object, Object, ModuleRef])
82
111
  ], RbacPermissionProvider);
83
112
  /**
84
113
  * The RBAC {@link RoleProvider} the Gate consults (via the shared {@link ROLE_PROVIDER}
@@ -88,23 +117,36 @@ RbacPermissionProvider = __decorate([
88
117
  */
89
118
  let RbacRoleProvider = class RbacRoleProvider {
90
119
  options;
120
+ context;
121
+ moduleRef;
91
122
  store;
92
- constructor(options) {
123
+ contextCache = { resolved: false, value: undefined };
124
+ constructor(options, context, moduleRef) {
93
125
  this.options = options;
126
+ this.context = context;
127
+ this.moduleRef = moduleRef;
94
128
  this.store = resolveStore(options);
95
129
  }
130
+ tenant(user, ref) {
131
+ return rbacTenant(this.options, user, ref, this.context, this.moduleRef, this.contextCache, false);
132
+ }
96
133
  async getRoles(user) {
97
134
  const map = this.options.userRefFrom ?? defaultUserRefMapper;
98
135
  const ref = map(user);
99
136
  if (ref === undefined)
100
137
  return undefined;
101
- return this.store.getRolesForUser(ref);
138
+ const tenant = this.tenant(user, ref);
139
+ const own = await this.store.getRolesForUser(ref, tenant.scope);
140
+ return tenant.roles.length === 0 ? own : [...new Set([...own, ...tenant.roles])];
102
141
  }
103
142
  };
104
143
  RbacRoleProvider = __decorate([
105
144
  Injectable(),
106
145
  __param(0, Inject(AUTHZ_RBAC_OPTIONS)),
107
- __metadata("design:paramtypes", [Object])
146
+ __param(1, Optional()),
147
+ __param(1, Inject(CONTEXT_ACCESSOR)),
148
+ __param(2, Optional()),
149
+ __metadata("design:paramtypes", [Object, Object, ModuleRef])
108
150
  ], RbacRoleProvider);
109
151
  /**
110
152
  * Runs `ensureSchema` on bootstrap when `autoCreateSchema` is enabled. For Prisma this is
@@ -1 +1 @@
1
- {"version":3,"file":"authz-rbac.module.js","sourceRoot":"","sources":["../src/authz-rbac.module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authz-rbac.module.js","sourceRoot":"","sources":["../src/authz-rbac.module.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  export { PRISMA_AUTHZ_STORE_OPTIONS, PRISMA_CLIENT, type PrismaAuthzClientLike, type PrismaAuthzStoreOptions, type PrismaModelDelegate, } from './prisma-client.js';
2
- export { PrismaAuthzStore } from './prisma-authz.store.js';
3
- export type { RoleAssignment, RoleAssignmentFilter, RoleSourceOptions, UserAuthz, UserRoleAssignment, } from './prisma-authz.store.js';
2
+ export { GLOBAL_TENANT, PrismaAuthzStore } from './prisma-authz.store.js';
3
+ export type { RoleAssignment, RoleAssignmentFilter, RoleSourceOptions, TenantScope, UserAuthz, UserRoleAssignment, } from './prisma-authz.store.js';
4
4
  export { AUTHZ_RBAC_OPTIONS, AUTHZ_RBAC_STORE, AuthzRbacModule, defaultUserRefMapper, } from './authz-rbac.module.js';
5
5
  export type { AuthzRbacModuleAsyncOptions, AuthzRbacModuleOptions, UserRefMapper, } from './authz-rbac.module.js';
6
+ export type { AuthzTenancyOption, TenantResolver } from './tenancy.js';
6
7
  export type { UserRef, UserRefInput } from '@dudousxd/nestjs-authz/store-kit';
7
8
  export { applyScope, compileScope } from './scope.js';
8
9
  export type { PrismaWhere, ScopeResolver } from './scope.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,2BAA2B,EAC3B,sBAAsB,EACtB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,2BAA2B,EAC3B,sBAAsB,EACtB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { PRISMA_AUTHZ_STORE_OPTIONS, PRISMA_CLIENT, } from './prisma-client.js';
2
- export { PrismaAuthzStore } from './prisma-authz.store.js';
2
+ export { GLOBAL_TENANT, PrismaAuthzStore } from './prisma-authz.store.js';
3
3
  export { AUTHZ_RBAC_OPTIONS, AUTHZ_RBAC_STORE, AuthzRbacModule, defaultUserRefMapper, } from './authz-rbac.module.js';
4
4
  export { applyScope, compileScope } from './scope.js';
5
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,aAAa,GAId,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAQ3D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,aAAa,GAId,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAS1E,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -1,10 +1,23 @@
1
1
  import { type RoleAssignment, type RoleAssignmentFilter, type UserAuthz, type UserRef, type UserRoleAssignment } from '@dudousxd/nestjs-authz/store-kit';
2
2
  import { type PrismaAuthzClientLike, type PrismaAuthzStoreOptions } from './prisma-client.js';
3
3
  export type { RoleAssignment, RoleAssignmentFilter, UserAuthz, UserRoleAssignment };
4
- /** Assignment source for role mutations (default `'manual'`) — see `setUserRoles`. */
5
- export interface RoleSourceOptions {
4
+ /**
5
+ * Optional tenant scope for a query. Omitted → the GLOBAL scope (only global assignments; a
6
+ * tenant-scoped role never leaks into an unscoped check). With a `tenantId`, global assignments
7
+ * AND that tenant's apply. Needs `tenantScoped: true`; without it every assignment is global.
8
+ */
9
+ export interface TenantScope {
10
+ tenantId?: string;
11
+ }
12
+ /**
13
+ * Assignment source (default `'manual'`, needs `roleSources: true`) and tenant (needs
14
+ * `tenantScoped: true`) for role mutations — see `setUserRoles`.
15
+ */
16
+ export interface RoleSourceOptions extends TenantScope {
6
17
  source?: string;
7
18
  }
19
+ /** The tenant id of a GLOBAL role assignment (applies in every tenant). */
20
+ export declare const GLOBAL_TENANT = "";
8
21
  /**
9
22
  * Prisma-backed RBAC store. Receives the app-owned Prisma client via the
10
23
  * {@link PRISMA_CLIENT} DI token — NO internal connection ownership, NO `@prisma/client`
@@ -22,6 +35,12 @@ export declare class PrismaAuthzStore {
22
35
  * `{}` otherwise (legacy schema without the column) — where a non-default source is an error.
23
36
  */
24
37
  private sourceField;
38
+ /** The `tenantId` value of a written assignment (`{}` without `tenantScoped`). */
39
+ private tenantField;
40
+ /** Assignments visible in a scope: global ones, plus the tenant's own when one is given. */
41
+ private tenantWhere;
42
+ /** The public `tenantId` of a stored row: `null` for a global assignment. */
43
+ private static rowTenant;
25
44
  /**
26
45
  * No-op: Prisma is schema-first / consumer-managed. Declare the RBAC models in your
27
46
  * `schema.prisma` (see {@link PrismaAuthzClientLike}) and apply them with
@@ -68,7 +87,9 @@ export declare class PrismaAuthzStore {
68
87
  assignRole(user: UserRef, roleName: string, opts?: RoleSourceOptions): Promise<void>;
69
88
  /**
70
89
  * Remove a role from a user. No-op if the role or assignment is absent. With `{ source }` only
71
- * that source's assignment goes; without it, the role is removed from every source.
90
+ * that source's assignment goes; without it, the role is removed from every source. With
91
+ * `tenantScoped`, `{ tenantId }` removes the assignment in that tenant and omitting it removes
92
+ * the global one.
72
93
  */
73
94
  removeRole(user: UserRef, roleName: string, opts?: RoleSourceOptions): Promise<void>;
74
95
  /**
@@ -76,18 +97,23 @@ export declare class PrismaAuthzStore {
76
97
  * `roleNames` — e.g. an SSO/SCIM sync calls `setUserRoles(user, mappedRoles, { source: 'sso' })`
77
98
  * on every login; other sources' assignments are untouched. Roles are created by name when
78
99
  * missing. Atomic when the client has `$transaction`. Without `roleSources: true` there is only
79
- * one (implicit manual) source, so this replaces ALL of the user's roles.
100
+ * one (implicit manual) source, so this replaces ALL of the user's roles. With `tenantScoped` it
101
+ * replaces the assignments of one tenant (`{ tenantId }`), or the global ones when omitted.
80
102
  */
81
103
  setUserRoles(user: UserRef, roleNames: readonly string[], opts?: RoleSourceOptions): Promise<void>;
82
- /** Every role assignment of a user, one entry per `(role, source)`. */
83
- getRoleAssignments(user: UserRef): Promise<RoleAssignment[]>;
104
+ /**
105
+ * Every role assignment of a user visible in a tenant scope (global ones always; the tenant's
106
+ * own with `{ tenantId }`), one entry per `(role, source, tenant)`.
107
+ */
108
+ getRoleAssignments(user: UserRef, scope?: TenantScope): Promise<RoleAssignment[]>;
84
109
  /**
85
110
  * Raw role-assignment rows for admin listings — e.g. who holds a role (`{ role: 'admin' }`) or
86
111
  * a user's assignments with their sources (`{ user }`). `role` accepts one name or a list;
87
112
  * `user` and `source` narrow further. Ordered by `(userType, userId, role, source)`.
88
113
  *
89
- * This adapter has no tenant-scoped assignments — every row is global (`tenantId: null`). So
90
- * `tenantId: undefined` or `null` lists everything, and a tenant id string matches nothing.
114
+ * `tenantId`: omitted = no tenant filter; `null` = global assignments only; a string = exactly
115
+ * that tenant's scoped assignments. Without `tenantScoped: true` every row is global
116
+ * (`tenantId: null`), so a tenant id string matches nothing.
91
117
  * Without `roleSources: true` every row is `'manual'`, so another `source` matches nothing.
92
118
  */
93
119
  listRoleAssignments(filter?: RoleAssignmentFilter): Promise<UserRoleAssignment[]>;
@@ -96,8 +122,8 @@ export declare class PrismaAuthzStore {
96
122
  * Roles and permissions are kept. (This adapter has no direct user permissions.)
97
123
  */
98
124
  removeUser(user: UserRef): Promise<void>;
99
- /** The role names a user holds. */
100
- getRolesForUser(user: UserRef): Promise<string[]>;
125
+ /** The role names a user holds, in a tenant scope (see {@link TenantScope}). */
126
+ getRolesForUser(user: UserRef, scope?: TenantScope): Promise<string[]>;
101
127
  /**
102
128
  * The flattened, distinct permission names a user has via their roles.
103
129
  *
@@ -107,12 +133,11 @@ export declare class PrismaAuthzStore {
107
133
  *
108
134
  * Fast path: when the injected client exposes `$queryRaw`, assemble the set in a
109
135
  * SINGLE database round-trip via one JOIN (3 round-trips → 1). On ANY failure
110
- * (missing `$queryRaw`, custom `@@map` table names, non-Postgres identifier
111
- * quoting, etc.) it degrades to {@link getPermissionsViaDelegates}, so correctness
136
+ * (custom `@@map` table names, non-Postgres identifier quoting, etc.) it degrades to {@link getPermissionsViaDelegates}, so correctness
112
137
  * is preserved everywhere and only the common (Postgres + documented schema) case
113
138
  * gets the speedup.
114
139
  */
115
- getPermissionsForUser(user: UserRef): Promise<string[]>;
140
+ getPermissionsForUser(user: UserRef, scope?: TenantScope): Promise<string[]>;
116
141
  /**
117
142
  * The original three-query implementation (userRole → rolePermission → permission),
118
143
  * returning the same deduped permission-name set as {@link getPermissionsForUser}.
@@ -120,9 +145,9 @@ export declare class PrismaAuthzStore {
120
145
  * fast path throws.
121
146
  */
122
147
  private getPermissionsViaDelegates;
123
- /** A user's roles + effective permissions in one shot. */
124
- getUserAuthz(user: UserRef): Promise<UserAuthz>;
125
- /** True when the user holds `permission` through any of their roles. */
126
- userHasPermission(user: UserRef, permission: string): Promise<boolean>;
148
+ /** A user's roles + effective permissions in one shot, in a tenant scope. */
149
+ getUserAuthz(user: UserRef, scope?: TenantScope): Promise<UserAuthz>;
150
+ /** True when the user holds `permission` through any of their roles, in a tenant scope. */
151
+ userHasPermission(user: UserRef, permission: string, scope?: TenantScope): Promise<boolean>;
127
152
  }
128
153
  //# sourceMappingURL=prisma-authz.store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prisma-authz.store.d.ts","sourceRoot":"","sources":["../src/prisma-authz.store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prisma-authz.store.d.ts","sourceRoot":"","sources":["../src/prisma-authz.store.ts"],"names":[],"mappings":"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"}