@rbacbee-lib/nest 0.1.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/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # @rbacbee-lib/nest
2
+
3
+ NestJS integration for `@rbacbee-lib/core`.
4
+
5
+ ```ts
6
+ @RequirePermission('posts:create')
7
+ @Post()
8
+ createPost() {}
9
+ ```
10
+
11
+ Register a global guard:
12
+
13
+ ```ts
14
+ providers: [{ provide: APP_GUARD, useClass: RbacGuard }];
15
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result) __defProp(target, key, result);
25
+ return result;
26
+ };
27
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
28
+
29
+ // src/index.ts
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
+ RBAC_ENGINE: () => RBAC_ENGINE,
33
+ RBAC_IDENTITY_RESOLVER: () => RBAC_IDENTITY_RESOLVER,
34
+ RBAC_OPTIONS: () => RBAC_OPTIONS,
35
+ RBAC_PERMISSIONS_METADATA: () => RBAC_PERMISSIONS_METADATA,
36
+ RBAC_POLICIES_METADATA: () => RBAC_POLICIES_METADATA,
37
+ RBAC_ROLES_METADATA: () => RBAC_ROLES_METADATA,
38
+ RbacGuard: () => RbacGuard,
39
+ RbacModule: () => RbacModule,
40
+ RequireAnyPermission: () => RequireAnyPermission,
41
+ RequireAnyPolicy: () => RequireAnyPolicy,
42
+ RequireAnyRole: () => RequireAnyRole,
43
+ RequirePermission: () => RequirePermission,
44
+ RequirePolicy: () => RequirePolicy,
45
+ RequireRole: () => RequireRole,
46
+ createDefaultRbacContext: () => createDefaultRbacContext,
47
+ createIdentityResolver: () => createIdentityResolver,
48
+ getByPath: () => getByPath
49
+ });
50
+ module.exports = __toCommonJS(index_exports);
51
+
52
+ // src/rbac.constants.ts
53
+ var RBAC_ENGINE = /* @__PURE__ */ Symbol("RBAC_ENGINE");
54
+ var RBAC_OPTIONS = /* @__PURE__ */ Symbol("RBAC_OPTIONS");
55
+ var RBAC_IDENTITY_RESOLVER = /* @__PURE__ */ Symbol("RBAC_IDENTITY_RESOLVER");
56
+ var RBAC_PERMISSIONS_METADATA = "rbac:permissions";
57
+ var RBAC_ROLES_METADATA = "rbac:roles";
58
+ var RBAC_POLICIES_METADATA = "rbac:policies";
59
+
60
+ // src/rbac-context.ts
61
+ function createIdentityResolver(identity) {
62
+ if (identity?.resolveUser !== void 0) {
63
+ return identity.resolveUser;
64
+ }
65
+ return ({ request }) => {
66
+ const userIdPath = identity?.userIdPath ?? defaultUserIdPath(identity?.strategy);
67
+ const tenantIdPath = identity?.tenantIdPath ?? defaultTenantIdPath(identity?.strategy);
68
+ const userId = firstString(getByPath(request, userIdPath), getByPath(request, "user.id"));
69
+ if (userId === void 0) {
70
+ return null;
71
+ }
72
+ const tenantId = firstString(
73
+ getByPath(request, tenantIdPath),
74
+ getByPath(request, "user.tenantId")
75
+ );
76
+ const principal = { userId };
77
+ if (tenantId !== void 0) {
78
+ return { ...principal, tenantId };
79
+ }
80
+ return principal;
81
+ };
82
+ }
83
+ function createDefaultRbacContext(request, principal) {
84
+ const resourceId = firstString(request.params?.id, request.params?.resourceId);
85
+ const resourceType = firstString(request.headers?.["x-resource-type"]);
86
+ const context = {};
87
+ if (principal.tenantId !== void 0) {
88
+ Object.assign(context, { tenantId: principal.tenantId });
89
+ }
90
+ if (resourceId !== void 0) {
91
+ Object.assign(context, { resourceId });
92
+ }
93
+ if (resourceType !== void 0) {
94
+ Object.assign(context, { resourceType });
95
+ }
96
+ return context;
97
+ }
98
+ function getByPath(source, path) {
99
+ const segments = path.split(".").filter(Boolean);
100
+ let current = source;
101
+ for (const segment of segments) {
102
+ if (!isRecord(current)) {
103
+ return void 0;
104
+ }
105
+ current = current[segment];
106
+ }
107
+ return current;
108
+ }
109
+ function defaultUserIdPath(strategy) {
110
+ if (strategy === "cookie") {
111
+ return "cookies.userId";
112
+ }
113
+ return "user.sub";
114
+ }
115
+ function defaultTenantIdPath(strategy) {
116
+ if (strategy === "cookie") {
117
+ return "cookies.tenantId";
118
+ }
119
+ return "user.tenantId";
120
+ }
121
+ function firstString(...values) {
122
+ for (const value of values) {
123
+ if (typeof value === "string" && value.trim().length > 0) {
124
+ return value.trim();
125
+ }
126
+ if (typeof value === "number") {
127
+ return String(value);
128
+ }
129
+ }
130
+ return void 0;
131
+ }
132
+ function isRecord(value) {
133
+ return typeof value === "object" && value !== null;
134
+ }
135
+
136
+ // src/rbac.guard.ts
137
+ var import_common = require("@nestjs/common");
138
+ var RbacGuard = class {
139
+ constructor(reflector, engine, resolveIdentity, options) {
140
+ this.reflector = reflector;
141
+ this.engine = engine;
142
+ this.resolveIdentity = resolveIdentity;
143
+ this.options = options;
144
+ }
145
+ reflector;
146
+ engine;
147
+ resolveIdentity;
148
+ options;
149
+ async canActivate(context) {
150
+ const permissionRequirements = this.getRequirements(RBAC_PERMISSIONS_METADATA, context);
151
+ const roleRequirements = this.getRequirements(RBAC_ROLES_METADATA, context);
152
+ const policyRequirements = this.getRequirements(RBAC_POLICIES_METADATA, context);
153
+ if (permissionRequirements.length === 0 && roleRequirements.length === 0 && policyRequirements.length === 0) {
154
+ return true;
155
+ }
156
+ const request = context.switchToHttp().getRequest();
157
+ const principal = await this.resolveIdentity({ context, request });
158
+ if (principal === null) {
159
+ throw new import_common.UnauthorizedException("RBAC principal could not be resolved");
160
+ }
161
+ const rbacContext = this.options.context === void 0 ? createDefaultRbacContext(request, principal) : await this.options.context({ context, request, principal });
162
+ await this.assertRequirements(
163
+ permissionRequirements,
164
+ (permission) => this.engine.can(principal, permission, rbacContext)
165
+ );
166
+ await this.assertRequirements(
167
+ roleRequirements,
168
+ (role) => this.engine.hasRole(principal, role, rbacContext)
169
+ );
170
+ await this.assertRequirements(
171
+ policyRequirements,
172
+ (policy) => this.engine.evaluatePolicy(policy, principal, rbacContext)
173
+ );
174
+ return true;
175
+ }
176
+ getRequirements(metadataKey, context) {
177
+ const controllerRequirement = this.reflector.get(
178
+ metadataKey,
179
+ context.getClass()
180
+ );
181
+ const handlerRequirement = this.reflector.get(
182
+ metadataKey,
183
+ context.getHandler()
184
+ );
185
+ return [controllerRequirement, handlerRequirement].filter(isRequirement);
186
+ }
187
+ async assertRequirements(requirements, check) {
188
+ for (const requirement of requirements) {
189
+ const results = await Promise.all(requirement.values.map((value) => check(value)));
190
+ const allowed = requirement.mode === "all" ? results.every((result) => result.decision === "allow") : results.some((result) => result.decision === "allow");
191
+ if (!allowed) {
192
+ throw new import_common.ForbiddenException("RBAC access denied");
193
+ }
194
+ }
195
+ }
196
+ };
197
+ RbacGuard = __decorateClass([
198
+ (0, import_common.Injectable)(),
199
+ __decorateParam(1, (0, import_common.Inject)(RBAC_ENGINE)),
200
+ __decorateParam(2, (0, import_common.Inject)(RBAC_IDENTITY_RESOLVER)),
201
+ __decorateParam(3, (0, import_common.Inject)(RBAC_OPTIONS))
202
+ ], RbacGuard);
203
+ function isRequirement(value) {
204
+ return value !== void 0 && value.values.length > 0;
205
+ }
206
+
207
+ // src/rbac.module.ts
208
+ var import_common2 = require("@nestjs/common");
209
+ var import_core = require("@rbacbee-lib/core");
210
+
211
+ // src/deny-all-access-repository.ts
212
+ var DenyAllAccessRepository = class {
213
+ async getAccessProfile() {
214
+ return null;
215
+ }
216
+ };
217
+
218
+ // src/rbac.module.ts
219
+ var RbacModule = class {
220
+ static forRoot(options) {
221
+ return {
222
+ module: RbacModule,
223
+ providers: [
224
+ { provide: RBAC_OPTIONS, useValue: options },
225
+ createIdentityResolverProvider(),
226
+ createEngineProvider(),
227
+ RbacGuard
228
+ ],
229
+ exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]
230
+ };
231
+ }
232
+ static forRootAsync(options) {
233
+ return {
234
+ module: RbacModule,
235
+ imports: options.imports,
236
+ providers: [
237
+ {
238
+ provide: RBAC_OPTIONS,
239
+ useFactory: options.useFactory,
240
+ inject: options.inject ?? []
241
+ },
242
+ createIdentityResolverProvider(),
243
+ createEngineProvider(),
244
+ RbacGuard
245
+ ],
246
+ exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]
247
+ };
248
+ }
249
+ };
250
+ RbacModule = __decorateClass([
251
+ (0, import_common2.Module)({})
252
+ ], RbacModule);
253
+ function createIdentityResolverProvider() {
254
+ return {
255
+ provide: RBAC_IDENTITY_RESOLVER,
256
+ inject: [RBAC_OPTIONS],
257
+ useFactory: (options) => createIdentityResolver(options.identity)
258
+ };
259
+ }
260
+ function createEngineProvider() {
261
+ return {
262
+ provide: RBAC_ENGINE,
263
+ inject: [RBAC_OPTIONS],
264
+ useFactory: (options) => {
265
+ if (options.engine !== void 0) {
266
+ return options.engine;
267
+ }
268
+ return (0, import_core.createRbacEngine)({
269
+ accessRepository: options.accessRepository ?? new DenyAllAccessRepository(),
270
+ audit: options.audit,
271
+ cache: options.cache,
272
+ policies: options.policies,
273
+ cacheTtlMs: options.cacheTtlMs
274
+ });
275
+ }
276
+ };
277
+ }
278
+
279
+ // src/decorators/require-any-permission.decorator.ts
280
+ var import_common3 = require("@nestjs/common");
281
+ function RequireAnyPermission(...permissions) {
282
+ return (0, import_common3.SetMetadata)(RBAC_PERMISSIONS_METADATA, {
283
+ values: permissions,
284
+ mode: "any"
285
+ });
286
+ }
287
+
288
+ // src/decorators/require-any-policy.decorator.ts
289
+ var import_common4 = require("@nestjs/common");
290
+ function RequireAnyPolicy(...policies) {
291
+ return (0, import_common4.SetMetadata)(RBAC_POLICIES_METADATA, {
292
+ values: policies,
293
+ mode: "any"
294
+ });
295
+ }
296
+
297
+ // src/decorators/require-any-role.decorator.ts
298
+ var import_common5 = require("@nestjs/common");
299
+ function RequireAnyRole(...roles) {
300
+ return (0, import_common5.SetMetadata)(RBAC_ROLES_METADATA, {
301
+ values: roles,
302
+ mode: "any"
303
+ });
304
+ }
305
+
306
+ // src/decorators/require-permission.decorator.ts
307
+ var import_common6 = require("@nestjs/common");
308
+ function RequirePermission(...permissions) {
309
+ return (0, import_common6.SetMetadata)(RBAC_PERMISSIONS_METADATA, {
310
+ values: permissions,
311
+ mode: "all"
312
+ });
313
+ }
314
+
315
+ // src/decorators/require-policy.decorator.ts
316
+ var import_common7 = require("@nestjs/common");
317
+ function RequirePolicy(...policies) {
318
+ return (0, import_common7.SetMetadata)(RBAC_POLICIES_METADATA, {
319
+ values: policies,
320
+ mode: "all"
321
+ });
322
+ }
323
+
324
+ // src/decorators/require-role.decorator.ts
325
+ var import_common8 = require("@nestjs/common");
326
+ function RequireRole(...roles) {
327
+ return (0, import_common8.SetMetadata)(RBAC_ROLES_METADATA, {
328
+ values: roles,
329
+ mode: "all"
330
+ });
331
+ }
332
+ // Annotate the CommonJS export names for ESM import in node:
333
+ 0 && (module.exports = {
334
+ RBAC_ENGINE,
335
+ RBAC_IDENTITY_RESOLVER,
336
+ RBAC_OPTIONS,
337
+ RBAC_PERMISSIONS_METADATA,
338
+ RBAC_POLICIES_METADATA,
339
+ RBAC_ROLES_METADATA,
340
+ RbacGuard,
341
+ RbacModule,
342
+ RequireAnyPermission,
343
+ RequireAnyPolicy,
344
+ RequireAnyRole,
345
+ RequirePermission,
346
+ RequirePolicy,
347
+ RequireRole,
348
+ createDefaultRbacContext,
349
+ createIdentityResolver,
350
+ getByPath
351
+ });
352
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/rbac.constants.ts","../src/rbac-context.ts","../src/rbac.guard.ts","../src/rbac.module.ts","../src/deny-all-access-repository.ts","../src/decorators/require-any-permission.decorator.ts","../src/decorators/require-any-policy.decorator.ts","../src/decorators/require-any-role.decorator.ts","../src/decorators/require-permission.decorator.ts","../src/decorators/require-policy.decorator.ts","../src/decorators/require-role.decorator.ts"],"sourcesContent":["export * from './rbac.constants';\nexport * from './rbac-context';\nexport * from './rbac.guard';\nexport * from './rbac.module';\nexport * from './rbac.types';\nexport * from './decorators/require-any-permission.decorator';\nexport * from './decorators/require-any-policy.decorator';\nexport * from './decorators/require-any-role.decorator';\nexport * from './decorators/require-permission.decorator';\nexport * from './decorators/require-policy.decorator';\nexport * from './decorators/require-role.decorator';\n","export const RBAC_ENGINE = Symbol('RBAC_ENGINE');\nexport const RBAC_OPTIONS = Symbol('RBAC_OPTIONS');\nexport const RBAC_IDENTITY_RESOLVER = Symbol('RBAC_IDENTITY_RESOLVER');\n\nexport const RBAC_PERMISSIONS_METADATA = 'rbac:permissions';\nexport const RBAC_ROLES_METADATA = 'rbac:roles';\nexport const RBAC_POLICIES_METADATA = 'rbac:policies';\n","import type { RbacAuthorizationContext, RbacPrincipal } from '@rbacbee-lib/core';\nimport type { RbacHttpRequest, RbacIdentityOptions, RbacIdentityResolver } from './rbac.types';\n\nexport function createIdentityResolver(identity?: RbacIdentityOptions): RbacIdentityResolver {\n if (identity?.resolveUser !== undefined) {\n return identity.resolveUser;\n }\n\n return ({ request }) => {\n const userIdPath = identity?.userIdPath ?? defaultUserIdPath(identity?.strategy);\n const tenantIdPath = identity?.tenantIdPath ?? defaultTenantIdPath(identity?.strategy);\n const userId = firstString(getByPath(request, userIdPath), getByPath(request, 'user.id'));\n\n if (userId === undefined) {\n return null;\n }\n\n const tenantId = firstString(\n getByPath(request, tenantIdPath),\n getByPath(request, 'user.tenantId')\n );\n const principal: RbacPrincipal = { userId };\n\n if (tenantId !== undefined) {\n return { ...principal, tenantId };\n }\n\n return principal;\n };\n}\n\nexport function createDefaultRbacContext(\n request: RbacHttpRequest,\n principal: RbacPrincipal\n): RbacAuthorizationContext {\n const resourceId = firstString(request.params?.id, request.params?.resourceId);\n const resourceType = firstString(request.headers?.['x-resource-type']);\n const context: RbacAuthorizationContext = {};\n\n if (principal.tenantId !== undefined) {\n Object.assign(context, { tenantId: principal.tenantId });\n }\n\n if (resourceId !== undefined) {\n Object.assign(context, { resourceId });\n }\n\n if (resourceType !== undefined) {\n Object.assign(context, { resourceType });\n }\n\n return context;\n}\n\nexport function getByPath(source: unknown, path: string): unknown {\n const segments = path.split('.').filter(Boolean);\n let current: unknown = source;\n\n for (const segment of segments) {\n if (!isRecord(current)) {\n return undefined;\n }\n\n current = current[segment];\n }\n\n return current;\n}\n\nfunction defaultUserIdPath(strategy?: RbacIdentityOptions['strategy']): string {\n if (strategy === 'cookie') {\n return 'cookies.userId';\n }\n\n return 'user.sub';\n}\n\nfunction defaultTenantIdPath(strategy?: RbacIdentityOptions['strategy']): string {\n if (strategy === 'cookie') {\n return 'cookies.tenantId';\n }\n\n return 'user.tenantId';\n}\n\nfunction firstString(...values: unknown[]): string | undefined {\n for (const value of values) {\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim();\n }\n\n if (typeof value === 'number') {\n return String(value);\n }\n }\n\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n","import {\n CanActivate,\n ExecutionContext,\n ForbiddenException,\n Inject,\n Injectable,\n UnauthorizedException\n} from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport type { AuthorizationResult, RbacEngine } from '@rbacbee-lib/core';\nimport {\n RBAC_ENGINE,\n RBAC_IDENTITY_RESOLVER,\n RBAC_OPTIONS,\n RBAC_PERMISSIONS_METADATA,\n RBAC_POLICIES_METADATA,\n RBAC_ROLES_METADATA\n} from './rbac.constants';\nimport { createDefaultRbacContext } from './rbac-context';\nimport type {\n RbacHttpRequest,\n RbacIdentityResolver,\n RbacNestModuleOptions,\n RbacRequirementMetadata\n} from './rbac.types';\n\n@Injectable()\nexport class RbacGuard implements CanActivate {\n public constructor(\n private readonly reflector: Reflector,\n @Inject(RBAC_ENGINE) private readonly engine: RbacEngine,\n @Inject(RBAC_IDENTITY_RESOLVER) private readonly resolveIdentity: RbacIdentityResolver,\n @Inject(RBAC_OPTIONS) private readonly options: RbacNestModuleOptions\n ) {}\n\n public async canActivate(context: ExecutionContext): Promise<boolean> {\n const permissionRequirements = this.getRequirements(RBAC_PERMISSIONS_METADATA, context);\n const roleRequirements = this.getRequirements(RBAC_ROLES_METADATA, context);\n const policyRequirements = this.getRequirements(RBAC_POLICIES_METADATA, context);\n\n if (\n permissionRequirements.length === 0 &&\n roleRequirements.length === 0 &&\n policyRequirements.length === 0\n ) {\n return true;\n }\n\n const request = context.switchToHttp().getRequest<RbacHttpRequest>();\n const principal = await this.resolveIdentity({ context, request });\n\n if (principal === null) {\n throw new UnauthorizedException('RBAC principal could not be resolved');\n }\n\n const rbacContext =\n this.options.context === undefined\n ? createDefaultRbacContext(request, principal)\n : await this.options.context({ context, request, principal });\n\n await this.assertRequirements(permissionRequirements, (permission) =>\n this.engine.can(principal, permission, rbacContext)\n );\n await this.assertRequirements(roleRequirements, (role) =>\n this.engine.hasRole(principal, role, rbacContext)\n );\n await this.assertRequirements(policyRequirements, (policy) =>\n this.engine.evaluatePolicy(policy, principal, rbacContext)\n );\n\n return true;\n }\n\n private getRequirements(\n metadataKey: string,\n context: ExecutionContext\n ): RbacRequirementMetadata[] {\n const controllerRequirement = this.reflector.get<RbacRequirementMetadata>(\n metadataKey,\n context.getClass()\n );\n const handlerRequirement = this.reflector.get<RbacRequirementMetadata>(\n metadataKey,\n context.getHandler()\n );\n\n return [controllerRequirement, handlerRequirement].filter(isRequirement);\n }\n\n private async assertRequirements(\n requirements: readonly RbacRequirementMetadata[],\n check: (value: string) => Promise<AuthorizationResult>\n ): Promise<void> {\n for (const requirement of requirements) {\n const results = await Promise.all(requirement.values.map((value) => check(value)));\n const allowed =\n requirement.mode === 'all'\n ? results.every((result) => result.decision === 'allow')\n : results.some((result) => result.decision === 'allow');\n\n if (!allowed) {\n throw new ForbiddenException('RBAC access denied');\n }\n }\n }\n}\n\nfunction isRequirement(\n value: RbacRequirementMetadata | undefined\n): value is RbacRequirementMetadata {\n return value !== undefined && value.values.length > 0;\n}\n","import { DynamicModule, Module, Provider } from '@nestjs/common';\nimport { createRbacEngine } from '@rbacbee-lib/core';\nimport { RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RBAC_OPTIONS } from './rbac.constants';\nimport { createIdentityResolver } from './rbac-context';\nimport { RbacGuard } from './rbac.guard';\nimport type { RbacNestModuleAsyncOptions, RbacNestModuleOptions } from './rbac.types';\nimport { DenyAllAccessRepository } from './deny-all-access-repository';\n\n@Module({})\nexport class RbacModule {\n public static forRoot(options: RbacNestModuleOptions): DynamicModule {\n return {\n module: RbacModule,\n providers: [\n { provide: RBAC_OPTIONS, useValue: options },\n createIdentityResolverProvider(),\n createEngineProvider(),\n RbacGuard\n ],\n exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]\n };\n }\n\n public static forRootAsync(options: RbacNestModuleAsyncOptions): DynamicModule {\n return {\n module: RbacModule,\n imports: options.imports,\n providers: [\n {\n provide: RBAC_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject ?? []\n },\n createIdentityResolverProvider(),\n createEngineProvider(),\n RbacGuard\n ],\n exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]\n };\n }\n}\n\nfunction createIdentityResolverProvider(): Provider {\n return {\n provide: RBAC_IDENTITY_RESOLVER,\n inject: [RBAC_OPTIONS],\n useFactory: (options: RbacNestModuleOptions) => createIdentityResolver(options.identity)\n };\n}\n\nfunction createEngineProvider(): Provider {\n return {\n provide: RBAC_ENGINE,\n inject: [RBAC_OPTIONS],\n useFactory: (options: RbacNestModuleOptions) => {\n if (options.engine !== undefined) {\n return options.engine;\n }\n\n return createRbacEngine({\n accessRepository: options.accessRepository ?? new DenyAllAccessRepository(),\n audit: options.audit,\n cache: options.cache,\n policies: options.policies,\n cacheTtlMs: options.cacheTtlMs\n });\n }\n };\n}\n","import type { AccessProfile, AccessRepository } from '@rbacbee-lib/core';\n\nexport class DenyAllAccessRepository implements AccessRepository {\n public async getAccessProfile(): Promise<AccessProfile | null> {\n return null;\n }\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_PERMISSIONS_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireAnyPermission(...permissions: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_PERMISSIONS_METADATA, {\n values: permissions,\n mode: 'any'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_POLICIES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireAnyPolicy(...policies: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_POLICIES_METADATA, {\n values: policies,\n mode: 'any'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_ROLES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireAnyRole(...roles: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_ROLES_METADATA, {\n values: roles,\n mode: 'any'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_PERMISSIONS_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequirePermission(...permissions: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_PERMISSIONS_METADATA, {\n values: permissions,\n mode: 'all'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_POLICIES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequirePolicy(...policies: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_POLICIES_METADATA, {\n values: policies,\n mode: 'all'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_ROLES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireRole(...roles: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_ROLES_METADATA, {\n values: roles,\n mode: 'all'\n } satisfies RbacRequirementMetadata);\n}\n"],"mappings":"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","names":["import_common","import_common","import_common","import_common","import_common","import_common","import_common"]}
@@ -0,0 +1,87 @@
1
+ import { RbacPrincipal, RbacAuthorizationContext, RbacEngine, AccessRepository, CachePort, AuditPort, PolicyRegistry, RbacRequirementMode } from '@rbacbee-lib/core';
2
+ import { ExecutionContext, ModuleMetadata, FactoryProvider, CanActivate, DynamicModule } from '@nestjs/common';
3
+ import { Reflector } from '@nestjs/core';
4
+
5
+ declare const RBAC_ENGINE: unique symbol;
6
+ declare const RBAC_OPTIONS: unique symbol;
7
+ declare const RBAC_IDENTITY_RESOLVER: unique symbol;
8
+ declare const RBAC_PERMISSIONS_METADATA = "rbac:permissions";
9
+ declare const RBAC_ROLES_METADATA = "rbac:roles";
10
+ declare const RBAC_POLICIES_METADATA = "rbac:policies";
11
+
12
+ interface RbacHttpRequest {
13
+ readonly user?: unknown;
14
+ readonly cookies?: Record<string, unknown>;
15
+ readonly headers?: Record<string, unknown>;
16
+ readonly params?: Record<string, unknown>;
17
+ readonly query?: Record<string, unknown>;
18
+ readonly body?: unknown;
19
+ readonly [key: string]: unknown;
20
+ }
21
+ interface RbacIdentityResolverInput {
22
+ readonly context: ExecutionContext;
23
+ readonly request: RbacHttpRequest;
24
+ }
25
+ type RbacIdentityResolver = (input: RbacIdentityResolverInput) => RbacPrincipal | null | Promise<RbacPrincipal | null>;
26
+ interface RbacContextResolverInput extends RbacIdentityResolverInput {
27
+ readonly principal: RbacPrincipal;
28
+ }
29
+ type RbacContextResolver = (input: RbacContextResolverInput) => RbacAuthorizationContext | Promise<RbacAuthorizationContext>;
30
+ interface RbacIdentityOptions {
31
+ readonly strategy?: 'jwt' | 'cookie' | 'custom';
32
+ readonly userIdPath?: string;
33
+ readonly tenantIdPath?: string;
34
+ readonly resolveUser?: RbacIdentityResolver;
35
+ }
36
+ interface RbacNestModuleOptions {
37
+ readonly engine?: RbacEngine;
38
+ readonly accessRepository?: AccessRepository;
39
+ readonly cache?: CachePort;
40
+ readonly audit?: AuditPort;
41
+ readonly policies?: PolicyRegistry;
42
+ readonly identity?: RbacIdentityOptions;
43
+ readonly context?: RbacContextResolver;
44
+ readonly cacheTtlMs?: number;
45
+ }
46
+ interface RbacNestModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
47
+ readonly inject?: FactoryProvider['inject'];
48
+ readonly useFactory: (...dependencies: any[]) => RbacNestModuleOptions | Promise<RbacNestModuleOptions>;
49
+ }
50
+ interface RbacRequirementMetadata {
51
+ readonly values: readonly string[];
52
+ readonly mode: RbacRequirementMode;
53
+ }
54
+
55
+ declare function createIdentityResolver(identity?: RbacIdentityOptions): RbacIdentityResolver;
56
+ declare function createDefaultRbacContext(request: RbacHttpRequest, principal: RbacPrincipal): RbacAuthorizationContext;
57
+ declare function getByPath(source: unknown, path: string): unknown;
58
+
59
+ declare class RbacGuard implements CanActivate {
60
+ private readonly reflector;
61
+ private readonly engine;
62
+ private readonly resolveIdentity;
63
+ private readonly options;
64
+ constructor(reflector: Reflector, engine: RbacEngine, resolveIdentity: RbacIdentityResolver, options: RbacNestModuleOptions);
65
+ canActivate(context: ExecutionContext): Promise<boolean>;
66
+ private getRequirements;
67
+ private assertRequirements;
68
+ }
69
+
70
+ declare class RbacModule {
71
+ static forRoot(options: RbacNestModuleOptions): DynamicModule;
72
+ static forRootAsync(options: RbacNestModuleAsyncOptions): DynamicModule;
73
+ }
74
+
75
+ declare function RequireAnyPermission(...permissions: string[]): MethodDecorator & ClassDecorator;
76
+
77
+ declare function RequireAnyPolicy(...policies: string[]): MethodDecorator & ClassDecorator;
78
+
79
+ declare function RequireAnyRole(...roles: string[]): MethodDecorator & ClassDecorator;
80
+
81
+ declare function RequirePermission(...permissions: string[]): MethodDecorator & ClassDecorator;
82
+
83
+ declare function RequirePolicy(...policies: string[]): MethodDecorator & ClassDecorator;
84
+
85
+ declare function RequireRole(...roles: string[]): MethodDecorator & ClassDecorator;
86
+
87
+ export { RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RBAC_OPTIONS, RBAC_PERMISSIONS_METADATA, RBAC_POLICIES_METADATA, RBAC_ROLES_METADATA, type RbacContextResolver, type RbacContextResolverInput, RbacGuard, type RbacHttpRequest, type RbacIdentityOptions, type RbacIdentityResolver, type RbacIdentityResolverInput, RbacModule, type RbacNestModuleAsyncOptions, type RbacNestModuleOptions, type RbacRequirementMetadata, RequireAnyPermission, RequireAnyPolicy, RequireAnyRole, RequirePermission, RequirePolicy, RequireRole, createDefaultRbacContext, createIdentityResolver, getByPath };
@@ -0,0 +1,87 @@
1
+ import { RbacPrincipal, RbacAuthorizationContext, RbacEngine, AccessRepository, CachePort, AuditPort, PolicyRegistry, RbacRequirementMode } from '@rbacbee-lib/core';
2
+ import { ExecutionContext, ModuleMetadata, FactoryProvider, CanActivate, DynamicModule } from '@nestjs/common';
3
+ import { Reflector } from '@nestjs/core';
4
+
5
+ declare const RBAC_ENGINE: unique symbol;
6
+ declare const RBAC_OPTIONS: unique symbol;
7
+ declare const RBAC_IDENTITY_RESOLVER: unique symbol;
8
+ declare const RBAC_PERMISSIONS_METADATA = "rbac:permissions";
9
+ declare const RBAC_ROLES_METADATA = "rbac:roles";
10
+ declare const RBAC_POLICIES_METADATA = "rbac:policies";
11
+
12
+ interface RbacHttpRequest {
13
+ readonly user?: unknown;
14
+ readonly cookies?: Record<string, unknown>;
15
+ readonly headers?: Record<string, unknown>;
16
+ readonly params?: Record<string, unknown>;
17
+ readonly query?: Record<string, unknown>;
18
+ readonly body?: unknown;
19
+ readonly [key: string]: unknown;
20
+ }
21
+ interface RbacIdentityResolverInput {
22
+ readonly context: ExecutionContext;
23
+ readonly request: RbacHttpRequest;
24
+ }
25
+ type RbacIdentityResolver = (input: RbacIdentityResolverInput) => RbacPrincipal | null | Promise<RbacPrincipal | null>;
26
+ interface RbacContextResolverInput extends RbacIdentityResolverInput {
27
+ readonly principal: RbacPrincipal;
28
+ }
29
+ type RbacContextResolver = (input: RbacContextResolverInput) => RbacAuthorizationContext | Promise<RbacAuthorizationContext>;
30
+ interface RbacIdentityOptions {
31
+ readonly strategy?: 'jwt' | 'cookie' | 'custom';
32
+ readonly userIdPath?: string;
33
+ readonly tenantIdPath?: string;
34
+ readonly resolveUser?: RbacIdentityResolver;
35
+ }
36
+ interface RbacNestModuleOptions {
37
+ readonly engine?: RbacEngine;
38
+ readonly accessRepository?: AccessRepository;
39
+ readonly cache?: CachePort;
40
+ readonly audit?: AuditPort;
41
+ readonly policies?: PolicyRegistry;
42
+ readonly identity?: RbacIdentityOptions;
43
+ readonly context?: RbacContextResolver;
44
+ readonly cacheTtlMs?: number;
45
+ }
46
+ interface RbacNestModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
47
+ readonly inject?: FactoryProvider['inject'];
48
+ readonly useFactory: (...dependencies: any[]) => RbacNestModuleOptions | Promise<RbacNestModuleOptions>;
49
+ }
50
+ interface RbacRequirementMetadata {
51
+ readonly values: readonly string[];
52
+ readonly mode: RbacRequirementMode;
53
+ }
54
+
55
+ declare function createIdentityResolver(identity?: RbacIdentityOptions): RbacIdentityResolver;
56
+ declare function createDefaultRbacContext(request: RbacHttpRequest, principal: RbacPrincipal): RbacAuthorizationContext;
57
+ declare function getByPath(source: unknown, path: string): unknown;
58
+
59
+ declare class RbacGuard implements CanActivate {
60
+ private readonly reflector;
61
+ private readonly engine;
62
+ private readonly resolveIdentity;
63
+ private readonly options;
64
+ constructor(reflector: Reflector, engine: RbacEngine, resolveIdentity: RbacIdentityResolver, options: RbacNestModuleOptions);
65
+ canActivate(context: ExecutionContext): Promise<boolean>;
66
+ private getRequirements;
67
+ private assertRequirements;
68
+ }
69
+
70
+ declare class RbacModule {
71
+ static forRoot(options: RbacNestModuleOptions): DynamicModule;
72
+ static forRootAsync(options: RbacNestModuleAsyncOptions): DynamicModule;
73
+ }
74
+
75
+ declare function RequireAnyPermission(...permissions: string[]): MethodDecorator & ClassDecorator;
76
+
77
+ declare function RequireAnyPolicy(...policies: string[]): MethodDecorator & ClassDecorator;
78
+
79
+ declare function RequireAnyRole(...roles: string[]): MethodDecorator & ClassDecorator;
80
+
81
+ declare function RequirePermission(...permissions: string[]): MethodDecorator & ClassDecorator;
82
+
83
+ declare function RequirePolicy(...policies: string[]): MethodDecorator & ClassDecorator;
84
+
85
+ declare function RequireRole(...roles: string[]): MethodDecorator & ClassDecorator;
86
+
87
+ export { RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RBAC_OPTIONS, RBAC_PERMISSIONS_METADATA, RBAC_POLICIES_METADATA, RBAC_ROLES_METADATA, type RbacContextResolver, type RbacContextResolverInput, RbacGuard, type RbacHttpRequest, type RbacIdentityOptions, type RbacIdentityResolver, type RbacIdentityResolverInput, RbacModule, type RbacNestModuleAsyncOptions, type RbacNestModuleOptions, type RbacRequirementMetadata, RequireAnyPermission, RequireAnyPolicy, RequireAnyRole, RequirePermission, RequirePolicy, RequireRole, createDefaultRbacContext, createIdentityResolver, getByPath };
package/dist/index.js ADDED
@@ -0,0 +1,317 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result) __defProp(target, key, result);
9
+ return result;
10
+ };
11
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
12
+
13
+ // src/rbac.constants.ts
14
+ var RBAC_ENGINE = /* @__PURE__ */ Symbol("RBAC_ENGINE");
15
+ var RBAC_OPTIONS = /* @__PURE__ */ Symbol("RBAC_OPTIONS");
16
+ var RBAC_IDENTITY_RESOLVER = /* @__PURE__ */ Symbol("RBAC_IDENTITY_RESOLVER");
17
+ var RBAC_PERMISSIONS_METADATA = "rbac:permissions";
18
+ var RBAC_ROLES_METADATA = "rbac:roles";
19
+ var RBAC_POLICIES_METADATA = "rbac:policies";
20
+
21
+ // src/rbac-context.ts
22
+ function createIdentityResolver(identity) {
23
+ if (identity?.resolveUser !== void 0) {
24
+ return identity.resolveUser;
25
+ }
26
+ return ({ request }) => {
27
+ const userIdPath = identity?.userIdPath ?? defaultUserIdPath(identity?.strategy);
28
+ const tenantIdPath = identity?.tenantIdPath ?? defaultTenantIdPath(identity?.strategy);
29
+ const userId = firstString(getByPath(request, userIdPath), getByPath(request, "user.id"));
30
+ if (userId === void 0) {
31
+ return null;
32
+ }
33
+ const tenantId = firstString(
34
+ getByPath(request, tenantIdPath),
35
+ getByPath(request, "user.tenantId")
36
+ );
37
+ const principal = { userId };
38
+ if (tenantId !== void 0) {
39
+ return { ...principal, tenantId };
40
+ }
41
+ return principal;
42
+ };
43
+ }
44
+ function createDefaultRbacContext(request, principal) {
45
+ const resourceId = firstString(request.params?.id, request.params?.resourceId);
46
+ const resourceType = firstString(request.headers?.["x-resource-type"]);
47
+ const context = {};
48
+ if (principal.tenantId !== void 0) {
49
+ Object.assign(context, { tenantId: principal.tenantId });
50
+ }
51
+ if (resourceId !== void 0) {
52
+ Object.assign(context, { resourceId });
53
+ }
54
+ if (resourceType !== void 0) {
55
+ Object.assign(context, { resourceType });
56
+ }
57
+ return context;
58
+ }
59
+ function getByPath(source, path) {
60
+ const segments = path.split(".").filter(Boolean);
61
+ let current = source;
62
+ for (const segment of segments) {
63
+ if (!isRecord(current)) {
64
+ return void 0;
65
+ }
66
+ current = current[segment];
67
+ }
68
+ return current;
69
+ }
70
+ function defaultUserIdPath(strategy) {
71
+ if (strategy === "cookie") {
72
+ return "cookies.userId";
73
+ }
74
+ return "user.sub";
75
+ }
76
+ function defaultTenantIdPath(strategy) {
77
+ if (strategy === "cookie") {
78
+ return "cookies.tenantId";
79
+ }
80
+ return "user.tenantId";
81
+ }
82
+ function firstString(...values) {
83
+ for (const value of values) {
84
+ if (typeof value === "string" && value.trim().length > 0) {
85
+ return value.trim();
86
+ }
87
+ if (typeof value === "number") {
88
+ return String(value);
89
+ }
90
+ }
91
+ return void 0;
92
+ }
93
+ function isRecord(value) {
94
+ return typeof value === "object" && value !== null;
95
+ }
96
+
97
+ // src/rbac.guard.ts
98
+ import {
99
+ ForbiddenException,
100
+ Inject,
101
+ Injectable,
102
+ UnauthorizedException
103
+ } from "@nestjs/common";
104
+ var RbacGuard = class {
105
+ constructor(reflector, engine, resolveIdentity, options) {
106
+ this.reflector = reflector;
107
+ this.engine = engine;
108
+ this.resolveIdentity = resolveIdentity;
109
+ this.options = options;
110
+ }
111
+ reflector;
112
+ engine;
113
+ resolveIdentity;
114
+ options;
115
+ async canActivate(context) {
116
+ const permissionRequirements = this.getRequirements(RBAC_PERMISSIONS_METADATA, context);
117
+ const roleRequirements = this.getRequirements(RBAC_ROLES_METADATA, context);
118
+ const policyRequirements = this.getRequirements(RBAC_POLICIES_METADATA, context);
119
+ if (permissionRequirements.length === 0 && roleRequirements.length === 0 && policyRequirements.length === 0) {
120
+ return true;
121
+ }
122
+ const request = context.switchToHttp().getRequest();
123
+ const principal = await this.resolveIdentity({ context, request });
124
+ if (principal === null) {
125
+ throw new UnauthorizedException("RBAC principal could not be resolved");
126
+ }
127
+ const rbacContext = this.options.context === void 0 ? createDefaultRbacContext(request, principal) : await this.options.context({ context, request, principal });
128
+ await this.assertRequirements(
129
+ permissionRequirements,
130
+ (permission) => this.engine.can(principal, permission, rbacContext)
131
+ );
132
+ await this.assertRequirements(
133
+ roleRequirements,
134
+ (role) => this.engine.hasRole(principal, role, rbacContext)
135
+ );
136
+ await this.assertRequirements(
137
+ policyRequirements,
138
+ (policy) => this.engine.evaluatePolicy(policy, principal, rbacContext)
139
+ );
140
+ return true;
141
+ }
142
+ getRequirements(metadataKey, context) {
143
+ const controllerRequirement = this.reflector.get(
144
+ metadataKey,
145
+ context.getClass()
146
+ );
147
+ const handlerRequirement = this.reflector.get(
148
+ metadataKey,
149
+ context.getHandler()
150
+ );
151
+ return [controllerRequirement, handlerRequirement].filter(isRequirement);
152
+ }
153
+ async assertRequirements(requirements, check) {
154
+ for (const requirement of requirements) {
155
+ const results = await Promise.all(requirement.values.map((value) => check(value)));
156
+ const allowed = requirement.mode === "all" ? results.every((result) => result.decision === "allow") : results.some((result) => result.decision === "allow");
157
+ if (!allowed) {
158
+ throw new ForbiddenException("RBAC access denied");
159
+ }
160
+ }
161
+ }
162
+ };
163
+ RbacGuard = __decorateClass([
164
+ Injectable(),
165
+ __decorateParam(1, Inject(RBAC_ENGINE)),
166
+ __decorateParam(2, Inject(RBAC_IDENTITY_RESOLVER)),
167
+ __decorateParam(3, Inject(RBAC_OPTIONS))
168
+ ], RbacGuard);
169
+ function isRequirement(value) {
170
+ return value !== void 0 && value.values.length > 0;
171
+ }
172
+
173
+ // src/rbac.module.ts
174
+ import { Module } from "@nestjs/common";
175
+ import { createRbacEngine } from "@rbacbee-lib/core";
176
+
177
+ // src/deny-all-access-repository.ts
178
+ var DenyAllAccessRepository = class {
179
+ async getAccessProfile() {
180
+ return null;
181
+ }
182
+ };
183
+
184
+ // src/rbac.module.ts
185
+ var RbacModule = class {
186
+ static forRoot(options) {
187
+ return {
188
+ module: RbacModule,
189
+ providers: [
190
+ { provide: RBAC_OPTIONS, useValue: options },
191
+ createIdentityResolverProvider(),
192
+ createEngineProvider(),
193
+ RbacGuard
194
+ ],
195
+ exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]
196
+ };
197
+ }
198
+ static forRootAsync(options) {
199
+ return {
200
+ module: RbacModule,
201
+ imports: options.imports,
202
+ providers: [
203
+ {
204
+ provide: RBAC_OPTIONS,
205
+ useFactory: options.useFactory,
206
+ inject: options.inject ?? []
207
+ },
208
+ createIdentityResolverProvider(),
209
+ createEngineProvider(),
210
+ RbacGuard
211
+ ],
212
+ exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]
213
+ };
214
+ }
215
+ };
216
+ RbacModule = __decorateClass([
217
+ Module({})
218
+ ], RbacModule);
219
+ function createIdentityResolverProvider() {
220
+ return {
221
+ provide: RBAC_IDENTITY_RESOLVER,
222
+ inject: [RBAC_OPTIONS],
223
+ useFactory: (options) => createIdentityResolver(options.identity)
224
+ };
225
+ }
226
+ function createEngineProvider() {
227
+ return {
228
+ provide: RBAC_ENGINE,
229
+ inject: [RBAC_OPTIONS],
230
+ useFactory: (options) => {
231
+ if (options.engine !== void 0) {
232
+ return options.engine;
233
+ }
234
+ return createRbacEngine({
235
+ accessRepository: options.accessRepository ?? new DenyAllAccessRepository(),
236
+ audit: options.audit,
237
+ cache: options.cache,
238
+ policies: options.policies,
239
+ cacheTtlMs: options.cacheTtlMs
240
+ });
241
+ }
242
+ };
243
+ }
244
+
245
+ // src/decorators/require-any-permission.decorator.ts
246
+ import { SetMetadata } from "@nestjs/common";
247
+ function RequireAnyPermission(...permissions) {
248
+ return SetMetadata(RBAC_PERMISSIONS_METADATA, {
249
+ values: permissions,
250
+ mode: "any"
251
+ });
252
+ }
253
+
254
+ // src/decorators/require-any-policy.decorator.ts
255
+ import { SetMetadata as SetMetadata2 } from "@nestjs/common";
256
+ function RequireAnyPolicy(...policies) {
257
+ return SetMetadata2(RBAC_POLICIES_METADATA, {
258
+ values: policies,
259
+ mode: "any"
260
+ });
261
+ }
262
+
263
+ // src/decorators/require-any-role.decorator.ts
264
+ import { SetMetadata as SetMetadata3 } from "@nestjs/common";
265
+ function RequireAnyRole(...roles) {
266
+ return SetMetadata3(RBAC_ROLES_METADATA, {
267
+ values: roles,
268
+ mode: "any"
269
+ });
270
+ }
271
+
272
+ // src/decorators/require-permission.decorator.ts
273
+ import { SetMetadata as SetMetadata4 } from "@nestjs/common";
274
+ function RequirePermission(...permissions) {
275
+ return SetMetadata4(RBAC_PERMISSIONS_METADATA, {
276
+ values: permissions,
277
+ mode: "all"
278
+ });
279
+ }
280
+
281
+ // src/decorators/require-policy.decorator.ts
282
+ import { SetMetadata as SetMetadata5 } from "@nestjs/common";
283
+ function RequirePolicy(...policies) {
284
+ return SetMetadata5(RBAC_POLICIES_METADATA, {
285
+ values: policies,
286
+ mode: "all"
287
+ });
288
+ }
289
+
290
+ // src/decorators/require-role.decorator.ts
291
+ import { SetMetadata as SetMetadata6 } from "@nestjs/common";
292
+ function RequireRole(...roles) {
293
+ return SetMetadata6(RBAC_ROLES_METADATA, {
294
+ values: roles,
295
+ mode: "all"
296
+ });
297
+ }
298
+ export {
299
+ RBAC_ENGINE,
300
+ RBAC_IDENTITY_RESOLVER,
301
+ RBAC_OPTIONS,
302
+ RBAC_PERMISSIONS_METADATA,
303
+ RBAC_POLICIES_METADATA,
304
+ RBAC_ROLES_METADATA,
305
+ RbacGuard,
306
+ RbacModule,
307
+ RequireAnyPermission,
308
+ RequireAnyPolicy,
309
+ RequireAnyRole,
310
+ RequirePermission,
311
+ RequirePolicy,
312
+ RequireRole,
313
+ createDefaultRbacContext,
314
+ createIdentityResolver,
315
+ getByPath
316
+ };
317
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rbac.constants.ts","../src/rbac-context.ts","../src/rbac.guard.ts","../src/rbac.module.ts","../src/deny-all-access-repository.ts","../src/decorators/require-any-permission.decorator.ts","../src/decorators/require-any-policy.decorator.ts","../src/decorators/require-any-role.decorator.ts","../src/decorators/require-permission.decorator.ts","../src/decorators/require-policy.decorator.ts","../src/decorators/require-role.decorator.ts"],"sourcesContent":["export const RBAC_ENGINE = Symbol('RBAC_ENGINE');\nexport const RBAC_OPTIONS = Symbol('RBAC_OPTIONS');\nexport const RBAC_IDENTITY_RESOLVER = Symbol('RBAC_IDENTITY_RESOLVER');\n\nexport const RBAC_PERMISSIONS_METADATA = 'rbac:permissions';\nexport const RBAC_ROLES_METADATA = 'rbac:roles';\nexport const RBAC_POLICIES_METADATA = 'rbac:policies';\n","import type { RbacAuthorizationContext, RbacPrincipal } from '@rbacbee-lib/core';\nimport type { RbacHttpRequest, RbacIdentityOptions, RbacIdentityResolver } from './rbac.types';\n\nexport function createIdentityResolver(identity?: RbacIdentityOptions): RbacIdentityResolver {\n if (identity?.resolveUser !== undefined) {\n return identity.resolveUser;\n }\n\n return ({ request }) => {\n const userIdPath = identity?.userIdPath ?? defaultUserIdPath(identity?.strategy);\n const tenantIdPath = identity?.tenantIdPath ?? defaultTenantIdPath(identity?.strategy);\n const userId = firstString(getByPath(request, userIdPath), getByPath(request, 'user.id'));\n\n if (userId === undefined) {\n return null;\n }\n\n const tenantId = firstString(\n getByPath(request, tenantIdPath),\n getByPath(request, 'user.tenantId')\n );\n const principal: RbacPrincipal = { userId };\n\n if (tenantId !== undefined) {\n return { ...principal, tenantId };\n }\n\n return principal;\n };\n}\n\nexport function createDefaultRbacContext(\n request: RbacHttpRequest,\n principal: RbacPrincipal\n): RbacAuthorizationContext {\n const resourceId = firstString(request.params?.id, request.params?.resourceId);\n const resourceType = firstString(request.headers?.['x-resource-type']);\n const context: RbacAuthorizationContext = {};\n\n if (principal.tenantId !== undefined) {\n Object.assign(context, { tenantId: principal.tenantId });\n }\n\n if (resourceId !== undefined) {\n Object.assign(context, { resourceId });\n }\n\n if (resourceType !== undefined) {\n Object.assign(context, { resourceType });\n }\n\n return context;\n}\n\nexport function getByPath(source: unknown, path: string): unknown {\n const segments = path.split('.').filter(Boolean);\n let current: unknown = source;\n\n for (const segment of segments) {\n if (!isRecord(current)) {\n return undefined;\n }\n\n current = current[segment];\n }\n\n return current;\n}\n\nfunction defaultUserIdPath(strategy?: RbacIdentityOptions['strategy']): string {\n if (strategy === 'cookie') {\n return 'cookies.userId';\n }\n\n return 'user.sub';\n}\n\nfunction defaultTenantIdPath(strategy?: RbacIdentityOptions['strategy']): string {\n if (strategy === 'cookie') {\n return 'cookies.tenantId';\n }\n\n return 'user.tenantId';\n}\n\nfunction firstString(...values: unknown[]): string | undefined {\n for (const value of values) {\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim();\n }\n\n if (typeof value === 'number') {\n return String(value);\n }\n }\n\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n","import {\n CanActivate,\n ExecutionContext,\n ForbiddenException,\n Inject,\n Injectable,\n UnauthorizedException\n} from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport type { AuthorizationResult, RbacEngine } from '@rbacbee-lib/core';\nimport {\n RBAC_ENGINE,\n RBAC_IDENTITY_RESOLVER,\n RBAC_OPTIONS,\n RBAC_PERMISSIONS_METADATA,\n RBAC_POLICIES_METADATA,\n RBAC_ROLES_METADATA\n} from './rbac.constants';\nimport { createDefaultRbacContext } from './rbac-context';\nimport type {\n RbacHttpRequest,\n RbacIdentityResolver,\n RbacNestModuleOptions,\n RbacRequirementMetadata\n} from './rbac.types';\n\n@Injectable()\nexport class RbacGuard implements CanActivate {\n public constructor(\n private readonly reflector: Reflector,\n @Inject(RBAC_ENGINE) private readonly engine: RbacEngine,\n @Inject(RBAC_IDENTITY_RESOLVER) private readonly resolveIdentity: RbacIdentityResolver,\n @Inject(RBAC_OPTIONS) private readonly options: RbacNestModuleOptions\n ) {}\n\n public async canActivate(context: ExecutionContext): Promise<boolean> {\n const permissionRequirements = this.getRequirements(RBAC_PERMISSIONS_METADATA, context);\n const roleRequirements = this.getRequirements(RBAC_ROLES_METADATA, context);\n const policyRequirements = this.getRequirements(RBAC_POLICIES_METADATA, context);\n\n if (\n permissionRequirements.length === 0 &&\n roleRequirements.length === 0 &&\n policyRequirements.length === 0\n ) {\n return true;\n }\n\n const request = context.switchToHttp().getRequest<RbacHttpRequest>();\n const principal = await this.resolveIdentity({ context, request });\n\n if (principal === null) {\n throw new UnauthorizedException('RBAC principal could not be resolved');\n }\n\n const rbacContext =\n this.options.context === undefined\n ? createDefaultRbacContext(request, principal)\n : await this.options.context({ context, request, principal });\n\n await this.assertRequirements(permissionRequirements, (permission) =>\n this.engine.can(principal, permission, rbacContext)\n );\n await this.assertRequirements(roleRequirements, (role) =>\n this.engine.hasRole(principal, role, rbacContext)\n );\n await this.assertRequirements(policyRequirements, (policy) =>\n this.engine.evaluatePolicy(policy, principal, rbacContext)\n );\n\n return true;\n }\n\n private getRequirements(\n metadataKey: string,\n context: ExecutionContext\n ): RbacRequirementMetadata[] {\n const controllerRequirement = this.reflector.get<RbacRequirementMetadata>(\n metadataKey,\n context.getClass()\n );\n const handlerRequirement = this.reflector.get<RbacRequirementMetadata>(\n metadataKey,\n context.getHandler()\n );\n\n return [controllerRequirement, handlerRequirement].filter(isRequirement);\n }\n\n private async assertRequirements(\n requirements: readonly RbacRequirementMetadata[],\n check: (value: string) => Promise<AuthorizationResult>\n ): Promise<void> {\n for (const requirement of requirements) {\n const results = await Promise.all(requirement.values.map((value) => check(value)));\n const allowed =\n requirement.mode === 'all'\n ? results.every((result) => result.decision === 'allow')\n : results.some((result) => result.decision === 'allow');\n\n if (!allowed) {\n throw new ForbiddenException('RBAC access denied');\n }\n }\n }\n}\n\nfunction isRequirement(\n value: RbacRequirementMetadata | undefined\n): value is RbacRequirementMetadata {\n return value !== undefined && value.values.length > 0;\n}\n","import { DynamicModule, Module, Provider } from '@nestjs/common';\nimport { createRbacEngine } from '@rbacbee-lib/core';\nimport { RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RBAC_OPTIONS } from './rbac.constants';\nimport { createIdentityResolver } from './rbac-context';\nimport { RbacGuard } from './rbac.guard';\nimport type { RbacNestModuleAsyncOptions, RbacNestModuleOptions } from './rbac.types';\nimport { DenyAllAccessRepository } from './deny-all-access-repository';\n\n@Module({})\nexport class RbacModule {\n public static forRoot(options: RbacNestModuleOptions): DynamicModule {\n return {\n module: RbacModule,\n providers: [\n { provide: RBAC_OPTIONS, useValue: options },\n createIdentityResolverProvider(),\n createEngineProvider(),\n RbacGuard\n ],\n exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]\n };\n }\n\n public static forRootAsync(options: RbacNestModuleAsyncOptions): DynamicModule {\n return {\n module: RbacModule,\n imports: options.imports,\n providers: [\n {\n provide: RBAC_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject ?? []\n },\n createIdentityResolverProvider(),\n createEngineProvider(),\n RbacGuard\n ],\n exports: [RBAC_ENGINE, RBAC_IDENTITY_RESOLVER, RbacGuard]\n };\n }\n}\n\nfunction createIdentityResolverProvider(): Provider {\n return {\n provide: RBAC_IDENTITY_RESOLVER,\n inject: [RBAC_OPTIONS],\n useFactory: (options: RbacNestModuleOptions) => createIdentityResolver(options.identity)\n };\n}\n\nfunction createEngineProvider(): Provider {\n return {\n provide: RBAC_ENGINE,\n inject: [RBAC_OPTIONS],\n useFactory: (options: RbacNestModuleOptions) => {\n if (options.engine !== undefined) {\n return options.engine;\n }\n\n return createRbacEngine({\n accessRepository: options.accessRepository ?? new DenyAllAccessRepository(),\n audit: options.audit,\n cache: options.cache,\n policies: options.policies,\n cacheTtlMs: options.cacheTtlMs\n });\n }\n };\n}\n","import type { AccessProfile, AccessRepository } from '@rbacbee-lib/core';\n\nexport class DenyAllAccessRepository implements AccessRepository {\n public async getAccessProfile(): Promise<AccessProfile | null> {\n return null;\n }\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_PERMISSIONS_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireAnyPermission(...permissions: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_PERMISSIONS_METADATA, {\n values: permissions,\n mode: 'any'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_POLICIES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireAnyPolicy(...policies: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_POLICIES_METADATA, {\n values: policies,\n mode: 'any'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_ROLES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireAnyRole(...roles: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_ROLES_METADATA, {\n values: roles,\n mode: 'any'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_PERMISSIONS_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequirePermission(...permissions: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_PERMISSIONS_METADATA, {\n values: permissions,\n mode: 'all'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_POLICIES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequirePolicy(...policies: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_POLICIES_METADATA, {\n values: policies,\n mode: 'all'\n } satisfies RbacRequirementMetadata);\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { RBAC_ROLES_METADATA } from '../rbac.constants';\nimport type { RbacRequirementMetadata } from '../rbac.types';\n\nexport function RequireRole(...roles: string[]): MethodDecorator & ClassDecorator {\n return SetMetadata(RBAC_ROLES_METADATA, {\n values: roles,\n mode: 'all'\n } satisfies RbacRequirementMetadata);\n}\n"],"mappings":"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","names":["SetMetadata","SetMetadata","SetMetadata","SetMetadata","SetMetadata","SetMetadata","SetMetadata","SetMetadata","SetMetadata","SetMetadata"]}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@rbacbee-lib/nest",
3
+ "version": "0.1.0",
4
+ "description": "NestJS adapter for @rbacbee-lib/core.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsup src/index.ts --format esm,cjs --dts --sourcemap --clean --external @nestjs/common --external @nestjs/core --external reflect-metadata --external rxjs --external @rbacbee-lib/core",
24
+ "dev": "tsup src/index.ts --format esm,cjs --dts --sourcemap --watch --external @nestjs/common --external @nestjs/core --external reflect-metadata --external rxjs --external @rbacbee-lib/core",
25
+ "test": "vitest run --passWithNoTests",
26
+ "test:watch": "vitest",
27
+ "lint": "eslint src --max-warnings=0",
28
+ "typecheck": "tsc --noEmit",
29
+ "clean": "rimraf dist coverage"
30
+ },
31
+ "dependencies": {
32
+ "@rbacbee-lib/core": "workspace:^"
33
+ },
34
+ "peerDependencies": {
35
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
36
+ "@nestjs/core": "^10.0.0 || ^11.0.0",
37
+ "reflect-metadata": "^0.1.13 || ^0.2.0",
38
+ "rxjs": "^7.8.0"
39
+ },
40
+ "devDependencies": {
41
+ "@nestjs/common": "^11.1.3",
42
+ "@nestjs/core": "^11.1.3",
43
+ "reflect-metadata": "^0.2.2",
44
+ "rxjs": "^7.8.2"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ }
49
+ }