@fuzdev/fuz_app 0.39.0 → 0.41.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.
Files changed (92) hide show
  1. package/dist/actions/action_codegen.d.ts +0 -9
  2. package/dist/actions/action_codegen.d.ts.map +1 -1
  3. package/dist/actions/action_codegen.js +2 -35
  4. package/dist/actions/action_event.d.ts.map +1 -1
  5. package/dist/actions/action_event.js +1 -1
  6. package/dist/actions/action_types.d.ts +1 -1
  7. package/dist/actions/action_types.d.ts.map +1 -1
  8. package/dist/actions/register_action_ws.d.ts +1 -1
  9. package/dist/actions/register_action_ws.d.ts.map +1 -1
  10. package/dist/actions/transports_ws_backend.d.ts +1 -1
  11. package/dist/actions/transports_ws_backend.d.ts.map +1 -1
  12. package/dist/actions/transports_ws_backend.js +1 -1
  13. package/dist/auth/CLAUDE.md +117 -22
  14. package/dist/auth/account_actions.d.ts +5 -3
  15. package/dist/auth/account_actions.d.ts.map +1 -1
  16. package/dist/auth/account_actions.js +5 -6
  17. package/dist/auth/account_queries.d.ts.map +1 -1
  18. package/dist/auth/account_routes.d.ts.map +1 -1
  19. package/dist/auth/account_routes.js +7 -7
  20. package/dist/auth/account_schema.d.ts +1 -1
  21. package/dist/auth/account_schema.d.ts.map +1 -1
  22. package/dist/auth/account_schema.js +1 -1
  23. package/dist/auth/admin_action_specs.d.ts +6 -138
  24. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  25. package/dist/auth/admin_action_specs.js +5 -4
  26. package/dist/auth/admin_actions.d.ts +4 -3
  27. package/dist/auth/admin_actions.d.ts.map +1 -1
  28. package/dist/auth/admin_actions.js +10 -10
  29. package/dist/auth/app_settings_schema.d.ts +1 -1
  30. package/dist/auth/app_settings_schema.d.ts.map +1 -1
  31. package/dist/auth/app_settings_schema.js +1 -1
  32. package/dist/auth/audit_log_queries.d.ts +16 -8
  33. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  34. package/dist/auth/audit_log_queries.js +8 -11
  35. package/dist/auth/audit_log_schema.d.ts +28 -75
  36. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  37. package/dist/auth/audit_log_schema.js +23 -5
  38. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  39. package/dist/auth/bootstrap_routes.js +3 -3
  40. package/dist/auth/cleanup.d.ts +9 -1
  41. package/dist/auth/cleanup.d.ts.map +1 -1
  42. package/dist/auth/cleanup.js +2 -2
  43. package/dist/auth/deps.d.ts +13 -1
  44. package/dist/auth/deps.d.ts.map +1 -1
  45. package/dist/auth/invite_schema.d.ts +1 -1
  46. package/dist/auth/invite_schema.d.ts.map +1 -1
  47. package/dist/auth/invite_schema.js +1 -1
  48. package/dist/auth/permit_offer_action_specs.d.ts.map +1 -1
  49. package/dist/auth/permit_offer_action_specs.js +1 -1
  50. package/dist/auth/permit_offer_actions.d.ts +16 -2
  51. package/dist/auth/permit_offer_actions.d.ts.map +1 -1
  52. package/dist/auth/permit_offer_actions.js +26 -8
  53. package/dist/auth/permit_offer_notifications.d.ts +11 -6
  54. package/dist/auth/permit_offer_notifications.d.ts.map +1 -1
  55. package/dist/auth/permit_offer_notifications.js +11 -8
  56. package/dist/auth/permit_offer_queries.d.ts +1 -1
  57. package/dist/auth/permit_offer_queries.d.ts.map +1 -1
  58. package/dist/auth/permit_offer_schema.d.ts +1 -1
  59. package/dist/auth/permit_offer_schema.d.ts.map +1 -1
  60. package/dist/auth/permit_offer_schema.js +1 -1
  61. package/dist/auth/permit_queries.d.ts +50 -1
  62. package/dist/auth/permit_queries.d.ts.map +1 -1
  63. package/dist/auth/permit_queries.js +55 -0
  64. package/dist/auth/self_service_role_action_specs.d.ts +83 -0
  65. package/dist/auth/self_service_role_action_specs.d.ts.map +1 -0
  66. package/dist/auth/self_service_role_action_specs.js +71 -0
  67. package/dist/auth/self_service_role_actions.d.ts +67 -0
  68. package/dist/auth/self_service_role_actions.d.ts.map +1 -0
  69. package/dist/auth/self_service_role_actions.js +139 -0
  70. package/dist/auth/signup_routes.d.ts.map +1 -1
  71. package/dist/auth/signup_routes.js +2 -2
  72. package/dist/auth/standard_rpc_actions.d.ts +1 -1
  73. package/dist/auth/standard_rpc_actions.js +1 -1
  74. package/dist/server/app_backend.d.ts +9 -1
  75. package/dist/server/app_backend.d.ts.map +1 -1
  76. package/dist/server/app_backend.js +12 -1
  77. package/dist/testing/CLAUDE.md +1 -1
  78. package/dist/testing/admin_integration.d.ts.map +1 -1
  79. package/dist/testing/app_server.d.ts +13 -2
  80. package/dist/testing/app_server.d.ts.map +1 -1
  81. package/dist/testing/app_server.js +6 -1
  82. package/dist/testing/entities.d.ts.map +1 -1
  83. package/dist/testing/ws_round_trip.d.ts +1 -1
  84. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  85. package/dist/testing/ws_round_trip.js +1 -1
  86. package/dist/ui/ui_format.d.ts +2 -3
  87. package/dist/ui/ui_format.d.ts.map +1 -1
  88. package/dist/ui/ui_format.js +1 -1
  89. package/package.json +4 -4
  90. package/dist/uuid.d.ts +0 -12
  91. package/dist/uuid.d.ts.map +0 -1
  92. package/dist/uuid.js +0 -9
