@dudousxd/nestjs-authz 0.8.1 → 0.9.1
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 +115 -0
- package/README.md +279 -0
- package/dist/authz.guard.d.ts +48 -0
- package/dist/authz.guard.d.ts.map +1 -0
- package/dist/authz.guard.js +144 -0
- package/dist/authz.guard.js.map +1 -0
- package/dist/can-endpoint.controller.d.ts +0 -19
- package/dist/can-endpoint.controller.d.ts.map +1 -1
- package/dist/can-endpoint.controller.js +18 -9
- package/dist/can-endpoint.controller.js.map +1 -1
- package/dist/decision-provider.d.ts +25 -16
- package/dist/decision-provider.d.ts.map +1 -1
- package/dist/decision-provider.js +11 -1
- package/dist/decision-provider.js.map +1 -1
- package/dist/decisions.d.ts +24 -0
- package/dist/decisions.d.ts.map +1 -0
- package/dist/decisions.js +87 -0
- package/dist/decisions.js.map +1 -0
- package/dist/decorator/roles.decorator.d.ts +6 -12
- package/dist/decorator/roles.decorator.d.ts.map +1 -1
- package/dist/decorator/roles.decorator.js +13 -15
- package/dist/decorator/roles.decorator.js.map +1 -1
- package/dist/diagnostics.d.ts +15 -5
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +3 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/errors/exceptions.d.ts +0 -8
- package/dist/errors/exceptions.d.ts.map +1 -1
- package/dist/errors/exceptions.js +0 -14
- package/dist/errors/exceptions.js.map +1 -1
- package/dist/gate.d.ts +83 -218
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +209 -611
- package/dist/gate.js.map +1 -1
- package/dist/helpers.d.ts +46 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +89 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +28 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -13
- package/dist/index.js.map +1 -1
- package/dist/links.d.ts +39 -0
- package/dist/links.d.ts.map +1 -0
- package/dist/links.js +57 -0
- package/dist/links.js.map +1 -0
- package/dist/module.d.ts +23 -22
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +129 -158
- package/dist/module.js.map +1 -1
- package/dist/official.d.ts +39 -0
- package/dist/official.d.ts.map +1 -0
- package/dist/official.js +44 -0
- package/dist/official.js.map +1 -0
- package/dist/policies/authz-policy.d.ts +42 -0
- package/dist/policies/authz-policy.d.ts.map +1 -0
- package/dist/policies/authz-policy.js +80 -0
- package/dist/policies/authz-policy.js.map +1 -0
- package/dist/policies/gate.policy.d.ts +18 -0
- package/dist/policies/gate.policy.d.ts.map +1 -0
- package/dist/policies/gate.policy.js +37 -0
- package/dist/policies/gate.policy.js.map +1 -0
- package/dist/policies/index.d.ts +5 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +5 -0
- package/dist/policies/index.js.map +1 -0
- package/dist/policies/permission.policy.d.ts +27 -0
- package/dist/policies/permission.policy.d.ts.map +1 -0
- package/dist/policies/permission.policy.js +61 -0
- package/dist/policies/permission.policy.js.map +1 -0
- package/dist/policies/role.policy.d.ts +27 -0
- package/dist/policies/role.policy.d.ts.map +1 -0
- package/dist/policies/role.policy.js +51 -0
- package/dist/policies/role.policy.js.map +1 -0
- package/dist/policy-index.d.ts +51 -0
- package/dist/policy-index.d.ts.map +1 -0
- package/dist/policy-index.js +135 -0
- package/dist/policy-index.js.map +1 -0
- package/dist/rbac.d.ts +92 -0
- package/dist/rbac.d.ts.map +1 -0
- package/dist/rbac.js +293 -0
- package/dist/rbac.js.map +1 -0
- package/dist/resource-resolver.d.ts +15 -17
- package/dist/resource-resolver.d.ts.map +1 -1
- package/dist/resource-resolver.js +8 -8
- package/dist/resource-resolver.js.map +1 -1
- package/dist/runtime.d.ts +31 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +40 -0
- package/dist/runtime.js.map +1 -0
- package/dist/tokens.d.ts +4 -8
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +4 -8
- package/dist/tokens.js.map +1 -1
- package/dist/types.d.ts +52 -171
- package/dist/types.d.ts.map +1 -1
- package/package.json +20 -11
- package/skills/authz-enforcement/SKILL.md +67 -135
- package/skills/authz-policies/SKILL.md +43 -117
- package/skills/authz-query-scopes/SKILL.md +16 -9
- package/skills/authz-rbac-seams/SKILL.md +29 -12
- package/skills/authz-setup/SKILL.md +45 -106
- package/dist/decorator/can.decorator.d.ts +0 -29
- package/dist/decorator/can.decorator.d.ts.map +0 -1
- package/dist/decorator/can.decorator.js +0 -23
- package/dist/decorator/can.decorator.js.map +0 -1
- package/dist/decorator/policy.decorator.d.ts +0 -18
- package/dist/decorator/policy.decorator.d.ts.map +0 -1
- package/dist/decorator/policy.decorator.js +0 -28
- package/dist/decorator/policy.decorator.js.map +0 -1
- package/dist/guard/can.guard.d.ts +0 -31
- package/dist/guard/can.guard.d.ts.map +0 -1
- package/dist/guard/can.guard.js +0 -92
- package/dist/guard/can.guard.js.map +0 -1
- package/dist/guard/roles.guard.d.ts +0 -21
- package/dist/guard/roles.guard.d.ts.map +0 -1
- package/dist/guard/roles.guard.js +0 -50
- package/dist/guard/roles.guard.js.map +0 -1
- package/dist/policy-registry.d.ts +0 -46
- package/dist/policy-registry.d.ts.map +0 -1
- package/dist/policy-registry.js +0 -101
- package/dist/policy-registry.js.map +0 -1
package/dist/rbac.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { InjectCapability } from '@dudousxd/nestjs-diagnostics/nestjs';
|
|
14
|
+
import { Inject, Injectable, Optional } from '@nestjs/common';
|
|
15
|
+
import { ModuleRef } from '@nestjs/core';
|
|
16
|
+
import { PermissionCache } from './permission-cache.js';
|
|
17
|
+
import { permissionSatisfied } from './permission-matcher.js';
|
|
18
|
+
import { defaultRoleResolver } from './role-provider.js';
|
|
19
|
+
import { AUTHZ_MODULE_OPTIONS, CONTEXT_ACCESSOR, DECISION_PROVIDER, PERMISSION_PROVIDER, ROLE_PROVIDER, } from './tokens.js';
|
|
20
|
+
/**
|
|
21
|
+
* Key of the per-request {@link PermissionCache} on the nestjs-context store. `Symbol.for`
|
|
22
|
+
* so every copy of this module shares it.
|
|
23
|
+
*/
|
|
24
|
+
const REQUEST_PERMISSION_CACHE = Symbol.for('@dudousxd/nestjs-authz:request-permission-cache');
|
|
25
|
+
/** Key under which the per-request `resolveUser` results are stashed on the context store. */
|
|
26
|
+
const REQUEST_USERS = Symbol.for('@dudousxd/nestjs-authz:request-users');
|
|
27
|
+
/**
|
|
28
|
+
* Roles and permissions of a user, from the persisted RBAC seams (`ROLE_PROVIDER`,
|
|
29
|
+
* `PERMISSION_PROVIDER`, registered by the TypeORM / MikroORM / Prisma / Drizzle adapters)
|
|
30
|
+
* and from the user object itself (`user.roles` / `user.role`); the optional external
|
|
31
|
+
* decision point (`DECISION_PROVIDER`); and the ambient user for `Gate` calls made without
|
|
32
|
+
* one. Shared by `RolePolicy`, `PermissionPolicy`, `AuthzPolicy` and the `Gate`.
|
|
33
|
+
*
|
|
34
|
+
* Within one request (a nestjs-context store), a user's permissions and provider roles
|
|
35
|
+
* are fetched once, however many checks run, in guards and in handlers alike.
|
|
36
|
+
*/
|
|
37
|
+
let AuthzRbac = class AuthzRbac {
|
|
38
|
+
context;
|
|
39
|
+
moduleRef;
|
|
40
|
+
permissionProvider;
|
|
41
|
+
roleProvider;
|
|
42
|
+
decisionProvider;
|
|
43
|
+
roleResolver;
|
|
44
|
+
resolveUser;
|
|
45
|
+
lookups = new Map();
|
|
46
|
+
authentication;
|
|
47
|
+
constructor(options, context, moduleRef, permissionProvider, roleProvider, decisionProvider) {
|
|
48
|
+
this.context = context;
|
|
49
|
+
this.moduleRef = moduleRef;
|
|
50
|
+
this.permissionProvider = permissionProvider;
|
|
51
|
+
this.roleProvider = roleProvider;
|
|
52
|
+
this.decisionProvider = decisionProvider;
|
|
53
|
+
this.roleResolver = options?.resolveRoles ?? defaultRoleResolver;
|
|
54
|
+
this.resolveUser = options?.resolveUser;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Finds `@nestjs/authentication`'s `AuthenticationContext` when that optional peer is
|
|
58
|
+
* installed and its module is imported. The class is the DI token, so the package is
|
|
59
|
+
* loaded only here, and its absence is not an error.
|
|
60
|
+
*/
|
|
61
|
+
async onModuleInit() {
|
|
62
|
+
if (!this.moduleRef || this.authentication)
|
|
63
|
+
return;
|
|
64
|
+
let token;
|
|
65
|
+
try {
|
|
66
|
+
const specifier = '@nestjs/authentication';
|
|
67
|
+
token = (await import(specifier))
|
|
68
|
+
.AuthenticationContext;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (typeof token !== 'function')
|
|
74
|
+
return;
|
|
75
|
+
try {
|
|
76
|
+
this.authentication = this.moduleRef.get(token, {
|
|
77
|
+
strict: false,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
this.authentication = undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A provider registered by any module: the injected one, else a non-strict lookup,
|
|
86
|
+
* memoized, so a global RBAC module or a root-level accessor is found too.
|
|
87
|
+
*/
|
|
88
|
+
lookup(token, injected) {
|
|
89
|
+
if (injected)
|
|
90
|
+
return injected;
|
|
91
|
+
const memo = this.lookups.get(token);
|
|
92
|
+
if (memo)
|
|
93
|
+
return memo.value;
|
|
94
|
+
let value;
|
|
95
|
+
try {
|
|
96
|
+
value = this.moduleRef?.get(token, { strict: false });
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
value = undefined;
|
|
100
|
+
}
|
|
101
|
+
this.lookups.set(token, { value });
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
/** @internal The nestjs-context accessor, when one is registered. */
|
|
105
|
+
contextAccessor() {
|
|
106
|
+
return this.lookup(CONTEXT_ACCESSOR, this.context);
|
|
107
|
+
}
|
|
108
|
+
/** The persisted permission seam, when an RBAC adapter registered one. */
|
|
109
|
+
permissions() {
|
|
110
|
+
return this.lookup(PERMISSION_PROVIDER, this.permissionProvider);
|
|
111
|
+
}
|
|
112
|
+
/** The persisted role seam, when an RBAC adapter registered one. */
|
|
113
|
+
roles() {
|
|
114
|
+
return this.lookup(ROLE_PROVIDER, this.roleProvider);
|
|
115
|
+
}
|
|
116
|
+
/** The external decision point (Cerbos, OPA, …), when one is registered. */
|
|
117
|
+
decisions() {
|
|
118
|
+
return this.lookup(DECISION_PROVIDER, this.decisionProvider);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The user for a `Gate` call made without one:
|
|
122
|
+
*
|
|
123
|
+
* 1. `@nestjs/authentication`'s `AuthenticationContext.user`, when that optional peer is
|
|
124
|
+
* installed and its scope is active (a call it handles, or `AuthenticationContext.run()`):
|
|
125
|
+
* its answer is final, so a `null` there is a guest;
|
|
126
|
+
* 2. else, with no authentication scope at all, nestjs-context's user ref, hydrated by
|
|
127
|
+
* `resolveUser` when configured (once per `type:id` per request);
|
|
128
|
+
* 3. else `null` (a guest).
|
|
129
|
+
*/
|
|
130
|
+
async currentUser() {
|
|
131
|
+
const authenticated = this.authenticatedUser();
|
|
132
|
+
if (authenticated !== undefined)
|
|
133
|
+
return authenticated;
|
|
134
|
+
const context = this.contextAccessor();
|
|
135
|
+
if (!context)
|
|
136
|
+
return null;
|
|
137
|
+
const ref = context.userRef();
|
|
138
|
+
if (ref === undefined)
|
|
139
|
+
return null;
|
|
140
|
+
const resolveUser = this.resolveUser;
|
|
141
|
+
if (!resolveUser)
|
|
142
|
+
return ref;
|
|
143
|
+
const hydrate = async () => (await resolveUser(ref)) ?? null;
|
|
144
|
+
const store = this.requestStore();
|
|
145
|
+
if (!store)
|
|
146
|
+
return hydrate();
|
|
147
|
+
let users = store[REQUEST_USERS];
|
|
148
|
+
if (!(users instanceof Map)) {
|
|
149
|
+
users = new Map();
|
|
150
|
+
store[REQUEST_USERS] = users;
|
|
151
|
+
}
|
|
152
|
+
const key = `${ref.type}:${typeof ref.id}:${ref.id}`;
|
|
153
|
+
const cached = users.get(key);
|
|
154
|
+
if (cached)
|
|
155
|
+
return cached;
|
|
156
|
+
const pending = hydrate();
|
|
157
|
+
users.set(key, pending);
|
|
158
|
+
pending.catch(() => users.delete(key));
|
|
159
|
+
return pending;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* `AuthenticationContext.user` (`null` for an anonymous call) when its scope is active;
|
|
163
|
+
* `undefined` without the package or outside its scope. A version that hides the scope is
|
|
164
|
+
* read as before: a user is an answer, `null` is not.
|
|
165
|
+
*/
|
|
166
|
+
authenticatedUser() {
|
|
167
|
+
const authentication = this.authentication;
|
|
168
|
+
if (!authentication)
|
|
169
|
+
return undefined;
|
|
170
|
+
try {
|
|
171
|
+
const scope = authentication.scope;
|
|
172
|
+
if (scope && typeof scope === 'object' && 'current' in scope) {
|
|
173
|
+
return scope.current === undefined ? undefined : (authentication.user ?? null);
|
|
174
|
+
}
|
|
175
|
+
return authentication.user ?? undefined;
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** The nestjs-context store for the current request, or `undefined` when there is none. */
|
|
182
|
+
requestStore() {
|
|
183
|
+
const context = this.contextAccessor();
|
|
184
|
+
if (!context || typeof context.get !== 'function')
|
|
185
|
+
return undefined;
|
|
186
|
+
let store;
|
|
187
|
+
try {
|
|
188
|
+
store = context.get();
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
store = undefined;
|
|
192
|
+
}
|
|
193
|
+
return store;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The per-request {@link PermissionCache} on the nestjs-context store, so every check
|
|
197
|
+
* in one request shares a single `getPermissions` and `getRoles` fetch per user.
|
|
198
|
+
* `undefined` without a store.
|
|
199
|
+
*/
|
|
200
|
+
requestCache() {
|
|
201
|
+
const store = this.requestStore();
|
|
202
|
+
if (!store)
|
|
203
|
+
return undefined;
|
|
204
|
+
const existing = store[REQUEST_PERMISSION_CACHE];
|
|
205
|
+
if (existing instanceof PermissionCache)
|
|
206
|
+
return existing;
|
|
207
|
+
const cache = new PermissionCache();
|
|
208
|
+
store[REQUEST_PERMISSION_CACHE] = cache;
|
|
209
|
+
return cache;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The user's role names: the role resolver's (the user object) and the role provider's,
|
|
213
|
+
* the latter fetched through `cache` (the request's, by default).
|
|
214
|
+
*/
|
|
215
|
+
async rolesOf(user, cache = this.requestCache()) {
|
|
216
|
+
const out = new Set();
|
|
217
|
+
if (user == null)
|
|
218
|
+
return out;
|
|
219
|
+
const fromResolver = await this.roleResolver(user);
|
|
220
|
+
if (Array.isArray(fromResolver)) {
|
|
221
|
+
for (const r of fromResolver)
|
|
222
|
+
if (typeof r === 'string')
|
|
223
|
+
out.add(r);
|
|
224
|
+
}
|
|
225
|
+
const provider = this.roles();
|
|
226
|
+
if (provider) {
|
|
227
|
+
const fromProvider = await (cache ? cache.getRoles(provider, user) : provider.getRoles(user));
|
|
228
|
+
if (Array.isArray(fromProvider)) {
|
|
229
|
+
for (const r of fromProvider)
|
|
230
|
+
if (typeof r === 'string')
|
|
231
|
+
out.add(r);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
/** True when the user holds any of `roles`. A guest holds none. */
|
|
237
|
+
async hasAnyRole(user, roles, cache) {
|
|
238
|
+
if (user == null || roles.length === 0)
|
|
239
|
+
return false;
|
|
240
|
+
const held = await this.rolesOf(user, cache ?? this.requestCache());
|
|
241
|
+
return roles.some((r) => held.has(r));
|
|
242
|
+
}
|
|
243
|
+
/** True when the user holds every one of `roles`. */
|
|
244
|
+
async hasAllRoles(user, roles) {
|
|
245
|
+
if (user == null || roles.length === 0)
|
|
246
|
+
return false;
|
|
247
|
+
const held = await this.rolesOf(user);
|
|
248
|
+
return roles.every((r) => held.has(r));
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* True when the permission seam grants `permission` to `user`. With `getPermissions`,
|
|
252
|
+
* wildcard grants apply (`posts.*` satisfies `posts.update`, `*` anything), fetched
|
|
253
|
+
* once per `cache` (the request's, by default). A set the provider marks
|
|
254
|
+
* `exhaustivePermissions` answers on its own; otherwise a miss still asks the
|
|
255
|
+
* exact-match `hasPermission`. A guest, or no seam, is never granted.
|
|
256
|
+
*/
|
|
257
|
+
async grants(user, permission, resource, cache = this.requestCache()) {
|
|
258
|
+
if (user == null)
|
|
259
|
+
return false;
|
|
260
|
+
const provider = this.permissions();
|
|
261
|
+
if (!provider)
|
|
262
|
+
return false;
|
|
263
|
+
if (typeof provider.getPermissions === 'function') {
|
|
264
|
+
const satisfied = cache
|
|
265
|
+
? await cache.satisfies(provider, user, permission)
|
|
266
|
+
: await (async () => {
|
|
267
|
+
const granted = await provider.getPermissions?.(user);
|
|
268
|
+
return granted == null ? undefined : permissionSatisfied(granted, permission);
|
|
269
|
+
})();
|
|
270
|
+
if (satisfied === true)
|
|
271
|
+
return true;
|
|
272
|
+
if (satisfied === false && provider.exhaustivePermissions === true)
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
return (await provider.hasPermission(user, permission, resource)) === true;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
AuthzRbac = __decorate([
|
|
279
|
+
Injectable(),
|
|
280
|
+
__param(0, Optional()),
|
|
281
|
+
__param(0, Inject(AUTHZ_MODULE_OPTIONS)),
|
|
282
|
+
__param(1, InjectCapability('context', 'accessor')),
|
|
283
|
+
__param(2, Optional()),
|
|
284
|
+
__param(3, Optional()),
|
|
285
|
+
__param(3, Inject(PERMISSION_PROVIDER)),
|
|
286
|
+
__param(4, Optional()),
|
|
287
|
+
__param(4, Inject(ROLE_PROVIDER)),
|
|
288
|
+
__param(5, Optional()),
|
|
289
|
+
__param(5, Inject(DECISION_PROVIDER)),
|
|
290
|
+
__metadata("design:paramtypes", [Object, Object, ModuleRef, Object, Object, Object])
|
|
291
|
+
], AuthzRbac);
|
|
292
|
+
export { AuthzRbac };
|
|
293
|
+
//# sourceMappingURL=rbac.js.map
|
package/dist/rbac.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rbac.js","sourceRoot":"","sources":["../src/rbac.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import type { ExecutionContext, Type } from '@nestjs/common';
|
|
2
|
+
/** Per-call hints `byId(Resource, { param })` passes to the resolver. */
|
|
3
|
+
export interface ResourceResolveHints {
|
|
4
|
+
/** The route param holding the id, when `byId` named one. */
|
|
5
|
+
param?: string;
|
|
6
|
+
}
|
|
2
7
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Class-level abilities (no resource class on `@Can`) never call the resolver.
|
|
8
|
+
* Loads the resource a `byId(Resource)` argument resolver hands to the policy
|
|
9
|
+
* (`@Can(PostPolicy, 'update', byId(Post))`). Register one, typically ORM-backed, with
|
|
10
|
+
* `AuthzModule.forRoot({ resourceResolver })`. Return `undefined` for "not found":
|
|
11
|
+
* `byId` then refuses the call with a 403 before the policy runs.
|
|
9
12
|
*/
|
|
10
13
|
export interface ResourceResolver {
|
|
11
|
-
|
|
12
|
-
* Load the resource instance for `resource` in the given request context.
|
|
13
|
-
* Return `undefined` to signal "not found" — the guard treats a missing
|
|
14
|
-
* resource as a denial.
|
|
15
|
-
*/
|
|
16
|
-
resolve(resource: Type<unknown>, ctx: ExecutionContext): Promise<object | undefined> | object | undefined;
|
|
14
|
+
resolve(resource: Type<unknown>, ctx: ExecutionContext, hints?: ResourceResolveHints): Promise<object | undefined> | object | undefined;
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
|
-
* Default resolver: reads the route `:id` param and produces a lightweight
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
17
|
+
* Default resolver: reads the route `:id` param and produces a lightweight `{ id }`
|
|
18
|
+
* object whose prototype is the resource class's, enough for ownership checks on
|
|
19
|
+
* `resource.id` without an ORM. Register your own {@link ResourceResolver} to load
|
|
20
|
+
* real entities.
|
|
23
21
|
*/
|
|
24
22
|
export declare class IdParamResourceResolver implements ResourceResolver {
|
|
25
23
|
private readonly param;
|
|
26
24
|
constructor(param?: string);
|
|
27
|
-
resolve(resource: Type<unknown>, ctx: ExecutionContext): object | undefined;
|
|
25
|
+
resolve(resource: Type<unknown>, ctx: ExecutionContext, hints?: ResourceResolveHints): object | undefined;
|
|
28
26
|
}
|
|
29
27
|
//# sourceMappingURL=resource-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-resolver.d.ts","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7D
|
|
1
|
+
{"version":3,"file":"resource-resolver.d.ts","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7D,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CACL,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,EACvB,GAAG,EAAE,gBAAgB,EACrB,KAAK,CAAC,EAAE,oBAAoB,GAC3B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;CACrD;AAED;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,gBAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,GAAE,MAAa;IAEjD,OAAO,CACL,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,EACvB,GAAG,EAAE,gBAAgB,EACrB,KAAK,CAAC,EAAE,oBAAoB,GAC3B,MAAM,GAAG,SAAS;CAStB"}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default resolver: reads the route `:id` param and produces a lightweight
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Default resolver: reads the route `:id` param and produces a lightweight `{ id }`
|
|
3
|
+
* object whose prototype is the resource class's, enough for ownership checks on
|
|
4
|
+
* `resource.id` without an ORM. Register your own {@link ResourceResolver} to load
|
|
5
|
+
* real entities.
|
|
6
6
|
*/
|
|
7
7
|
export class IdParamResourceResolver {
|
|
8
8
|
param;
|
|
9
9
|
constructor(param = 'id') {
|
|
10
10
|
this.param = param;
|
|
11
11
|
}
|
|
12
|
-
resolve(resource, ctx) {
|
|
12
|
+
resolve(resource, ctx, hints) {
|
|
13
|
+
if (ctx.getType() !== 'http')
|
|
14
|
+
return undefined;
|
|
13
15
|
const req = ctx.switchToHttp().getRequest();
|
|
14
|
-
const id = req?.params?.[this.param];
|
|
16
|
+
const id = req?.params?.[hints?.param ?? this.param];
|
|
15
17
|
if (id === undefined)
|
|
16
18
|
return undefined;
|
|
17
|
-
// Construct a shaped instance so `instance.constructor === resource`, which
|
|
18
|
-
// is how PolicyRegistry maps an instance back to its policy.
|
|
19
19
|
const instance = Object.create(resource.prototype);
|
|
20
20
|
instance.id = id;
|
|
21
21
|
return instance;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-resolver.js","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IACL;IAA7B,YAA6B,QAAgB,IAAI;QAApB,UAAK,GAAL,KAAK,CAAe;IAAG,CAAC;IAErD,OAAO,
|
|
1
|
+
{"version":3,"file":"resource-resolver.js","sourceRoot":"","sources":["../src/resource-resolver.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IACL;IAA7B,YAA6B,QAAgB,IAAI;QAApB,UAAK,GAAL,KAAK,CAAe;IAAG,CAAC;IAErD,OAAO,CACL,QAAuB,EACvB,GAAqB,EACrB,KAA4B;QAE5B,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC;QAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAwC,CAAC;QAClF,MAAM,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAA4B,CAAC;QAC9E,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import type { DecisionProvider } from './decision-provider.js';
|
|
3
|
+
import { type ResourceResolver } from './resource-resolver.js';
|
|
4
|
+
import type { SuperAdminHook } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* What `@Can()` argument resolvers and policy base classes need from the app but
|
|
7
|
+
* cannot inject: the official resolvers run with only the `ExecutionContext`, and a
|
|
8
|
+
* policy base class cannot add constructor parameters to its subclasses. `AuthzModule`
|
|
9
|
+
* fills this in when it boots. One application per process is the expected case; with
|
|
10
|
+
* several, the last one to boot wins.
|
|
11
|
+
*/
|
|
12
|
+
interface AuthzRuntime {
|
|
13
|
+
resourceResolver: ResourceResolver;
|
|
14
|
+
superAdmin: SuperAdminHook | undefined;
|
|
15
|
+
/** The external decision point, looked up lazily (an adapter may register it late). */
|
|
16
|
+
decisionProvider: () => DecisionProvider | undefined;
|
|
17
|
+
getUser: (context: ExecutionContext) => unknown;
|
|
18
|
+
}
|
|
19
|
+
/** @internal Called by `AuthzModule` at boot, and by the testing helpers. */
|
|
20
|
+
export declare function configureAuthzRuntime(patch: Partial<AuthzRuntime>): void;
|
|
21
|
+
/** @internal Restore the defaults (tests). */
|
|
22
|
+
export declare function resetAuthzRuntime(): void;
|
|
23
|
+
/** @internal */
|
|
24
|
+
export declare function authzRuntime(): Readonly<AuthzRuntime>;
|
|
25
|
+
/**
|
|
26
|
+
* The user the official guard sees for this call: the `getUser` given to
|
|
27
|
+
* `AuthorizationModule.forRoot()`, else the official `defaultGetUser`. `null` for a guest.
|
|
28
|
+
*/
|
|
29
|
+
export declare function currentUserOf(context: ExecutionContext): Promise<unknown>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;GAMG;AACH,UAAU,YAAY;IACpB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,UAAU,EAAE,cAAc,GAAG,SAAS,CAAC;IACvC,uFAAuF;IACvF,gBAAgB,EAAE,MAAM,gBAAgB,GAAG,SAAS,CAAC;IACrD,OAAO,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC;CACjD;AAWD,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAKxE;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED,gBAAgB;AAChB,wBAAgB,YAAY,IAAI,QAAQ,CAAC,YAAY,CAAC,CAErD;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAG/E"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { defaultGetUser } from '@nestjs/authorization';
|
|
2
|
+
import { IdParamResourceResolver } from './resource-resolver.js';
|
|
3
|
+
const noDecisionProvider = () => undefined;
|
|
4
|
+
const runtime = {
|
|
5
|
+
resourceResolver: new IdParamResourceResolver(),
|
|
6
|
+
superAdmin: undefined,
|
|
7
|
+
decisionProvider: noDecisionProvider,
|
|
8
|
+
getUser: defaultGetUser,
|
|
9
|
+
};
|
|
10
|
+
/** @internal Called by `AuthzModule` at boot, and by the testing helpers. */
|
|
11
|
+
export function configureAuthzRuntime(patch) {
|
|
12
|
+
if (patch.resourceResolver)
|
|
13
|
+
runtime.resourceResolver = patch.resourceResolver;
|
|
14
|
+
if ('superAdmin' in patch)
|
|
15
|
+
runtime.superAdmin = patch.superAdmin;
|
|
16
|
+
if (patch.decisionProvider)
|
|
17
|
+
runtime.decisionProvider = patch.decisionProvider;
|
|
18
|
+
if (patch.getUser)
|
|
19
|
+
runtime.getUser = patch.getUser;
|
|
20
|
+
}
|
|
21
|
+
/** @internal Restore the defaults (tests). */
|
|
22
|
+
export function resetAuthzRuntime() {
|
|
23
|
+
runtime.resourceResolver = new IdParamResourceResolver();
|
|
24
|
+
runtime.superAdmin = undefined;
|
|
25
|
+
runtime.decisionProvider = noDecisionProvider;
|
|
26
|
+
runtime.getUser = defaultGetUser;
|
|
27
|
+
}
|
|
28
|
+
/** @internal */
|
|
29
|
+
export function authzRuntime() {
|
|
30
|
+
return runtime;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The user the official guard sees for this call: the `getUser` given to
|
|
34
|
+
* `AuthorizationModule.forRoot()`, else the official `defaultGetUser`. `null` for a guest.
|
|
35
|
+
*/
|
|
36
|
+
export async function currentUserOf(context) {
|
|
37
|
+
const user = await runtime.getUser(context);
|
|
38
|
+
return user === undefined || user === false ? null : user;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,uBAAuB,EAAyB,MAAM,wBAAwB,CAAC;AAkBxF,MAAM,kBAAkB,GAAG,GAAiC,EAAE,CAAC,SAAS,CAAC;AAEzE,MAAM,OAAO,GAAiB;IAC5B,gBAAgB,EAAE,IAAI,uBAAuB,EAAE;IAC/C,UAAU,EAAE,SAAS;IACrB,gBAAgB,EAAE,kBAAkB;IACpC,OAAO,EAAE,cAAc;CACxB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CAAC,KAA4B;IAChE,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC9E,IAAI,YAAY,IAAI,KAAK;QAAE,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACjE,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC9E,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;AACrD,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CAAC,gBAAgB,GAAG,IAAI,uBAAuB,EAAE,CAAC;IACzD,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,gBAAgB,GAAG,kBAAkB,CAAC;IAC9C,OAAO,CAAC,OAAO,GAAG,cAAc,CAAC;AACnC,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAyB;IAC3D,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC"}
|
package/dist/tokens.d.ts
CHANGED
|
@@ -17,12 +17,8 @@ export declare const RESOURCE_RESOLVER: symbol;
|
|
|
17
17
|
* or empty, the endpoint behaves exactly as before (class-level / ad-hoc only).
|
|
18
18
|
*/
|
|
19
19
|
export declare const RESOURCE_HYDRATOR: symbol;
|
|
20
|
-
/** Metadata key
|
|
21
|
-
export
|
|
22
|
-
/** Metadata key for `@Can(ability, Resource?)` — stores the ability descriptor on a route. */
|
|
23
|
-
export declare const CAN_METADATA = "nestjs-authz:can";
|
|
24
|
-
/** Metadata key for `@Roles(...roles)` — stores the allowed role names on a route. */
|
|
25
|
-
export declare const ROLES_METADATA = "nestjs-authz:roles";
|
|
20
|
+
/** Metadata key of the `@PolicyFor(Resource)` link on a policy class. */
|
|
21
|
+
export { POLICY_RESOURCE_METADATA } from './links.js';
|
|
26
22
|
/**
|
|
27
23
|
* Cross-lib injection token for an optional {@link PermissionProvider} — the seam the
|
|
28
24
|
* RBAC adapter (`@dudousxd/nestjs-authz-typeorm`) registers so that a model-less,
|
|
@@ -31,8 +27,8 @@ export declare const ROLES_METADATA = "nestjs-authz:roles";
|
|
|
31
27
|
*
|
|
32
28
|
* `Symbol.for(key)` uses the global symbol registry so an RBAC package registering
|
|
33
29
|
* this same key resolves to the SAME symbol instance without importing core internals.
|
|
34
|
-
* The token is consulted with `@Optional()` — when absent,
|
|
35
|
-
*
|
|
30
|
+
* The token is consulted with `@Optional()` — when absent, an unknown string ability
|
|
31
|
+
* still throws.
|
|
36
32
|
*/
|
|
37
33
|
export declare const PERMISSION_PROVIDER: symbol;
|
|
38
34
|
/**
|
package/dist/tokens.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,QAAiC,CAAC;AAEnE,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E,
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,QAAiC,CAAC;AAEnE,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E,yEAAyE;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,QAA6C,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAE1E;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,QAAoC,CAAC"}
|
package/dist/tokens.js
CHANGED
|
@@ -18,12 +18,8 @@ export const RESOURCE_RESOLVER = capability('authz', 'resource-resolver');
|
|
|
18
18
|
* or empty, the endpoint behaves exactly as before (class-level / ad-hoc only).
|
|
19
19
|
*/
|
|
20
20
|
export const RESOURCE_HYDRATOR = capability('authz', 'resource-hydrator');
|
|
21
|
-
/** Metadata key
|
|
22
|
-
export
|
|
23
|
-
/** Metadata key for `@Can(ability, Resource?)` — stores the ability descriptor on a route. */
|
|
24
|
-
export const CAN_METADATA = 'nestjs-authz:can';
|
|
25
|
-
/** Metadata key for `@Roles(...roles)` — stores the allowed role names on a route. */
|
|
26
|
-
export const ROLES_METADATA = 'nestjs-authz:roles';
|
|
21
|
+
/** Metadata key of the `@PolicyFor(Resource)` link on a policy class. */
|
|
22
|
+
export { POLICY_RESOURCE_METADATA } from './links.js';
|
|
27
23
|
/**
|
|
28
24
|
* Cross-lib injection token for an optional {@link PermissionProvider} — the seam the
|
|
29
25
|
* RBAC adapter (`@dudousxd/nestjs-authz-typeorm`) registers so that a model-less,
|
|
@@ -32,8 +28,8 @@ export const ROLES_METADATA = 'nestjs-authz:roles';
|
|
|
32
28
|
*
|
|
33
29
|
* `Symbol.for(key)` uses the global symbol registry so an RBAC package registering
|
|
34
30
|
* this same key resolves to the SAME symbol instance without importing core internals.
|
|
35
|
-
* The token is consulted with `@Optional()` — when absent,
|
|
36
|
-
*
|
|
31
|
+
* The token is consulted with `@Optional()` — when absent, an unknown string ability
|
|
32
|
+
* still throws.
|
|
37
33
|
*/
|
|
38
34
|
export const PERMISSION_PROVIDER = capability('authz', 'permission-provider');
|
|
39
35
|
/**
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAEnE,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E,
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAEnE,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E,yEAAyE;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC"}
|