@fuzdev/fuz_app 0.30.0 → 0.31.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 (207) hide show
  1. package/dist/actions/CLAUDE.md +630 -0
  2. package/dist/actions/action_rpc.d.ts +29 -0
  3. package/dist/actions/action_rpc.d.ts.map +1 -1
  4. package/dist/actions/action_rpc.js +42 -6
  5. package/dist/actions/action_types.d.ts +2 -2
  6. package/dist/actions/cancel.d.ts +12 -13
  7. package/dist/actions/cancel.d.ts.map +1 -1
  8. package/dist/actions/cancel.js +10 -13
  9. package/dist/actions/heartbeat.d.ts +8 -13
  10. package/dist/actions/heartbeat.d.ts.map +1 -1
  11. package/dist/actions/heartbeat.js +5 -8
  12. package/dist/actions/register_action_ws.d.ts +3 -3
  13. package/dist/actions/register_action_ws.js +2 -2
  14. package/dist/actions/register_ws_endpoint.d.ts +4 -4
  15. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  16. package/dist/actions/register_ws_endpoint.js +3 -3
  17. package/dist/actions/socket.svelte.d.ts +16 -16
  18. package/dist/actions/socket.svelte.d.ts.map +1 -1
  19. package/dist/actions/socket.svelte.js +15 -15
  20. package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
  21. package/dist/auth/CLAUDE.md +923 -0
  22. package/dist/auth/account_action_specs.d.ts +216 -0
  23. package/dist/auth/account_action_specs.d.ts.map +1 -0
  24. package/dist/auth/account_action_specs.js +159 -0
  25. package/dist/auth/account_actions.d.ts +51 -0
  26. package/dist/auth/account_actions.d.ts.map +1 -0
  27. package/dist/auth/account_actions.js +119 -0
  28. package/dist/auth/account_queries.d.ts +6 -2
  29. package/dist/auth/account_queries.d.ts.map +1 -1
  30. package/dist/auth/account_queries.js +40 -4
  31. package/dist/auth/account_routes.d.ts +94 -16
  32. package/dist/auth/account_routes.d.ts.map +1 -1
  33. package/dist/auth/account_routes.js +108 -180
  34. package/dist/auth/account_schema.d.ts +85 -30
  35. package/dist/auth/account_schema.d.ts.map +1 -1
  36. package/dist/auth/account_schema.js +40 -8
  37. package/dist/auth/admin_action_specs.d.ts +674 -0
  38. package/dist/auth/admin_action_specs.d.ts.map +1 -0
  39. package/dist/auth/admin_action_specs.js +287 -0
  40. package/dist/auth/admin_actions.d.ts +69 -0
  41. package/dist/auth/admin_actions.d.ts.map +1 -0
  42. package/dist/auth/admin_actions.js +256 -0
  43. package/dist/auth/api_token.d.ts +10 -0
  44. package/dist/auth/api_token.d.ts.map +1 -1
  45. package/dist/auth/api_token.js +9 -0
  46. package/dist/auth/api_token_queries.d.ts +3 -3
  47. package/dist/auth/api_token_queries.js +3 -3
  48. package/dist/auth/app_settings_schema.d.ts +4 -3
  49. package/dist/auth/app_settings_schema.d.ts.map +1 -1
  50. package/dist/auth/app_settings_schema.js +2 -1
  51. package/dist/auth/audit_log_routes.d.ts +14 -6
  52. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  53. package/dist/auth/audit_log_routes.js +22 -79
  54. package/dist/auth/audit_log_schema.d.ts +100 -29
  55. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  56. package/dist/auth/audit_log_schema.js +83 -11
  57. package/dist/auth/bootstrap_routes.d.ts +14 -0
  58. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  59. package/dist/auth/bootstrap_routes.js +10 -3
  60. package/dist/auth/cleanup.d.ts +63 -0
  61. package/dist/auth/cleanup.d.ts.map +1 -0
  62. package/dist/auth/cleanup.js +80 -0
  63. package/dist/auth/invite_schema.d.ts +11 -10
  64. package/dist/auth/invite_schema.d.ts.map +1 -1
  65. package/dist/auth/invite_schema.js +4 -3
  66. package/dist/auth/migrations.d.ts +6 -0
  67. package/dist/auth/migrations.d.ts.map +1 -1
  68. package/dist/auth/migrations.js +28 -0
  69. package/dist/auth/permit_offer_action_specs.d.ts +364 -0
  70. package/dist/auth/permit_offer_action_specs.d.ts.map +1 -0
  71. package/dist/auth/permit_offer_action_specs.js +216 -0
  72. package/dist/auth/permit_offer_actions.d.ts +96 -0
  73. package/dist/auth/permit_offer_actions.d.ts.map +1 -0
  74. package/dist/auth/permit_offer_actions.js +428 -0
  75. package/dist/auth/permit_offer_notifications.d.ts +361 -0
  76. package/dist/auth/permit_offer_notifications.d.ts.map +1 -0
  77. package/dist/auth/permit_offer_notifications.js +179 -0
  78. package/dist/auth/permit_offer_queries.d.ts +165 -0
  79. package/dist/auth/permit_offer_queries.d.ts.map +1 -0
  80. package/dist/auth/permit_offer_queries.js +390 -0
  81. package/dist/auth/permit_offer_schema.d.ts +103 -0
  82. package/dist/auth/permit_offer_schema.d.ts.map +1 -0
  83. package/dist/auth/permit_offer_schema.js +142 -0
  84. package/dist/auth/permit_queries.d.ts +77 -14
  85. package/dist/auth/permit_queries.d.ts.map +1 -1
  86. package/dist/auth/permit_queries.js +119 -24
  87. package/dist/auth/session_queries.d.ts +4 -2
  88. package/dist/auth/session_queries.d.ts.map +1 -1
  89. package/dist/auth/session_queries.js +4 -2
  90. package/dist/auth/signup_routes.d.ts +13 -0
  91. package/dist/auth/signup_routes.d.ts.map +1 -1
  92. package/dist/auth/signup_routes.js +14 -7
  93. package/dist/http/CLAUDE.md +584 -0
  94. package/dist/http/pending_effects.d.ts +29 -0
  95. package/dist/http/pending_effects.d.ts.map +1 -0
  96. package/dist/http/pending_effects.js +31 -0
  97. package/dist/http/route_spec.d.ts.map +1 -1
  98. package/dist/http/route_spec.js +4 -3
  99. package/dist/rate_limiter.d.ts +30 -0
  100. package/dist/rate_limiter.d.ts.map +1 -1
  101. package/dist/rate_limiter.js +25 -2
  102. package/dist/realtime/sse_auth_guard.d.ts +2 -0
  103. package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
  104. package/dist/realtime/sse_auth_guard.js +5 -3
  105. package/dist/testing/CLAUDE.md +668 -1
  106. package/dist/testing/admin_integration.d.ts +10 -7
  107. package/dist/testing/admin_integration.d.ts.map +1 -1
  108. package/dist/testing/admin_integration.js +382 -482
  109. package/dist/testing/app_server.d.ts +7 -6
  110. package/dist/testing/app_server.d.ts.map +1 -1
  111. package/dist/testing/attack_surface.d.ts +9 -3
  112. package/dist/testing/attack_surface.d.ts.map +1 -1
  113. package/dist/testing/attack_surface.js +4 -4
  114. package/dist/testing/audit_completeness.d.ts +6 -0
  115. package/dist/testing/audit_completeness.d.ts.map +1 -1
  116. package/dist/testing/audit_completeness.js +158 -134
  117. package/dist/testing/auth_apps.d.ts.map +1 -1
  118. package/dist/testing/auth_apps.js +4 -33
  119. package/dist/testing/db.d.ts +1 -1
  120. package/dist/testing/db.d.ts.map +1 -1
  121. package/dist/testing/db.js +2 -0
  122. package/dist/testing/entities.d.ts +35 -13
  123. package/dist/testing/entities.d.ts.map +1 -1
  124. package/dist/testing/entities.js +17 -0
  125. package/dist/testing/integration.d.ts +10 -0
  126. package/dist/testing/integration.d.ts.map +1 -1
  127. package/dist/testing/integration.js +352 -340
  128. package/dist/testing/integration_helpers.d.ts +16 -5
  129. package/dist/testing/integration_helpers.d.ts.map +1 -1
  130. package/dist/testing/integration_helpers.js +24 -4
  131. package/dist/testing/rate_limiting.d.ts +7 -0
  132. package/dist/testing/rate_limiting.d.ts.map +1 -1
  133. package/dist/testing/rate_limiting.js +41 -10
  134. package/dist/testing/rpc_helpers.d.ts +153 -1
  135. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  136. package/dist/testing/rpc_helpers.js +184 -8
  137. package/dist/testing/sse_round_trip.d.ts +8 -0
  138. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  139. package/dist/testing/sse_round_trip.js +10 -3
  140. package/dist/testing/standard.d.ts +9 -1
  141. package/dist/testing/standard.d.ts.map +1 -1
  142. package/dist/testing/standard.js +6 -2
  143. package/dist/testing/surface_invariants.d.ts +7 -3
  144. package/dist/testing/surface_invariants.d.ts.map +1 -1
  145. package/dist/testing/surface_invariants.js +5 -4
  146. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  147. package/dist/testing/ws_round_trip.js +9 -38
  148. package/dist/ui/AccountSessions.svelte +8 -4
  149. package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
  150. package/dist/ui/AdminAccounts.svelte +61 -33
  151. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  152. package/dist/ui/AdminAuditLog.svelte +3 -2
  153. package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -1
  154. package/dist/ui/AdminInvites.svelte +3 -2
  155. package/dist/ui/AdminInvites.svelte.d.ts.map +1 -1
  156. package/dist/ui/AdminOverview.svelte +14 -9
  157. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  158. package/dist/ui/AdminPermitHistory.svelte +3 -2
  159. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -1
  160. package/dist/ui/AdminSessions.svelte +29 -25
  161. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
  162. package/dist/ui/CLAUDE.md +351 -0
  163. package/dist/ui/OpenSignupToggle.svelte +6 -3
  164. package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
  165. package/dist/ui/PermitOfferForm.svelte +141 -0
  166. package/dist/ui/PermitOfferForm.svelte.d.ts +14 -0
  167. package/dist/ui/PermitOfferForm.svelte.d.ts.map +1 -0
  168. package/dist/ui/PermitOfferHistory.svelte +109 -0
  169. package/dist/ui/PermitOfferHistory.svelte.d.ts +11 -0
  170. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +1 -0
  171. package/dist/ui/PermitOfferInbox.svelte +121 -0
  172. package/dist/ui/PermitOfferInbox.svelte.d.ts +12 -0
  173. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +1 -0
  174. package/dist/ui/account_sessions_state.svelte.d.ts +53 -3
  175. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  176. package/dist/ui/account_sessions_state.svelte.js +39 -16
  177. package/dist/ui/admin_accounts_state.svelte.d.ts +118 -2
  178. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  179. package/dist/ui/admin_accounts_state.svelte.js +99 -23
  180. package/dist/ui/admin_invites_state.svelte.d.ts +47 -1
  181. package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -1
  182. package/dist/ui/admin_invites_state.svelte.js +38 -26
  183. package/dist/ui/admin_sessions_state.svelte.d.ts +26 -0
  184. package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -1
  185. package/dist/ui/admin_sessions_state.svelte.js +35 -21
  186. package/dist/ui/app_settings_state.svelte.d.ts +39 -0
  187. package/dist/ui/app_settings_state.svelte.d.ts.map +1 -1
  188. package/dist/ui/app_settings_state.svelte.js +34 -18
  189. package/dist/ui/audit_log_state.svelte.d.ts +40 -3
  190. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  191. package/dist/ui/audit_log_state.svelte.js +36 -42
  192. package/dist/ui/auth_state.svelte.d.ts +4 -3
  193. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  194. package/dist/ui/auth_state.svelte.js +4 -1
  195. package/dist/ui/permit_offers_state.svelte.d.ts +125 -0
  196. package/dist/ui/permit_offers_state.svelte.d.ts.map +1 -0
  197. package/dist/ui/permit_offers_state.svelte.js +197 -0
  198. package/package.json +3 -3
  199. package/dist/auth/admin_routes.d.ts +0 -29
  200. package/dist/auth/admin_routes.d.ts.map +0 -1
  201. package/dist/auth/admin_routes.js +0 -226
  202. package/dist/auth/app_settings_routes.d.ts +0 -27
  203. package/dist/auth/app_settings_routes.d.ts.map +0 -1
  204. package/dist/auth/app_settings_routes.js +0 -66
  205. package/dist/auth/invite_routes.d.ts +0 -18
  206. package/dist/auth/invite_routes.d.ts.map +0 -1
  207. package/dist/auth/invite_routes.js +0 -129