@@ -7,7 +7,7 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
- import { Uuid } from '../uuid.js';
10
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
11
11
  /**
12
12
  * All tracked auth event types. Frozen to convert accidental in-process
13
13
  * mutation (test cross-contamination, cast escapes) into loud TypeErrors.
@@ -103,12 +103,14 @@ export declare const AUDIT_METADATA_SCHEMAS: Readonly<{
103
103
  permit_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
104
104
  scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
105
105
  source_offer_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
106
+ self_service: z.ZodOptional<z.ZodBoolean>;
106
107
  }, z.core.$loose>;
107
108
  permit_revoke: z.ZodObject<{
108
109
  role: z.ZodString;
109
110
  permit_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
110
111
  scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
111
112
  reason: z.ZodOptional<z.ZodString>;
113
+ self_service: z.ZodOptional<z.ZodBoolean>;
112
114
  }, z.core.$loose>;
113
115
  permit_offer_create: z.ZodObject<{
114
116
  offer_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
@@ -145,6 +147,7 @@ export declare const AUDIT_METADATA_SCHEMAS: Readonly<{
145
147
  reason: z.ZodEnum<{
146
148
  sibling_accepted: "sibling_accepted";
147
149
  permit_revoked: "permit_revoked";
150
+ scope_destroyed: "scope_destroyed";
148
151
  }>;
149
152
  cause_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
150
153
  }, z.core.$loose>;
@@ -166,11 +169,11 @@ export declare const AUDIT_METADATA_SCHEMAS: Readonly<{
166
169
  export type AuditMetadataMap = {
167
170
  [K in AuditEventType]: z.infer<(typeof AUDIT_METADATA_SCHEMAS)[K]>;
168
171
  };
169
- /** Audit log row from the database. */
172
+ /** Audit log row from the database. See `AuditLogEventJson` for `event_type` widening rationale. */
170
173
  export interface AuditLogEvent {
171
174
  id: Uuid;
172
175
  seq: number;
173
- event_type: AuditEventType;
176
+ event_type: AuditEventTypeName;
174
177
  outcome: AuditOutcome;
175
178
  actor_id: Uuid | null;
176
179
  account_id: Uuid | null;
@@ -254,44 +257,38 @@ export interface CreateAuditLogConfigOptions {
254
257
  * pick up `BUILTIN_AUDIT_LOG_CONFIG`.
255
258
  */
256
259
  export declare const create_audit_log_config: (options?: CreateAuditLogConfigOptions) => AuditLogConfig;
260
+ /** Default page size for audit log listings. */
261
+ export declare const AUDIT_LOG_DEFAULT_LIMIT = 50;
257
262
  /** Options for listing audit log entries. */
258
263
  export interface AuditLogListOptions {
259
264
  limit?: number;
260
265
  offset?: number;
261
- event_type?: AuditEventType;
262
- event_type_in?: Array<AuditEventType>;
266
+ /**
267
+ * Event-type filter. Accepts any string — builtins or consumer-registered
268
+ * via `create_audit_log_config({extra_events})`. The DB column is
269
+ * `TEXT NOT NULL` with no CHECK, so unknown strings simply match nothing.
270
+ */
271
+ event_type?: string;
272
+ event_type_in?: Array<string>;
263
273
  account_id?: Uuid;
264
274
  outcome?: AuditOutcome;
265
275
  /** When set, only return events with `seq` greater than this value. Enables SSE reconnection gap fill. */
266
276
  since_seq?: number;
267
277
  }
268
- /** Zod schema for client-safe audit log event. */
278
+ /**
279
+ * Zod schema for client-safe audit log event.
280
+ *
281
+ * `event_type` is `AuditEventTypeName` (regex-validated string) — matches
282
+ * the `AuditLogEvent` row and the DB's `TEXT NOT NULL` column. Consumer
283
+ * types registered via `create_audit_log_config({extra_events})` round-trip
284
+ * through queries, `on_audit_event` callbacks, and JSON-RPC responses
285
+ * identically to builtins. `AuditLogInput<T>` stays parameterized on the
286
+ * write side so `AuditMetadataMap` narrowing via `get_audit_metadata` works.
287
+ */
269
288
  export declare const AuditLogEventJson: z.ZodObject<{
270
289
  id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
271
290
  seq: z.ZodNumber;
272
- event_type: z.ZodEnum<{
273
- login: "login";
274
- logout: "logout";
275
- bootstrap: "bootstrap";
276
- signup: "signup";
277
- password_change: "password_change";
278
- session_revoke: "session_revoke";
279
- session_revoke_all: "session_revoke_all";
280
- token_create: "token_create";
281
- token_revoke: "token_revoke";
282
- token_revoke_all: "token_revoke_all";
283
- permit_grant: "permit_grant";
284
- permit_revoke: "permit_revoke";
285
- permit_offer_create: "permit_offer_create";
286
- permit_offer_accept: "permit_offer_accept";
287
- permit_offer_decline: "permit_offer_decline";
288
- permit_offer_retract: "permit_offer_retract";
289
- permit_offer_expire: "permit_offer_expire";
290
- permit_offer_supersede: "permit_offer_supersede";
291
- invite_create: "invite_create";
292
- invite_delete: "invite_delete";
293
- app_settings_update: "app_settings_update";
294
- }>;
291
+ event_type: z.ZodString;
295
292
  outcome: z.ZodEnum<{
296
293
  success: "success";
297
294
  failure: "failure";
@@ -308,29 +305,7 @@ export type AuditLogEventJson = z.infer<typeof AuditLogEventJson>;
308
305
  export declare const AuditLogEventWithUsernamesJson: z.ZodObject<{
309
306
  id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
310
307
  seq: z.ZodNumber;
311
- event_type: z.ZodEnum<{
312
- login: "login";
313
- logout: "logout";
314
- bootstrap: "bootstrap";
315
- signup: "signup";
316
- password_change: "password_change";
317
- session_revoke: "session_revoke";
318
- session_revoke_all: "session_revoke_all";
319
- token_create: "token_create";
320
- token_revoke: "token_revoke";
321
- token_revoke_all: "token_revoke_all";
322
- permit_grant: "permit_grant";
323
- permit_revoke: "permit_revoke";
324
- permit_offer_create: "permit_offer_create";
325
- permit_offer_accept: "permit_offer_accept";
326
- permit_offer_decline: "permit_offer_decline";
327
- permit_offer_retract: "permit_offer_retract";
328
- permit_offer_expire: "permit_offer_expire";
329
- permit_offer_supersede: "permit_offer_supersede";
330
- invite_create: "invite_create";
331
- invite_delete: "invite_delete";
332
- app_settings_update: "app_settings_update";
333
- }>;
308
+ event_type: z.ZodString;
334
309
  outcome: z.ZodEnum<{
335
310
  success: "success";
336
311
  failure: "failure";
@@ -349,29 +324,7 @@ export type AuditLogEventWithUsernamesJson = z.infer<typeof AuditLogEventWithUse
349
324
  export declare const PermitHistoryEventJson: z.ZodObject<{
350
325
  id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
351
326
  seq: z.ZodNumber;
352
- event_type: z.ZodEnum<{
353
- login: "login";
354
- logout: "logout";
355
- bootstrap: "bootstrap";
356
- signup: "signup";
357
- password_change: "password_change";
358
- session_revoke: "session_revoke";
359
- session_revoke_all: "session_revoke_all";
360
- token_create: "token_create";
361
- token_revoke: "token_revoke";
362
- token_revoke_all: "token_revoke_all";
363
- permit_grant: "permit_grant";
364
- permit_revoke: "permit_revoke";
365
- permit_offer_create: "permit_offer_create";
366
- permit_offer_accept: "permit_offer_accept";
367
- permit_offer_decline: "permit_offer_decline";
368
- permit_offer_retract: "permit_offer_retract";
369
- permit_offer_expire: "permit_offer_expire";
370
- permit_offer_supersede: "permit_offer_supersede";
371
- invite_create: "invite_create";
372
- invite_delete: "invite_delete";
373
- app_settings_update: "app_settings_update";
374
- }>;
327
+ event_type: z.ZodString;
375
328
  outcome: z.ZodEnum<{
376
329
  success: "success";
377
330
  failure: "failure";
@@ -1 +1 @@
1
- {"version":3,"file":"audit_log_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit_log_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_schema.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
- import { Uuid } from '../uuid.js';
10
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
11
11
  import { AuthSessionJson } from './account_schema.js';
12
12
  /**
13
13
  * All tracked auth event types. Frozen to convert accidental in-process
@@ -89,17 +89,23 @@ export const AUDIT_METADATA_SCHEMAS = Object.freeze({
89
89
  }),
90
90
  // `permit_id` is optional on `permit_grant` because failed grants
91
91
  // (e.g. `web_grantable` denied) never produce a permit row.
92
+ // `self_service: true` is set by the self-service role toggle in
93
+ // `self_service_role_actions.ts` — declared explicitly rather than
94
+ // riding on `z.looseObject` permissiveness so the field is part of
95
+ // the documented schema surface.
92
96
  permit_grant: z.looseObject({
93
97
  role: z.string(),
94
98
  permit_id: Uuid.optional(),
95
99
  scope_id: Uuid.nullish(),
96
100
  source_offer_id: Uuid.optional(),
101
+ self_service: z.boolean().optional(),
97
102
  }),
98
103
  permit_revoke: z.looseObject({
99
104
  role: z.string(),
100
105
  permit_id: Uuid,
101
106
  scope_id: Uuid.nullish(),
102
107
  reason: z.string().optional(),
108
+ self_service: z.boolean().optional(),
103
109
  }),
104
110
  // `offer_id` is optional because failed creates (e.g. `web_grantable`
105
111
  // denied, `authorize` callback denied) never produce an offer row.
@@ -135,12 +141,13 @@ export const AUDIT_METADATA_SCHEMAS = Object.freeze({
135
141
  }),
136
142
  // Emitted when an offer is obsoleted by an external event. `reason`
137
143
  // distinguishes the trigger; `cause_id` points to the accepted offer
138
- // (for `sibling_accepted`) or the revoked permit (for `permit_revoked`).
144
+ // (for `sibling_accepted`), the revoked permit (for `permit_revoked`),
145
+ // or the destroyed parent scope row (for `scope_destroyed`).
139
146
  permit_offer_supersede: z.looseObject({
140
147
  offer_id: Uuid,
141
148
  role: z.string(),
142
149
  scope_id: Uuid.nullish(),
143
- reason: z.enum(['sibling_accepted', 'permit_revoked']),
150
+ reason: z.enum(['sibling_accepted', 'permit_revoked', 'scope_destroyed']),
144
151
  cause_id: Uuid,
145
152
  }),
146
153
  invite_create: z.looseObject({
@@ -205,11 +212,22 @@ export const create_audit_log_config = (options) => {
205
212
  metadata_schemas: Object.freeze(metadata_schemas),
206
213
  });
207
214
  };
208
- /** Zod schema for client-safe audit log event. */
215
+ /** Default page size for audit log listings. */
216
+ export const AUDIT_LOG_DEFAULT_LIMIT = 50;
217
+ /**
218
+ * Zod schema for client-safe audit log event.
219
+ *
220
+ * `event_type` is `AuditEventTypeName` (regex-validated string) — matches
221
+ * the `AuditLogEvent` row and the DB's `TEXT NOT NULL` column. Consumer
222
+ * types registered via `create_audit_log_config({extra_events})` round-trip
223
+ * through queries, `on_audit_event` callbacks, and JSON-RPC responses
224
+ * identically to builtins. `AuditLogInput<T>` stays parameterized on the
225
+ * write side so `AuditMetadataMap` narrowing via `get_audit_metadata` works.
226
+ */
209
227
  export const AuditLogEventJson = z.strictObject({
210
228
  id: Uuid,
211
229
  seq: z.number().int(),
212
- event_type: AuditEventType,
230
+ event_type: AuditEventTypeName,
213
231
  outcome: AuditOutcome,
214
232
  actor_id: Uuid.nullable(),
215
233
  account_id: Uuid.nullable(),
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAoB,KAAK,uBAAuB,EAAC,MAAM,wBAAwB,CAAC;AAGvF,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAkB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAA+B,KAAK,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAanD,gFAAgF;AAChF,eAAO,MAAM,cAAc;;;;kBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,iFAAiF;AACjF,eAAO,MAAM,eAAe;;;kBAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,8EAA8E;IAC9E,gBAAgB,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,EAAE,EAAE,EAAE,CAAC;IACP,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,wBAAwB,EAC9B,SAAS;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,KAClC,OAAO,CAAC,eAAe,CAwBzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,gBAAgB,EACtB,SAAS,qBAAqB,KAC5B,KAAK,CAAC,SAAS,CAyHjB,CAAC"}
1
+ {"version":3,"file":"bootstrap_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAoB,KAAK,uBAAuB,EAAC,MAAM,wBAAwB,CAAC;AAGvF,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAkB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAA+B,KAAK,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAanD,gFAAgF;AAChF,eAAO,MAAM,cAAc;;;;kBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,iFAAiF;AACjF,eAAO,MAAM,eAAe;;;kBAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,8EAA8E;IAC9E,gBAAgB,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,EAAE,EAAE,EAAE,CAAC;IACP,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,wBAAwB,EAC9B,SAAS;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,KAClC,OAAO,CAAC,eAAe,CAwBzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,gBAAgB,EACtB,SAAS,qBAAqB,KAC5B,KAAK,CAAC,SAAS,CAuHjB,CAAC"}
@@ -67,7 +67,7 @@ export const check_bootstrap_status = async (deps, options) => {
67
67
  * @returns route specs (not yet applied to Hono)
68
68
  */
69
69
  export const create_bootstrap_route_specs = (deps, options) => {
70
- const { keyring, on_audit_event } = deps;
70
+ const { keyring } = deps;
71
71
  const { session_options, bootstrap_status, on_bootstrap, ip_rate_limiter } = options;
72
72
  const { token_path } = bootstrap_status;
73
73
  return [
@@ -123,7 +123,7 @@ export const create_bootstrap_route_specs = (deps, options) => {
123
123
  outcome: 'failure',
124
124
  ip: get_client_ip(c),
125
125
  metadata: { error: result.error },
126
- }, deps.log, on_audit_event);
126
+ }, deps);
127
127
  return c.json({ error: result.error }, result.status);
128
128
  }
129
129
  // Successful bootstrap — update state immediately
@@ -150,7 +150,7 @@ export const create_bootstrap_route_specs = (deps, options) => {
150
150
  actor_id: result.actor.id,
151
151
  account_id: result.account.id,
152
152
  ip: get_client_ip(c),
153
- }, deps.log, on_audit_event);
153
+ }, deps);
154
154
  // CRITICAL: If token file deletion failed, throw to force operator attention.
155
155
  // All success work (session, on_bootstrap, audit) has completed above.
156
156
  // The error response alerts the operator to delete the token file manually.
@@ -20,7 +20,7 @@
20
20
  */
21
21
  import type { Logger } from '@fuzdev/fuz_util/log.js';
22
22
  import type { QueryDeps } from '../db/query_deps.js';
23
- import type { AuditLogEvent } from './audit_log_schema.js';
23
+ import type { AuditLogConfig, AuditLogEvent } from './audit_log_schema.js';
24
24
  /** Dependencies for the cleanup helpers. */
25
25
  export interface AuthCleanupDeps extends QueryDeps {
26
26
  log: Logger;
@@ -30,6 +30,14 @@ export interface AuthCleanupDeps extends QueryDeps {
30
30
  * to skip broadcast — the audit rows still land in the DB.
31
31
  */
32
32
  on_audit_event?: ((event: AuditLogEvent) => void) | null;
33
+ /**
34
+ * Audit-log config. Only the builtin `permit_offer_expire` event type is
35
+ * emitted here, so omitting this is safe — the field exists so consumers
36
+ * threading the same `AppDeps` bundle to scheduled cleanup keep using
37
+ * their registered config (and consumer extensions to the
38
+ * `permit_offer_expire` metadata schema get validated).
39
+ */
40
+ audit_log_config?: AuditLogConfig;
33
41
  }
34
42
  /** Result of `run_auth_cleanup`. */
35
43
  export interface AuthCleanupResult {
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEzD,4CAA4C;AAC5C,MAAM,WAAW,eAAgB,SAAQ,SAAS;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CACzD;AAED,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IACjC,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,GAAU,MAAM,eAAe,KAAG,OAAO,CAAC,MAAM,CA6BzF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAU,MAAM,eAAe,KAAG,OAAO,CAAC,iBAAiB,CAIvF,CAAC"}
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEzE,4CAA4C;AAC5C,MAAM,WAAW,eAAgB,SAAQ,SAAS;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC;CAClC;AAED,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IACjC,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,GAAU,MAAM,eAAe,KAAG,OAAO,CAAC,MAAM,CAiCzF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAU,MAAM,eAAe,KAAG,OAAO,CAAC,iBAAiB,CAIvF,CAAC"}
@@ -33,7 +33,7 @@ import { query_audit_log } from './audit_log_queries.js';
33
33
  */
34
34
  export const cleanup_expired_permit_offers = async (deps) => {
35
35
  const expired = await query_permit_offer_sweep_expired(deps);
36
- const { on_audit_event } = deps;
36
+ const { on_audit_event, audit_log_config } = deps;
37
37
  for (const offer of expired) {
38
38
  try {
39
39
  const event = await query_audit_log(deps, {
@@ -46,7 +46,7 @@ export const cleanup_expired_permit_offers = async (deps) => {
46
46
  role: offer.role,
47
47
  scope_id: offer.scope_id,
48
48
  },
49
- });
49
+ }, audit_log_config);
50
50
  if (on_audit_event) {
51
51
  try {
52
52
  on_audit_event(event);
@@ -12,7 +12,7 @@ import type { Keyring } from './keyring.js';
12
12
  import type { PasswordHashDeps } from './password.js';
13
13
  import type { Db } from '../db/db.js';
14
14
  import type { StatResult } from '../runtime/deps.js';
15
- import type { AuditLogEvent } from './audit_log_schema.js';
15
+ import type { AuditLogConfig, AuditLogEvent } from './audit_log_schema.js';
16
16
  /**
17
17
  * Stateless capabilities bundle for fuz_app backends.
18
18
  *
@@ -41,6 +41,18 @@ export interface AppDeps {
41
41
  * Defaults to a noop when not wired to SSE.
42
42
  */
43
43
  on_audit_event: (event: AuditLogEvent) => void;
44
+ /**
45
+ * Audit-log config for `audit_log_fire_and_forget` and `query_audit_log`.
46
+ * Built once at startup via `create_audit_log_config({extra_events})` to
47
+ * register consumer event types. Optional — defaults to
48
+ * `BUILTIN_AUDIT_LOG_CONFIG` when absent.
49
+ *
50
+ * Threaded through `AppDeps` (instead of a per-call positional arg) so
51
+ * consumer handlers cannot silently fall back to the builtin config by
52
+ * forgetting to pass theirs — the deps bundle carries it everywhere
53
+ * fuz_app emits an audit event.
54
+ */
55
+ audit_log_config?: AuditLogConfig;
44
56
  }
45
57
  /**
46
58
  * Capabilities for route spec factories.
@@ -1 +1 @@
1
- {"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACvB,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,yBAAyB;IACzB,EAAE,EAAE,EAAE,CAAC;IACP,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACvB,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,yBAAyB;IACzB,EAAE,EAAE,EAAE,CAAC;IACP,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC"}
@@ -7,7 +7,7 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
- import { Uuid } from '../uuid.js';
10
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
11
11
  import { Username, Email } from './account_schema.js';
12
12
  /** Invite row from the database. */
13
13
  export interface Invite {
@@ -1 +1 @@
1
- {"version":3,"file":"invite_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/invite_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAChC,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAEpD,oCAAoC;AACpC,MAAM,WAAW,MAAM;IACtB,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED,8CAA8C;AAC9C,eAAO,MAAM,UAAU;;;;;;;;kBAQrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB;;;;;;;;;;kBAGlC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE9E,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IACjC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB"}
1
+ {"version":3,"file":"invite_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/invite_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAE5C,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAEpD,oCAAoC;AACpC,MAAM,WAAW,MAAM;IACtB,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED,8CAA8C;AAC9C,eAAO,MAAM,UAAU;;;;;;;;kBAQrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB;;;;;;;;;;kBAGlC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE9E,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IACjC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB"}
@@ -7,7 +7,7 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
- import { Uuid } from '../uuid.js';
10
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
11
11
  import { Username, Email } from './account_schema.js';
12
12
  /** Zod schema for client-safe invite data. */
13
13
  export const InviteJson = z.strictObject({
@@ -1 +1 @@
1
- {"version":3,"file":"permit_offer_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/permit_offer_action_specs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permit_offer_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/permit_offer_action_specs.ts"],"names":[],"mappings":"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"}
@@ -18,7 +18,7 @@
18
18
  * @module
19
19
  */
20
20
  import { z } from 'zod';
21
- import { Uuid } from '../uuid.js';
21
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
22
22
  import { RoleName } from './role_schema.js';
23
23
  import { PERMIT_OFFER_MESSAGE_LENGTH_MAX, PermitOfferJson } from './permit_offer_schema.js';
24
24
  import { PERMIT_REVOKED_REASON_LENGTH_MAX } from './account_schema.js';
@@ -72,6 +72,20 @@ export interface PermitOfferActionOptions {
72
72
  */
73
73
  authorize?: PermitOfferCreateAuthorize;
74
74
  }
75
+ /**
76
+ * Authorization callback that admits any admin and otherwise falls back to
77
+ * the symmetric default (caller must hold the offered role globally).
78
+ *
79
+ * The `web_grantable` filter in `create_handler` runs **before** the
80
+ * `authorize` callback, so this never sees non-web-grantable roles. Drop
81
+ * into `create_permit_offer_actions({authorize: authorize_admin_or_holder})`
82
+ * (or any factory that forwards `authorize`, e.g. `create_standard_rpc_actions`)
83
+ * for the common "admins offer anything; users offer what they hold"
84
+ * pattern. Scope-aware policies (e.g. classroom_teacher offering
85
+ * classroom_student in their own scope) wrap this and short-circuit `true`
86
+ * before delegating.
87
+ */
88
+ export declare const authorize_admin_or_holder: PermitOfferCreateAuthorize;
75
89
  /**
76
90
  * Dependencies for `create_permit_offer_actions`.
77
91
  *
@@ -80,7 +94,7 @@ export interface PermitOfferActionOptions {
80
94
  * directly (the transport's `send_to_account` signature accepts the broader
81
95
  * `JsonrpcMessageFromServerToClient`, which is contravariantly compatible).
82
96
  */
83
- export interface PermitOfferActionDeps extends Pick<RouteFactoryDeps, 'log' | 'on_audit_event'> {
97
+ export interface PermitOfferActionDeps extends Pick<RouteFactoryDeps, 'log' | 'on_audit_event' | 'audit_log_config'> {
84
98
  /** Optional WS fan-out primitive. `null` or absent → notifications skipped. */
85
99
  notification_sender?: NotificationSender | null;
86
100
  }
@@ -88,7 +102,7 @@ export interface PermitOfferActionDeps extends Pick<RouteFactoryDeps, 'log' | 'o
88
102
  * Create the seven permit-offer RPC actions (six offer-lifecycle methods
89
103
  * plus `permit_revoke`).
90
104
  *
91
- * @param deps - stateless capabilities; needs `log` and `on_audit_event`; optional `notification_sender` for WS fan-out
105
+ * @param deps - `PermitOfferActionDeps` `log`, `on_audit_event`, optional `audit_log_config` (slice of `AppDeps`); optional `notification_sender` for WS fan-out
92
106
  * @param options - role schema, default TTL, authorization override
93
107
  * @returns the `RpcAction` array to spread into a `create_rpc_endpoint` call
94
108
  */
@@ -1 +1 @@
1
- {"version":3,"file":"permit_offer_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/permit_offer_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAa,KAAK,aAAa,EAAE,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAGxF,OAAO,EAAmC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAsBzF,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,EAON,KAAK,kBAAkB,EACvB,MAAM,iCAAiC,CAAC;AAmCzC;;;;;;;;GAQG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACxC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,EACrE,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,EACnC,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,iDAAiD;AACjD,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACvC;AAqCD;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,gBAAgB,CAAC;IAC9F,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACvC,MAAM,qBAAqB,EAC3B,UAAS,wBAA6B,KACpC,KAAK,CAAC,SAAS,CA8djB,CAAC"}
1
+ {"version":3,"file":"permit_offer_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/permit_offer_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAa,KAAK,aAAa,EAAE,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAGxF,OAAO,EAAmC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAsBzF,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,EAON,KAAK,kBAAkB,EACvB,MAAM,iCAAiC,CAAC;AAmCzC;;;;;;;;GAQG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACxC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,EACrE,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,EACnC,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,iDAAiD;AACjD,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACvC;AAyBD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,EAAE,0BAQvC,CAAC;AAcF;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAClD,gBAAgB,EAChB,KAAK,GAAG,gBAAgB,GAAG,kBAAkB,CAC7C;IACA,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACvC,MAAM,qBAAqB,EAC3B,UAAS,wBAA6B,KACpC,KAAK,CAAC,SAAS,CAudjB,CAAC"}
@@ -66,6 +66,24 @@ const default_authorize = async (auth, input, _deps, ctx) => {
66
66
  // check — the scope-aware "only in this classroom" policy is consumer-level.
67
67
  return query_permit_has_role(ctx, auth.actor.id, input.role);
68
68
  };
69
+ /**
70
+ * Authorization callback that admits any admin and otherwise falls back to
71
+ * the symmetric default (caller must hold the offered role globally).
72
+ *
73
+ * The `web_grantable` filter in `create_handler` runs **before** the
74
+ * `authorize` callback, so this never sees non-web-grantable roles. Drop
75
+ * into `create_permit_offer_actions({authorize: authorize_admin_or_holder})`
76
+ * (or any factory that forwards `authorize`, e.g. `create_standard_rpc_actions`)
77
+ * for the common "admins offer anything; users offer what they hold"
78
+ * pattern. Scope-aware policies (e.g. classroom_teacher offering
79
+ * classroom_student in their own scope) wrap this and short-circuit `true`
80
+ * before delegating.
81
+ */
82
+ export const authorize_admin_or_holder = async (auth, input, _deps, ctx) => {
83
+ if (has_role(auth, ROLE_ADMIN))
84
+ return true;
85
+ return query_permit_has_role(ctx, auth.actor.id, input.role);
86
+ };
69
87
  /**
70
88
  * Narrow `ctx.auth` to non-null. The RPC dispatcher has already enforced
71
89
  * `auth: 'authenticated'` before the handler runs — this is a type narrow,
@@ -80,7 +98,7 @@ const require_request_auth = (auth) => {
80
98
  * Create the seven permit-offer RPC actions (six offer-lifecycle methods
81
99
  * plus `permit_revoke`).
82
100
  *
83
- * @param deps - stateless capabilities; needs `log` and `on_audit_event`; optional `notification_sender` for WS fan-out
101
+ * @param deps - `PermitOfferActionDeps` `log`, `on_audit_event`, optional `audit_log_config` (slice of `AppDeps`); optional `notification_sender` for WS fan-out
84
102
  * @param options - role schema, default TTL, authorization override
85
103
  * @returns the `RpcAction` array to spread into a `create_rpc_endpoint` call
86
104
  */
@@ -104,7 +122,7 @@ export const create_permit_offer_actions = (deps, options = {}) => {
104
122
  scope_id: input.scope_id ?? null,
105
123
  to_account_id: input.to_account_id,
106
124
  },
107
- }, log, on_audit_event);
125
+ }, deps);
108
126
  };
109
127
  // Returns {offer} only — no auto-accept. Recipient must call
110
128
  // permit_offer_accept; admin tests materialize permits via
@@ -162,7 +180,7 @@ export const create_permit_offer_actions = (deps, options = {}) => {
162
180
  scope_id: offer.scope_id,
163
181
  to_account_id: offer.to_account_id,
164
182
  },
165
- }, log, on_audit_event);
183
+ }, deps);
166
184
  const offer_json = to_permit_offer_json(offer);
167
185
  if (notification_sender) {
168
186
  emit_after_commit(ctx, () => {
@@ -258,7 +276,7 @@ export const create_permit_offer_actions = (deps, options = {}) => {
258
276
  scope_id: declined.scope_id,
259
277
  reason: input.reason ?? undefined,
260
278
  },
261
- }, log, on_audit_event);
279
+ }, deps);
262
280
  if (notification_sender) {
263
281
  // Look up the grantor's account (SELECT by PK, same tx) for the
264
282
  // notification target. The decline reason rides along on
@@ -299,7 +317,7 @@ export const create_permit_offer_actions = (deps, options = {}) => {
299
317
  role: retracted.role,
300
318
  scope_id: retracted.scope_id,
301
319
  },
302
- }, log, on_audit_event);
320
+ }, deps);
303
321
  if (notification_sender) {
304
322
  const offer_json = to_permit_offer_json(retracted);
305
323
  emit_after_commit(ctx, () => {
@@ -355,7 +373,7 @@ export const create_permit_offer_actions = (deps, options = {}) => {
355
373
  target_account_id,
356
374
  ip: ctx.client_ip,
357
375
  metadata: { role: permit_row.role, permit_id: input.permit_id },
358
- }, log, on_audit_event);
376
+ }, deps);
359
377
  throw jsonrpc_errors.forbidden('role not web-grantable', {
360
378
  reason: ERROR_ROLE_NOT_WEB_GRANTABLE,
361
379
  });
@@ -378,7 +396,7 @@ export const create_permit_offer_actions = (deps, options = {}) => {
378
396
  scope_id: result.scope_id,
379
397
  reason: input.reason ?? undefined,
380
398
  },
381
- }, log, on_audit_event);
399
+ }, deps);
382
400
  for (const offer of result.superseded_offers) {
383
401
  void audit_log_fire_and_forget(ctx, {
384
402
  event_type: 'permit_offer_supersede',
@@ -392,7 +410,7 @@ export const create_permit_offer_actions = (deps, options = {}) => {
392
410
  reason: 'permit_revoked',
393
411
  cause_id: result.id,
394
412
  },
395
- }, log, on_audit_event);
413
+ }, deps);
396
414
  }
