@mahiframework/permissions 0.1.4

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/assignee.d.ts +57 -0
  4. package/dist/assignee.d.ts.map +1 -0
  5. package/dist/assignee.js +46 -0
  6. package/dist/assignee.js.map +1 -0
  7. package/dist/commands/permissions-cache-reset.d.ts +20 -0
  8. package/dist/commands/permissions-cache-reset.d.ts.map +1 -0
  9. package/dist/commands/permissions-cache-reset.js +24 -0
  10. package/dist/commands/permissions-cache-reset.js.map +1 -0
  11. package/dist/commands/permissions-check.d.ts +37 -0
  12. package/dist/commands/permissions-check.d.ts.map +1 -0
  13. package/dist/commands/permissions-check.js +92 -0
  14. package/dist/commands/permissions-check.js.map +1 -0
  15. package/dist/commands/permissions-show.d.ts +20 -0
  16. package/dist/commands/permissions-show.d.ts.map +1 -0
  17. package/dist/commands/permissions-show.js +49 -0
  18. package/dist/commands/permissions-show.js.map +1 -0
  19. package/dist/errors.d.ts +77 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +106 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/index.d.ts +25 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +18 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/listeners/invalidate-permission-cache.listener.d.ts +39 -0
  28. package/dist/listeners/invalidate-permission-cache.listener.d.ts.map +1 -0
  29. package/dist/listeners/invalidate-permission-cache.listener.js +50 -0
  30. package/dist/listeners/invalidate-permission-cache.listener.js.map +1 -0
  31. package/dist/middleware/current-subject.d.ts +23 -0
  32. package/dist/middleware/current-subject.d.ts.map +1 -0
  33. package/dist/middleware/current-subject.js +31 -0
  34. package/dist/middleware/current-subject.js.map +1 -0
  35. package/dist/middleware/permission.d.ts +19 -0
  36. package/dist/middleware/permission.d.ts.map +1 -0
  37. package/dist/middleware/permission.js +34 -0
  38. package/dist/middleware/permission.js.map +1 -0
  39. package/dist/middleware/role-or-permission.d.ts +29 -0
  40. package/dist/middleware/role-or-permission.d.ts.map +1 -0
  41. package/dist/middleware/role-or-permission.js +45 -0
  42. package/dist/middleware/role-or-permission.js.map +1 -0
  43. package/dist/middleware/role.d.ts +21 -0
  44. package/dist/middleware/role.d.ts.map +1 -0
  45. package/dist/middleware/role.js +36 -0
  46. package/dist/middleware/role.js.map +1 -0
  47. package/dist/migrations/0001_create_permission_tables.d.ts +63 -0
  48. package/dist/migrations/0001_create_permission_tables.d.ts.map +1 -0
  49. package/dist/migrations/0001_create_permission_tables.js +113 -0
  50. package/dist/migrations/0001_create_permission_tables.js.map +1 -0
  51. package/dist/models/permission.model.d.ts +58 -0
  52. package/dist/models/permission.model.d.ts.map +1 -0
  53. package/dist/models/permission.model.js +18 -0
  54. package/dist/models/permission.model.js.map +1 -0
  55. package/dist/models/role.model.d.ts +60 -0
  56. package/dist/models/role.model.d.ts.map +1 -0
  57. package/dist/models/role.model.js +18 -0
  58. package/dist/models/role.model.js.map +1 -0
  59. package/dist/permission-map.d.ts +97 -0
  60. package/dist/permission-map.d.ts.map +1 -0
  61. package/dist/permission-map.js +93 -0
  62. package/dist/permission-map.js.map +1 -0
  63. package/dist/permission-registrar.d.ts +183 -0
  64. package/dist/permission-registrar.d.ts.map +1 -0
  65. package/dist/permission-registrar.js +573 -0
  66. package/dist/permission-registrar.js.map +1 -0
  67. package/dist/permissions-config.d.ts +80 -0
  68. package/dist/permissions-config.d.ts.map +1 -0
  69. package/dist/permissions-config.js +22 -0
  70. package/dist/permissions-config.js.map +1 -0
  71. package/dist/permissions-facade.d.ts +74 -0
  72. package/dist/permissions-facade.d.ts.map +1 -0
  73. package/dist/permissions-facade.js +131 -0
  74. package/dist/permissions-facade.js.map +1 -0
  75. package/dist/permissions-service-provider.d.ts +91 -0
  76. package/dist/permissions-service-provider.d.ts.map +1 -0
  77. package/dist/permissions-service-provider.js +137 -0
  78. package/dist/permissions-service-provider.js.map +1 -0
  79. package/dist/relations.d.ts +63 -0
  80. package/dist/relations.d.ts.map +1 -0
  81. package/dist/relations.js +62 -0
  82. package/dist/relations.js.map +1 -0
  83. package/dist/request-cache.d.ts +50 -0
  84. package/dist/request-cache.d.ts.map +1 -0
  85. package/dist/request-cache.js +40 -0
  86. package/dist/request-cache.js.map +1 -0
  87. package/dist/tokens.d.ts +15 -0
  88. package/dist/tokens.d.ts.map +1 -0
  89. package/dist/tokens.js +15 -0
  90. package/dist/tokens.js.map +1 -0
  91. package/package.json +69 -0
