@dudousxd/nestjs-authz-mikro-orm 0.7.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.
- package/CHANGELOG.md +46 -0
- package/README.md +87 -9
- package/dist/authz-rbac.module.d.ts +12 -0
- package/dist/authz-rbac.module.d.ts.map +1 -1
- package/dist/authz-rbac.module.js +47 -8
- package/dist/authz-rbac.module.js.map +1 -1
- package/dist/entities.d.ts +15 -1
- package/dist/entities.d.ts.map +1 -1
- package/dist/entities.js +14 -1
- package/dist/entities.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mikro-orm-authz.store.d.ts +45 -15
- package/dist/mikro-orm-authz.store.d.ts.map +1 -1
- package/dist/mikro-orm-authz.store.js +114 -33
- package/dist/mikro-orm-authz.store.js.map +1 -1
- package/dist/tenancy.d.ts +100 -0
- package/dist/tenancy.d.ts.map +1 -0
- package/dist/tenancy.js +128 -0
- package/dist/tenancy.js.map +1 -0
- package/package.json +10 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# @dudousxd/nestjs-authz-mikro-orm
|
|
2
2
|
|
|
3
|
+
## 0.9.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.9.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.9.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.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- [#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.
|
|
20
|
+
|
|
21
|
+
- 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.
|
|
22
|
+
- `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' }`.
|
|
23
|
+
- New `tenant` resolver option, `(user) => tenantId | null | undefined`: an explicit tenant that wins over the context.
|
|
24
|
+
- 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.
|
|
25
|
+
|
|
26
|
+
## 1.0.0
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [[`750a6b3`](https://github.com/DavideCarvalho/nestjs-authz/commit/750a6b3f80deea3803dec8df5f9f8cf67a046ac1)]:
|
|
31
|
+
- @dudousxd/nestjs-authz@0.10.0
|
|
32
|
+
|
|
33
|
+
## 0.8.0
|
|
34
|
+
|
|
35
|
+
### Minor Changes
|
|
36
|
+
|
|
37
|
+
- [#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
|
|
38
|
+
permissions now guard routes through the official guard as the core's `RolePolicy` /
|
|
39
|
+
`PermissionPolicy` (`@Roles('editor')`, `@Permission('posts.publish')`), and the guard and the
|
|
40
|
+
handler's `Gate` calls share one permission and role fetch per request. The store API
|
|
41
|
+
(role sources, admin management, tenant-scoped roles where supported) and `AuthzRbacModule`
|
|
42
|
+
are unchanged. A persisted permission named like a policy ability no longer bypasses that
|
|
43
|
+
policy (see the core changeset). Requires NestJS 12, `@nestjs/authorization` ^0.1.3 and Node 22+.
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- [#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.
|
|
48
|
+
|
|
3
49
|
## 0.7.1
|
|
4
50
|
|
|
5
51
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @dudousxd/nestjs-authz-mikro-orm
|
|
2
2
|
|
|
3
3
|
MikroORM RBAC persistence for [`@dudousxd/nestjs-authz`](https://github.com/DavideCarvalho/nestjs-authz) —
|
|
4
|
-
roles
|
|
4
|
+
roles and permissions for the official `@nestjs/authorization` policies, with **zero connection ownership** (your app owns the
|
|
5
5
|
`EntityManager`; this package never opens a connection).
|
|
6
6
|
|
|
7
7
|
This is the MikroORM sibling of `@dudousxd/nestjs-authz-typeorm`: identical store surface
|
|
@@ -15,7 +15,7 @@ separate `@mikro-orm/decorators` package), so no extra peer is required.
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
pnpm add @dudousxd/nestjs-authz-mikro-orm @dudousxd/nestjs-authz @mikro-orm/core @mikro-orm/nestjs
|
|
18
|
+
pnpm add @dudousxd/nestjs-authz-mikro-orm @dudousxd/nestjs-authz @nestjs/authorization @mikro-orm/core @mikro-orm/nestjs
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Entities
|
|
@@ -110,16 +110,30 @@ import { EntityManager } from '@mikro-orm/core';
|
|
|
110
110
|
export class AppModule {}
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
Once wired,
|
|
113
|
+
Once wired, persisted roles and permissions guard routes through the official
|
|
114
|
+
`@nestjs/authorization` guard, as the core's `RolePolicy` / `PermissionPolicy`:
|
|
114
115
|
|
|
115
116
|
```ts
|
|
116
|
-
await store.givePermissionToRole('editor', 'posts
|
|
117
|
+
await store.givePermissionToRole('editor', 'posts.*');
|
|
117
118
|
await store.assignRole({ type: 'user', id: 7 }, 'editor');
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
@Permission('posts.publish') // posts.* grants it
|
|
121
|
+
@Can(PermissionPolicy, 'has', permission('posts.publish')) // the same, spelled out
|
|
122
|
+
@Roles('editor') // @Can(RolePolicy, 'has', roles('editor'))
|
|
121
123
|
```
|
|
122
124
|
|
|
125
|
+
and in services, through the `Gate`:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
gate.forUser(user).allows('posts.publish'); // true (PERMISSION_PROVIDER seam)
|
|
129
|
+
gate.forUser(user).allows(PermissionPolicy, 'has', 'posts.publish');
|
|
130
|
+
gate.forUser(user).hasRole('editor'); // true (ROLE_PROVIDER seam)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The user is the one the official guard reads (`AuthorizationModule.forRoot({ getUser })`,
|
|
134
|
+
default `request.user`), mapped to a store ref with `userRefFrom` (default `{ type, id }` or
|
|
135
|
+
`{ id }`).
|
|
136
|
+
|
|
123
137
|
## Schema
|
|
124
138
|
|
|
125
139
|
`autoCreateSchema` (default `true`) runs `ensureAuthzSchema` on `onModuleInit` via MikroORM's
|
|
@@ -199,9 +213,73 @@ await store.listRoleAssignments({ user: { type: 'user', id: 7 } });
|
|
|
199
213
|
await store.removeUser({ type: 'user', id: 7 });
|
|
200
214
|
```
|
|
201
215
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
nothing.
|
|
216
|
+
`tenantId` filters: omitted = every tenant, `null` = global assignments only, a string = that
|
|
217
|
+
tenant's scoped assignments only. Without the tenant column (below) every row has
|
|
218
|
+
`tenantId: null`, so a tenant id string matches nothing.
|
|
219
|
+
|
|
220
|
+
## Tenant-scoped roles
|
|
221
|
+
|
|
222
|
+
Build the entities with `tenantScoped: true` to assign roles per tenant. The user-role table
|
|
223
|
+
gets a `tenant_id` column (default `''`, a global assignment) in its primary key:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
import { createAuthzEntitySchemas } from '@dudousxd/nestjs-authz-mikro-orm';
|
|
227
|
+
|
|
228
|
+
const authz = createAuthzEntitySchemas({}, { tenantScoped: true }); // or your own table names
|
|
229
|
+
MikroOrmModule.forRoot({ entities: [...authz.all /* , your entities */] });
|
|
230
|
+
|
|
231
|
+
await store.assignRole(user, 'editor', { tenantId: 'acme' }); // only inside acme
|
|
232
|
+
await store.assignRole(user, 'viewer'); // everywhere
|
|
233
|
+
await store.getRolesForUser(user, { tenantId: 'acme' }); // ['editor', 'viewer']
|
|
234
|
+
await store.getRolesForUser(user); // ['viewer']
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
`removeRole` and `setUserRoles` take the same `{ tenantId }` (omitted = the global
|
|
238
|
+
assignments). Without `tenantScoped`, every assignment is global and reads ignore the tenant.
|
|
239
|
+
`assignRole` and `setUserRoles` with a `tenantId` throw; `removeRole` with one does nothing,
|
|
240
|
+
since there is no tenant assignment to remove.
|
|
241
|
+
|
|
242
|
+
### Migrating an existing database
|
|
243
|
+
|
|
244
|
+
`ensureAuthzSchema` / `autoCreateSchema` (or `authzSchemaSql` in a migration) add the `tenant_id`
|
|
245
|
+
column, so existing rows become global assignments. Widen the primary key once, so the same role
|
|
246
|
+
can be assigned in two tenants:
|
|
247
|
+
|
|
248
|
+
```sql
|
|
249
|
+
-- PostgreSQL (default constraint name; check yours with \d authz_user_role)
|
|
250
|
+
ALTER TABLE authz_user_role DROP CONSTRAINT authz_user_role_pkey,
|
|
251
|
+
ADD PRIMARY KEY (user_type, user_id, role_id, source, tenant_id);
|
|
252
|
+
-- MySQL
|
|
253
|
+
ALTER TABLE authz_user_role DROP PRIMARY KEY,
|
|
254
|
+
ADD PRIMARY KEY (user_type, user_id, role_id, source, tenant_id);
|
|
255
|
+
-- SQLite: recreate the table with the 5-column key (SQLite cannot alter a primary key).
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Tenancy
|
|
259
|
+
|
|
260
|
+
The RBAC module reads the tenant only when tenancy is on: turn it on with
|
|
261
|
+
`ContextModule.forRoot({ tenancy: { enabled: true } })` in `@dudousxd/nestjs-context`. Checks
|
|
262
|
+
are then scoped to the request's tenant from `Context.setTenant(...)`.
|
|
263
|
+
A request with no tenant, or inside `Context.allTenants()`, sees global assignments only.
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
AuthzRbacModule.forRoot({
|
|
267
|
+
store,
|
|
268
|
+
tenancy: {
|
|
269
|
+
kinds: ['organization'], // optional: tenant kinds this module honours
|
|
270
|
+
roles: { owner: 'org_admin', member: 'org_member' }, // optional: tenant.role → authz roles in that tenant
|
|
271
|
+
},
|
|
272
|
+
tenant: (user) => (user as { orgId?: string }).orgId, // optional: an explicit tenant wins over the context
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
`tenancy` defaults to `'inherit'` (follow the context switch); `false` keeps this module out.
|
|
277
|
+
Roles mapped with `roles` apply only inside that tenant and only to the context's current user.
|
|
278
|
+
The `tenant` resolver returns a tenant id, `null` for the global scope, or `undefined` to fall
|
|
279
|
+
back to the context.
|
|
280
|
+
|
|
281
|
+
With tenancy on and the default entities, every assignment is global, so only `roles` and the
|
|
282
|
+
`tenant` resolver change what a check sees.
|
|
205
283
|
|
|
206
284
|
## License
|
|
207
285
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { UserRef } from '@dudousxd/nestjs-authz/store-kit';
|
|
2
2
|
import { type DynamicModule } from '@nestjs/common';
|
|
3
3
|
import type { MikroOrmAuthzStore } from './mikro-orm-authz.store.js';
|
|
4
|
+
import { type AuthzTenancyOption, type TenantResolver } from './tenancy.js';
|
|
4
5
|
/** Injection token holding the {@link MikroOrmAuthzStore} the RBAC module manages. */
|
|
5
6
|
export declare const AUTHZ_RBAC_STORE: unique symbol;
|
|
6
7
|
/** Injection token holding the resolved {@link AuthzRbacModuleOptions}. */
|
|
@@ -23,6 +24,17 @@ export interface AuthzRbacModuleOptions {
|
|
|
23
24
|
* {@link defaultUserRefMapper} (`{ type, id }` or `{ id }`).
|
|
24
25
|
*/
|
|
25
26
|
userRefFrom?: UserRefMapper;
|
|
27
|
+
/**
|
|
28
|
+
* Tenancy, from `@dudousxd/nestjs-context`. `'inherit'` (default) follows `ContextModule`'s
|
|
29
|
+
* `tenancy.enabled`; with it on, checks are scoped to the context tenant. The object form adds
|
|
30
|
+
* `kinds` and `roles` (map the caller's `tenant.role` to authz roles in that tenant).
|
|
31
|
+
*/
|
|
32
|
+
tenancy?: AuthzTenancyOption;
|
|
33
|
+
/**
|
|
34
|
+
* Explicit tenant for a check, from the user being checked. Wins over the context: return a
|
|
35
|
+
* tenant id, `null` for the global scope, or `undefined` to fall back to the context.
|
|
36
|
+
*/
|
|
37
|
+
tenant?: TenantResolver;
|
|
26
38
|
}
|
|
27
39
|
export interface AuthzRbacModuleAsyncOptions {
|
|
28
40
|
imports?: unknown[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authz-rbac.module.d.ts","sourceRoot":"","sources":["../src/authz-rbac.module.ts"],"names":[],"mappings":"
|
|
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,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EACL,KAAK,kBAAkB,EAIvB,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AAEtB,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,eAAuD,CAAC;AACrF,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,eAAyD,CAAC;AAEzF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,2EAA2E;IAC3E,KAAK,EAAE,kBAAkB,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;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;AAqHD;;;;;;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,8 +11,10 @@ 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';
|
|
17
|
+
import { rbacTenant, } from './tenancy.js';
|
|
16
18
|
/** Injection token holding the {@link MikroOrmAuthzStore} the RBAC module manages. */
|
|
17
19
|
export const AUTHZ_RBAC_STORE = Symbol.for('@dudousxd/nestjs-authz-mikro-orm:store');
|
|
18
20
|
/** Injection token holding the resolved {@link AuthzRbacModuleOptions}. */
|
|
@@ -36,10 +38,24 @@ export function defaultUserRefMapper(user) {
|
|
|
36
38
|
*/
|
|
37
39
|
let RbacPermissionProvider = class RbacPermissionProvider {
|
|
38
40
|
options;
|
|
41
|
+
context;
|
|
42
|
+
moduleRef;
|
|
39
43
|
// `getPermissions` lists every grant `hasPermission` can find, for any resource.
|
|
40
44
|
exhaustivePermissions = true;
|
|
41
|
-
|
|
45
|
+
contextCache = { resolved: false, value: undefined };
|
|
46
|
+
constructor(options, context, moduleRef) {
|
|
42
47
|
this.options = options;
|
|
48
|
+
this.context = context;
|
|
49
|
+
this.moduleRef = moduleRef;
|
|
50
|
+
}
|
|
51
|
+
tenant(user, ref) {
|
|
52
|
+
return rbacTenant(this.options, user, ref, this.context, this.moduleRef, this.contextCache, false);
|
|
53
|
+
}
|
|
54
|
+
/** The permissions `tenancy.roles` grants through the caller's role in the tenant. */
|
|
55
|
+
async tenantRolePermissions(roles) {
|
|
56
|
+
if (roles.length === 0)
|
|
57
|
+
return [];
|
|
58
|
+
return Object.values(await this.options.store.getRolePermissions(roles)).flat();
|
|
43
59
|
}
|
|
44
60
|
// The core `PermissionProvider` interface passes an optional `resource` (3rd
|
|
45
61
|
// arg); it is intentionally ignored here. RBAC grants are model-less,
|
|
@@ -50,7 +66,10 @@ let RbacPermissionProvider = class RbacPermissionProvider {
|
|
|
50
66
|
const ref = map(user);
|
|
51
67
|
if (ref === undefined)
|
|
52
68
|
return undefined;
|
|
53
|
-
|
|
69
|
+
const tenant = this.tenant(user, ref);
|
|
70
|
+
if (await this.options.store.userHasPermission(ref, permission, tenant.scope))
|
|
71
|
+
return true;
|
|
72
|
+
return (await this.tenantRolePermissions(tenant.roles)).includes(permission);
|
|
54
73
|
}
|
|
55
74
|
// Expose the user's full granted permission set so the core can apply
|
|
56
75
|
// Laravel/spatie-style wildcard matching (a granted `posts.*` satisfies a check
|
|
@@ -60,13 +79,20 @@ let RbacPermissionProvider = class RbacPermissionProvider {
|
|
|
60
79
|
const ref = map(user);
|
|
61
80
|
if (ref === undefined)
|
|
62
81
|
return undefined;
|
|
63
|
-
|
|
82
|
+
const tenant = this.tenant(user, ref);
|
|
83
|
+
const own = await this.options.store.getPermissionsForUser(ref, tenant.scope);
|
|
84
|
+
if (tenant.roles.length === 0)
|
|
85
|
+
return own;
|
|
86
|
+
return [...new Set([...own, ...(await this.tenantRolePermissions(tenant.roles))])];
|
|
64
87
|
}
|
|
65
88
|
};
|
|
66
89
|
RbacPermissionProvider = __decorate([
|
|
67
90
|
Injectable(),
|
|
68
91
|
__param(0, Inject(AUTHZ_RBAC_OPTIONS)),
|
|
69
|
-
|
|
92
|
+
__param(1, Optional()),
|
|
93
|
+
__param(1, Inject(CONTEXT_ACCESSOR)),
|
|
94
|
+
__param(2, Optional()),
|
|
95
|
+
__metadata("design:paramtypes", [Object, Object, ModuleRef])
|
|
70
96
|
], RbacPermissionProvider);
|
|
71
97
|
/**
|
|
72
98
|
* The RBAC {@link RoleProvider} the Gate consults (via the shared {@link ROLE_PROVIDER}
|
|
@@ -76,21 +102,34 @@ RbacPermissionProvider = __decorate([
|
|
|
76
102
|
*/
|
|
77
103
|
let RbacRoleProvider = class RbacRoleProvider {
|
|
78
104
|
options;
|
|
79
|
-
|
|
105
|
+
context;
|
|
106
|
+
moduleRef;
|
|
107
|
+
contextCache = { resolved: false, value: undefined };
|
|
108
|
+
constructor(options, context, moduleRef) {
|
|
80
109
|
this.options = options;
|
|
110
|
+
this.context = context;
|
|
111
|
+
this.moduleRef = moduleRef;
|
|
112
|
+
}
|
|
113
|
+
tenant(user, ref) {
|
|
114
|
+
return rbacTenant(this.options, user, ref, this.context, this.moduleRef, this.contextCache, false);
|
|
81
115
|
}
|
|
82
116
|
async getRoles(user) {
|
|
83
117
|
const map = this.options.userRefFrom ?? defaultUserRefMapper;
|
|
84
118
|
const ref = map(user);
|
|
85
119
|
if (ref === undefined)
|
|
86
120
|
return undefined;
|
|
87
|
-
|
|
121
|
+
const tenant = this.tenant(user, ref);
|
|
122
|
+
const own = await this.options.store.getRolesForUser(ref, tenant.scope);
|
|
123
|
+
return tenant.roles.length === 0 ? own : [...new Set([...own, ...tenant.roles])];
|
|
88
124
|
}
|
|
89
125
|
};
|
|
90
126
|
RbacRoleProvider = __decorate([
|
|
91
127
|
Injectable(),
|
|
92
128
|
__param(0, Inject(AUTHZ_RBAC_OPTIONS)),
|
|
93
|
-
|
|
129
|
+
__param(1, Optional()),
|
|
130
|
+
__param(1, Inject(CONTEXT_ACCESSOR)),
|
|
131
|
+
__param(2, Optional()),
|
|
132
|
+
__metadata("design:paramtypes", [Object, Object, ModuleRef])
|
|
94
133
|
], RbacRoleProvider);
|
|
95
134
|
/** Runs `ensureAuthzSchema` on bootstrap when `autoCreateSchema` is not disabled. */
|
|
96
135
|
let AuthzRbacBootstrap = class AuthzRbacBootstrap {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authz-rbac.module.js","sourceRoot":"","sources":["../src/authz-rbac.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,OAAO,EACL,mBAAmB,EAEnB,aAAa,GAEd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,MAAM,EACN,UAAU,EACV,MAAM,EAEN,QAAQ,GAGT,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"authz-rbac.module.js","sourceRoot":"","sources":["../src/authz-rbac.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAEnB,aAAa,GAEd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,MAAM,EACN,UAAU,EACV,MAAM,EAEN,QAAQ,GAGT,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAML,UAAU,GACX,MAAM,cAAc,CAAC;AAEtB,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACrF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;AAwCzF,qFAAqF;AACrF,MAAM,UAAU,oBAAoB,CAAC,IAAa;IAChD,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IACnC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACtE,MAAM,CAAC,GAAG,IAAwC,CAAC;IACnD,IAAI,CAAC,CAAC,EAAE,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAqB,CAAC;IACnC,OAAO,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,IACM,sBAAsB,GAD5B,MACM,sBAAsB;IAOqB;IACU;IAC1B;IAR/B,iFAAiF;IACxE,qBAAqB,GAAG,IAAI,CAAC;IAErB,YAAY,GAAuB,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAE1F,YAC+C,OAA+B,EACrB,OAA+B,EACzD,SAAqB;QAFL,YAAO,GAAP,OAAO,CAAwB;QACrB,YAAO,GAAP,OAAO,CAAwB;QACzD,cAAS,GAAT,SAAS,CAAY;IACjD,CAAC;IAEI,MAAM,CAAC,IAAa,EAAE,GAAY;QACxC,OAAO,UAAU,CACf,IAAI,CAAC,OAAO,EACZ,IAAI,EACJ,GAAG,EACH,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,YAAY,EACjB,KAAK,CACN,CAAC;IACJ,CAAC;IAED,sFAAsF;IAC9E,KAAK,CAAC,qBAAqB,CAAC,KAAe;QACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClF,CAAC;IAED,6EAA6E;IAC7E,sEAAsE;IACtE,yEAAyE;IACzE,yDAAyD;IACzD,KAAK,CAAC,aAAa,CAAC,IAAa,EAAE,UAAkB;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;QAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3F,OAAO,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/E,CAAC;IAED,sEAAsE;IACtE,gFAAgF;IAChF,6EAA6E;IAC7E,KAAK,CAAC,cAAc,CAAC,IAAa;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;QAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC;QAC1C,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC;CACF,CAAA;AAvDK,sBAAsB;IAD3B,UAAU,EAAE;IAQR,WAAA,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC1B,WAAA,QAAQ,EAAE,CAAA;IAAE,WAAA,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACpC,WAAA,QAAQ,EAAE,CAAA;qDAA8B,SAAS;GAThD,sBAAsB,CAuD3B;AAED;;;;;GAKG;AACH,IACM,gBAAgB,GADtB,MACM,gBAAgB;IAI2B;IACU;IAC1B;IALd,YAAY,GAAuB,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAE1F,YAC+C,OAA+B,EACrB,OAA+B,EACzD,SAAqB;QAFL,YAAO,GAAP,OAAO,CAAwB;QACrB,YAAO,GAAP,OAAO,CAAwB;QACzD,cAAS,GAAT,SAAS,CAAY;IACjD,CAAC;IAEI,MAAM,CAAC,IAAa,EAAE,GAAY;QACxC,OAAO,UAAU,CACf,IAAI,CAAC,OAAO,EACZ,IAAI,EACJ,GAAG,EACH,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,YAAY,EACjB,KAAK,CACN,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAa;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;QAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC;CACF,CAAA;AA7BK,gBAAgB;IADrB,UAAU,EAAE;IAKR,WAAA,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC1B,WAAA,QAAQ,EAAE,CAAA;IAAE,WAAA,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACpC,WAAA,QAAQ,EAAE,CAAA;qDAA8B,SAAS;GANhD,gBAAgB,CA6BrB;AAED,qFAAqF;AACrF,IACM,kBAAkB,GADxB,MACM,kBAAkB;IAEqC;IAD3D,YAC2D,OAAgC;QAAhC,YAAO,GAAP,OAAO,CAAyB;IACxF,CAAC;IAEJ,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,KAAK,KAAK;YAAE,OAAO;QACpD,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;IAC1C,CAAC;CACF,CAAA;AAVK,kBAAkB;IADvB,UAAU,EAAE;IAGR,WAAA,QAAQ,EAAE,CAAA;IAAE,WAAA,MAAM,CAAC,kBAAkB,CAAC,CAAA;;GAFrC,kBAAkB,CAUvB;AAED;;;;;;GAMG;AAEI,IAAM,eAAe,uBAArB,MAAM,eAAe;IAC1B,MAAM,CAAC,OAAO,CAAC,OAA+B;QAC5C,OAAO;YACL,MAAM,EAAE,iBAAe;YACvB,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE;gBACT,EAAE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE;gBAClD,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE;gBACtD,GAAG,iBAAe,CAAC,eAAe,EAAE;aACrC;YACD,OAAO,EAAE,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,aAAa,CAAC;SAChE,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAoC;QACtD,OAAO;YACL,MAAM,EAAE,iBAAe;YACvB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAoB;YACnD,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,kBAAkB;oBAC3B,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAyB;iBACvD;gBACD;oBACE,OAAO,EAAE,gBAAgB;oBACzB,UAAU,EAAE,CAAC,IAA4B,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK;oBACxD,MAAM,EAAE,CAAC,kBAAkB,CAAC;iBAC7B;gBACD,GAAG,iBAAe,CAAC,eAAe,EAAE;aACrC;YACD,OAAO,EAAE,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,aAAa,CAAC;SAChE,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,eAAe;QAC5B,OAAO;YACL,sBAAsB;YACtB,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,sBAAsB,EAAE;YACrE,gBAAgB;YAChB,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE;YACzD,kBAAkB;SACnB,CAAC;IACJ,CAAC;CACF,CAAA;AA7CY,eAAe;IAD3B,MAAM,CAAC,EAAE,CAAC;GACE,eAAe,CA6C3B"}
|
package/dist/entities.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export declare const DEFAULT_TABLE_NAMES: {
|
|
|
12
12
|
readonly rolePermission: "authz_role_permission";
|
|
13
13
|
readonly userRole: "authz_user_role";
|
|
14
14
|
};
|
|
15
|
+
/** The tenant id of a GLOBAL role assignment (applies in every tenant). */
|
|
16
|
+
export declare const GLOBAL_TENANT = "";
|
|
15
17
|
/** Physical table names for the four authz tables. */
|
|
16
18
|
export interface AuthzTableNames {
|
|
17
19
|
roles: string;
|
|
@@ -82,6 +84,15 @@ export declare class UserRoleEntity {
|
|
|
82
84
|
*/
|
|
83
85
|
source: string;
|
|
84
86
|
}
|
|
87
|
+
/** Options for {@link createAuthzEntitySchemas}. */
|
|
88
|
+
export interface AuthzEntitySchemaOptions {
|
|
89
|
+
/**
|
|
90
|
+
* Add a `tenantId` column (default `''` = global) to the user-role pivot, in its primary key,
|
|
91
|
+
* so role assignments can be scoped to a tenant. Default `false`: the tables keep their shape
|
|
92
|
+
* and every assignment is global.
|
|
93
|
+
*/
|
|
94
|
+
tenantScoped?: boolean;
|
|
95
|
+
}
|
|
85
96
|
/** The four {@link EntitySchema} definitions produced by {@link createAuthzEntitySchemas}. */
|
|
86
97
|
export interface AuthzEntitySchemas {
|
|
87
98
|
role: EntitySchema<RoleEntity>;
|
|
@@ -108,8 +119,11 @@ export interface AuthzEntitySchemas {
|
|
|
108
119
|
* Going through the factory (rather than hand-writing `new EntitySchema({ tableName })`)
|
|
109
120
|
* keeps the custom repository binding and the index names attached to the renamed tables;
|
|
110
121
|
* a hand-rolled re-declaration silently drops both.
|
|
122
|
+
*
|
|
123
|
+
* `{ tenantScoped: true }` adds a `tenantId` column to the user-role pivot (in its primary key),
|
|
124
|
+
* so a role can be assigned per tenant. Pass `{}` as the names to keep the default table names.
|
|
111
125
|
*/
|
|
112
|
-
export declare function createAuthzEntitySchemas(tableNames?: Partial<AuthzTableNames
|
|
126
|
+
export declare function createAuthzEntitySchemas(tableNames?: Partial<AuthzTableNames>, options?: AuthzEntitySchemaOptions): AuthzEntitySchemas;
|
|
113
127
|
export declare const RoleEntitySchema: EntitySchema<RoleEntity, never>;
|
|
114
128
|
export declare const PermissionEntitySchema: EntitySchema<PermissionEntity, never>;
|
|
115
129
|
export declare const RolePermissionEntitySchema: EntitySchema<RolePermissionEntity, never>;
|
package/dist/entities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAEX,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;GAGG;AACH,qBAAa,UAAU;IACb,CAAC,oBAAoB,CAAC,CAAC,EAAE,mBAAmB,CAAC;IACrD,EAAE,EAAG,MAAM,CAAC;IACZ,IAAI,EAAG,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,oGAAoG;AACpG,qBAAa,gBAAgB;IACnB,CAAC,oBAAoB,CAAC,CAAC,EAAE,yBAAyB,CAAC;IAC3D,EAAE,EAAG,MAAM,CAAC;IACZ,IAAI,EAAG,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,uEAAuE;AACvE,qBAAa,oBAAoB;IACvB,CAAC,oBAAoB,CAAC,CAAC,EAAE,6BAA6B,CAAC;IAC/D,MAAM,EAAG,MAAM,CAAC;IAChB,YAAY,EAAG,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACjB,CAAC,oBAAoB,CAAC,CAAC,EAAE,uBAAuB,CAAC;IACzD,QAAQ,EAAG,MAAM,CAAC;IAClB,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAG,MAAM,CAAC;CACjB;AAED,8FAA8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAC/B,UAAU,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAC3C,cAAc,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IACnD,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IACvC,qEAAqE;IACrE,GAAG,EAAE;QACH,YAAY,CAAC,UAAU,CAAC;QACxB,YAAY,CAAC,gBAAgB,CAAC;QAC9B,YAAY,CAAC,oBAAoB,CAAC;QAClC,YAAY,CAAC,cAAc,CAAC;KAC7B,CAAC;CACH;AAED
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAEX,2EAA2E;AAC3E,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;GAGG;AACH,qBAAa,UAAU;IACb,CAAC,oBAAoB,CAAC,CAAC,EAAE,mBAAmB,CAAC;IACrD,EAAE,EAAG,MAAM,CAAC;IACZ,IAAI,EAAG,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,oGAAoG;AACpG,qBAAa,gBAAgB;IACnB,CAAC,oBAAoB,CAAC,CAAC,EAAE,yBAAyB,CAAC;IAC3D,EAAE,EAAG,MAAM,CAAC;IACZ,IAAI,EAAG,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,uEAAuE;AACvE,qBAAa,oBAAoB;IACvB,CAAC,oBAAoB,CAAC,CAAC,EAAE,6BAA6B,CAAC;IAC/D,MAAM,EAAG,MAAM,CAAC;IAChB,YAAY,EAAG,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACjB,CAAC,oBAAoB,CAAC,CAAC,EAAE,uBAAuB,CAAC;IACzD,QAAQ,EAAG,MAAM,CAAC;IAClB,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAG,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,8FAA8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAC/B,UAAU,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAC3C,cAAc,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IACnD,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IACvC,qEAAqE;IACrE,GAAG,EAAE;QACH,YAAY,CAAC,UAAU,CAAC;QACxB,YAAY,CAAC,gBAAgB,CAAC;QAC9B,YAAY,CAAC,oBAAoB,CAAC;QAClC,YAAY,CAAC,cAAc,CAAC;KAC7B,CAAC;CACH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,GAAE,OAAO,CAAC,eAAe,CAAM,EACzC,OAAO,GAAE,wBAA6B,GACrC,kBAAkB,CAgFpB;AAID,eAAO,MAAM,gBAAgB,iCAAsB,CAAC;AACpD,eAAO,MAAM,sBAAsB,uCAA4B,CAAC;AAChE,eAAO,MAAM,0BAA0B,2CAAgC,CAAC;AACxE,eAAO,MAAM,oBAAoB,qCAA0B,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,cAAc,0JAAqB,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,2GAKvB,CAAC"}
|
package/dist/entities.js
CHANGED
|
@@ -13,6 +13,8 @@ export const DEFAULT_TABLE_NAMES = {
|
|
|
13
13
|
rolePermission: 'authz_role_permission',
|
|
14
14
|
userRole: 'authz_user_role',
|
|
15
15
|
};
|
|
16
|
+
/** The tenant id of a GLOBAL role assignment (applies in every tenant). */
|
|
17
|
+
export const GLOBAL_TENANT = '';
|
|
16
18
|
/**
|
|
17
19
|
* The entities are described with {@link EntitySchema} (the schema-first definition style)
|
|
18
20
|
* rather than property decorators. This is the ONE definition surface that lives entirely
|
|
@@ -84,8 +86,11 @@ export class UserRoleEntity {
|
|
|
84
86
|
* Going through the factory (rather than hand-writing `new EntitySchema({ tableName })`)
|
|
85
87
|
* keeps the custom repository binding and the index names attached to the renamed tables;
|
|
86
88
|
* a hand-rolled re-declaration silently drops both.
|
|
89
|
+
*
|
|
90
|
+
* `{ tenantScoped: true }` adds a `tenantId` column to the user-role pivot (in its primary key),
|
|
91
|
+
* so a role can be assigned per tenant. Pass `{}` as the names to keep the default table names.
|
|
87
92
|
*/
|
|
88
|
-
export function createAuthzEntitySchemas(tableNames = {}) {
|
|
93
|
+
export function createAuthzEntitySchemas(tableNames = {}, options = {}) {
|
|
89
94
|
const names = { ...DEFAULT_TABLE_NAMES, ...tableNames };
|
|
90
95
|
const role = new EntitySchema({
|
|
91
96
|
class: RoleEntity,
|
|
@@ -145,6 +150,14 @@ export function createAuthzEntitySchemas(tableNames = {}) {
|
|
|
145
150
|
},
|
|
146
151
|
indexes: [{ name: `${names.userRole}_user_idx`, properties: ['userType', 'userId'] }],
|
|
147
152
|
});
|
|
153
|
+
if (options.tenantScoped) {
|
|
154
|
+
// `tenantId` is not a field of the class (the default schemas don't map it), hence the cast.
|
|
155
|
+
userRole.addProperty('tenantId', 'string', {
|
|
156
|
+
length: 191,
|
|
157
|
+
primary: true,
|
|
158
|
+
default: GLOBAL_TENANT,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
148
161
|
return {
|
|
149
162
|
role,
|
|
150
163
|
permission,
|
package/dist/entities.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAwB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,aAAa;IACpB,WAAW,EAAE,mBAAmB;IAChC,cAAc,EAAE,uBAAuB;IACvC,QAAQ,EAAE,iBAAiB;CACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
export { AUTHZ_ENTITIES, AUTHZ_ENTITY_CLASSES, createAuthzEntitySchemas, DEFAULT_TABLE_NAMES, PermissionEntity, PermissionEntitySchema, RoleEntity, RoleEntitySchema, RolePermissionEntity, RolePermissionEntitySchema, UserRoleEntity, UserRoleEntitySchema, } from './entities.js';
|
|
2
|
-
export type { AuthzEntitySchemas, AuthzTableNames } from './entities.js';
|
|
1
|
+
export { AUTHZ_ENTITIES, AUTHZ_ENTITY_CLASSES, createAuthzEntitySchemas, DEFAULT_TABLE_NAMES, GLOBAL_TENANT, PermissionEntity, PermissionEntitySchema, RoleEntity, RoleEntitySchema, RolePermissionEntity, RolePermissionEntitySchema, UserRoleEntity, UserRoleEntitySchema, } from './entities.js';
|
|
2
|
+
export type { AuthzEntitySchemaOptions, AuthzEntitySchemas, AuthzTableNames, } from './entities.js';
|
|
3
3
|
export { AuthzPermissionRepository, AuthzRolePermissionRepository, AuthzRoleRepository, AuthzUserRoleRepository, } from './repositories.js';
|
|
4
4
|
export { authzSchemaSql, ensureAuthzSchema } from './schema.js';
|
|
5
5
|
export { MikroOrmAuthzStore } from './mikro-orm-authz.store.js';
|
|
6
|
-
export type { RoleAssignment, RoleAssignmentFilter, RoleSourceOptions, UserAuthz, UserRoleAssignment, } from './mikro-orm-authz.store.js';
|
|
6
|
+
export type { RoleAssignment, RoleAssignmentFilter, RoleSourceOptions, TenantScope, UserAuthz, UserRoleAssignment, } from './mikro-orm-authz.store.js';
|
|
7
7
|
export { AUTHZ_RBAC_OPTIONS, AUTHZ_RBAC_STORE, AuthzRbacModule, defaultUserRefMapper, } from './authz-rbac.module.js';
|
|
8
8
|
export type { AuthzRbacModuleAsyncOptions, AuthzRbacModuleOptions, UserRefMapper, } from './authz-rbac.module.js';
|
|
9
9
|
export type { AuthzStoreOptions } from './types.js';
|
|
10
|
+
export type { AuthzTenancyOption, TenantResolver } from './tenancy.js';
|
|
10
11
|
export type { UserRef, UserRefInput } from '@dudousxd/nestjs-authz/store-kit';
|
|
11
12
|
export { applyScope, compileScope } from './scope.js';
|
|
12
13
|
export type { ScopeResolver } from './scope.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,GAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AACpC,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,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,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,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AUTHZ_ENTITIES, AUTHZ_ENTITY_CLASSES, createAuthzEntitySchemas, DEFAULT_TABLE_NAMES, PermissionEntity, PermissionEntitySchema, RoleEntity, RoleEntitySchema, RolePermissionEntity, RolePermissionEntitySchema, UserRoleEntity, UserRoleEntitySchema, } from './entities.js';
|
|
1
|
+
export { AUTHZ_ENTITIES, AUTHZ_ENTITY_CLASSES, createAuthzEntitySchemas, DEFAULT_TABLE_NAMES, GLOBAL_TENANT, PermissionEntity, PermissionEntitySchema, RoleEntity, RoleEntitySchema, RolePermissionEntity, RolePermissionEntitySchema, UserRoleEntity, UserRoleEntitySchema, } from './entities.js';
|
|
2
2
|
// VALUE exports on purpose: these classes are the DI tokens `MikroOrmModule.forFeature()`
|
|
3
3
|
// registers, so `export type` would compile green and be `undefined` at runtime.
|
|
4
4
|
export { AuthzPermissionRepository, AuthzRolePermissionRepository, AuthzRoleRepository, AuthzUserRoleRepository, } from './repositories.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAMvB,0FAA0F;AAC1F,iFAAiF;AACjF,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAShE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAShC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { type RoleAssignment, type RoleAssignmentFilter, type UserAuthz, type UserRef, type UserRoleAssignment } from '@dudousxd/nestjs-authz/store-kit';
|
|
2
2
|
import type { EntityManager } from '@mikro-orm/core';
|
|
3
3
|
export type { RoleAssignment, RoleAssignmentFilter, UserAuthz, UserRoleAssignment };
|
|
4
|
-
/**
|
|
5
|
-
|
|
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 entities built with `tenantScoped: true`; without that column
|
|
8
|
+
* every assignment is global.
|
|
9
|
+
*/
|
|
10
|
+
export interface TenantScope {
|
|
11
|
+
tenantId?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Assignment source (default `'manual'`, see `setUserRoles`) and tenant for role mutations.
|
|
15
|
+
* `tenantId` scopes the assignment to one tenant; it needs entities built with
|
|
16
|
+
* `createAuthzEntitySchemas(names, { tenantScoped: true })`.
|
|
17
|
+
*/
|
|
18
|
+
export interface RoleSourceOptions extends TenantScope {
|
|
6
19
|
source?: string;
|
|
7
20
|
}
|
|
8
21
|
/**
|
|
@@ -19,6 +32,14 @@ export declare class MikroOrmAuthzStore {
|
|
|
19
32
|
constructor(em: EntityManager, _opts?: Record<string, never>);
|
|
20
33
|
/** Create/upgrade the RBAC tables (non-destructive, delegates to {@link ensureAuthzSchema}). */
|
|
21
34
|
ensureSchema(): Promise<void>;
|
|
35
|
+
/** True when the user-role entity maps `tenantId` (built with `tenantScoped: true`). */
|
|
36
|
+
private tenantScoped;
|
|
37
|
+
/** The `tenantId` value of a written assignment (`{}` without the column). */
|
|
38
|
+
private tenantValue;
|
|
39
|
+
/** Assignments visible in a scope: global ones, plus the tenant's own when one is given. */
|
|
40
|
+
private tenantWhere;
|
|
41
|
+
/** The public `tenantId` of a stored row: `null` for a global assignment. */
|
|
42
|
+
private static rowTenant;
|
|
22
43
|
/**
|
|
23
44
|
* Create the role if absent; returns its id. Idempotent and race-tolerant: it re-reads
|
|
24
45
|
* by the unique `name` after a create so two concurrent creators converge on the same row.
|
|
@@ -53,12 +74,15 @@ export declare class MikroOrmAuthzStore {
|
|
|
53
74
|
getRolePermissions(roleNames: readonly string[]): Promise<Record<string, string[]>>;
|
|
54
75
|
/**
|
|
55
76
|
* Assign a role to a user (creating the role by name if needed). Idempotent. `{ source }`
|
|
56
|
-
* (default `'manual'`) records where the assignment came from.
|
|
77
|
+
* (default `'manual'`) records where the assignment came from. `{ tenantId }` scopes it to that
|
|
78
|
+
* tenant; omitted, the assignment is global (applies in every tenant).
|
|
57
79
|
*/
|
|
58
80
|
assignRole(user: UserRef, roleName: string, opts?: RoleSourceOptions): Promise<void>;
|
|
59
81
|
/**
|
|
60
82
|
* Remove a role from a user. No-op if the role or assignment is absent. With `{ source }` only
|
|
61
|
-
* that source's assignment goes; without it, the role is removed from every source.
|
|
83
|
+
* that source's assignment goes; without it, the role is removed from every source. With
|
|
84
|
+
* tenant-scoped entities, `{ tenantId }` removes the assignment in that tenant and omitting it
|
|
85
|
+
* removes the global one.
|
|
62
86
|
*/
|
|
63
87
|
removeRole(user: UserRef, roleName: string, opts?: RoleSourceOptions): Promise<void>;
|
|
64
88
|
/**
|
|
@@ -66,17 +90,23 @@ export declare class MikroOrmAuthzStore {
|
|
|
66
90
|
* `roleNames` — e.g. an SSO/SCIM sync calls `setUserRoles(user, mappedRoles, { source: 'sso' })`
|
|
67
91
|
* on every login. Other sources' assignments are untouched, so a role held both manually and via
|
|
68
92
|
* SSO survives an SSO sync that drops it. Roles are created by name when missing. Transactional.
|
|
93
|
+
* With tenant-scoped entities it replaces the assignments of one tenant (`{ tenantId }`), or the
|
|
94
|
+
* global ones when omitted.
|
|
69
95
|
*/
|
|
70
96
|
setUserRoles(user: UserRef, roleNames: readonly string[], opts?: RoleSourceOptions): Promise<void>;
|
|
71
|
-
/**
|
|
72
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Every role assignment of a user visible in a tenant scope (global ones always; the tenant's
|
|
99
|
+
* own with `{ tenantId }`), one entry per `(role, source, tenant)`.
|
|
100
|
+
*/
|
|
101
|
+
getRoleAssignments(user: UserRef, scope?: TenantScope): Promise<RoleAssignment[]>;
|
|
73
102
|
/**
|
|
74
103
|
* Raw role-assignment rows for admin listings — e.g. who holds a role (`{ role: 'admin' }`) or
|
|
75
104
|
* a user's assignments with their sources (`{ user }`). `role` accepts one name or a list;
|
|
76
105
|
* `user` and `source` narrow further. Ordered by `(userType, userId, role, source)`.
|
|
77
106
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
107
|
+
* `tenantId`: omitted = no tenant filter; `null` = global assignments only; a string = exactly
|
|
108
|
+
* that tenant's scoped assignments. Without tenant-scoped entities every row is global
|
|
109
|
+
* (`tenantId: null`), so a tenant id string matches nothing.
|
|
80
110
|
*/
|
|
81
111
|
listRoleAssignments(filter?: RoleAssignmentFilter): Promise<UserRoleAssignment[]>;
|
|
82
112
|
/**
|
|
@@ -84,8 +114,8 @@ export declare class MikroOrmAuthzStore {
|
|
|
84
114
|
* Roles and permissions are kept. (This adapter has no direct user permissions.)
|
|
85
115
|
*/
|
|
86
116
|
removeUser(user: UserRef): Promise<void>;
|
|
87
|
-
/** The role names a user holds. */
|
|
88
|
-
getRolesForUser(user: UserRef): Promise<string[]>;
|
|
117
|
+
/** The role names a user holds, in a tenant scope (see {@link TenantScope}). */
|
|
118
|
+
getRolesForUser(user: UserRef, scope?: TenantScope): Promise<string[]>;
|
|
89
119
|
/**
|
|
90
120
|
* The flattened, distinct permission names a user has via their roles.
|
|
91
121
|
*
|
|
@@ -95,10 +125,10 @@ export declare class MikroOrmAuthzStore {
|
|
|
95
125
|
* returned set is the FULL granted permission name set, deduped — callers (incl. the
|
|
96
126
|
* wildcard matcher) rely on getting every granted name (e.g. a granted `posts.*`).
|
|
97
127
|
*/
|
|
98
|
-
getPermissionsForUser(user: UserRef): Promise<string[]>;
|
|
99
|
-
/** A user's roles + effective permissions in one shot. */
|
|
100
|
-
getUserAuthz(user: UserRef): Promise<UserAuthz>;
|
|
101
|
-
/** True when the user holds `permission` through any of their roles. */
|
|
102
|
-
userHasPermission(user: UserRef, permission: string): Promise<boolean>;
|
|
128
|
+
getPermissionsForUser(user: UserRef, scope?: TenantScope): Promise<string[]>;
|
|
129
|
+
/** A user's roles + effective permissions in one shot, in a tenant scope. */
|
|
130
|
+
getUserAuthz(user: UserRef, scope?: TenantScope): Promise<UserAuthz>;
|
|
131
|
+
/** True when the user holds `permission` through any of their roles, in a tenant scope. */
|
|
132
|
+
userHasPermission(user: UserRef, permission: string, scope?: TenantScope): Promise<boolean>;
|
|
103
133
|
}
|
|
104
134
|
//# sourceMappingURL=mikro-orm-authz.store.d.ts.map
|