397
415
  if (notification_sender) {
398
416
  const superseded = result.superseded_offers.map((o) => ({
@@ -10,8 +10,9 @@
10
10
  * - `permit_offer_retracted` → recipient's sockets when a grantor retracts
11
11
  * - `permit_offer_accepted` → grantor's sockets when the recipient accepts
12
12
  * - `permit_offer_declined` → grantor's sockets when the recipient declines
13
- * - `permit_offer_supersede` → grantor's sockets when a sibling accept or
14
- * a revoke of the resulting permit obsoletes their pending offer
13
+ * - `permit_offer_supersede` → grantor's sockets when a sibling accept,
14
+ * a revoke of the resulting permit, or destruction of the parent scope
15
+ * row obsoletes their pending offer
15
16
  * - `permit_revoke` → revokee's sockets when one of their active permits
16
17
  * is revoked (companion to the `permit_revoke` audit event)
17
18
  *
@@ -29,9 +30,9 @@
29
30
  * @module
30
31
  */
31
32
  import { z } from 'zod';
33
+ import { type Uuid } from '@fuzdev/fuz_util/id.js';
32
34
  import type { EventSpec } from '../realtime/sse.js';
33
35
  import type { JsonrpcNotification } from '../http/jsonrpc.js';
34
- import { type Uuid } from '../uuid.js';
35
36
  /**
36
37
  * Narrow structural capability for sending a JSON-RPC notification to every
37
38
  * socket bound to an account.
@@ -142,9 +143,11 @@ export type PermitOfferDeclinedParams = z.infer<typeof PermitOfferDeclinedParams
142
143
  /**
143
144
  * Params for `permit_offer_supersede`. Fires to the grantor's sockets when
144
145
  * their pending offer is obsoleted — either by a sibling accept
145
- * (`reason: 'sibling_accepted'`) or by revoke of the resulting permit
146
- * (`reason: 'permit_revoked'`). `cause_id` points at the accepted offer id
147
- * or the revoked permit id respectively.
146
+ * (`reason: 'sibling_accepted'`), by revoke of the resulting permit
147
+ * (`reason: 'permit_revoked'`), or by deletion of the parent scope row
148
+ * the offer was bound to (`reason: 'scope_destroyed'`). `cause_id` points
149
+ * at the accepted offer id, the revoked permit id, or the destroyed scope
150
+ * row id respectively.
148
151
  */
149
152
  export declare const PermitOfferSupersedeParams: z.ZodObject<{
150
153
  offer: z.ZodObject<{
@@ -166,6 +169,7 @@ export declare const PermitOfferSupersedeParams: z.ZodObject<{
166
169
  reason: z.ZodEnum<{
167
170
  sibling_accepted: "sibling_accepted";
168
171
  permit_revoked: "permit_revoked";
172
+ scope_destroyed: "scope_destroyed";
169
173
  }>;
170
174
  cause_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
171
175
  }, z.core.$strict>;
@@ -322,6 +326,7 @@ export declare const permit_offer_supersede_notification_spec: {
322
326
  reason: z.ZodEnum<{
323
327
  sibling_accepted: "sibling_accepted";
324
328
  permit_revoked: "permit_revoked";
329
+ scope_destroyed: "scope_destroyed";
325
330
  }>;
326
331
  cause_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
327
332
  }, z.core.$strict>;