@@ -0,0 +1,573 @@
1
+ import { AUTH_TOKEN, CACHE_TOKEN } from "@mahiframework/core";
2
+ import { DB } from "@mahiframework/database";
3
+ import { assigneeCacheKey, resolveAssignee, } from "./assignee.js";
4
+ import { DuplicateNameError, PermissionNotFoundError, RoleNotFoundError, UnresolvedGuardError, } from "./errors.js";
5
+ import { buildMap, deserializeMap, mapKey, serializeMap, } from "./permission-map.js";
6
+ import { Permission } from "./models/permission.model.js";
7
+ import { Role } from "./models/role.model.js";
8
+ import { assignmentMemo, forgetMemoisedAssignments, } from "./request-cache.js";
9
+ /** Roles and permissions, their relationships, and who holds them. */
10
+ export class PermissionRegistrar {
11
+ app;
12
+ config;
13
+ constructor(app, config) {
14
+ this.app = app;
15
+ this.config = config;
16
+ }
17
+ // ---------------------------------------------------------------- guards
18
+ /**
19
+ * The guard a call operates on.
20
+ *
21
+ * `auth.default` is the last resort rather than the ambient
22
+ * `currentGuard()`, which would read the guard that authenticated THIS
23
+ * request. That is tempting and wrong: it throws outside a request
24
+ * scope (`MissingAuthContextError`), so a queue job or a seeder
25
+ * assigning a role would crash, and it would make the same
26
+ * `createRole("admin")` produce a different row depending on who
27
+ * happened to call it.
28
+ *
29
+ * Throws rather than defaulting to `""`: `guard_name` is NOT NULL with
30
+ * no wildcard, so an unresolvable guard has no safe representation, and
31
+ * a role stamped with the empty string is a role no check will ever
32
+ * match.
33
+ */
34
+ guardName(options = {}) {
35
+ const named = options.guard ?? this.config.guard ?? this.defaultGuard();
36
+ if (named === null || named === "") {
37
+ throw new UnresolvedGuardError();
38
+ }
39
+ return named;
40
+ }
41
+ defaultGuard() {
42
+ if (!this.app.has(AUTH_TOKEN)) {
43
+ return null;
44
+ }
45
+ return this.app.make(AUTH_TOKEN).getDefaultDriver();
46
+ }
47
+ // ----------------------------------------------------------- the cache
48
+ /**
49
+ * The role/permission map, from cache or the database.
50
+ *
51
+ * `remember()` treats `undefined` as its miss sentinel, so the loader
52
+ * must never return it — this one always returns an object, even for an
53
+ * app with no roles at all.
54
+ *
55
+ * The map crosses the cache boundary serialised (ids as strings): see
56
+ * `permission-map.ts` for why a `bigint` cannot be cached.
57
+ */
58
+ async map() {
59
+ const store = this.cache().store(this.config.cacheStore);
60
+ const serialized = await store.remember(this.config.cacheKey, () => this.loadMap(), this.config.cacheTtlSeconds);
61
+ return deserializeMap(serialized);
62
+ }
63
+ /** Read every role, permission, and role-permission link. Three queries, no joins. */
64
+ async loadMap() {
65
+ const [roleRows, permissionRows, links] = await Promise.all([
66
+ DB.table("roles").select("id", "name", "guard_name").get(),
67
+ DB.table("permissions").select("id", "name", "guard_name").get(),
68
+ DB.table("role_has_permissions").select("role_id", "permission_id").get(),
69
+ ]);
70
+ const grouped = new Map();
71
+ for (const link of links) {
72
+ const key = String(link.role_id);
73
+ const existing = grouped.get(key);
74
+ if (existing === undefined) {
75
+ grouped.set(key, [BigInt(link.permission_id)]);
76
+ }
77
+ else {
78
+ existing.push(BigInt(link.permission_id));
79
+ }
80
+ }
81
+ const roles = roleRows.map((row) => ({
82
+ id: BigInt(row.id),
83
+ name: row.name,
84
+ guardName: row.guard_name,
85
+ permissionIds: grouped.get(String(row.id)) ?? [],
86
+ }));
87
+ const permissions = permissionRows.map((row) => ({
88
+ id: BigInt(row.id),
89
+ name: row.name,
90
+ guardName: row.guard_name,
91
+ }));
92
+ return serializeMap(buildMap(roles, permissions));
93
+ }
94
+ /**
95
+ * Drop the cached map and every memoised assignment.
96
+ *
97
+ * Called by every write here, and by the model-event listeners for
98
+ * writes that bypass this class (a seeder calling `Role.create()`).
99
+ * Forgets exactly one key — `@mahiframework/cache` has no tags, so
100
+ * there is no flush-by-pattern, and `flush()` would take out the app's
101
+ * entire cache.
102
+ */
103
+ async forgetCache() {
104
+ forgetMemoisedAssignments();
105
+ await this.cache().store(this.config.cacheStore).forget(this.config.cacheKey);
106
+ }
107
+ cache() {
108
+ return this.app.make(CACHE_TOKEN);
109
+ }
110
+ // ------------------------------------------------------ role/permission CRUD
111
+ /** Create a role. Throws if one already exists with this name for this guard. */
112
+ async createRole(name, options = {}) {
113
+ const guard = this.guardName(options);
114
+ if ((await this.map()).roleByName.has(mapKey(guard, name))) {
115
+ throw new DuplicateNameError("role", name, guard);
116
+ }
117
+ const role = await Role.create({ name, guard_name: guard });
118
+ await this.forgetCache();
119
+ return role;
120
+ }
121
+ /** Create a permission. Throws if one already exists with this name for this guard. */
122
+ async createPermission(name, options = {}) {
123
+ const guard = this.guardName(options);
124
+ if ((await this.map()).permissionByName.has(mapKey(guard, name))) {
125
+ throw new DuplicateNameError("permission", name, guard);
126
+ }
127
+ const permission = await Permission.create({ name, guard_name: guard });
128
+ await this.forgetCache();
129
+ return permission;
130
+ }
131
+ /** Create a role only if it doesn't exist, returning either way. */
132
+ async findOrCreateRole(name, options = {}) {
133
+ const guard = this.guardName(options);
134
+ const existing = (await this.map()).roleByName.get(mapKey(guard, name));
135
+ if (existing !== undefined) {
136
+ return (await Role.findOrFail(existing.id));
137
+ }
138
+ return this.createRole(name, { guard });
139
+ }
140
+ /** Create a permission only if it doesn't exist, returning either way. */
141
+ async findOrCreatePermission(name, options = {}) {
142
+ const guard = this.guardName(options);
143
+ const existing = (await this.map()).permissionByName.get(mapKey(guard, name));
144
+ if (existing !== undefined) {
145
+ return (await Permission.findOrFail(existing.id));
146
+ }
147
+ return this.createPermission(name, { guard });
148
+ }
149
+ /** The role with this name, or `RoleNotFoundError`. */
150
+ async findRole(name, options = {}) {
151
+ const guard = this.guardName(options);
152
+ const mapped = (await this.map()).roleByName.get(mapKey(guard, name));
153
+ if (mapped === undefined) {
154
+ throw new RoleNotFoundError(name, guard);
155
+ }
156
+ return (await Role.findOrFail(mapped.id));
157
+ }
158
+ /** The permission with this name, or `PermissionNotFoundError`. */
159
+ async findPermission(name, options = {}) {
160
+ const guard = this.guardName(options);
161
+ const mapped = (await this.map()).permissionByName.get(mapKey(guard, name));
162
+ if (mapped === undefined) {
163
+ throw new PermissionNotFoundError(name, guard);
164
+ }
165
+ return (await Permission.findOrFail(mapped.id));
166
+ }
167
+ /**
168
+ * Delete a role. Its assignments and permission links go with it, via
169
+ * the pivots' `cascadeOnDelete` foreign keys.
170
+ */
171
+ async deleteRole(role, options = {}) {
172
+ const id = await this.roleId(role, options);
173
+ await Role.delete(id);
174
+ await this.forgetCache();
175
+ }
176
+ /** Delete a permission. Its assignments and role links cascade. */
177
+ async deletePermission(permission, options = {}) {
178
+ const id = await this.permissionId(permission, options);
179
+ await Permission.delete(id);
180
+ await this.forgetCache();
181
+ }
182
+ // --------------------------------------------------- role -> permissions
183
+ /** Grant permissions to a role, ignoring any it already has. */
184
+ async givePermissionToRole(role, permissions, options = {}) {
185
+ const roleId = await this.roleId(role, options);
186
+ const ids = await this.permissionIds(permissions, options);
187
+ const held = new Set(((await this.map()).roleById.get(roleId)?.permissionIds ?? []).map(String));
188
+ const missing = ids.filter((id) => !held.has(String(id)));
189
+ if (missing.length === 0) {
190
+ return;
191
+ }
192
+ await this.insertChunked("role_has_permissions", missing.map((id) => ({ role_id: roleId, permission_id: id })));
193
+ await this.forgetCache();
194
+ }
195
+ /** Revoke permissions from a role. */
196
+ async revokePermissionFromRole(role, permissions, options = {}) {
197
+ const roleId = await this.roleId(role, options);
198
+ const ids = await this.permissionIds(permissions, options);
199
+ if (ids.length === 0) {
200
+ return;
201
+ }
202
+ await DB.table("role_has_permissions")
203
+ .where("role_id", roleId)
204
+ .whereIn("permission_id", ids)
205
+ .delete();
206
+ await this.forgetCache();
207
+ }
208
+ /**
209
+ * Make a role's permissions exactly this list.
210
+ *
211
+ * An empty list revokes everything, which is the whole point of a sync
212
+ * and the one behaviour worth being explicit about: the framework's own
213
+ * `detach([])` is a deliberate no-op, so a caller passing
214
+ * `request.input("permissions")` through that API would silently keep
215
+ * the old set. This writes pivots directly and means what it says.
216
+ */
217
+ async syncRolePermissions(role, permissions, options = {}) {
218
+ const roleId = await this.roleId(role, options);
219
+ const wanted = await this.permissionIds(permissions, options);
220
+ await DB.transaction(async () => {
221
+ await DB.table("role_has_permissions").where("role_id", roleId).delete();
222
+ await this.insertChunked("role_has_permissions", wanted.map((id) => ({ role_id: roleId, permission_id: id })));
223
+ });
224
+ await this.forgetCache();
225
+ }
226
+ // ------------------------------------------------------- subject -> roles
227
+ /** Assign roles to a subject. Already-held roles are skipped, so this is idempotent. */
228
+ async assignRole(assignee, roles, options = {}) {
229
+ const subject = resolveAssignee(assignee);
230
+ const ids = await this.roleIds(roles, options);
231
+ const current = await this.assignmentsFor(subject);
232
+ const held = new Set(current.roleIds.map(String));
233
+ const missing = ids.filter((id) => !held.has(String(id)));
234
+ if (missing.length === 0) {
235
+ return;
236
+ }
237
+ await this.insertChunked("model_has_roles", missing.map((id) => ({
238
+ role_id: id,
239
+ model_type: subject.morphType,
240
+ model_id: subject.key,
241
+ })));
242
+ forgetMemoisedAssignments(assigneeCacheKey(subject));
243
+ }
244
+ /** Remove roles from a subject. */
245
+ async removeRole(assignee, roles, options = {}) {
246
+ const subject = resolveAssignee(assignee);
247
+ const ids = await this.roleIds(roles, options);
248
+ if (ids.length === 0) {
249
+ return;
250
+ }
251
+ await DB.table("model_has_roles")
252
+ .where("model_type", subject.morphType)
253
+ .where("model_id", subject.key)
254
+ .whereIn("role_id", ids)
255
+ .delete();
256
+ forgetMemoisedAssignments(assigneeCacheKey(subject));
257
+ }
258
+ /** Make a subject's roles exactly this list. An empty list removes all of them. */
259
+ async syncRoles(assignee, roles, options = {}) {
260
+ const subject = resolveAssignee(assignee);
261
+ const wanted = await this.roleIds(roles, options);
262
+ await DB.transaction(async () => {
263
+ await DB.table("model_has_roles")
264
+ .where("model_type", subject.morphType)
265
+ .where("model_id", subject.key)
266
+ .delete();
267
+ await this.insertChunked("model_has_roles", wanted.map((id) => ({
268
+ role_id: id,
269
+ model_type: subject.morphType,
270
+ model_id: subject.key,
271
+ })));
272
+ });
273
+ forgetMemoisedAssignments(assigneeCacheKey(subject));
274
+ }
275
+ // ------------------------------------------------- subject -> permissions
276
+ /** Grant permissions to a subject directly, alongside whatever its roles grant. */
277
+ async givePermissionTo(assignee, permissions, options = {}) {
278
+ const subject = resolveAssignee(assignee);
279
+ const ids = await this.permissionIds(permissions, options);
280
+ const current = await this.assignmentsFor(subject);
281
+ const held = new Set(current.permissionIds.map(String));
282
+ const missing = ids.filter((id) => !held.has(String(id)));
283
+ if (missing.length === 0) {
284
+ return;
285
+ }
286
+ await this.insertChunked("model_has_permissions", missing.map((id) => ({
287
+ permission_id: id,
288
+ model_type: subject.morphType,
289
+ model_id: subject.key,
290
+ })));
291
+ forgetMemoisedAssignments(assigneeCacheKey(subject));
292
+ }
293
+ /**
294
+ * Revoke a directly-granted permission.
295
+ *
296
+ * Only touches `model_has_permissions`. A permission the subject also
297
+ * holds through a role survives this call, and `hasPermissionTo()` will
298
+ * still answer true — which is correct, and the reason
299
+ * `hasDirectPermission()` exists to tell the two apart.
300
+ */
301
+ async revokePermissionTo(assignee, permissions, options = {}) {
302
+ const subject = resolveAssignee(assignee);
303
+ const ids = await this.permissionIds(permissions, options);
304
+ if (ids.length === 0) {
305
+ return;
306
+ }
307
+ await DB.table("model_has_permissions")
308
+ .where("model_type", subject.morphType)
309
+ .where("model_id", subject.key)
310
+ .whereIn("permission_id", ids)
311
+ .delete();
312
+ forgetMemoisedAssignments(assigneeCacheKey(subject));
313
+ }
314
+ /** Make a subject's direct permissions exactly this list. An empty list removes all of them. */
315
+ async syncPermissions(assignee, permissions, options = {}) {
316
+ const subject = resolveAssignee(assignee);
317
+ const wanted = await this.permissionIds(permissions, options);
318
+ await DB.transaction(async () => {
319
+ await DB.table("model_has_permissions")
320
+ .where("model_type", subject.morphType)
321
+ .where("model_id", subject.key)
322
+ .delete();
323
+ await this.insertChunked("model_has_permissions", wanted.map((id) => ({
324
+ permission_id: id,
325
+ model_type: subject.morphType,
326
+ model_id: subject.key,
327
+ })));
328
+ });
329
+ forgetMemoisedAssignments(assigneeCacheKey(subject));
330
+ }
331
+ // ------------------------------------------------------------- the checks
332
+ /** Does this subject hold this role? */
333
+ async hasRole(assignee, role, options = {}) {
334
+ return this.hasAnyRole(assignee, [role], options);
335
+ }
336
+ /** Does this subject hold at least one of these roles? */
337
+ async hasAnyRole(assignee, roles, options = {}) {
338
+ const names = await this.getRoleNames(assignee, options);
339
+ const map = await this.map();
340
+ const guard = this.guardName(options);
341
+ return roles.some((role) => names.has(this.roleNameOf(map, role, guard)));
342
+ }
343
+ /** Does this subject hold every one of these roles? */
344
+ async hasAllRoles(assignee, roles, options = {}) {
345
+ const names = await this.getRoleNames(assignee, options);
346
+ const map = await this.map();
347
+ const guard = this.guardName(options);
348
+ return roles.every((role) => names.has(this.roleNameOf(map, role, guard)));
349
+ }
350
+ /**
351
+ * Does this subject hold this permission, by any route?
352
+ *
353
+ * An unknown permission name returns false rather than throwing. This
354
+ * one is a check, not a write: the gate hook calls it with every
355
+ * ability string in the app, almost none of which are permissions, so
356
+ * throwing would turn `can("view-dashboard")` into a 500. The write
357
+ * methods still throw on an unknown name, which is where a typo
358
+ * actually matters.
359
+ */
360
+ async hasPermissionTo(assignee, permission, options = {}) {
361
+ return this.hasAnyPermission(assignee, [permission], options);
362
+ }
363
+ /** Does this subject hold at least one of these permissions, by any route? */
364
+ async hasAnyPermission(assignee, permissions, options = {}) {
365
+ const held = await this.getAllPermissions(assignee, options);
366
+ const map = await this.map();
367
+ const guard = this.guardName(options);
368
+ return permissions.some((permission) => held.has(this.permissionNameOf(map, permission, guard)));
369
+ }
370
+ /** Does this subject hold every one of these permissions, by any route? */
371
+ async hasAllPermissions(assignee, permissions, options = {}) {
372
+ const held = await this.getAllPermissions(assignee, options);
373
+ const map = await this.map();
374
+ const guard = this.guardName(options);
375
+ return permissions.every((permission) => held.has(this.permissionNameOf(map, permission, guard)));
376
+ }
377
+ /** Does this subject hold this permission DIRECTLY, ignoring its roles? */
378
+ async hasDirectPermission(assignee, permission, options = {}) {
379
+ const held = await this.getDirectPermissions(assignee, options);
380
+ const map = await this.map();
381
+ return held.has(this.permissionNameOf(map, permission, this.guardName(options)));
382
+ }
383
+ // ------------------------------------------------------- introspection
384
+ /** This subject's role names, for the resolved guard. */
385
+ async getRoleNames(assignee, options = {}) {
386
+ const guard = this.guardName(options);
387
+ const map = await this.map();
388
+ const assignments = await this.assignmentsFor(resolveAssignee(assignee));
389
+ const names = new Set();
390
+ for (const roleId of assignments.roleIds) {
391
+ const role = map.roleById.get(roleId);
392
+ // A guard mismatch is not a filter but the entire isolation
393
+ // guarantee: an `api` role must not answer a `web` question, even
394
+ // though the assignment row says the subject holds it.
395
+ if (role !== undefined && role.guardName === guard) {
396
+ names.add(role.name);
397
+ }
398
+ }
399
+ return names;
400
+ }
401
+ /** Permission names this subject holds via its roles only. */
402
+ async getPermissionsViaRoles(assignee, options = {}) {
403
+ const guard = this.guardName(options);
404
+ const map = await this.map();
405
+ const assignments = await this.assignmentsFor(resolveAssignee(assignee));
406
+ const names = new Set();
407
+ for (const roleId of assignments.roleIds) {
408
+ const role = map.roleById.get(roleId);
409
+ if (role === undefined || role.guardName !== guard) {
410
+ continue;
411
+ }
412
+ for (const permissionId of role.permissionIds) {
413
+ const permission = map.permissionById.get(permissionId);
414
+ if (permission !== undefined && permission.guardName === guard) {
415
+ names.add(permission.name);
416
+ }
417
+ }
418
+ }
419
+ return names;
420
+ }
421
+ /** Permission names granted to this subject directly, ignoring its roles. */
422
+ async getDirectPermissions(assignee, options = {}) {
423
+ const guard = this.guardName(options);
424
+ const map = await this.map();
425
+ const assignments = await this.assignmentsFor(resolveAssignee(assignee));
426
+ const names = new Set();
427
+ for (const permissionId of assignments.permissionIds) {
428
+ const permission = map.permissionById.get(permissionId);
429
+ if (permission !== undefined && permission.guardName === guard) {
430
+ names.add(permission.name);
431
+ }
432
+ }
433
+ return names;
434
+ }
435
+ /** Every permission name this subject holds, by either route. */
436
+ async getAllPermissions(assignee, options = {}) {
437
+ const [viaRoles, direct] = await Promise.all([
438
+ this.getPermissionsViaRoles(assignee, options),
439
+ this.getDirectPermissions(assignee, options),
440
+ ]);
441
+ for (const name of direct) {
442
+ viaRoles.add(name);
443
+ }
444
+ return viaRoles;
445
+ }
446
+ // ------------------------------------------------------------- internals
447
+ /**
448
+ * One subject's raw assignment ids, memoised per request.
449
+ *
450
+ * Two queries, in parallel, and at most once per subject per request.
451
+ * The memo is what makes the gate hook affordable: it fires on every
452
+ * authorization check, so a controller with five `can()` calls would
453
+ * otherwise be ten queries against rows that cannot have changed.
454
+ */
455
+ async assignmentsFor(subject) {
456
+ const memo = assignmentMemo();
457
+ const key = assigneeCacheKey(subject);
458
+ const cached = memo?.get(key);
459
+ if (cached !== undefined) {
460
+ return cached;
461
+ }
462
+ const [roleRows, permissionRows] = await Promise.all([
463
+ DB.table("model_has_roles")
464
+ .select("role_id")
465
+ .where("model_type", subject.morphType)
466
+ .where("model_id", subject.key)
467
+ .get(),
468
+ DB.table("model_has_permissions")
469
+ .select("permission_id")
470
+ .where("model_type", subject.morphType)
471
+ .where("model_id", subject.key)
472
+ .get(),
473
+ ]);
474
+ const record = {
475
+ roleIds: roleRows.map((row) => BigInt(row.role_id)),
476
+ permissionIds: permissionRows.map((row) => BigInt(row.permission_id)),
477
+ };
478
+ memo?.set(key, record);
479
+ return record;
480
+ }
481
+ /** The role's name, whether it was named by name or by id. Unknown ids yield a non-matching sentinel. */
482
+ roleNameOf(map, role, guard) {
483
+ if (typeof role === "string") {
484
+ return role;
485
+ }
486
+ const mapped = map.roleById.get(role);
487
+ return mapped !== undefined && mapped.guardName === guard ? mapped.name : UNMATCHABLE;
488
+ }
489
+ permissionNameOf(map, permission, guard) {
490
+ if (typeof permission === "string") {
491
+ return permission;
492
+ }
493
+ const mapped = map.permissionById.get(permission);
494
+ return mapped !== undefined && mapped.guardName === guard ? mapped.name : UNMATCHABLE;
495
+ }
496
+ /** Resolve a role reference to its id, throwing on an unknown name. */
497
+ async roleId(role, options) {
498
+ if (typeof role === "bigint") {
499
+ return role;
500
+ }
501
+ if (role instanceof Role) {
502
+ return role.id;
503
+ }
504
+ const guard = this.guardName(options);
505
+ const mapped = (await this.map()).roleByName.get(mapKey(guard, role));
506
+ if (mapped === undefined) {
507
+ throw new RoleNotFoundError(role, guard);
508
+ }
509
+ return mapped.id;
510
+ }
511
+ async permissionId(permission, options) {
512
+ if (typeof permission === "bigint") {
513
+ return permission;
514
+ }
515
+ if (permission instanceof Permission) {
516
+ return permission.id;
517
+ }
518
+ const guard = this.guardName(options);
519
+ const mapped = (await this.map()).permissionByName.get(mapKey(guard, permission));
520
+ if (mapped === undefined) {
521
+ throw new PermissionNotFoundError(permission, guard);
522
+ }
523
+ return mapped.id;
524
+ }
525
+ async roleIds(roles, options) {
526
+ const list = Array.isArray(roles) ? roles : [roles];
527
+ return Promise.all(list.map((role) => this.roleId(role, options)));
528
+ }
529
+ async permissionIds(permissions, options) {
530
+ const list = Array.isArray(permissions) ? permissions : [permissions];
531
+ return Promise.all(list.map((permission) => this.permissionId(permission, options)));
532
+ }
533
+ /**
534
+ * Insert pivot rows, in chunks, as one multi-row statement each.
535
+ *
536
+ * Goes to raw Kysely rather than `QueryBuilder`, whose `insert()` takes
537
+ * a single row: a per-row loop would turn a 500-permission sync into
538
+ * 500 round trips. `Role.resolveConnection()` is the handle rather
539
+ * than a `DatabaseManager` lookup because it swaps in the active
540
+ * transaction when there is one, which is what makes the `sync*`
541
+ * methods' delete-then-insert atomic.
542
+ *
543
+ * Chunked because pivot writes in this framework do not bound their
544
+ * parameter count, and a multi-row insert binds one parameter per
545
+ * column per row — three columns here, so a sync of 12,000 would
546
+ * exceed SQLite's 32,766-binding ceiling (Postgres' is 65,535) and
547
+ * fail at the driver rather than anywhere meaningful. 1,000 rows is
548
+ * 3,000 bindings, well inside every engine. Sequential, since the
549
+ * chunks all target one table inside one transaction.
550
+ */
551
+ async insertChunked(table, rows) {
552
+ if (rows.length === 0) {
553
+ return;
554
+ }
555
+ const connection = Role.resolveConnection();
556
+ for (let index = 0; index < rows.length; index += INSERT_CHUNK) {
557
+ await connection
558
+ .insertInto(table)
559
+ .values(rows.slice(index, index + INSERT_CHUNK))
560
+ .execute();
561
+ }
562
+ }
563
+ }
564
+ /**
565
+ * A name no role or permission can have, returned when an id-addressed
566
+ * lookup finds nothing. Returning this rather than throwing keeps
567
+ * `hasAnyRole([someDeletedId, "admin"])` answering the question it was
568
+ * asked; `\u0000` cannot appear in a name that came from the map, because
569
+ * the map's own keys use it as a separator.
570
+ */
571
+ const UNMATCHABLE = "\u0000unmatchable";
572
+ const INSERT_CHUNK = 1_000;
573
+ //# sourceMappingURL=permission-registrar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-registrar.js","sourceRoot":"","sources":["../src/permission-registrar.ts"],"names":[],"mappings":"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"}