@dudousxd/nestjs-authz-typeorm 0.2.1 → 0.3.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 +58 -0
- package/dist/authz-rbac.module.d.ts.map +1 -1
- package/dist/authz-rbac.module.js +86 -8
- package/dist/authz-rbac.module.js.map +1 -1
- package/dist/entities.d.ts +30 -1
- package/dist/entities.d.ts.map +1 -1
- package/dist/entities.js +51 -0
- package/dist/entities.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +28 -4
- package/dist/schema.js.map +1 -1
- package/dist/scope.d.ts +75 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +124 -0
- package/dist/scope.js.map +1 -0
- package/dist/typeorm-authz.store.d.ts +57 -13
- package/dist/typeorm-authz.store.d.ts.map +1 -1
- package/dist/typeorm-authz.store.js +128 -26
- package/dist/typeorm-authz.store.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @dudousxd/nestjs-authz-typeorm
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#9](https://github.com/DavideCarvalho/nestjs-authz/pull/9) [`07d01de`](https://github.com/DavideCarvalho/nestjs-authz/commit/07d01de286e7dfcae5fbeb10b7e8d48533214087) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Ecosystem improvements across the authz packages.
|
|
8
|
+
|
|
9
|
+
### Permissions
|
|
10
|
+
|
|
11
|
+
- **Wildcard / hierarchical permissions.** Permission strings now support wildcard
|
|
12
|
+
and hierarchical matching (e.g. `posts:*` or `posts:read:*`), so a single granted
|
|
13
|
+
permission can authorize a family of related actions instead of enumerating each one.
|
|
14
|
+
|
|
15
|
+
### Authorization decisions
|
|
16
|
+
|
|
17
|
+
- **Deny reason / message surfaced on `ForbiddenException`.** When a check fails, the
|
|
18
|
+
reason for the denial is propagated onto the thrown `ForbiddenException`, making it
|
|
19
|
+
possible to return a meaningful message to the caller and to debug authorization
|
|
20
|
+
failures.
|
|
21
|
+
- **Gate `after` hook.** The Gate now exposes an `after` hook that runs once a decision
|
|
22
|
+
has been made, enabling cross-cutting concerns such as auditing, logging, and metrics.
|
|
23
|
+
|
|
24
|
+
### Batch authorization
|
|
25
|
+
|
|
26
|
+
- **`allowsMany`** for evaluating multiple permission checks in a single call.
|
|
27
|
+
- **Batch `/authz/can` endpoint** so clients can resolve many checks in one round trip.
|
|
28
|
+
- **`createCanBatch`** client helper that batches `can` calls transparently.
|
|
29
|
+
|
|
30
|
+
### Performance
|
|
31
|
+
|
|
32
|
+
- **Request-scoped permission cache.** Permissions resolved during a request are cached
|
|
33
|
+
for the lifetime of that request, avoiding repeated lookups on the hot path.
|
|
34
|
+
|
|
35
|
+
### RBAC adapters (TypeORM)
|
|
36
|
+
|
|
37
|
+
- **Direct user permissions** granted to a user independent of their roles.
|
|
38
|
+
- **Tenant-scoped roles** so the same role can be assigned per tenant in multi-tenant
|
|
39
|
+
deployments.
|
|
40
|
+
|
|
41
|
+
### Query scoping / policy filter (ABAC)
|
|
42
|
+
|
|
43
|
+
- **ORM-neutral constraint AST.** Policies can produce a portable constraint
|
|
44
|
+
representation describing which rows a subject may access.
|
|
45
|
+
- **Per-ORM application.** The constraint AST is translated and applied for
|
|
46
|
+
**TypeORM**, **MikroORM**, and **Prisma**, giving ABAC-style query scoping that
|
|
47
|
+
filters data at the database layer regardless of the ORM in use.
|
|
48
|
+
|
|
49
|
+
### Testing
|
|
50
|
+
|
|
51
|
+
- **New `@dudousxd/nestjs-authz-testing` package** with fakes and helpers for testing
|
|
52
|
+
authorization in consumer applications.
|
|
53
|
+
- **Postgres / MySQL testcontainers + contract tests** so the ORM stores are verified
|
|
54
|
+
against real database engines, and a shared contract suite keeps the adapters
|
|
55
|
+
behaviorally consistent.
|
|
56
|
+
|
|
57
|
+
### Housekeeping
|
|
58
|
+
|
|
59
|
+
- **Packaging hygiene** across the published packages.
|
|
60
|
+
|
|
3
61
|
## 0.2.1
|
|
4
62
|
|
|
5
63
|
### Patch Changes
|
|
@@ -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,EACL,KAAK,aAAa,EAQnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,qFAAqF;AACrF,eAAO,MAAM,gBAAgB,eAAqD,CAAC;AACnF,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,eAAuD,CAAC;AAEvF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,KAAK,EAAE,iBAAiB,CAAC;IACzB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;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;AAgDD,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAOvE;AA+FD;;;;;;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,12 +11,49 @@ 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
|
/** Injection token holding the {@link TypeOrmAuthzStore} the RBAC module manages. */
|
|
17
18
|
export const AUTHZ_RBAC_STORE = Symbol.for('@dudousxd/nestjs-authz-typeorm:store');
|
|
18
19
|
/** Injection token holding the resolved {@link AuthzRbacModuleOptions}. */
|
|
19
20
|
export const AUTHZ_RBAC_OPTIONS = Symbol.for('@dudousxd/nestjs-authz-typeorm:options');
|
|
21
|
+
/** Read the current tenant from the (optional) context accessor, defensively. */
|
|
22
|
+
function tenantScopeFrom(context) {
|
|
23
|
+
if (!context || typeof context.tenantId !== 'function')
|
|
24
|
+
return {};
|
|
25
|
+
let tenantId;
|
|
26
|
+
try {
|
|
27
|
+
tenantId = context.tenantId();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
tenantId = undefined;
|
|
31
|
+
}
|
|
32
|
+
return tenantId == null ? {} : { tenantId };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Locate the context accessor for tenant scoping. Prefers a value injected into
|
|
36
|
+
* this module; falls back to a non-strict {@link ModuleRef} lookup so an accessor
|
|
37
|
+
* provided by ANY module (the app root, a global ContextModule) is still found —
|
|
38
|
+
* the RBAC module is global and its providers don't import the app's modules, so a
|
|
39
|
+
* plain `@Inject` would miss a root-provided accessor. Mirrors the Gate's seam.
|
|
40
|
+
*/
|
|
41
|
+
function resolveTenantContext(injected, moduleRef, cache) {
|
|
42
|
+
if (injected)
|
|
43
|
+
return injected;
|
|
44
|
+
if (cache.resolved)
|
|
45
|
+
return cache.value;
|
|
46
|
+
cache.resolved = true;
|
|
47
|
+
if (moduleRef) {
|
|
48
|
+
try {
|
|
49
|
+
cache.value = moduleRef.get(CONTEXT_ACCESSOR, { strict: false });
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
cache.value = undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return cache.value;
|
|
56
|
+
}
|
|
20
57
|
/** Default mapping: accept a `{ type, id }` ref, a `{ id }` object, or a bare id. */
|
|
21
58
|
export function defaultUserRefMapper(user) {
|
|
22
59
|
if (user == null)
|
|
@@ -36,25 +73,52 @@ export function defaultUserRefMapper(user) {
|
|
|
36
73
|
*/
|
|
37
74
|
let RbacPermissionProvider = class RbacPermissionProvider {
|
|
38
75
|
options;
|
|
39
|
-
|
|
76
|
+
context;
|
|
77
|
+
moduleRef;
|
|
78
|
+
contextCache = {
|
|
79
|
+
resolved: false,
|
|
80
|
+
value: undefined,
|
|
81
|
+
};
|
|
82
|
+
constructor(options, context, moduleRef) {
|
|
40
83
|
this.options = options;
|
|
84
|
+
this.context = context;
|
|
85
|
+
this.moduleRef = moduleRef;
|
|
86
|
+
}
|
|
87
|
+
scope() {
|
|
88
|
+
return tenantScopeFrom(resolveTenantContext(this.context, this.moduleRef, this.contextCache));
|
|
41
89
|
}
|
|
42
90
|
// The core `PermissionProvider` interface passes an optional `resource` (3rd
|
|
43
91
|
// arg); it is intentionally ignored here. RBAC grants are model-less,
|
|
44
92
|
// named-ability grants (the Laravel/spatie `Gate::before` grant), so the
|
|
45
|
-
// verdict never depends on a specific resource instance.
|
|
93
|
+
// verdict never depends on a specific resource instance. Permissions are scoped
|
|
94
|
+
// by the current tenant (from nestjs-context, when present) — a tenant-scoped
|
|
95
|
+
// role only grants within its tenant; direct user grants always apply.
|
|
46
96
|
async hasPermission(user, permission) {
|
|
47
97
|
const map = this.options.userRefFrom ?? defaultUserRefMapper;
|
|
48
98
|
const ref = map(user);
|
|
49
99
|
if (ref === undefined)
|
|
50
100
|
return undefined;
|
|
51
|
-
return this.options.store.userHasPermission(ref, permission);
|
|
101
|
+
return this.options.store.userHasPermission(ref, permission, this.scope());
|
|
102
|
+
}
|
|
103
|
+
// Expose the user's full granted permission set so the core can apply
|
|
104
|
+
// Laravel/spatie-style wildcard matching (a granted `posts.*` satisfies a check
|
|
105
|
+
// for `posts.update`, `*` satisfies anything). The matching itself lives in core,
|
|
106
|
+
// so every adapter that lists grants gets wildcard semantics for free.
|
|
107
|
+
async getPermissions(user) {
|
|
108
|
+
const map = this.options.userRefFrom ?? defaultUserRefMapper;
|
|
109
|
+
const ref = map(user);
|
|
110
|
+
if (ref === undefined)
|
|
111
|
+
return undefined;
|
|
112
|
+
return this.options.store.getPermissionsForUser(ref, this.scope());
|
|
52
113
|
}
|
|
53
114
|
};
|
|
54
115
|
RbacPermissionProvider = __decorate([
|
|
55
116
|
Injectable(),
|
|
56
117
|
__param(0, Inject(AUTHZ_RBAC_OPTIONS)),
|
|
57
|
-
|
|
118
|
+
__param(1, Optional()),
|
|
119
|
+
__param(1, Inject(CONTEXT_ACCESSOR)),
|
|
120
|
+
__param(2, Optional()),
|
|
121
|
+
__metadata("design:paramtypes", [Object, Object, ModuleRef])
|
|
58
122
|
], RbacPermissionProvider);
|
|
59
123
|
/**
|
|
60
124
|
* The RBAC {@link RoleProvider} the Gate consults (via the shared {@link ROLE_PROVIDER}
|
|
@@ -64,21 +128,35 @@ RbacPermissionProvider = __decorate([
|
|
|
64
128
|
*/
|
|
65
129
|
let RbacRoleProvider = class RbacRoleProvider {
|
|
66
130
|
options;
|
|
67
|
-
|
|
131
|
+
context;
|
|
132
|
+
moduleRef;
|
|
133
|
+
contextCache = {
|
|
134
|
+
resolved: false,
|
|
135
|
+
value: undefined,
|
|
136
|
+
};
|
|
137
|
+
constructor(options, context, moduleRef) {
|
|
68
138
|
this.options = options;
|
|
139
|
+
this.context = context;
|
|
140
|
+
this.moduleRef = moduleRef;
|
|
69
141
|
}
|
|
70
142
|
async getRoles(user) {
|
|
71
143
|
const map = this.options.userRefFrom ?? defaultUserRefMapper;
|
|
72
144
|
const ref = map(user);
|
|
73
145
|
if (ref === undefined)
|
|
74
146
|
return undefined;
|
|
75
|
-
|
|
147
|
+
// Scope roles by the current tenant (when nestjs-context is present): a
|
|
148
|
+
// tenant-scoped role only counts within its tenant; global roles always count.
|
|
149
|
+
const scope = tenantScopeFrom(resolveTenantContext(this.context, this.moduleRef, this.contextCache));
|
|
150
|
+
return this.options.store.getRolesForUser(ref, scope);
|
|
76
151
|
}
|
|
77
152
|
};
|
|
78
153
|
RbacRoleProvider = __decorate([
|
|
79
154
|
Injectable(),
|
|
80
155
|
__param(0, Inject(AUTHZ_RBAC_OPTIONS)),
|
|
81
|
-
|
|
156
|
+
__param(1, Optional()),
|
|
157
|
+
__param(1, Inject(CONTEXT_ACCESSOR)),
|
|
158
|
+
__param(2, Optional()),
|
|
159
|
+
__metadata("design:paramtypes", [Object, Object, ModuleRef])
|
|
82
160
|
], RbacRoleProvider);
|
|
83
161
|
/** Runs `ensureAuthzSchema` on bootstrap when `autoCreateSchema` is not disabled. */
|
|
84
162
|
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;AAChC,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":"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"}
|
package/dist/entities.d.ts
CHANGED
|
@@ -9,7 +9,17 @@ export declare const DEFAULT_TABLE_NAMES: {
|
|
|
9
9
|
readonly permissions: "authz_permissions";
|
|
10
10
|
readonly rolePermission: "authz_role_permission";
|
|
11
11
|
readonly userRole: "authz_user_role";
|
|
12
|
+
readonly userPermission: "authz_user_permission";
|
|
12
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* The "no tenant" sentinel for the user-role pivot's `tenantId`. A GLOBAL (unscoped)
|
|
16
|
+
* assignment stores this empty string rather than `NULL` so the column stays part of
|
|
17
|
+
* the composite primary key with portable, dialect-correct uniqueness (SQL treats
|
|
18
|
+
* `NULL`s as distinct, which would break idempotency of a global grant and silently
|
|
19
|
+
* permit duplicates). The column is added post-v1 with a default of this value, so an
|
|
20
|
+
* older populated table self-heals via `ensureAuthzSchema` (`ADD COLUMN ... DEFAULT ''`).
|
|
21
|
+
*/
|
|
22
|
+
export declare const GLOBAL_TENANT = "";
|
|
13
23
|
/**
|
|
14
24
|
* A named role (e.g. `editor`). Permissions are attached via {@link RolePermissionEntity};
|
|
15
25
|
* users are attached via {@link UserRoleEntity}.
|
|
@@ -40,12 +50,31 @@ export declare class RolePermissionEntity {
|
|
|
40
50
|
* Pivot: user ↔ role. References the user BY ID ONLY — this package NEVER defines or
|
|
41
51
|
* owns a users table. `userType` lets the same table key polymorphic principals
|
|
42
52
|
* (mirrors nestjs-context's `UserRef` shape).
|
|
53
|
+
*
|
|
54
|
+
* `tenantId` (post-v1, defaulted to {@link GLOBAL_TENANT} = `''`) scopes the
|
|
55
|
+
* assignment to a tenant: an empty value = global (applies in every tenant), a
|
|
56
|
+
* non-empty value = only within that tenant. It is part of the composite PK so the
|
|
57
|
+
* same `(user, role)` can be granted independently in multiple tenants while staying
|
|
58
|
+
* idempotent per tenant. Defaulted (not nullable) so the column belongs to the PK
|
|
59
|
+
* with portable uniqueness — see {@link GLOBAL_TENANT}.
|
|
43
60
|
*/
|
|
44
61
|
export declare class UserRoleEntity {
|
|
45
62
|
userType: string;
|
|
46
63
|
userId: string;
|
|
47
64
|
roleId: string;
|
|
65
|
+
tenantId: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Pivot: user ↔ permission (a DIRECT grant, no role needed — Laravel/spatie's
|
|
69
|
+
* `$user->givePermissionTo(...)`). Mirrors {@link UserRoleEntity}: the user is
|
|
70
|
+
* referenced BY ID ONLY and `userType` keys polymorphic principals. Composite PK
|
|
71
|
+
* `(userType, userId, permissionId)`.
|
|
72
|
+
*/
|
|
73
|
+
export declare class UserPermissionEntity {
|
|
74
|
+
userType: string;
|
|
75
|
+
userId: string;
|
|
76
|
+
permissionId: string;
|
|
48
77
|
}
|
|
49
78
|
/** All entities, in dependency order — convenient for `entities: [...]` registration. */
|
|
50
|
-
export declare const AUTHZ_ENTITIES: readonly [typeof RoleEntity, typeof PermissionEntity, typeof RolePermissionEntity, typeof UserRoleEntity];
|
|
79
|
+
export declare const AUTHZ_ENTITIES: readonly [typeof RoleEntity, typeof PermissionEntity, typeof RolePermissionEntity, typeof UserRoleEntity, typeof UserPermissionEntity];
|
|
51
80
|
//# sourceMappingURL=entities.d.ts.map
|
package/dist/entities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;;CAMtB,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC;;;;;;;GAOG;AACH,qBACa,UAAU;IAErB,EAAE,EAAG,MAAM,CAAC;IAIZ,IAAI,EAAG,MAAM,CAAC;IAGd,KAAK,EAAG,MAAM,GAAG,IAAI,CAAC;IAGtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,oGAAoG;AACpG,qBACa,gBAAgB;IAE3B,EAAE,EAAG,MAAM,CAAC;IAIZ,IAAI,EAAG,MAAM,CAAC;IAGd,KAAK,EAAG,MAAM,GAAG,IAAI,CAAC;IAGtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,uEAAuE;AACvE,qBACa,oBAAoB;IAE/B,MAAM,EAAG,MAAM,CAAC;IAGhB,YAAY,EAAG,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,qBAEa,cAAc;IAEzB,QAAQ,EAAG,MAAM,CAAC;IAGlB,MAAM,EAAG,MAAM,CAAC;IAGhB,MAAM,EAAG,MAAM,CAAC;IAGhB,QAAQ,EAAG,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,qBAEa,oBAAoB;IAE/B,QAAQ,EAAG,MAAM,CAAC;IAGlB,MAAM,EAAG,MAAM,CAAC;IAGhB,YAAY,EAAG,MAAM,CAAC;CACvB;AAED,yFAAyF;AACzF,eAAO,MAAM,cAAc,wIAMjB,CAAC"}
|
package/dist/entities.js
CHANGED
|
@@ -19,7 +19,17 @@ export const DEFAULT_TABLE_NAMES = {
|
|
|
19
19
|
permissions: 'authz_permissions',
|
|
20
20
|
rolePermission: 'authz_role_permission',
|
|
21
21
|
userRole: 'authz_user_role',
|
|
22
|
+
userPermission: 'authz_user_permission',
|
|
22
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* The "no tenant" sentinel for the user-role pivot's `tenantId`. A GLOBAL (unscoped)
|
|
26
|
+
* assignment stores this empty string rather than `NULL` so the column stays part of
|
|
27
|
+
* the composite primary key with portable, dialect-correct uniqueness (SQL treats
|
|
28
|
+
* `NULL`s as distinct, which would break idempotency of a global grant and silently
|
|
29
|
+
* permit duplicates). The column is added post-v1 with a default of this value, so an
|
|
30
|
+
* older populated table self-heals via `ensureAuthzSchema` (`ADD COLUMN ... DEFAULT ''`).
|
|
31
|
+
*/
|
|
32
|
+
export const GLOBAL_TENANT = '';
|
|
23
33
|
/**
|
|
24
34
|
* A named role (e.g. `editor`). Permissions are attached via {@link RolePermissionEntity};
|
|
25
35
|
* users are attached via {@link UserRoleEntity}.
|
|
@@ -104,11 +114,19 @@ export { RolePermissionEntity };
|
|
|
104
114
|
* Pivot: user ↔ role. References the user BY ID ONLY — this package NEVER defines or
|
|
105
115
|
* owns a users table. `userType` lets the same table key polymorphic principals
|
|
106
116
|
* (mirrors nestjs-context's `UserRef` shape).
|
|
117
|
+
*
|
|
118
|
+
* `tenantId` (post-v1, defaulted to {@link GLOBAL_TENANT} = `''`) scopes the
|
|
119
|
+
* assignment to a tenant: an empty value = global (applies in every tenant), a
|
|
120
|
+
* non-empty value = only within that tenant. It is part of the composite PK so the
|
|
121
|
+
* same `(user, role)` can be granted independently in multiple tenants while staying
|
|
122
|
+
* idempotent per tenant. Defaulted (not nullable) so the column belongs to the PK
|
|
123
|
+
* with portable uniqueness — see {@link GLOBAL_TENANT}.
|
|
107
124
|
*/
|
|
108
125
|
let UserRoleEntity = class UserRoleEntity {
|
|
109
126
|
userType;
|
|
110
127
|
userId;
|
|
111
128
|
roleId;
|
|
129
|
+
tenantId;
|
|
112
130
|
};
|
|
113
131
|
__decorate([
|
|
114
132
|
PrimaryColumn({ type: 'varchar', length: 191 }),
|
|
@@ -122,16 +140,49 @@ __decorate([
|
|
|
122
140
|
PrimaryColumn({ type: 'varchar', length: 191 }),
|
|
123
141
|
__metadata("design:type", String)
|
|
124
142
|
], UserRoleEntity.prototype, "roleId", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
PrimaryColumn({ type: 'varchar', length: 191, default: GLOBAL_TENANT }),
|
|
145
|
+
__metadata("design:type", String)
|
|
146
|
+
], UserRoleEntity.prototype, "tenantId", void 0);
|
|
125
147
|
UserRoleEntity = __decorate([
|
|
126
148
|
Entity({ name: DEFAULT_TABLE_NAMES.userRole }),
|
|
127
149
|
Index(['userType', 'userId'])
|
|
128
150
|
], UserRoleEntity);
|
|
129
151
|
export { UserRoleEntity };
|
|
152
|
+
/**
|
|
153
|
+
* Pivot: user ↔ permission (a DIRECT grant, no role needed — Laravel/spatie's
|
|
154
|
+
* `$user->givePermissionTo(...)`). Mirrors {@link UserRoleEntity}: the user is
|
|
155
|
+
* referenced BY ID ONLY and `userType` keys polymorphic principals. Composite PK
|
|
156
|
+
* `(userType, userId, permissionId)`.
|
|
157
|
+
*/
|
|
158
|
+
let UserPermissionEntity = class UserPermissionEntity {
|
|
159
|
+
userType;
|
|
160
|
+
userId;
|
|
161
|
+
permissionId;
|
|
162
|
+
};
|
|
163
|
+
__decorate([
|
|
164
|
+
PrimaryColumn({ type: 'varchar', length: 191 }),
|
|
165
|
+
__metadata("design:type", String)
|
|
166
|
+
], UserPermissionEntity.prototype, "userType", void 0);
|
|
167
|
+
__decorate([
|
|
168
|
+
PrimaryColumn({ type: 'varchar', length: 191 }),
|
|
169
|
+
__metadata("design:type", String)
|
|
170
|
+
], UserPermissionEntity.prototype, "userId", void 0);
|
|
171
|
+
__decorate([
|
|
172
|
+
PrimaryColumn({ type: 'varchar', length: 191 }),
|
|
173
|
+
__metadata("design:type", String)
|
|
174
|
+
], UserPermissionEntity.prototype, "permissionId", void 0);
|
|
175
|
+
UserPermissionEntity = __decorate([
|
|
176
|
+
Entity({ name: DEFAULT_TABLE_NAMES.userPermission }),
|
|
177
|
+
Index(['userType', 'userId'])
|
|
178
|
+
], UserPermissionEntity);
|
|
179
|
+
export { UserPermissionEntity };
|
|
130
180
|
/** All entities, in dependency order — convenient for `entities: [...]` registration. */
|
|
131
181
|
export const AUTHZ_ENTITIES = [
|
|
132
182
|
RoleEntity,
|
|
133
183
|
PermissionEntity,
|
|
134
184
|
RolePermissionEntity,
|
|
135
185
|
UserRoleEntity,
|
|
186
|
+
UserPermissionEntity,
|
|
136
187
|
];
|
|
137
188
|
//# sourceMappingURL=entities.js.map
|
package/dist/entities.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,aAAa;IACpB,WAAW,EAAE,mBAAmB;IAChC,cAAc,EAAE,uBAAuB;IACvC,QAAQ,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
export { AUTHZ_ENTITIES, DEFAULT_TABLE_NAMES, PermissionEntity, RoleEntity, RolePermissionEntity, UserRoleEntity, } from './entities.js';
|
|
1
|
+
export { AUTHZ_ENTITIES, DEFAULT_TABLE_NAMES, GLOBAL_TENANT, PermissionEntity, RoleEntity, RolePermissionEntity, UserPermissionEntity, UserRoleEntity, } from './entities.js';
|
|
2
2
|
export { createAuthzTables, ensureAuthzSchema } from './schema.js';
|
|
3
3
|
export { TypeOrmAuthzStore } from './typeorm-authz.store.js';
|
|
4
4
|
export type { UserAuthz } from './typeorm-authz.store.js';
|
|
5
5
|
export { AUTHZ_RBAC_OPTIONS, AUTHZ_RBAC_STORE, AuthzRbacModule, defaultUserRefMapper, } from './authz-rbac.module.js';
|
|
6
6
|
export type { AuthzRbacModuleAsyncOptions, AuthzRbacModuleOptions, UserRefMapper, } from './authz-rbac.module.js';
|
|
7
|
-
export type { AuthzStoreOptions, TableNames, UserRef, UserRefInput } from './types.js';
|
|
7
|
+
export type { AuthzStoreOptions, TableNames, TenantScope, UserRef, UserRefInput, } from './types.js';
|
|
8
|
+
export { applyScope, applyScopeConstraint, compileScope } from './scope.js';
|
|
9
|
+
export type { CompiledScope, ScopeResolver } from './scope.js';
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
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,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,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,EACV,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,OAAO,EACP,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5E,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { AUTHZ_ENTITIES, DEFAULT_TABLE_NAMES, PermissionEntity, RoleEntity, RolePermissionEntity, UserRoleEntity, } from './entities.js';
|
|
1
|
+
export { AUTHZ_ENTITIES, DEFAULT_TABLE_NAMES, GLOBAL_TENANT, PermissionEntity, RoleEntity, RolePermissionEntity, UserPermissionEntity, UserRoleEntity, } from './entities.js';
|
|
2
2
|
export { createAuthzTables, ensureAuthzSchema } from './schema.js';
|
|
3
3
|
export { TypeOrmAuthzStore } from './typeorm-authz.store.js';
|
|
4
4
|
export { AUTHZ_RBAC_OPTIONS, AUTHZ_RBAC_STORE, AuthzRbacModule, defaultUserRefMapper, } from './authz-rbac.module.js';
|
|
5
|
+
export { applyScope, applyScopeConstraint, compileScope } from './scope.js';
|
|
5
6
|
//# 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,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAahC,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,WAAW,EAGjB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,WAAW,EAGjB,MAAM,SAAS,CAAC;AAWjB,OAAO,KAAK,EAAE,iBAAiB,EAAc,MAAM,YAAY,CAAC;AAqFhE;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,WAAW,EACxB,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAUf;AA4BD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,UAAU,EACtB,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
package/dist/schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Table, TableColumn, } from 'typeorm';
|
|
2
2
|
import { TableUtils } from 'typeorm/schema-builder/util/TableUtils.js';
|
|
3
|
-
import { DEFAULT_TABLE_NAMES, PermissionEntity, RoleEntity, RolePermissionEntity, UserRoleEntity, } from './entities.js';
|
|
3
|
+
import { DEFAULT_TABLE_NAMES, PermissionEntity, RoleEntity, RolePermissionEntity, UserPermissionEntity, UserRoleEntity, } from './entities.js';
|
|
4
4
|
import { assertSafeIdentifier } from './sql.js';
|
|
5
5
|
/** Resolve the (schema-qualified) table name for an entity, applying BYO overrides. */
|
|
6
6
|
function tableName(base, schema) {
|
|
@@ -12,6 +12,7 @@ function resolveNames(tableNames) {
|
|
|
12
12
|
permissions: tableNames?.permissions ?? DEFAULT_TABLE_NAMES.permissions,
|
|
13
13
|
rolePermission: tableNames?.rolePermission ?? DEFAULT_TABLE_NAMES.rolePermission,
|
|
14
14
|
userRole: tableNames?.userRole ?? DEFAULT_TABLE_NAMES.userRole,
|
|
15
|
+
userPermission: tableNames?.userPermission ?? DEFAULT_TABLE_NAMES.userPermission,
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
18
|
/** The four table plans (entity + resolved name) for a given options set. */
|
|
@@ -29,16 +30,39 @@ function plans(opts) {
|
|
|
29
30
|
{ entity: PermissionEntity, name: tableName(names.permissions, schema) },
|
|
30
31
|
{ entity: RolePermissionEntity, name: tableName(names.rolePermission, schema) },
|
|
31
32
|
{ entity: UserRoleEntity, name: tableName(names.userRole, schema) },
|
|
33
|
+
{ entity: UserPermissionEntity, name: tableName(names.userPermission, schema) },
|
|
32
34
|
];
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* Build a driver-portable {@link Table} from entity metadata, overriding the table name
|
|
36
38
|
* so BYO names + an optional Postgres schema are honored (the metadata's own name is the
|
|
37
39
|
* entity-decorator default).
|
|
40
|
+
*
|
|
41
|
+
* Constraint-name rewrite (Postgres-critical): TypeORM derives index / unique / primary-key
|
|
42
|
+
* names by hashing the table name + columns (see `DefaultNamingStrategy.indexName` et al.).
|
|
43
|
+
* `Table.create` computes those from the entity's DEFAULT name, so simply reassigning
|
|
44
|
+
* `table.name` leaves the constraints carrying the OLD name's hash. Two tables created from
|
|
45
|
+
* the SAME entity metadata under DIFFERENT runtime names (BYO table names, or a per-test
|
|
46
|
+
* unique prefix) then emit IDENTICAL constraint names. SQLite scopes index names per-table
|
|
47
|
+
* and tolerates this; Postgres treats index/constraint names as schema-global and rejects
|
|
48
|
+
* the second `CREATE TABLE` with `relation "IDX_..." already exists`. So after renaming we
|
|
49
|
+
* regenerate every constraint name from the NEW table name via the connection's naming
|
|
50
|
+
* strategy, keeping each created table's constraints globally unique.
|
|
38
51
|
*/
|
|
39
|
-
function tableFromMetadata(metadata, driver, name) {
|
|
52
|
+
function tableFromMetadata(connection, metadata, driver, name) {
|
|
40
53
|
const table = Table.create(metadata, driver);
|
|
41
54
|
table.name = name;
|
|
55
|
+
const naming = connection.namingStrategy;
|
|
56
|
+
for (const index of table.indices) {
|
|
57
|
+
index.name = naming.indexName(name, index.columnNames, index.where);
|
|
58
|
+
}
|
|
59
|
+
for (const unique of table.uniques) {
|
|
60
|
+
unique.name = naming.uniqueConstraintName(name, unique.columnNames);
|
|
61
|
+
}
|
|
62
|
+
for (const check of table.checks) {
|
|
63
|
+
if (check.expression)
|
|
64
|
+
check.name = naming.checkConstraintName(name, check.expression);
|
|
65
|
+
}
|
|
42
66
|
return table;
|
|
43
67
|
}
|
|
44
68
|
/**
|
|
@@ -60,7 +84,7 @@ export async function createAuthzTables(queryRunner, opts) {
|
|
|
60
84
|
if (await queryRunner.hasTable(plan.name))
|
|
61
85
|
continue;
|
|
62
86
|
const metadata = queryRunner.connection.getMetadata(plan.entity);
|
|
63
|
-
await queryRunner.createTable(tableFromMetadata(metadata, driver, plan.name), true);
|
|
87
|
+
await queryRunner.createTable(tableFromMetadata(queryRunner.connection, metadata, driver, plan.name), true);
|
|
64
88
|
}
|
|
65
89
|
}
|
|
66
90
|
/**
|
|
@@ -105,7 +129,7 @@ export async function ensureAuthzSchema(dataSource, opts) {
|
|
|
105
129
|
}
|
|
106
130
|
else {
|
|
107
131
|
const metadata = queryRunner.connection.getMetadata(plan.entity);
|
|
108
|
-
await queryRunner.createTable(tableFromMetadata(metadata, driver, plan.name), true);
|
|
132
|
+
await queryRunner.createTable(tableFromMetadata(queryRunner.connection, metadata, driver, plan.name), true);
|
|
109
133
|
}
|
|
110
134
|
}
|
|
111
135
|
}
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,EACL,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,2CAA2C,CAAC;AACvE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAShD,uFAAuF;AACvF,SAAS,SAAS,CAAC,IAAY,EAAE,MAA0B;IACzD,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,SAAS,YAAY,CAAC,UAAkC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ScopeConstraint } from '@dudousxd/nestjs-authz';
|
|
2
|
+
import type { Type } from '@nestjs/common';
|
|
3
|
+
import type { ObjectLiteral, SelectQueryBuilder } from 'typeorm';
|
|
4
|
+
/**
|
|
5
|
+
* The minimal scope-resolving surface shared by `Gate` and `BoundGate`. Accepting
|
|
6
|
+
* this (rather than `Gate`) lets {@link applyScope} take either a Gate (current/context
|
|
7
|
+
* user) or a `gate.forUser(...)` BoundGate without a cast.
|
|
8
|
+
*/
|
|
9
|
+
export interface ScopeResolver {
|
|
10
|
+
scope(entity: Type<unknown>, ability?: string): Promise<ScopeConstraint>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A compiled scope predicate: a SQL fragment using TypeORM named placeholders
|
|
14
|
+
* (`:name`, `:...name` for `IN`) plus the parameter map to bind. TypeORM binds the
|
|
15
|
+
* values itself (dialect-correct), so we never interpolate values — only identifiers,
|
|
16
|
+
* which are validated by {@link assertSafeIdentifier}.
|
|
17
|
+
*/
|
|
18
|
+
export interface CompiledScope {
|
|
19
|
+
sql: string;
|
|
20
|
+
params: ObjectLiteral;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Quote a SQL identifier. Defaults to ANSI double-quotes (Postgres / SQLite), but a
|
|
24
|
+
* dialect-correct escaper can be injected — MySQL/MariaDB quote with backticks and
|
|
25
|
+
* REJECT `"..."` as an identifier, so `applyScopeConstraint` passes the DataSource's
|
|
26
|
+
* `driver.escape` to make the compiled predicate portable across engines.
|
|
27
|
+
*/
|
|
28
|
+
export type EscapeIdentifier = (identifier: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* Compile an ORM-neutral {@link ScopeConstraint} into a parameterized SQL predicate
|
|
31
|
+
* for TypeORM. Returns:
|
|
32
|
+
* - `undefined` for `allow-all` — the caller adds NO `WHERE` (every row is visible);
|
|
33
|
+
* - `{ sql: '1 = 0', params: {} }` for `deny-all` — an always-false predicate;
|
|
34
|
+
* - otherwise the compiled condition tree.
|
|
35
|
+
*
|
|
36
|
+
* `paramPrefix` namespaces the generated placeholders so multiple `applyScope` calls
|
|
37
|
+
* (or other `andWhere`s) on one query never collide. `alias` (the entity's query
|
|
38
|
+
* alias) prefixes every column as `"alias"."field"`; omit it to emit bare `"field"`.
|
|
39
|
+
*
|
|
40
|
+
* SAFE: column names and the alias are interpolated into SQL, so each is validated
|
|
41
|
+
* against the package's `assertSafeIdentifier` allowlist (letters/digits/underscore,
|
|
42
|
+
* not leading-digit) — a hostile field/alias throws. Values are NEVER interpolated;
|
|
43
|
+
* they are returned in `params` for TypeORM to bind.
|
|
44
|
+
*
|
|
45
|
+
* `escapeId` controls identifier quoting; it defaults to ANSI double-quotes (Postgres /
|
|
46
|
+
* SQLite). `applyScopeConstraint` injects the DataSource's `driver.escape` so the
|
|
47
|
+
* predicate is also valid on MySQL/MariaDB (backtick-quoted), which rejects `"..."`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function compileScope(constraint: ScopeConstraint, paramPrefix: string, alias?: string, escapeId?: EscapeIdentifier): CompiledScope | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Apply a {@link ScopeConstraint} to a TypeORM {@link SelectQueryBuilder} as an
|
|
52
|
+
* `andWhere`, parameterized and identifier-safe. `allow-all` adds nothing; `deny-all`
|
|
53
|
+
* adds an always-false predicate so the query returns no rows.
|
|
54
|
+
*
|
|
55
|
+
* The query's primary alias is used to qualify columns (so the predicate is correct
|
|
56
|
+
* across joins). Each call uses a fresh parameter prefix, so repeated calls never
|
|
57
|
+
* clash. Returns the same builder for chaining.
|
|
58
|
+
*/
|
|
59
|
+
export declare function applyScopeConstraint<T extends ObjectLiteral>(qb: SelectQueryBuilder<T>, constraint: ScopeConstraint): SelectQueryBuilder<T>;
|
|
60
|
+
/**
|
|
61
|
+
* Ergonomic entry point: resolve the query scope for the current (context) user via
|
|
62
|
+
* the {@link Gate} and apply it to `qb` in one call. Equivalent to
|
|
63
|
+
* `applyScopeConstraint(qb, await gate.scope(entity, ability))`.
|
|
64
|
+
*
|
|
65
|
+
* The manual path (`gate.scope(...)` + `applyScopeConstraint(...)`) remains primary;
|
|
66
|
+
* this just folds the two steps together for the common list-endpoint case.
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* const qb = repo.createQueryBuilder('post');
|
|
70
|
+
* await applyScope(qb, gate, Post); // current user's accessible posts
|
|
71
|
+
* const posts = await qb.getMany();
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function applyScope<T extends ObjectLiteral>(qb: SelectQueryBuilder<T>, gate: ScopeResolver, entity: Type<unknown>, ability?: string): Promise<SelectQueryBuilder<T>>;
|
|
75
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAGhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGjE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC1E;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,aAAa,CAAC;CACvB;AAKD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;AAa9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,eAAe,EAC3B,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,QAAQ,GAAE,gBAA4B,GACrC,aAAa,GAAG,SAAS,CA+C3B;AAID;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,aAAa,EAC1D,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,EACzB,UAAU,EAAE,eAAe,GAC1B,kBAAkB,CAAC,CAAC,CAAC,CAQvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,aAAa,EACtD,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,EACzB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,EACrB,OAAO,SAAY,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAEhC"}
|
package/dist/scope.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { assertSafeIdentifier } from './sql.js';
|
|
2
|
+
/** An always-false predicate (deny-all / empty `IN`). Binds no parameters. */
|
|
3
|
+
const ALWAYS_FALSE = { sql: '1 = 0', params: {} };
|
|
4
|
+
const ansiQuote = (id) => `"${id}"`;
|
|
5
|
+
/** TypeORM/SQL operator tokens for the binary comparison operators. */
|
|
6
|
+
const BINARY_OPS = {
|
|
7
|
+
eq: '=',
|
|
8
|
+
ne: '!=',
|
|
9
|
+
gt: '>',
|
|
10
|
+
gte: '>=',
|
|
11
|
+
lt: '<',
|
|
12
|
+
lte: '<=',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Compile an ORM-neutral {@link ScopeConstraint} into a parameterized SQL predicate
|
|
16
|
+
* for TypeORM. Returns:
|
|
17
|
+
* - `undefined` for `allow-all` — the caller adds NO `WHERE` (every row is visible);
|
|
18
|
+
* - `{ sql: '1 = 0', params: {} }` for `deny-all` — an always-false predicate;
|
|
19
|
+
* - otherwise the compiled condition tree.
|
|
20
|
+
*
|
|
21
|
+
* `paramPrefix` namespaces the generated placeholders so multiple `applyScope` calls
|
|
22
|
+
* (or other `andWhere`s) on one query never collide. `alias` (the entity's query
|
|
23
|
+
* alias) prefixes every column as `"alias"."field"`; omit it to emit bare `"field"`.
|
|
24
|
+
*
|
|
25
|
+
* SAFE: column names and the alias are interpolated into SQL, so each is validated
|
|
26
|
+
* against the package's `assertSafeIdentifier` allowlist (letters/digits/underscore,
|
|
27
|
+
* not leading-digit) — a hostile field/alias throws. Values are NEVER interpolated;
|
|
28
|
+
* they are returned in `params` for TypeORM to bind.
|
|
29
|
+
*
|
|
30
|
+
* `escapeId` controls identifier quoting; it defaults to ANSI double-quotes (Postgres /
|
|
31
|
+
* SQLite). `applyScopeConstraint` injects the DataSource's `driver.escape` so the
|
|
32
|
+
* predicate is also valid on MySQL/MariaDB (backtick-quoted), which rejects `"..."`.
|
|
33
|
+
*/
|
|
34
|
+
export function compileScope(constraint, paramPrefix, alias, escapeId = ansiQuote) {
|
|
35
|
+
if (constraint.kind === 'all')
|
|
36
|
+
return undefined;
|
|
37
|
+
if (constraint.kind === 'none')
|
|
38
|
+
return ALWAYS_FALSE;
|
|
39
|
+
if (alias !== undefined)
|
|
40
|
+
assertSafeIdentifier(alias, `scope alias "${alias}"`);
|
|
41
|
+
const params = {};
|
|
42
|
+
let counter = 0;
|
|
43
|
+
const nextParam = () => `${paramPrefix}_${counter++}`;
|
|
44
|
+
const column = (field) => {
|
|
45
|
+
assertSafeIdentifier(field, `scope field "${field}"`);
|
|
46
|
+
return alias === undefined ? escapeId(field) : `${escapeId(alias)}.${escapeId(field)}`;
|
|
47
|
+
};
|
|
48
|
+
const compileCondition = (c) => {
|
|
49
|
+
const col = column(c.field);
|
|
50
|
+
if (c.op === 'isNull')
|
|
51
|
+
return `${col} IS NULL`;
|
|
52
|
+
if (c.op === 'isNotNull')
|
|
53
|
+
return `${col} IS NOT NULL`;
|
|
54
|
+
if (c.op === 'in' || c.op === 'nin') {
|
|
55
|
+
const values = Array.isArray(c.value) ? c.value : [c.value];
|
|
56
|
+
// An empty `IN ()` is invalid SQL and matches nothing; an empty `NOT IN ()`
|
|
57
|
+
// matches everything. Encode both with constant predicates.
|
|
58
|
+
if (values.length === 0)
|
|
59
|
+
return c.op === 'in' ? '1 = 0' : '1 = 1';
|
|
60
|
+
const name = nextParam();
|
|
61
|
+
params[name] = values;
|
|
62
|
+
const not = c.op === 'nin' ? 'NOT ' : '';
|
|
63
|
+
return `${col} ${not}IN (:...${name})`;
|
|
64
|
+
}
|
|
65
|
+
const token = BINARY_OPS[c.op];
|
|
66
|
+
if (!token)
|
|
67
|
+
throw new Error(`Unsupported scope operator: ${c.op}`);
|
|
68
|
+
const name = nextParam();
|
|
69
|
+
params[name] = c.value;
|
|
70
|
+
return `${col} ${token} :${name}`;
|
|
71
|
+
};
|
|
72
|
+
const compileNode = (node) => {
|
|
73
|
+
if (node.kind === 'condition')
|
|
74
|
+
return compileCondition(node);
|
|
75
|
+
const joiner = node.kind === 'and' ? ' AND ' : ' OR ';
|
|
76
|
+
// An empty AND is the identity (true); an empty OR is the zero (false).
|
|
77
|
+
if (node.nodes.length === 0)
|
|
78
|
+
return node.kind === 'and' ? '1 = 1' : '1 = 0';
|
|
79
|
+
return `(${node.nodes.map(compileNode).join(joiner)})`;
|
|
80
|
+
};
|
|
81
|
+
const sql = compileNode(constraint);
|
|
82
|
+
// A top-level empty `IN` collapses to the always-false constant with no params.
|
|
83
|
+
if (sql === '1 = 0' && Object.keys(params).length === 0)
|
|
84
|
+
return ALWAYS_FALSE;
|
|
85
|
+
return { sql, params };
|
|
86
|
+
}
|
|
87
|
+
let scopeApplyCounter = 0;
|
|
88
|
+
/**
|
|
89
|
+
* Apply a {@link ScopeConstraint} to a TypeORM {@link SelectQueryBuilder} as an
|
|
90
|
+
* `andWhere`, parameterized and identifier-safe. `allow-all` adds nothing; `deny-all`
|
|
91
|
+
* adds an always-false predicate so the query returns no rows.
|
|
92
|
+
*
|
|
93
|
+
* The query's primary alias is used to qualify columns (so the predicate is correct
|
|
94
|
+
* across joins). Each call uses a fresh parameter prefix, so repeated calls never
|
|
95
|
+
* clash. Returns the same builder for chaining.
|
|
96
|
+
*/
|
|
97
|
+
export function applyScopeConstraint(qb, constraint) {
|
|
98
|
+
const prefix = `authz_scope_${scopeApplyCounter++}`;
|
|
99
|
+
// Quote identifiers with the DataSource's own dialect-correct escaper so the predicate
|
|
100
|
+
// is valid on MySQL/MariaDB (backticks) as well as Postgres/SQLite (double-quotes).
|
|
101
|
+
const escapeId = (id) => qb.connection.driver.escape(id);
|
|
102
|
+
const compiled = compileScope(constraint, prefix, qb.alias, escapeId);
|
|
103
|
+
if (compiled)
|
|
104
|
+
qb.andWhere(compiled.sql, compiled.params);
|
|
105
|
+
return qb;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Ergonomic entry point: resolve the query scope for the current (context) user via
|
|
109
|
+
* the {@link Gate} and apply it to `qb` in one call. Equivalent to
|
|
110
|
+
* `applyScopeConstraint(qb, await gate.scope(entity, ability))`.
|
|
111
|
+
*
|
|
112
|
+
* The manual path (`gate.scope(...)` + `applyScopeConstraint(...)`) remains primary;
|
|
113
|
+
* this just folds the two steps together for the common list-endpoint case.
|
|
114
|
+
*
|
|
115
|
+
* ```ts
|
|
116
|
+
* const qb = repo.createQueryBuilder('post');
|
|
117
|
+
* await applyScope(qb, gate, Post); // current user's accessible posts
|
|
118
|
+
* const posts = await qb.getMany();
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export async function applyScope(qb, gate, entity, ability = 'viewAny') {
|
|
122
|
+
return applyScopeConstraint(qb, await gate.scope(entity, ability));
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DataSource } from 'typeorm';
|
|
2
|
-
import type { AuthzStoreOptions, UserRef } from './types.js';
|
|
2
|
+
import type { AuthzStoreOptions, TenantScope, UserRef } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* A user's effective permissions: the role names they hold and the flattened set of
|
|
5
5
|
* permission names granted by those roles.
|
|
@@ -48,17 +48,61 @@ export declare class TypeOrmAuthzStore {
|
|
|
48
48
|
givePermissionToRole(roleName: string, permissionName: string): Promise<void>;
|
|
49
49
|
/** Revoke a permission from a role. No-op if either is absent or not linked. */
|
|
50
50
|
revokePermissionFromRole(roleName: string, permissionName: string): Promise<void>;
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Assign a role to a user (creating the role by name if needed). Idempotent.
|
|
53
|
+
*
|
|
54
|
+
* Pass `{ tenantId }` to scope the assignment to a tenant — it then applies ONLY
|
|
55
|
+
* within that tenant. Omitting it (the default) makes a GLOBAL assignment that
|
|
56
|
+
* applies in every tenant (and in an unscoped check). The same `(user, role)` can
|
|
57
|
+
* be assigned in multiple tenants independently.
|
|
58
|
+
*/
|
|
59
|
+
assignRole(user: UserRef, roleName: string, scope?: TenantScope): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Remove a role from a user. No-op if the role or assignment is absent. When
|
|
62
|
+
* `{ tenantId }` is given, only the assignment in THAT tenant is removed; omitting
|
|
63
|
+
* it removes the GLOBAL assignment (tenant `''`).
|
|
64
|
+
*/
|
|
65
|
+
removeRole(user: UserRef, roleName: string, scope?: TenantScope): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Grant a permission DIRECTLY to a user (creating the permission by name if
|
|
68
|
+
* needed) — no role required. Mirrors Laravel/spatie's `$user->givePermissionTo`.
|
|
69
|
+
* Idempotent.
|
|
70
|
+
*/
|
|
71
|
+
giveUserPermission(user: UserRef, permissionName: string): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Revoke a DIRECT user permission. No-op if the permission or grant is absent.
|
|
74
|
+
* Only the direct grant is removed — a permission the user ALSO has via a role
|
|
75
|
+
* survives.
|
|
76
|
+
*/
|
|
77
|
+
revokeUserPermission(user: UserRef, permissionName: string): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* SQL fragment + params matching role assignments visible for a tenant scope: a
|
|
80
|
+
* GLOBAL assignment (tenant `''`) always applies; a tenant-scoped one applies only
|
|
81
|
+
* when its tenant matches the requested one. With no requested tenant, only global
|
|
82
|
+
* assignments are visible (a tenant-scoped role never leaks into an unscoped check).
|
|
83
|
+
*/
|
|
84
|
+
private tenantFilter;
|
|
85
|
+
/** Bind values for {@link tenantFilter}, in the same order it emits placeholders. */
|
|
86
|
+
private tenantParams;
|
|
87
|
+
/**
|
|
88
|
+
* The role names a user holds, optionally restricted to a tenant scope (see
|
|
89
|
+
* {@link assignRole}). With no scope, only global roles are returned.
|
|
90
|
+
*/
|
|
91
|
+
getRolesForUser(user: UserRef, scope?: TenantScope): Promise<string[]>;
|
|
92
|
+
/**
|
|
93
|
+
* The flattened, distinct permission names a user has — the UNION of role-derived
|
|
94
|
+
* permissions (honoring the tenant scope) and DIRECT user permissions (which are
|
|
95
|
+
* not tenant-scoped). With no scope, role-derived permissions come from global
|
|
96
|
+
* roles only.
|
|
97
|
+
*/
|
|
98
|
+
getPermissionsForUser(user: UserRef, scope?: TenantScope): Promise<string[]>;
|
|
99
|
+
/** A user's roles + effective permissions in one shot (tenant-aware). */
|
|
100
|
+
getUserAuthz(user: UserRef, scope?: TenantScope): Promise<UserAuthz>;
|
|
101
|
+
/**
|
|
102
|
+
* True when the user holds `permission` — via a (tenant-scoped) role OR a direct
|
|
103
|
+
* grant. With no scope, only global role assignments count toward the role path;
|
|
104
|
+
* direct grants always count.
|
|
105
|
+
*/
|
|
106
|
+
userHasPermission(user: UserRef, permission: string, scope?: TenantScope): Promise<boolean>;
|
|
63
107
|
}
|
|
64
108
|
//# sourceMappingURL=typeorm-authz.store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typeorm-authz.store.d.ts","sourceRoot":"","sources":["../src/typeorm-authz.store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"typeorm-authz.store.d.ts","sourceRoot":"","sources":["../src/typeorm-authz.store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAU1E;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAQ1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI;IARvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAGpB;IACF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAGzB,UAAU,EAAE,UAAU,EACtB,IAAI,GAAE,iBAAsB;IAqB/C,+EAA+E;IAC/E,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,+EAA+E;IAC/E,OAAO,CAAC,MAAM;IAId,wDAAwD;IACxD,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,GAAG;IAMX,qFAAqF;IACrF,OAAO,CAAC,kBAAkB;IAS1B,yEAAyE;IACzE,OAAO,CAAC,gBAAgB;IAMxB;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB/C,qFAAqF;IAC/E,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAevC,UAAU;YAWV,gBAAgB;IAa9B,kFAAkF;IAC5E,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnF,gFAAgF;IAC1E,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAevF;;;;;;;OAOG;IACG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAarF;;;;OAIG;IACG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrF;;;;OAIG;IACG,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9E;;;;OAIG;IACG,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAehF;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAWpB,qFAAqF;IACrF,OAAO,CAAC,YAAY;IAKpB;;;OAGG;IACG,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgB5E;;;;;OAKG;IACG,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqClF,yEAAyE;IACnE,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IAQ1E;;;;OAIG;IACG,iBAAiB,CACrB,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,OAAO,CAAC;CAsCpB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { DEFAULT_TABLE_NAMES } from './entities.js';
|
|
2
|
+
import { DEFAULT_TABLE_NAMES, GLOBAL_TENANT } from './entities.js';
|
|
3
3
|
import { ensureAuthzSchema } from './schema.js';
|
|
4
4
|
import { Placeholders, assertSafeIdentifier } from './sql.js';
|
|
5
5
|
/** Normalize a {@link UserRef} to `{ type, id }` with `id` stringified. */
|
|
@@ -30,6 +30,7 @@ export class TypeOrmAuthzStore {
|
|
|
30
30
|
permissions: opts.tableNames?.permissions ?? DEFAULT_TABLE_NAMES.permissions,
|
|
31
31
|
rolePermission: opts.tableNames?.rolePermission ?? DEFAULT_TABLE_NAMES.rolePermission,
|
|
32
32
|
userRole: opts.tableNames?.userRole ?? DEFAULT_TABLE_NAMES.userRole,
|
|
33
|
+
userPermission: opts.tableNames?.userPermission ?? DEFAULT_TABLE_NAMES.userPermission,
|
|
33
34
|
};
|
|
34
35
|
this.schema = opts.schema;
|
|
35
36
|
// P4: identifiers are interpolated into SQL — validate BYO names/schema up
|
|
@@ -134,63 +135,164 @@ export class TypeOrmAuthzStore {
|
|
|
134
135
|
await this.dataSource.query(`DELETE FROM ${this.table('rolePermission')} WHERE ${this.col('roleId')} = ${p.next()} AND ${this.col('permissionId')} = ${p.next()}`, [roleId, permissionId]);
|
|
135
136
|
}
|
|
136
137
|
// --- user ↔ role ---
|
|
137
|
-
/**
|
|
138
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Assign a role to a user (creating the role by name if needed). Idempotent.
|
|
140
|
+
*
|
|
141
|
+
* Pass `{ tenantId }` to scope the assignment to a tenant — it then applies ONLY
|
|
142
|
+
* within that tenant. Omitting it (the default) makes a GLOBAL assignment that
|
|
143
|
+
* applies in every tenant (and in an unscoped check). The same `(user, role)` can
|
|
144
|
+
* be assigned in multiple tenants independently.
|
|
145
|
+
*/
|
|
146
|
+
async assignRole(user, roleName, scope) {
|
|
139
147
|
const { type, id } = normalizeUserRef(user);
|
|
140
148
|
const roleId = await this.createRole(roleName);
|
|
149
|
+
const tenantId = scope?.tenantId ?? GLOBAL_TENANT;
|
|
141
150
|
const p = this.params();
|
|
142
|
-
await this.dataSource.query(`${this.insertIgnoreVerb()} INTO ${this.table('userRole')} (${this.col('userType')}, ${this.col('userId')}, ${this.col('roleId')}) VALUES (${p.next()}, ${p.next()}, ${p.next()})${this.insertIgnoreSuffix()}`, [type, id, roleId]);
|
|
151
|
+
await this.dataSource.query(`${this.insertIgnoreVerb()} INTO ${this.table('userRole')} (${this.col('userType')}, ${this.col('userId')}, ${this.col('roleId')}, ${this.col('tenantId')}) VALUES (${p.next()}, ${p.next()}, ${p.next()}, ${p.next()})${this.insertIgnoreSuffix()}`, [type, id, roleId, tenantId]);
|
|
143
152
|
}
|
|
144
|
-
/**
|
|
145
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Remove a role from a user. No-op if the role or assignment is absent. When
|
|
155
|
+
* `{ tenantId }` is given, only the assignment in THAT tenant is removed; omitting
|
|
156
|
+
* it removes the GLOBAL assignment (tenant `''`).
|
|
157
|
+
*/
|
|
158
|
+
async removeRole(user, roleName, scope) {
|
|
146
159
|
const { type, id } = normalizeUserRef(user);
|
|
147
160
|
const roleId = await this.findRoleId(roleName);
|
|
148
161
|
if (!roleId)
|
|
149
162
|
return;
|
|
163
|
+
const tenantId = scope?.tenantId ?? GLOBAL_TENANT;
|
|
164
|
+
const p = this.params();
|
|
165
|
+
await this.dataSource.query(`DELETE FROM ${this.table('userRole')} WHERE ${this.col('userType')} = ${p.next()} AND ${this.col('userId')} = ${p.next()} AND ${this.col('roleId')} = ${p.next()} AND ${this.col('tenantId')} = ${p.next()}`, [type, id, roleId, tenantId]);
|
|
166
|
+
}
|
|
167
|
+
// --- user ↔ permission (DIRECT grant, no role) ---
|
|
168
|
+
/**
|
|
169
|
+
* Grant a permission DIRECTLY to a user (creating the permission by name if
|
|
170
|
+
* needed) — no role required. Mirrors Laravel/spatie's `$user->givePermissionTo`.
|
|
171
|
+
* Idempotent.
|
|
172
|
+
*/
|
|
173
|
+
async giveUserPermission(user, permissionName) {
|
|
174
|
+
const { type, id } = normalizeUserRef(user);
|
|
175
|
+
const permissionId = await this.createPermission(permissionName);
|
|
150
176
|
const p = this.params();
|
|
151
|
-
await this.dataSource.query(
|
|
177
|
+
await this.dataSource.query(`${this.insertIgnoreVerb()} INTO ${this.table('userPermission')} (${this.col('userType')}, ${this.col('userId')}, ${this.col('permissionId')}) VALUES (${p.next()}, ${p.next()}, ${p.next()})${this.insertIgnoreSuffix()}`, [type, id, permissionId]);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Revoke a DIRECT user permission. No-op if the permission or grant is absent.
|
|
181
|
+
* Only the direct grant is removed — a permission the user ALSO has via a role
|
|
182
|
+
* survives.
|
|
183
|
+
*/
|
|
184
|
+
async revokeUserPermission(user, permissionName) {
|
|
185
|
+
const { type, id } = normalizeUserRef(user);
|
|
186
|
+
const permissionId = await this.findPermissionId(permissionName);
|
|
187
|
+
if (!permissionId)
|
|
188
|
+
return;
|
|
189
|
+
const p = this.params();
|
|
190
|
+
await this.dataSource.query(`DELETE FROM ${this.table('userPermission')} WHERE ${this.col('userType')} = ${p.next()} AND ${this.col('userId')} = ${p.next()} AND ${this.col('permissionId')} = ${p.next()}`, [type, id, permissionId]);
|
|
152
191
|
}
|
|
153
192
|
// --- queries ---
|
|
154
|
-
/**
|
|
155
|
-
|
|
193
|
+
/**
|
|
194
|
+
* SQL fragment + params matching role assignments visible for a tenant scope: a
|
|
195
|
+
* GLOBAL assignment (tenant `''`) always applies; a tenant-scoped one applies only
|
|
196
|
+
* when its tenant matches the requested one. With no requested tenant, only global
|
|
197
|
+
* assignments are visible (a tenant-scoped role never leaks into an unscoped check).
|
|
198
|
+
*/
|
|
199
|
+
tenantFilter(alias, scope, p) {
|
|
200
|
+
const tenantId = scope?.tenantId ?? GLOBAL_TENANT;
|
|
201
|
+
if (tenantId === GLOBAL_TENANT) {
|
|
202
|
+
return ` AND ${alias}.${this.col('tenantId')} = ${p.next()}`;
|
|
203
|
+
}
|
|
204
|
+
// Visible = global OR exactly this tenant.
|
|
205
|
+
return ` AND (${alias}.${this.col('tenantId')} = ${p.next()} OR ${alias}.${this.col('tenantId')} = ${p.next()})`;
|
|
206
|
+
}
|
|
207
|
+
/** Bind values for {@link tenantFilter}, in the same order it emits placeholders. */
|
|
208
|
+
tenantParams(scope) {
|
|
209
|
+
const tenantId = scope?.tenantId ?? GLOBAL_TENANT;
|
|
210
|
+
return tenantId === GLOBAL_TENANT ? [GLOBAL_TENANT] : [GLOBAL_TENANT, tenantId];
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* The role names a user holds, optionally restricted to a tenant scope (see
|
|
214
|
+
* {@link assignRole}). With no scope, only global roles are returned.
|
|
215
|
+
*/
|
|
216
|
+
async getRolesForUser(user, scope) {
|
|
156
217
|
const { type, id } = normalizeUserRef(user);
|
|
157
218
|
const p = this.params();
|
|
219
|
+
const userType = p.next();
|
|
220
|
+
const userId = p.next();
|
|
221
|
+
const filter = this.tenantFilter('ur', scope, p);
|
|
158
222
|
const rows = (await this.dataSource.query(`SELECT r.${this.col('name')} AS name
|
|
159
223
|
FROM ${this.table('userRole')} ur
|
|
160
224
|
JOIN ${this.table('roles')} r ON r.${this.col('id')} = ur.${this.col('roleId')}
|
|
161
|
-
WHERE ur.${this.col('userType')} = ${
|
|
225
|
+
WHERE ur.${this.col('userType')} = ${userType} AND ur.${this.col('userId')} = ${userId}${filter}`, [type, id, ...this.tenantParams(scope)]));
|
|
162
226
|
return rows.map((row) => row.name);
|
|
163
227
|
}
|
|
164
|
-
/**
|
|
165
|
-
|
|
228
|
+
/**
|
|
229
|
+
* The flattened, distinct permission names a user has — the UNION of role-derived
|
|
230
|
+
* permissions (honoring the tenant scope) and DIRECT user permissions (which are
|
|
231
|
+
* not tenant-scoped). With no scope, role-derived permissions come from global
|
|
232
|
+
* roles only.
|
|
233
|
+
*/
|
|
234
|
+
async getPermissionsForUser(user, scope) {
|
|
166
235
|
const { type, id } = normalizeUserRef(user);
|
|
167
|
-
|
|
168
|
-
const
|
|
236
|
+
// Role-derived (tenant-aware).
|
|
237
|
+
const pr = this.params();
|
|
238
|
+
const rUserType = pr.next();
|
|
239
|
+
const rUserId = pr.next();
|
|
240
|
+
const rFilter = this.tenantFilter('ur', scope, pr);
|
|
241
|
+
const roleRows = (await this.dataSource.query(`SELECT DISTINCT p.${this.col('name')} AS name
|
|
169
242
|
FROM ${this.table('userRole')} ur
|
|
170
243
|
JOIN ${this.table('rolePermission')} rp ON rp.${this.col('roleId')} = ur.${this.col('roleId')}
|
|
171
244
|
JOIN ${this.table('permissions')} p ON p.${this.col('id')} = rp.${this.col('permissionId')}
|
|
172
|
-
WHERE ur.${this.col('userType')} = ${
|
|
173
|
-
|
|
245
|
+
WHERE ur.${this.col('userType')} = ${rUserType} AND ur.${this.col('userId')} = ${rUserId}${rFilter}`, [type, id, ...this.tenantParams(scope)]));
|
|
246
|
+
// Direct grants (not tenant-scoped).
|
|
247
|
+
const pd = this.params();
|
|
248
|
+
const directRows = (await this.dataSource.query(`SELECT DISTINCT p.${this.col('name')} AS name
|
|
249
|
+
FROM ${this.table('userPermission')} up
|
|
250
|
+
JOIN ${this.table('permissions')} p ON p.${this.col('id')} = up.${this.col('permissionId')}
|
|
251
|
+
WHERE up.${this.col('userType')} = ${pd.next()} AND up.${this.col('userId')} = ${pd.next()}`, [type, id]));
|
|
252
|
+
const out = new Set();
|
|
253
|
+
for (const row of roleRows)
|
|
254
|
+
out.add(row.name);
|
|
255
|
+
for (const row of directRows)
|
|
256
|
+
out.add(row.name);
|
|
257
|
+
return [...out];
|
|
174
258
|
}
|
|
175
|
-
/** A user's roles + effective permissions in one shot. */
|
|
176
|
-
async getUserAuthz(user) {
|
|
259
|
+
/** A user's roles + effective permissions in one shot (tenant-aware). */
|
|
260
|
+
async getUserAuthz(user, scope) {
|
|
177
261
|
const [roles, permissions] = await Promise.all([
|
|
178
|
-
this.getRolesForUser(user),
|
|
179
|
-
this.getPermissionsForUser(user),
|
|
262
|
+
this.getRolesForUser(user, scope),
|
|
263
|
+
this.getPermissionsForUser(user, scope),
|
|
180
264
|
]);
|
|
181
265
|
return { roles, permissions };
|
|
182
266
|
}
|
|
183
|
-
/**
|
|
184
|
-
|
|
267
|
+
/**
|
|
268
|
+
* True when the user holds `permission` — via a (tenant-scoped) role OR a direct
|
|
269
|
+
* grant. With no scope, only global role assignments count toward the role path;
|
|
270
|
+
* direct grants always count.
|
|
271
|
+
*/
|
|
272
|
+
async userHasPermission(user, permission, scope) {
|
|
185
273
|
const { type, id } = normalizeUserRef(user);
|
|
186
|
-
|
|
187
|
-
const
|
|
274
|
+
// Role path (tenant-aware).
|
|
275
|
+
const pr = this.params();
|
|
276
|
+
const rUserType = pr.next();
|
|
277
|
+
const rUserId = pr.next();
|
|
278
|
+
const rName = pr.next();
|
|
279
|
+
const rFilter = this.tenantFilter('ur', scope, pr);
|
|
280
|
+
const roleRows = (await this.dataSource.query(`SELECT 1 AS x
|
|
188
281
|
FROM ${this.table('userRole')} ur
|
|
189
282
|
JOIN ${this.table('rolePermission')} rp ON rp.${this.col('roleId')} = ur.${this.col('roleId')}
|
|
190
283
|
JOIN ${this.table('permissions')} p ON p.${this.col('id')} = rp.${this.col('permissionId')}
|
|
191
|
-
WHERE ur.${this.col('userType')} = ${
|
|
284
|
+
WHERE ur.${this.col('userType')} = ${rUserType} AND ur.${this.col('userId')} = ${rUserId} AND p.${this.col('name')} = ${rName}${rFilter}
|
|
285
|
+
LIMIT 1`, [type, id, permission, ...this.tenantParams(scope)]));
|
|
286
|
+
if (roleRows.length > 0)
|
|
287
|
+
return true;
|
|
288
|
+
// Direct path.
|
|
289
|
+
const pd = this.params();
|
|
290
|
+
const directRows = (await this.dataSource.query(`SELECT 1 AS x
|
|
291
|
+
FROM ${this.table('userPermission')} up
|
|
292
|
+
JOIN ${this.table('permissions')} p ON p.${this.col('id')} = up.${this.col('permissionId')}
|
|
293
|
+
WHERE up.${this.col('userType')} = ${pd.next()} AND up.${this.col('userId')} = ${pd.next()} AND p.${this.col('name')} = ${pd.next()}
|
|
192
294
|
LIMIT 1`, [type, id, permission]));
|
|
193
|
-
return
|
|
295
|
+
return directRows.length > 0;
|
|
194
296
|
}
|
|
195
297
|
}
|
|
196
298
|
//# sourceMappingURL=typeorm-authz.store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typeorm-authz.store.js","sourceRoot":"","sources":["../src/typeorm-authz.store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"typeorm-authz.store.js","sourceRoot":"","sources":["../src/typeorm-authz.store.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,17 @@ export interface TableNames {
|
|
|
4
4
|
permissions?: string;
|
|
5
5
|
rolePermission?: string;
|
|
6
6
|
userRole?: string;
|
|
7
|
+
/** Direct user→permission pivot (post-v1). Defaults to `authz_user_permission`. */
|
|
8
|
+
userPermission?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Optional tenant scope for a user-role assignment / role-or-permission query. */
|
|
11
|
+
export interface TenantScope {
|
|
12
|
+
/**
|
|
13
|
+
* Restrict a role assignment (or a query) to this tenant. Omitted/undefined →
|
|
14
|
+
* the GLOBAL scope (an assignment applies in every tenant; a query sees global
|
|
15
|
+
* assignments only — a tenant-scoped role does NOT leak into an unscoped check).
|
|
16
|
+
*/
|
|
17
|
+
tenantId?: string;
|
|
7
18
|
}
|
|
8
19
|
/**
|
|
9
20
|
* A reference to a user. Matches nestjs-context's `UserRef` shape (`{ type, id }`),
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED,4EAA4E;AAC5E,MAAM,MAAM,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED,4EAA4E;AAC5E,MAAM,MAAM,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dudousxd/nestjs-authz-typeorm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "TypeORM RBAC persistence for @dudousxd/nestjs-authz — roles, permissions, and a Gate seam (zero connection ownership).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -35,14 +35,18 @@
|
|
|
35
35
|
"@nestjs/common": "^11.0.0",
|
|
36
36
|
"@nestjs/core": "^11.0.0",
|
|
37
37
|
"@nestjs/testing": "^11.0.0",
|
|
38
|
+
"@testcontainers/mysql": "^12.0.3",
|
|
39
|
+
"@testcontainers/postgresql": "^12.0.3",
|
|
38
40
|
"@types/node": "^20.0.0",
|
|
41
|
+
"mysql2": "^3.22.5",
|
|
42
|
+
"pg": "^8.21.0",
|
|
39
43
|
"reflect-metadata": "^0.2.2",
|
|
40
44
|
"rxjs": "^7.8.1",
|
|
41
45
|
"sqlite3": "^5.1.7",
|
|
42
46
|
"typeorm": "^0.3.20",
|
|
43
47
|
"typescript": "^5.4.0",
|
|
44
48
|
"vitest": "^3.0.0",
|
|
45
|
-
"@dudousxd/nestjs-authz": "^0.
|
|
49
|
+
"@dudousxd/nestjs-authz": "^0.6.0"
|
|
46
50
|
},
|
|
47
51
|
"engines": {
|
|
48
52
|
"node": ">=20"
|
|
@@ -59,6 +63,9 @@
|
|
|
59
63
|
"scripts": {
|
|
60
64
|
"build": "tsc -p tsconfig.json",
|
|
61
65
|
"test": "vitest run --passWithNoTests",
|
|
66
|
+
"test:db": "pnpm test:db:pg && pnpm test:db:mysql",
|
|
67
|
+
"test:db:pg": "AUTHZ_TEST_DIALECT=postgres vitest run --config vitest.db.config.ts",
|
|
68
|
+
"test:db:mysql": "AUTHZ_TEST_DIALECT=mysql vitest run --config vitest.db.config.ts",
|
|
62
69
|
"test:watch": "vitest",
|
|
63
70
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
64
71
|
}
|