@@ -94,9 +94,9 @@ export const query_api_token_list_for_account = async (deps, account_id) => {
94
94
  * Enforce a per-account token limit by evicting the oldest tokens.
95
95
  *
96
96
  * Race safety: this function must run inside a transaction alongside the
97
- * INSERT that created the new token. The caller (`POST /tokens/create`)
98
- * uses the default `transaction: true` (framework-managed transaction
99
- * wrapping in `apply_route_specs`), ensuring the INSERT + enforce_limit
97
+ * INSERT that created the new token. The caller (the `account_token_create`
98
+ * RPC handler) runs under the dispatcher's transaction path because the
99
+ * spec declares `side_effects: true`, ensuring the INSERT + enforce_limit
100
100
  * pair is atomic — concurrent token creation cannot interleave.
101
101
  *
102
102
  * @param deps - query dependencies (must be transaction-scoped)
@@ -6,24 +6,25 @@
6
6
  * @module
7
7
  */
8
8
  import { z } from 'zod';
9
+ import { Uuid } from '../uuid.js';
9
10
  /** App settings row from the database. */
10
11
  export interface AppSettings {
11
12
  open_signup: boolean;
12
13
  updated_at: string | null;
13
- updated_by: string | null;
14
+ updated_by: Uuid | null;
14
15
  }
15
16
  /** Zod schema for client-safe app settings data. */
16
17
  export declare const AppSettingsJson: z.ZodObject<{
17
18
  open_signup: z.ZodBoolean;
18
19
  updated_at: z.ZodNullable<z.ZodString>;
19
- updated_by: z.ZodNullable<z.ZodString>;
20
+ updated_by: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
20
21
  }, z.core.$strict>;
21
22
  export type AppSettingsJson = z.infer<typeof AppSettingsJson>;
22
23
  /** Zod schema for admin app settings with resolved updater username. */
23
24
  export declare const AppSettingsWithUsernameJson: z.ZodObject<{
24
25
  open_signup: z.ZodBoolean;
25
26
  updated_at: z.ZodNullable<z.ZodString>;
26
- updated_by: z.ZodNullable<z.ZodString>;
27
+ updated_by: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
27
28
  updated_by_username: z.ZodNullable<z.ZodString>;
28
29
  }, z.core.$strict>;
29
30
  export type AppSettingsWithUsernameJson = z.infer<typeof AppSettingsWithUsernameJson>;
@@ -1 +1 @@
1
- {"version":3,"file":"app_settings_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/app_settings_schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,oDAAoD;AACpD,eAAO,MAAM,eAAe;;;;kBAI1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,wEAAwE;AACxE,eAAO,MAAM,2BAA2B;;;;;kBAEtC,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEtF,4CAA4C;AAC5C,eAAO,MAAM,sBAAsB;;kBAEjC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"app_settings_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/app_settings_schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAEhC,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED,oDAAoD;AACpD,eAAO,MAAM,eAAe;;;;kBAI1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,wEAAwE;AACxE,eAAO,MAAM,2BAA2B;;;;;kBAEtC,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEtF,4CAA4C;AAC5C,eAAO,MAAM,sBAAsB;;kBAEjC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -6,11 +6,12 @@
6
6
  * @module
7
7
  */
8
8
  import { z } from 'zod';
9
+ import { Uuid } from '../uuid.js';
9
10
  /** Zod schema for client-safe app settings data. */
10
11
  export const AppSettingsJson = z.strictObject({
11
12
  open_signup: z.boolean(),
12
13
  updated_at: z.string().nullable(),
13
- updated_by: z.string().nullable(),
14
+ updated_by: Uuid.nullable(),
14
15
  });
15
16
  /** Zod schema for admin app settings with resolved updater username. */
16
17
  export const AppSettingsWithUsernameJson = AppSettingsJson.extend({
@@ -1,8 +1,13 @@
1
1
  /**
2
- * Audit log and admin observability route specs.
2
+ * Audit log SSE stream route.
3
3
  *
4
- * All routes require admin role by default. Provides audit event listing,
5
- * permit history shortcut, and active session overview.
4
+ * The two list-reads (`audit_log_list`, `audit_log_permit_history`) moved to
5
+ * RPC in `admin_actions.ts`, and the admin session listing moved to
6
+ * `admin_session_list` on the same file. What remains here is the optional
7
+ * `GET /audit-log/stream` SSE route — streams aren't an action-kind, so they
8
+ * stay on REST. The event payload broadcast on the stream surfaces via
9
+ * `AUDIT_LOG_EVENT_SPECS` (one `EventSpec` per audit event type) declared
10
+ * alongside the broadcaster in `../realtime/sse_auth_guard.ts`.
6
11
  *
7
12
  * @module
8
13
  */
@@ -25,10 +30,13 @@ export interface AuditLogRouteOptions {
25
30
  };
26
31
  }
27
32
  /**
28
- * Create audit log and admin observability route specs.
33
+ * Create the optional audit-log SSE route spec.
29
34
  *
30
- * @param options - optional options with role override
31
- * @returns route specs for audit log and admin session management
35
+ * Returns an empty array when `options.stream` is not set — no REST routes
36
+ * live here apart from the stream.
37
+ *
38
+ * @param options - optional stream wiring + role override
39
+ * @returns the SSE route spec (when `options.stream` is provided) or an empty array
32
40
  */
33
41
  export declare const create_audit_log_route_specs: (options?: AuditLogRouteOptions) => Array<RouteSpec>;
34
42
  //# sourceMappingURL=audit_log_routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit_log_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAQpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAQrD,OAAO,EAAsB,KAAK,SAAS,EAAE,KAAK,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAC7F,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,oCAAoC,CAAC;AAUzE,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACpC,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QACR,SAAS,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM,IAAI,CAAC;QAC1F,GAAG,EAAE,MAAM,CAAC;KACZ,CAAC;CACF;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,GAAI,UAAU,oBAAoB,KAAG,KAAK,CAAC,SAAS,CAgG5F,CAAC"}
1
+ {"version":3,"file":"audit_log_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAsB,KAAK,SAAS,EAAE,KAAK,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAC7F,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,oCAAoC,CAAC;AAIzE,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACpC,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QACR,SAAS,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM,IAAI,CAAC;QAC1F,GAAG,EAAE,MAAM,CAAC;KACZ,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,GAAI,UAAU,oBAAoB,KAAG,KAAK,CAAC,SAAS,CAgC5F,CAAC"}
@@ -1,92 +1,36 @@
1
1
  /**
2
- * Audit log and admin observability route specs.
2
+ * Audit log SSE stream route.
3
3
  *
4
- * All routes require admin role by default. Provides audit event listing,
5
- * permit history shortcut, and active session overview.
4
+ * The two list-reads (`audit_log_list`, `audit_log_permit_history`) moved to
5
+ * RPC in `admin_actions.ts`, and the admin session listing moved to
6
+ * `admin_session_list` on the same file. What remains here is the optional
7
+ * `GET /audit-log/stream` SSE route — streams aren't an action-kind, so they
8
+ * stay on REST. The event payload broadcast on the stream surfaces via
9
+ * `AUDIT_LOG_EVENT_SPECS` (one `EventSpec` per audit event type) declared
10
+ * alongside the broadcaster in `../realtime/sse_auth_guard.ts`.
6
11
  *
7
12
  * @module
8
13
  */
9
14
  import { z } from 'zod';
10
- import { AuditLogEventWithUsernamesJson, AdminSessionJson, AuditEventType, PermitHistoryEventJson, } from './audit_log_schema.js';
11
- import { AUDIT_LOG_DEFAULT_LIMIT, query_audit_log_list_with_usernames, query_audit_log_list_permit_history, } from './audit_log_queries.js';
12
- import { query_session_list_all_active } from './session_queries.js';
13
- import { ERROR_INVALID_EVENT_TYPE } from '../http/error_schemas.js';
14
15
  import { create_sse_response } from '../realtime/sse.js';
15
16
  import { AUTH_SESSION_TOKEN_HASH_KEY, require_request_context } from './request_context.js';
16
- // TODO upstream to fuz_util
17
- /** Parse a string to an integer, returning `undefined` for non-numeric input (including `NaN`). */
18
- const parse_int_or_undefined = (value) => {
19
- const n = parseInt(value, 10);
20
- return Number.isFinite(n) ? n : undefined;
21
- };
17
+ import { AUDIT_LOG_CHANNEL } from '../realtime/sse_auth_guard.js';
22
18
  /**
23
- * Create audit log and admin observability route specs.
19
+ * Create the optional audit-log SSE route spec.
20
+ *
21
+ * Returns an empty array when `options.stream` is not set — no REST routes
22
+ * live here apart from the stream.
24
23
  *
25
- * @param options - optional options with role override
26
- * @returns route specs for audit log and admin session management
24
+ * @param options - optional stream wiring + role override
25
+ * @returns the SSE route spec (when `options.stream` is provided) or an empty array
27
26
  */
28
27
  export const create_audit_log_route_specs = (options) => {
29
28
  const role = options?.required_role ?? 'admin';
30
- const routes = [
31
- {
32
- method: 'GET',
33
- path: '/audit-log',
34
- auth: { type: 'role', role },
35
- description: 'List audit log events with optional filters',
36
- input: z.null(),
37
- output: z.strictObject({ events: z.array(AuditLogEventWithUsernamesJson) }),
38
- errors: { 400: z.looseObject({ error: z.literal(ERROR_INVALID_EVENT_TYPE) }) },
39
- handler: async (c, route) => {
40
- const raw_event_type = c.req.query('event_type') || undefined;
41
- if (raw_event_type && !AuditEventType.safeParse(raw_event_type).success) {
42
- return c.json({ error: ERROR_INVALID_EVENT_TYPE }, 400);
43
- }
44
- const event_type = raw_event_type;
45
- const account_id = c.req.query('account_id') || undefined;
46
- const limit = Math.max(1, Math.min(200, parseInt(c.req.query('limit') ?? '', 10) || AUDIT_LOG_DEFAULT_LIMIT));
47
- const offset = Math.max(0, parseInt(c.req.query('offset') ?? '', 10) || 0);
48
- const raw_since_seq = c.req.query('since_seq');
49
- const since_seq = raw_since_seq != null ? parse_int_or_undefined(raw_since_seq) : undefined;
50
- const events = await query_audit_log_list_with_usernames(route, {
51
- event_type,
52
- account_id,
53
- limit,
54
- offset,
55
- since_seq,
56
- });
57
- return c.json({ events });
58
- },
59
- },
29
+ if (!options?.stream)
30
+ return [];
31
+ const { subscribe, log } = options.stream;
32
+ return [
60
33
  {
61
- method: 'GET',
62
- path: '/audit-log/permit-history',
63
- auth: { type: 'role', role },
64
- description: 'List permit grant and revoke events with usernames',
65
- input: z.null(),
66
- output: z.strictObject({ events: z.array(PermitHistoryEventJson) }),
67
- handler: async (c, route) => {
68
- const limit = Math.max(1, Math.min(200, parseInt(c.req.query('limit') ?? '', 10) || AUDIT_LOG_DEFAULT_LIMIT));
69
- const offset = Math.max(0, parseInt(c.req.query('offset') ?? '', 10) || 0);
70
- const events = await query_audit_log_list_permit_history(route, limit, offset);
71
- return c.json({ events });
72
- },
73
- },
74
- {
75
- method: 'GET',
76
- path: '/sessions',
77
- auth: { type: 'role', role },
78
- description: 'List all active sessions across all accounts',
79
- input: z.null(),
80
- output: z.strictObject({ sessions: z.array(AdminSessionJson) }),
81
- handler: async (c, route) => {
82
- const sessions = await query_session_list_all_active(route);
83
- return c.json({ sessions });
84
- },
85
- },
86
- ];
87
- if (options?.stream) {
88
- const { subscribe, log } = options.stream;
89
- routes.push({
90
34
  method: 'GET',
91
35
  path: '/audit-log/stream',
92
36
  auth: { type: 'role', role },
@@ -102,14 +46,13 @@ export const create_audit_log_route_specs = (options) => {
102
46
  const token_hash = c.get(AUTH_SESSION_TOKEN_HASH_KEY) ?? null;
103
47
  const { response, stream } = create_sse_response(c, log);
104
48
  const unsubscribe = subscribe(stream, {
105
- channels: ['audit_log'],
49
+ channels: [AUDIT_LOG_CHANNEL],
106
50
  scope: token_hash ?? undefined,
107
51
  groups: [ctx.account.id],
108
52
  });
109
53
  stream.on_close(unsubscribe);
110
54
  return response;
111
55
  },
112
- });
113
- }
114
- return routes;
56
+ },
57
+ ];
115
58
  };
@@ -7,8 +7,9 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
+ import { Uuid } from '../uuid.js';
10
11
  /** All tracked auth event types. */
11
- export declare const AUDIT_EVENT_TYPES: readonly ["login", "logout", "bootstrap", "signup", "password_change", "session_revoke", "session_revoke_all", "token_create", "token_revoke", "token_revoke_all", "permit_grant", "permit_revoke", "invite_create", "invite_delete", "app_settings_update"];
12
+ export declare const AUDIT_EVENT_TYPES: readonly ["login", "logout", "bootstrap", "signup", "password_change", "session_revoke", "session_revoke_all", "token_create", "token_revoke", "token_revoke_all", "permit_grant", "permit_revoke", "permit_offer_create", "permit_offer_accept", "permit_offer_decline", "permit_offer_retract", "permit_offer_expire", "permit_offer_supersede", "invite_create", "invite_delete", "app_settings_update"];
12
13
  /** Zod schema for audit event types. */
13
14
  export declare const AuditEventType: z.ZodEnum<{
14
15
  login: "login";
@@ -23,6 +24,12 @@ export declare const AuditEventType: z.ZodEnum<{
23
24
  token_revoke_all: "token_revoke_all";
24
25
  permit_grant: "permit_grant";
25
26
  permit_revoke: "permit_revoke";
27
+ permit_offer_create: "permit_offer_create";
28
+ permit_offer_accept: "permit_offer_accept";
29
+ permit_offer_decline: "permit_offer_decline";
30
+ permit_offer_retract: "permit_offer_retract";
31
+ permit_offer_expire: "permit_offer_expire";
32
+ permit_offer_supersede: "permit_offer_supersede";
26
33
  invite_create: "invite_create";
27
34
  invite_delete: "invite_delete";
28
35
  app_settings_update: "app_settings_update";
@@ -51,7 +58,7 @@ export declare const AUDIT_METADATA_SCHEMAS: {
51
58
  }, z.core.$loose>>;
52
59
  signup: z.ZodObject<{
53
60
  username: z.ZodString;
54
- invite_id: z.ZodOptional<z.ZodString>;
61
+ invite_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
55
62
  open_signup: z.ZodOptional<z.ZodBoolean>;
56
63
  }, z.core.$loose>;
57
64
  password_change: z.ZodNullable<z.ZodObject<{
@@ -61,7 +68,9 @@ export declare const AUDIT_METADATA_SCHEMAS: {
61
68
  session_id: z.ZodString;
62
69
  }, z.core.$loose>;
63
70
  session_revoke_all: z.ZodObject<{
64
- count: z.ZodNumber;
71
+ count: z.ZodOptional<z.ZodNumber>;
72
+ reason: z.ZodOptional<z.ZodString>;
73
+ attempted_account_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
65
74
  }, z.core.$loose>;
66
75
  token_create: z.ZodObject<{
67
76
  token_id: z.ZodString;
@@ -71,23 +80,67 @@ export declare const AUDIT_METADATA_SCHEMAS: {
71
80
  token_id: z.ZodString;
72
81
  }, z.core.$loose>;
73
82
  token_revoke_all: z.ZodObject<{
74
- count: z.ZodNumber;
83
+ count: z.ZodOptional<z.ZodNumber>;
84
+ reason: z.ZodOptional<z.ZodString>;
85
+ attempted_account_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
75
86
  }, z.core.$loose>;
76
87
  permit_grant: z.ZodObject<{
77
88
  role: z.ZodString;
78
- permit_id: z.ZodOptional<z.ZodString>;
89
+ permit_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
90
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
91
+ source_offer_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
79
92
  }, z.core.$loose>;
80
93
  permit_revoke: z.ZodObject<{
81
94
  role: z.ZodString;
82
- permit_id: z.ZodString;
95
+ permit_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
96
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
97
+ reason: z.ZodOptional<z.ZodString>;
98
+ }, z.core.$loose>;
99
+ permit_offer_create: z.ZodObject<{
100
+ offer_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
101
+ role: z.ZodString;
102
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
103
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
104
+ }, z.core.$loose>;
105
+ permit_offer_accept: z.ZodObject<{
106
+ offer_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
107
+ permit_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
108
+ role: z.ZodString;
109
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
110
+ }, z.core.$loose>;
111
+ permit_offer_decline: z.ZodObject<{
112
+ offer_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
113
+ role: z.ZodString;
114
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
115
+ reason: z.ZodOptional<z.ZodString>;
116
+ }, z.core.$loose>;
117
+ permit_offer_retract: z.ZodObject<{
118
+ offer_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
119
+ role: z.ZodString;
120
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
121
+ }, z.core.$loose>;
122
+ permit_offer_expire: z.ZodObject<{
123
+ offer_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
124
+ role: z.ZodString;
125
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
126
+ }, z.core.$loose>;
127
+ permit_offer_supersede: z.ZodObject<{
128
+ offer_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
129
+ role: z.ZodString;
130
+ scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
131
+ reason: z.ZodEnum<{
132
+ sibling_accepted: "sibling_accepted";
133
+ permit_revoked: "permit_revoked";
134
+ }>;
135
+ cause_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
83
136
  }, z.core.$loose>;
84
137
  invite_create: z.ZodObject<{
85
- invite_id: z.ZodString;
138
+ invite_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
86
139
  email: z.ZodNullable<z.ZodString>;
87
140
  username: z.ZodNullable<z.ZodString>;
88
141
  }, z.core.$loose>;
89
142
  invite_delete: z.ZodObject<{
90
- invite_id: z.ZodString;
143
+ invite_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
91
144
  }, z.core.$loose>;
92
145
  app_settings_update: z.ZodObject<{
93
146
  setting: z.ZodString;
@@ -101,13 +154,13 @@ export type AuditMetadataMap = {
101
154
  };
102
155
  /** Audit log row from the database. */
103
156
  export interface AuditLogEvent {
104
- id: string;
157
+ id: Uuid;
105
158
  seq: number;
106
159
  event_type: AuditEventType;
107
160
  outcome: AuditOutcome;
108
- actor_id: string | null;
109
- account_id: string | null;
110
- target_account_id: string | null;
161
+ actor_id: Uuid | null;
162
+ account_id: Uuid | null;
163
+ target_account_id: Uuid | null;
111
164
  ip: string | null;
112
165
  created_at: string;
113
166
  metadata: Record<string, unknown> | null;
@@ -124,9 +177,9 @@ export declare const get_audit_metadata: <T extends AuditEventType>(event: Audit
124
177
  export interface AuditLogInput<T extends AuditEventType = AuditEventType> {
125
178
  event_type: T;
126
179
  outcome?: AuditOutcome;
127
- actor_id?: string | null;
128
- account_id?: string | null;
129
- target_account_id?: string | null;
180
+ actor_id?: Uuid | null;
181
+ account_id?: Uuid | null;
182
+ target_account_id?: Uuid | null;
130
183
  ip?: string | null;
131
184
  metadata?: (AuditMetadataMap[T] & Record<string, unknown>) | null;
132
185
  }
@@ -136,14 +189,14 @@ export interface AuditLogListOptions {
136
189
  offset?: number;
137
190
  event_type?: AuditEventType;
138
191
  event_type_in?: Array<AuditEventType>;
139
- account_id?: string;
192
+ account_id?: Uuid;
140
193
  outcome?: AuditOutcome;
141
194
  /** When set, only return events with `seq` greater than this value. Enables SSE reconnection gap fill. */
142
195
  since_seq?: number;
143
196
  }
144
197
  /** Zod schema for client-safe audit log event. */
145
198
  export declare const AuditLogEventJson: z.ZodObject<{
146
- id: z.ZodString;
199
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
147
200
  seq: z.ZodNumber;
148
201
  event_type: z.ZodEnum<{
149
202
  login: "login";
@@ -158,6 +211,12 @@ export declare const AuditLogEventJson: z.ZodObject<{
158
211
  token_revoke_all: "token_revoke_all";
159
212
  permit_grant: "permit_grant";
160
213
  permit_revoke: "permit_revoke";
214
+ permit_offer_create: "permit_offer_create";
215
+ permit_offer_accept: "permit_offer_accept";
216
+ permit_offer_decline: "permit_offer_decline";
217
+ permit_offer_retract: "permit_offer_retract";
218
+ permit_offer_expire: "permit_offer_expire";
219
+ permit_offer_supersede: "permit_offer_supersede";
161
220
  invite_create: "invite_create";
162
221
  invite_delete: "invite_delete";
163
222
  app_settings_update: "app_settings_update";
@@ -166,9 +225,9 @@ export declare const AuditLogEventJson: z.ZodObject<{
166
225
  success: "success";
167
226
  failure: "failure";
168
227
  }>;
169
- actor_id: z.ZodNullable<z.ZodString>;
170
- account_id: z.ZodNullable<z.ZodString>;
171
- target_account_id: z.ZodNullable<z.ZodString>;
228
+ actor_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
229
+ account_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
230
+ target_account_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
172
231
  ip: z.ZodNullable<z.ZodString>;
173
232
  created_at: z.ZodString;
174
233
  metadata: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -176,7 +235,7 @@ export declare const AuditLogEventJson: z.ZodObject<{
176
235
  export type AuditLogEventJson = z.infer<typeof AuditLogEventJson>;
177
236
  /** Zod schema for audit log events with resolved usernames. */
178
237
  export declare const AuditLogEventWithUsernamesJson: z.ZodObject<{
179
- id: z.ZodString;
238
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
180
239
  seq: z.ZodNumber;
181
240
  event_type: z.ZodEnum<{
182
241
  login: "login";
@@ -191,6 +250,12 @@ export declare const AuditLogEventWithUsernamesJson: z.ZodObject<{
191
250
  token_revoke_all: "token_revoke_all";
192
251
  permit_grant: "permit_grant";
193
252
  permit_revoke: "permit_revoke";
253
+ permit_offer_create: "permit_offer_create";
254
+ permit_offer_accept: "permit_offer_accept";
255
+ permit_offer_decline: "permit_offer_decline";
256
+ permit_offer_retract: "permit_offer_retract";
257
+ permit_offer_expire: "permit_offer_expire";
258
+ permit_offer_supersede: "permit_offer_supersede";
194
259
  invite_create: "invite_create";
195
260
  invite_delete: "invite_delete";
196
261
  app_settings_update: "app_settings_update";
@@ -199,9 +264,9 @@ export declare const AuditLogEventWithUsernamesJson: z.ZodObject<{
199
264
  success: "success";
200
265
  failure: "failure";
201
266
  }>;
202
- actor_id: z.ZodNullable<z.ZodString>;
203
- account_id: z.ZodNullable<z.ZodString>;
204
- target_account_id: z.ZodNullable<z.ZodString>;
267
+ actor_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
268
+ account_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
269
+ target_account_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
205
270
  ip: z.ZodNullable<z.ZodString>;
206
271
  created_at: z.ZodString;
207
272
  metadata: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -211,7 +276,7 @@ export declare const AuditLogEventWithUsernamesJson: z.ZodObject<{
211
276
  export type AuditLogEventWithUsernamesJson = z.infer<typeof AuditLogEventWithUsernamesJson>;
212
277
  /** Zod schema for permit history events with resolved usernames. */
213
278
  export declare const PermitHistoryEventJson: z.ZodObject<{
214
- id: z.ZodString;
279
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
215
280
  seq: z.ZodNumber;
216
281
  event_type: z.ZodEnum<{
217
282
  login: "login";
@@ -226,6 +291,12 @@ export declare const PermitHistoryEventJson: z.ZodObject<{
226
291
  token_revoke_all: "token_revoke_all";
227
292
  permit_grant: "permit_grant";
228
293
  permit_revoke: "permit_revoke";
294
+ permit_offer_create: "permit_offer_create";
295
+ permit_offer_accept: "permit_offer_accept";
296
+ permit_offer_decline: "permit_offer_decline";
297
+ permit_offer_retract: "permit_offer_retract";
298
+ permit_offer_expire: "permit_offer_expire";
299
+ permit_offer_supersede: "permit_offer_supersede";
229
300
  invite_create: "invite_create";
230
301
  invite_delete: "invite_delete";
231
302
  app_settings_update: "app_settings_update";
@@ -234,9 +305,9 @@ export declare const PermitHistoryEventJson: z.ZodObject<{
234
305
  success: "success";
235
306
  failure: "failure";
236
307
  }>;
237
- actor_id: z.ZodNullable<z.ZodString>;
238
- account_id: z.ZodNullable<z.ZodString>;
239
- target_account_id: z.ZodNullable<z.ZodString>;
308
+ actor_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
309
+ account_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
310
+ target_account_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
240
311
  ip: z.ZodNullable<z.ZodString>;
241
312
  created_at: z.ZodString;
242
313
  metadata: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -247,7 +318,7 @@ export type PermitHistoryEventJson = z.infer<typeof PermitHistoryEventJson>;
247
318
  /** Zod schema for admin session listing (session + username). */
248
319
  export declare const AdminSessionJson: z.ZodObject<{
249
320
  id: z.ZodString;
250
- account_id: z.ZodString;
321
+ account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
251
322
  created_at: z.ZodString;
252
323
  expires_at: z.ZodString;
253
324
  last_seen_at: z.ZodString;
@@ -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,6 +7,7 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
+ import { Uuid } from '../uuid.js';
10
11
  import { AuthSessionJson } from './account_schema.js';
11
12
  /** All tracked auth event types. */
12
13
  export const AUDIT_EVENT_TYPES = [
@@ -22,6 +23,12 @@ export const AUDIT_EVENT_TYPES = [
22
23
  'token_revoke_all',
23
24
  'permit_grant',
24
25
  'permit_revoke',
26
+ 'permit_offer_create',
27
+ 'permit_offer_accept',
28
+ 'permit_offer_decline',
29
+ 'permit_offer_retract',
30
+ 'permit_offer_expire',
31
+ 'permit_offer_supersede',
25
32
  'invite_create',
26
33
  'invite_delete',
27
34
  'app_settings_update',
@@ -43,25 +50,90 @@ export const AUDIT_METADATA_SCHEMAS = {
43
50
  bootstrap: z.looseObject({ error: z.string() }).nullable(),
44
51
  signup: z.looseObject({
45
52
  username: z.string(),
46
- invite_id: z.string().optional(),
53
+ invite_id: Uuid.optional(),
47
54
  open_signup: z.boolean().optional(),
48
55
  }),
49
56
  password_change: z.looseObject({ sessions_revoked: z.number() }).nullable(),
50
57
  session_revoke: z.looseObject({ session_id: z.string() }),
51
- session_revoke_all: z.looseObject({ count: z.number() }),
58
+ session_revoke_all: z.looseObject({
59
+ // Omitted on `outcome='failure'` (no revocation attempted — e.g. target
60
+ // account not found); `reason` carries the failure category, and
61
+ // `attempted_account_id` preserves the probed id (the `target_account_id`
62
+ // column is null in that case because it's a FK to `account`).
63
+ count: z.number().optional(),
64
+ reason: z.string().optional(),
65
+ attempted_account_id: Uuid.optional(),
66
+ }),
52
67
  token_create: z.looseObject({ token_id: z.string(), name: z.string() }),
53
68
  token_revoke: z.looseObject({ token_id: z.string() }),
54
- token_revoke_all: z.looseObject({ count: z.number() }),
69
+ token_revoke_all: z.looseObject({
70
+ // Same shape as `session_revoke_all` for failures.
71
+ count: z.number().optional(),
72
+ reason: z.string().optional(),
73
+ attempted_account_id: Uuid.optional(),
74
+ }),
55
75
  // `permit_id` is optional on `permit_grant` because failed grants
56
76
  // (e.g. `web_grantable` denied) never produce a permit row.
57
- permit_grant: z.looseObject({ role: z.string(), permit_id: z.string().optional() }),
58
- permit_revoke: z.looseObject({ role: z.string(), permit_id: z.string() }),
77
+ permit_grant: z.looseObject({
78
+ role: z.string(),
79
+ permit_id: Uuid.optional(),
80
+ scope_id: Uuid.nullish(),
81
+ source_offer_id: Uuid.optional(),
82
+ }),
83
+ permit_revoke: z.looseObject({
84
+ role: z.string(),
85
+ permit_id: Uuid,
86
+ scope_id: Uuid.nullish(),
87
+ reason: z.string().optional(),
88
+ }),
89
+ // `offer_id` is optional because failed creates (e.g. `web_grantable`
90
+ // denied, `authorize` callback denied) never produce an offer row.
91
+ permit_offer_create: z.looseObject({
92
+ offer_id: Uuid.optional(),
93
+ role: z.string(),
94
+ scope_id: Uuid.nullish(),
95
+ to_account_id: Uuid,
96
+ }),
97
+ // `permit_grant` is emitted alongside on accept — two events per accept by
98
+ // design: offer-lifecycle audit + permit-lifecycle audit.
99
+ permit_offer_accept: z.looseObject({
100
+ offer_id: Uuid,
101
+ permit_id: Uuid,
102
+ role: z.string(),
103
+ scope_id: Uuid.nullish(),
104
+ }),
105
+ permit_offer_decline: z.looseObject({
106
+ offer_id: Uuid,
107
+ role: z.string(),
108
+ scope_id: Uuid.nullish(),
109
+ reason: z.string().optional(),
110
+ }),
111
+ permit_offer_retract: z.looseObject({
112
+ offer_id: Uuid,
113
+ role: z.string(),
114
+ scope_id: Uuid.nullish(),
115
+ }),
116
+ permit_offer_expire: z.looseObject({
117
+ offer_id: Uuid,
118
+ role: z.string(),
119
+ scope_id: Uuid.nullish(),
120
+ }),
121
+ // Emitted when an offer is obsoleted by an external event. `reason`
122
+ // distinguishes the trigger; `cause_id` points to the accepted offer
123
+ // (for `sibling_accepted`) or the revoked permit (for `permit_revoked`).
124
+ permit_offer_supersede: z.looseObject({
125
+ offer_id: Uuid,
126
+ role: z.string(),
127
+ scope_id: Uuid.nullish(),
128
+ reason: z.enum(['sibling_accepted', 'permit_revoked']),
129
+ cause_id: Uuid,
130
+ }),
59
131
  invite_create: z.looseObject({
60
- invite_id: z.string(),
132
+ invite_id: Uuid,
61
133
  email: z.string().nullable(),
62
134
  username: z.string().nullable(),
63
135
  }),
64
- invite_delete: z.looseObject({ invite_id: z.string() }),
136
+ invite_delete: z.looseObject({ invite_id: Uuid }),
65
137
  app_settings_update: z.looseObject({
66
138
  setting: z.string(),
67
139
  old_value: z.unknown(),
@@ -78,13 +150,13 @@ export const get_audit_metadata = (event) => {
78
150
  };
79
151
  /** Zod schema for client-safe audit log event. */
80
152
  export const AuditLogEventJson = z.strictObject({
81
- id: z.string(),
153
+ id: Uuid,
82
154
  seq: z.number().int(),
83
155
  event_type: AuditEventType,
84
156
  outcome: AuditOutcome,
85
- actor_id: z.string().nullable(),
86
- account_id: z.string().nullable(),
87
- target_account_id: z.string().nullable(),
157
+ actor_id: Uuid.nullable(),
158
+ account_id: Uuid.nullable(),
159
+ target_account_id: Uuid.nullable(),
88
160
  ip: z.string().nullable(),
89
161
  created_at: z.string(),
90
162
  metadata: z.record(z.string(), z.unknown()).nullable(),