@fuzdev/fuz_app 0.29.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 (210) 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/actions/transports_ws_backend.d.ts +15 -0
  22. package/dist/actions/transports_ws_backend.d.ts.map +1 -1
  23. package/dist/actions/transports_ws_backend.js +17 -0
  24. package/dist/auth/CLAUDE.md +923 -0
  25. package/dist/auth/account_action_specs.d.ts +216 -0
  26. package/dist/auth/account_action_specs.d.ts.map +1 -0
  27. package/dist/auth/account_action_specs.js +159 -0
  28. package/dist/auth/account_actions.d.ts +51 -0
  29. package/dist/auth/account_actions.d.ts.map +1 -0
  30. package/dist/auth/account_actions.js +119 -0
  31. package/dist/auth/account_queries.d.ts +6 -2
  32. package/dist/auth/account_queries.d.ts.map +1 -1
  33. package/dist/auth/account_queries.js +40 -4
  34. package/dist/auth/account_routes.d.ts +94 -16
  35. package/dist/auth/account_routes.d.ts.map +1 -1
  36. package/dist/auth/account_routes.js +108 -180
  37. package/dist/auth/account_schema.d.ts +85 -30
  38. package/dist/auth/account_schema.d.ts.map +1 -1
  39. package/dist/auth/account_schema.js +40 -8
  40. package/dist/auth/admin_action_specs.d.ts +674 -0
  41. package/dist/auth/admin_action_specs.d.ts.map +1 -0
  42. package/dist/auth/admin_action_specs.js +287 -0
  43. package/dist/auth/admin_actions.d.ts +69 -0
  44. package/dist/auth/admin_actions.d.ts.map +1 -0
  45. package/dist/auth/admin_actions.js +256 -0
  46. package/dist/auth/api_token.d.ts +10 -0
  47. package/dist/auth/api_token.d.ts.map +1 -1
  48. package/dist/auth/api_token.js +9 -0
  49. package/dist/auth/api_token_queries.d.ts +3 -3
  50. package/dist/auth/api_token_queries.js +3 -3
  51. package/dist/auth/app_settings_schema.d.ts +4 -3
  52. package/dist/auth/app_settings_schema.d.ts.map +1 -1
  53. package/dist/auth/app_settings_schema.js +2 -1
  54. package/dist/auth/audit_log_routes.d.ts +14 -6
  55. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  56. package/dist/auth/audit_log_routes.js +22 -79
  57. package/dist/auth/audit_log_schema.d.ts +100 -29
  58. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  59. package/dist/auth/audit_log_schema.js +83 -11
  60. package/dist/auth/bootstrap_routes.d.ts +14 -0
  61. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  62. package/dist/auth/bootstrap_routes.js +10 -3
  63. package/dist/auth/cleanup.d.ts +63 -0
  64. package/dist/auth/cleanup.d.ts.map +1 -0
  65. package/dist/auth/cleanup.js +80 -0
  66. package/dist/auth/invite_schema.d.ts +11 -10
  67. package/dist/auth/invite_schema.d.ts.map +1 -1
  68. package/dist/auth/invite_schema.js +4 -3
  69. package/dist/auth/migrations.d.ts +6 -0
  70. package/dist/auth/migrations.d.ts.map +1 -1
  71. package/dist/auth/migrations.js +28 -0
  72. package/dist/auth/permit_offer_action_specs.d.ts +364 -0
  73. package/dist/auth/permit_offer_action_specs.d.ts.map +1 -0
  74. package/dist/auth/permit_offer_action_specs.js +216 -0
  75. package/dist/auth/permit_offer_actions.d.ts +96 -0
  76. package/dist/auth/permit_offer_actions.d.ts.map +1 -0
  77. package/dist/auth/permit_offer_actions.js +428 -0
  78. package/dist/auth/permit_offer_notifications.d.ts +361 -0
  79. package/dist/auth/permit_offer_notifications.d.ts.map +1 -0
  80. package/dist/auth/permit_offer_notifications.js +179 -0
  81. package/dist/auth/permit_offer_queries.d.ts +165 -0
  82. package/dist/auth/permit_offer_queries.d.ts.map +1 -0
  83. package/dist/auth/permit_offer_queries.js +390 -0
  84. package/dist/auth/permit_offer_schema.d.ts +103 -0
  85. package/dist/auth/permit_offer_schema.d.ts.map +1 -0
  86. package/dist/auth/permit_offer_schema.js +142 -0
  87. package/dist/auth/permit_queries.d.ts +77 -14
  88. package/dist/auth/permit_queries.d.ts.map +1 -1
  89. package/dist/auth/permit_queries.js +119 -24
  90. package/dist/auth/session_queries.d.ts +4 -2
  91. package/dist/auth/session_queries.d.ts.map +1 -1
  92. package/dist/auth/session_queries.js +4 -2
  93. package/dist/auth/signup_routes.d.ts +13 -0
  94. package/dist/auth/signup_routes.d.ts.map +1 -1
  95. package/dist/auth/signup_routes.js +14 -7
  96. package/dist/http/CLAUDE.md +584 -0
  97. package/dist/http/pending_effects.d.ts +29 -0
  98. package/dist/http/pending_effects.d.ts.map +1 -0
  99. package/dist/http/pending_effects.js +31 -0
  100. package/dist/http/route_spec.d.ts.map +1 -1
  101. package/dist/http/route_spec.js +4 -3
  102. package/dist/rate_limiter.d.ts +30 -0
  103. package/dist/rate_limiter.d.ts.map +1 -1
  104. package/dist/rate_limiter.js +25 -2
  105. package/dist/realtime/sse_auth_guard.d.ts +2 -0
  106. package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
  107. package/dist/realtime/sse_auth_guard.js +5 -3
  108. package/dist/testing/CLAUDE.md +668 -1
  109. package/dist/testing/admin_integration.d.ts +10 -7
  110. package/dist/testing/admin_integration.d.ts.map +1 -1
  111. package/dist/testing/admin_integration.js +382 -482
  112. package/dist/testing/app_server.d.ts +7 -6
  113. package/dist/testing/app_server.d.ts.map +1 -1
  114. package/dist/testing/attack_surface.d.ts +9 -3
  115. package/dist/testing/attack_surface.d.ts.map +1 -1
  116. package/dist/testing/attack_surface.js +4 -4
  117. package/dist/testing/audit_completeness.d.ts +6 -0
  118. package/dist/testing/audit_completeness.d.ts.map +1 -1
  119. package/dist/testing/audit_completeness.js +158 -134
  120. package/dist/testing/auth_apps.d.ts.map +1 -1
  121. package/dist/testing/auth_apps.js +4 -33
  122. package/dist/testing/db.d.ts +1 -1
  123. package/dist/testing/db.d.ts.map +1 -1
  124. package/dist/testing/db.js +2 -0
  125. package/dist/testing/entities.d.ts +35 -13
  126. package/dist/testing/entities.d.ts.map +1 -1
  127. package/dist/testing/entities.js +17 -0
  128. package/dist/testing/integration.d.ts +10 -0
  129. package/dist/testing/integration.d.ts.map +1 -1
  130. package/dist/testing/integration.js +352 -340
  131. package/dist/testing/integration_helpers.d.ts +16 -5
  132. package/dist/testing/integration_helpers.d.ts.map +1 -1
  133. package/dist/testing/integration_helpers.js +24 -4
  134. package/dist/testing/rate_limiting.d.ts +7 -0
  135. package/dist/testing/rate_limiting.d.ts.map +1 -1
  136. package/dist/testing/rate_limiting.js +41 -10
  137. package/dist/testing/rpc_helpers.d.ts +153 -1
  138. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  139. package/dist/testing/rpc_helpers.js +184 -8
  140. package/dist/testing/sse_round_trip.d.ts +8 -0
  141. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  142. package/dist/testing/sse_round_trip.js +10 -3
  143. package/dist/testing/standard.d.ts +9 -1
  144. package/dist/testing/standard.d.ts.map +1 -1
  145. package/dist/testing/standard.js +6 -2
  146. package/dist/testing/surface_invariants.d.ts +7 -3
  147. package/dist/testing/surface_invariants.d.ts.map +1 -1
  148. package/dist/testing/surface_invariants.js +5 -4
  149. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  150. package/dist/testing/ws_round_trip.js +9 -38
  151. package/dist/ui/AccountSessions.svelte +8 -4
  152. package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
  153. package/dist/ui/AdminAccounts.svelte +61 -33
  154. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  155. package/dist/ui/AdminAuditLog.svelte +3 -2
  156. package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -1
  157. package/dist/ui/AdminInvites.svelte +3 -2
  158. package/dist/ui/AdminInvites.svelte.d.ts.map +1 -1
  159. package/dist/ui/AdminOverview.svelte +14 -9
  160. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  161. package/dist/ui/AdminPermitHistory.svelte +3 -2
  162. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -1
  163. package/dist/ui/AdminSessions.svelte +29 -25
  164. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
  165. package/dist/ui/CLAUDE.md +351 -0
  166. package/dist/ui/OpenSignupToggle.svelte +6 -3
  167. package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
  168. package/dist/ui/PermitOfferForm.svelte +141 -0
  169. package/dist/ui/PermitOfferForm.svelte.d.ts +14 -0
  170. package/dist/ui/PermitOfferForm.svelte.d.ts.map +1 -0
  171. package/dist/ui/PermitOfferHistory.svelte +109 -0
  172. package/dist/ui/PermitOfferHistory.svelte.d.ts +11 -0
  173. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +1 -0
  174. package/dist/ui/PermitOfferInbox.svelte +121 -0
  175. package/dist/ui/PermitOfferInbox.svelte.d.ts +12 -0
  176. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +1 -0
  177. package/dist/ui/account_sessions_state.svelte.d.ts +53 -3
  178. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  179. package/dist/ui/account_sessions_state.svelte.js +39 -16
  180. package/dist/ui/admin_accounts_state.svelte.d.ts +118 -2
  181. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  182. package/dist/ui/admin_accounts_state.svelte.js +99 -23
  183. package/dist/ui/admin_invites_state.svelte.d.ts +47 -1
  184. package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -1
  185. package/dist/ui/admin_invites_state.svelte.js +38 -26
  186. package/dist/ui/admin_sessions_state.svelte.d.ts +26 -0
  187. package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -1
  188. package/dist/ui/admin_sessions_state.svelte.js +35 -21
  189. package/dist/ui/app_settings_state.svelte.d.ts +39 -0
  190. package/dist/ui/app_settings_state.svelte.d.ts.map +1 -1
  191. package/dist/ui/app_settings_state.svelte.js +34 -18
  192. package/dist/ui/audit_log_state.svelte.d.ts +40 -3
  193. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  194. package/dist/ui/audit_log_state.svelte.js +36 -42
  195. package/dist/ui/auth_state.svelte.d.ts +4 -3
  196. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  197. package/dist/ui/auth_state.svelte.js +4 -1
  198. package/dist/ui/permit_offers_state.svelte.d.ts +125 -0
  199. package/dist/ui/permit_offers_state.svelte.d.ts.map +1 -0
  200. package/dist/ui/permit_offers_state.svelte.js +197 -0
  201. package/package.json +3 -3
  202. package/dist/auth/admin_routes.d.ts +0 -29
  203. package/dist/auth/admin_routes.d.ts.map +0 -1
  204. package/dist/auth/admin_routes.js +0 -226
  205. package/dist/auth/app_settings_routes.d.ts +0 -27
  206. package/dist/auth/app_settings_routes.d.ts.map +0 -1
  207. package/dist/auth/app_settings_routes.js +0 -66
  208. package/dist/auth/invite_routes.d.ts +0 -18
  209. package/dist/auth/invite_routes.d.ts.map +0 -1
  210. package/dist/auth/invite_routes.js +0 -129
@@ -0,0 +1,361 @@
1
+ /**
2
+ * Permit offer WebSocket notification specs, builders, and the narrow
3
+ * `NotificationSender` interface that decouples offer/revoke send sites
4
+ * from `BackendWebsocketTransport`.
5
+ *
6
+ * Six `RemoteNotificationActionSpec`s cover the consentful-permits
7
+ * lifecycle events the server pushes to affected accounts:
8
+ *
9
+ * - `permit_offer_received` → recipient's sockets when an offer is created
10
+ * - `permit_offer_retracted` → recipient's sockets when a grantor retracts
11
+ * - `permit_offer_accepted` → grantor's sockets when the recipient accepts
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
15
+ * - `permit_revoke` → revokee's sockets when one of their active permits
16
+ * is revoked (companion to the `permit_revoke` audit event)
17
+ *
18
+ * Payloads are flat and normalized — `PermitOfferJson` for the offer-lifecycle
19
+ * notifications (decline reason rides on `offer.decline_reason`, not a
20
+ * sibling field), and `{permit_id, role, scope_id, reason?}` for `permit_revoke`. The
21
+ * revokee/grantor/recipient account id travels via the send target (the
22
+ * `NotificationSender.send_to_account` argument), not in the payload.
23
+ *
24
+ * The specs surface as `EventSpec`s via `create_action_event_spec` — callers
25
+ * append `PERMIT_OFFER_NOTIFICATION_SPECS` to their `event_specs` on
26
+ * `create_app_server` so the surface reflects them and DEV-mode broadcast
27
+ * validation catches payload drift.
28
+ *
29
+ * @module
30
+ */
31
+ import { z } from 'zod';
32
+ import type { EventSpec } from '../realtime/sse.js';
33
+ import type { JsonrpcNotification } from '../http/jsonrpc.js';
34
+ import { type Uuid } from '../uuid.js';
35
+ /**
36
+ * Narrow structural capability for sending a JSON-RPC notification to every
37
+ * socket bound to an account.
38
+ *
39
+ * `BackendWebsocketTransport` satisfies this interface — its
40
+ * `send_to_account(account_id, message)` signature accepts the broader
41
+ * `JsonrpcMessageFromServerToClient` type, which is contravariantly
42
+ * compatible with `JsonrpcNotification` here. The interface stays local so
43
+ * handlers don't couple to the concrete transport, and tests can inject a
44
+ * capturing stub with no WS machinery.
45
+ *
46
+ * Returns the number of sockets the notification was sent to — callers
47
+ * typically ignore it (used by telemetry / tests).
48
+ */
49
+ export interface NotificationSender {
50
+ send_to_account: (account_id: Uuid, message: JsonrpcNotification) => number;
51
+ }
52
+ export declare const PERMIT_OFFER_RECEIVED_NOTIFICATION_METHOD = "permit_offer_received";
53
+ export declare const PERMIT_OFFER_RETRACTED_NOTIFICATION_METHOD = "permit_offer_retracted";
54
+ export declare const PERMIT_OFFER_ACCEPTED_NOTIFICATION_METHOD = "permit_offer_accepted";
55
+ export declare const PERMIT_OFFER_DECLINED_NOTIFICATION_METHOD = "permit_offer_declined";
56
+ export declare const PERMIT_OFFER_SUPERSEDE_NOTIFICATION_METHOD = "permit_offer_supersede";
57
+ export declare const PERMIT_REVOKE_NOTIFICATION_METHOD = "permit_revoke";
58
+ /** Params for `permit_offer_received` — offer delivered to its recipient. */
59
+ export declare const PermitOfferReceivedParams: z.ZodObject<{
60
+ offer: z.ZodObject<{
61
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
62
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
63
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
64
+ role: z.ZodString;
65
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
66
+ message: z.ZodNullable<z.ZodString>;
67
+ created_at: z.ZodString;
68
+ expires_at: z.ZodString;
69
+ accepted_at: z.ZodNullable<z.ZodString>;
70
+ declined_at: z.ZodNullable<z.ZodString>;
71
+ decline_reason: z.ZodNullable<z.ZodString>;
72
+ retracted_at: z.ZodNullable<z.ZodString>;
73
+ superseded_at: z.ZodNullable<z.ZodString>;
74
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
75
+ }, z.core.$strict>;
76
+ }, z.core.$strict>;
77
+ export type PermitOfferReceivedParams = z.infer<typeof PermitOfferReceivedParams>;
78
+ /** Params for `permit_offer_retracted` — grantor-side retraction. */
79
+ export declare const PermitOfferRetractedParams: z.ZodObject<{
80
+ offer: z.ZodObject<{
81
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
82
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
83
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
84
+ role: z.ZodString;
85
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
86
+ message: z.ZodNullable<z.ZodString>;
87
+ created_at: z.ZodString;
88
+ expires_at: z.ZodString;
89
+ accepted_at: z.ZodNullable<z.ZodString>;
90
+ declined_at: z.ZodNullable<z.ZodString>;
91
+ decline_reason: z.ZodNullable<z.ZodString>;
92
+ retracted_at: z.ZodNullable<z.ZodString>;
93
+ superseded_at: z.ZodNullable<z.ZodString>;
94
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
95
+ }, z.core.$strict>;
96
+ }, z.core.$strict>;
97
+ export type PermitOfferRetractedParams = z.infer<typeof PermitOfferRetractedParams>;
98
+ /** Params for `permit_offer_accepted` — recipient accepted the offer. */
99
+ export declare const PermitOfferAcceptedParams: z.ZodObject<{
100
+ offer: z.ZodObject<{
101
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
102
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
103
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
104
+ role: z.ZodString;
105
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
106
+ message: z.ZodNullable<z.ZodString>;
107
+ created_at: z.ZodString;
108
+ expires_at: z.ZodString;
109
+ accepted_at: z.ZodNullable<z.ZodString>;
110
+ declined_at: z.ZodNullable<z.ZodString>;
111
+ decline_reason: z.ZodNullable<z.ZodString>;
112
+ retracted_at: z.ZodNullable<z.ZodString>;
113
+ superseded_at: z.ZodNullable<z.ZodString>;
114
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
115
+ }, z.core.$strict>;
116
+ }, z.core.$strict>;
117
+ export type PermitOfferAcceptedParams = z.infer<typeof PermitOfferAcceptedParams>;
118
+ /**
119
+ * Params for `permit_offer_declined`. The decline reason (if any) rides along
120
+ * inside `offer.decline_reason` — the DB stamps it on the offer row during
121
+ * decline, so a sibling `reason` field would just duplicate it.
122
+ */
123
+ export declare const PermitOfferDeclinedParams: z.ZodObject<{
124
+ offer: z.ZodObject<{
125
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
126
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
127
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
128
+ role: z.ZodString;
129
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
130
+ message: z.ZodNullable<z.ZodString>;
131
+ created_at: z.ZodString;
132
+ expires_at: z.ZodString;
133
+ accepted_at: z.ZodNullable<z.ZodString>;
134
+ declined_at: z.ZodNullable<z.ZodString>;
135
+ decline_reason: z.ZodNullable<z.ZodString>;
136
+ retracted_at: z.ZodNullable<z.ZodString>;
137
+ superseded_at: z.ZodNullable<z.ZodString>;
138
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
139
+ }, z.core.$strict>;
140
+ }, z.core.$strict>;
141
+ export type PermitOfferDeclinedParams = z.infer<typeof PermitOfferDeclinedParams>;
142
+ /**
143
+ * Params for `permit_offer_supersede`. Fires to the grantor's sockets when
144
+ * 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.
148
+ */
149
+ export declare const PermitOfferSupersedeParams: z.ZodObject<{
150
+ offer: z.ZodObject<{
151
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
152
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
153
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
154
+ role: z.ZodString;
155
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
156
+ message: z.ZodNullable<z.ZodString>;
157
+ created_at: z.ZodString;
158
+ expires_at: z.ZodString;
159
+ accepted_at: z.ZodNullable<z.ZodString>;
160
+ declined_at: z.ZodNullable<z.ZodString>;
161
+ decline_reason: z.ZodNullable<z.ZodString>;
162
+ retracted_at: z.ZodNullable<z.ZodString>;
163
+ superseded_at: z.ZodNullable<z.ZodString>;
164
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
165
+ }, z.core.$strict>;
166
+ reason: z.ZodEnum<{
167
+ sibling_accepted: "sibling_accepted";
168
+ permit_revoked: "permit_revoked";
169
+ }>;
170
+ cause_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
171
+ }, z.core.$strict>;
172
+ export type PermitOfferSupersedeParams = z.infer<typeof PermitOfferSupersedeParams>;
173
+ /**
174
+ * Params for `permit_revoke`. Delivered to the revokee's sockets when one
175
+ * of their active permits is revoked. Flat wire shape — `revoked_by` is
176
+ * admin-UI-visible but deliberately omitted here (the revokee doesn't need
177
+ * to learn the admin's identity). Target account is implicit in the send
178
+ * target.
179
+ */
180
+ export declare const PermitRevokeParams: z.ZodObject<{
181
+ permit_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
182
+ role: z.ZodString;
183
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
184
+ reason: z.ZodNullable<z.ZodString>;
185
+ }, z.core.$strict>;
186
+ export type PermitRevokeParams = z.infer<typeof PermitRevokeParams>;
187
+ export declare const permit_offer_received_notification_spec: {
188
+ method: string;
189
+ kind: "remote_notification";
190
+ initiator: "backend";
191
+ auth: null;
192
+ side_effects: true;
193
+ input: z.ZodObject<{
194
+ offer: z.ZodObject<{
195
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
196
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
197
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
198
+ role: z.ZodString;
199
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
200
+ message: z.ZodNullable<z.ZodString>;
201
+ created_at: z.ZodString;
202
+ expires_at: z.ZodString;
203
+ accepted_at: z.ZodNullable<z.ZodString>;
204
+ declined_at: z.ZodNullable<z.ZodString>;
205
+ decline_reason: z.ZodNullable<z.ZodString>;
206
+ retracted_at: z.ZodNullable<z.ZodString>;
207
+ superseded_at: z.ZodNullable<z.ZodString>;
208
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
209
+ }, z.core.$strict>;
210
+ }, z.core.$strict>;
211
+ output: z.ZodVoid;
212
+ async: true;
213
+ description: string;
214
+ };
215
+ export declare const permit_offer_retracted_notification_spec: {
216
+ method: string;
217
+ kind: "remote_notification";
218
+ initiator: "backend";
219
+ auth: null;
220
+ side_effects: true;
221
+ input: z.ZodObject<{
222
+ offer: z.ZodObject<{
223
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
224
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
225
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
226
+ role: z.ZodString;
227
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
228
+ message: z.ZodNullable<z.ZodString>;
229
+ created_at: z.ZodString;
230
+ expires_at: z.ZodString;
231
+ accepted_at: z.ZodNullable<z.ZodString>;
232
+ declined_at: z.ZodNullable<z.ZodString>;
233
+ decline_reason: z.ZodNullable<z.ZodString>;
234
+ retracted_at: z.ZodNullable<z.ZodString>;
235
+ superseded_at: z.ZodNullable<z.ZodString>;
236
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
237
+ }, z.core.$strict>;
238
+ }, z.core.$strict>;
239
+ output: z.ZodVoid;
240
+ async: true;
241
+ description: string;
242
+ };
243
+ export declare const permit_offer_accepted_notification_spec: {
244
+ method: string;
245
+ kind: "remote_notification";
246
+ initiator: "backend";
247
+ auth: null;
248
+ side_effects: true;
249
+ input: z.ZodObject<{
250
+ offer: z.ZodObject<{
251
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
252
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
253
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
254
+ role: z.ZodString;
255
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
256
+ message: z.ZodNullable<z.ZodString>;
257
+ created_at: z.ZodString;
258
+ expires_at: z.ZodString;
259
+ accepted_at: z.ZodNullable<z.ZodString>;
260
+ declined_at: z.ZodNullable<z.ZodString>;
261
+ decline_reason: z.ZodNullable<z.ZodString>;
262
+ retracted_at: z.ZodNullable<z.ZodString>;
263
+ superseded_at: z.ZodNullable<z.ZodString>;
264
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
265
+ }, z.core.$strict>;
266
+ }, z.core.$strict>;
267
+ output: z.ZodVoid;
268
+ async: true;
269
+ description: string;
270
+ };
271
+ export declare const permit_offer_declined_notification_spec: {
272
+ method: string;
273
+ kind: "remote_notification";
274
+ initiator: "backend";
275
+ auth: null;
276
+ side_effects: true;
277
+ input: z.ZodObject<{
278
+ offer: z.ZodObject<{
279
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
280
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
281
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
282
+ role: z.ZodString;
283
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
284
+ message: z.ZodNullable<z.ZodString>;
285
+ created_at: z.ZodString;
286
+ expires_at: z.ZodString;
287
+ accepted_at: z.ZodNullable<z.ZodString>;
288
+ declined_at: z.ZodNullable<z.ZodString>;
289
+ decline_reason: z.ZodNullable<z.ZodString>;
290
+ retracted_at: z.ZodNullable<z.ZodString>;
291
+ superseded_at: z.ZodNullable<z.ZodString>;
292
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
293
+ }, z.core.$strict>;
294
+ }, z.core.$strict>;
295
+ output: z.ZodVoid;
296
+ async: true;
297
+ description: string;
298
+ };
299
+ export declare const permit_offer_supersede_notification_spec: {
300
+ method: string;
301
+ kind: "remote_notification";
302
+ initiator: "backend";
303
+ auth: null;
304
+ side_effects: true;
305
+ input: z.ZodObject<{
306
+ offer: z.ZodObject<{
307
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
308
+ from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
309
+ to_account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
310
+ role: z.ZodString;
311
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
312
+ message: z.ZodNullable<z.ZodString>;
313
+ created_at: z.ZodString;
314
+ expires_at: z.ZodString;
315
+ accepted_at: z.ZodNullable<z.ZodString>;
316
+ declined_at: z.ZodNullable<z.ZodString>;
317
+ decline_reason: z.ZodNullable<z.ZodString>;
318
+ retracted_at: z.ZodNullable<z.ZodString>;
319
+ superseded_at: z.ZodNullable<z.ZodString>;
320
+ resulting_permit_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
321
+ }, z.core.$strict>;
322
+ reason: z.ZodEnum<{
323
+ sibling_accepted: "sibling_accepted";
324
+ permit_revoked: "permit_revoked";
325
+ }>;
326
+ cause_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
327
+ }, z.core.$strict>;
328
+ output: z.ZodVoid;
329
+ async: true;
330
+ description: string;
331
+ };
332
+ export declare const permit_revoke_notification_spec: {
333
+ method: string;
334
+ kind: "remote_notification";
335
+ initiator: "backend";
336
+ auth: null;
337
+ side_effects: true;
338
+ input: z.ZodObject<{
339
+ permit_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
340
+ role: z.ZodString;
341
+ scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
342
+ reason: z.ZodNullable<z.ZodString>;
343
+ }, z.core.$strict>;
344
+ output: z.ZodVoid;
345
+ async: true;
346
+ description: string;
347
+ };
348
+ /**
349
+ * SSE/WS event specs for the consentful-permits notification surface.
350
+ *
351
+ * Pass to `create_app_server`'s `event_specs` so the attack surface reflects
352
+ * them and DEV-mode `create_validated_broadcaster` catches payload drift.
353
+ */
354
+ export declare const PERMIT_OFFER_NOTIFICATION_SPECS: Array<EventSpec>;
355
+ export declare const build_permit_offer_received_notification: (params: PermitOfferReceivedParams) => JsonrpcNotification;
356
+ export declare const build_permit_offer_retracted_notification: (params: PermitOfferRetractedParams) => JsonrpcNotification;
357
+ export declare const build_permit_offer_accepted_notification: (params: PermitOfferAcceptedParams) => JsonrpcNotification;
358
+ export declare const build_permit_offer_declined_notification: (params: PermitOfferDeclinedParams) => JsonrpcNotification;
359
+ export declare const build_permit_offer_supersede_notification: (params: PermitOfferSupersedeParams) => JsonrpcNotification;
360
+ export declare const build_permit_revoke_notification: (params: PermitRevokeParams) => JsonrpcNotification;
361
+ //# sourceMappingURL=permit_offer_notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permit_offer_notifications.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/permit_offer_notifications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Permit offer WebSocket notification specs, builders, and the narrow
3
+ * `NotificationSender` interface that decouples offer/revoke send sites
4
+ * from `BackendWebsocketTransport`.
5
+ *
6
+ * Six `RemoteNotificationActionSpec`s cover the consentful-permits
7
+ * lifecycle events the server pushes to affected accounts:
8
+ *
9
+ * - `permit_offer_received` → recipient's sockets when an offer is created
10
+ * - `permit_offer_retracted` → recipient's sockets when a grantor retracts
11
+ * - `permit_offer_accepted` → grantor's sockets when the recipient accepts
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
15
+ * - `permit_revoke` → revokee's sockets when one of their active permits
16
+ * is revoked (companion to the `permit_revoke` audit event)
17
+ *
18
+ * Payloads are flat and normalized — `PermitOfferJson` for the offer-lifecycle
19
+ * notifications (decline reason rides on `offer.decline_reason`, not a
20
+ * sibling field), and `{permit_id, role, scope_id, reason?}` for `permit_revoke`. The
21
+ * revokee/grantor/recipient account id travels via the send target (the
22
+ * `NotificationSender.send_to_account` argument), not in the payload.
23
+ *
24
+ * The specs surface as `EventSpec`s via `create_action_event_spec` — callers
25
+ * append `PERMIT_OFFER_NOTIFICATION_SPECS` to their `event_specs` on
26
+ * `create_app_server` so the surface reflects them and DEV-mode broadcast
27
+ * validation catches payload drift.
28
+ *
29
+ * @module
30
+ */
31
+ import { z } from 'zod';
32
+ import { create_action_event_spec } from '../actions/action_bridge.js';
33
+ import { create_jsonrpc_notification } from '../http/jsonrpc_helpers.js';
34
+ import { Uuid as UuidSchema } from '../uuid.js';
35
+ import { RoleName } from './role_schema.js';
36
+ import { PermitOfferJson } from './permit_offer_schema.js';
37
+ import { PERMIT_REVOKED_REASON_LENGTH_MAX } from './account_schema.js';
38
+ // -- Method constants -------------------------------------------------------
39
+ export const PERMIT_OFFER_RECEIVED_NOTIFICATION_METHOD = 'permit_offer_received';
40
+ export const PERMIT_OFFER_RETRACTED_NOTIFICATION_METHOD = 'permit_offer_retracted';
41
+ export const PERMIT_OFFER_ACCEPTED_NOTIFICATION_METHOD = 'permit_offer_accepted';
42
+ export const PERMIT_OFFER_DECLINED_NOTIFICATION_METHOD = 'permit_offer_declined';
43
+ export const PERMIT_OFFER_SUPERSEDE_NOTIFICATION_METHOD = 'permit_offer_supersede';
44
+ export const PERMIT_REVOKE_NOTIFICATION_METHOD = 'permit_revoke';
45
+ // -- Params schemas ---------------------------------------------------------
46
+ /** Params for `permit_offer_received` — offer delivered to its recipient. */
47
+ export const PermitOfferReceivedParams = z.strictObject({
48
+ offer: PermitOfferJson,
49
+ });
50
+ /** Params for `permit_offer_retracted` — grantor-side retraction. */
51
+ export const PermitOfferRetractedParams = z.strictObject({
52
+ offer: PermitOfferJson,
53
+ });
54
+ /** Params for `permit_offer_accepted` — recipient accepted the offer. */
55
+ export const PermitOfferAcceptedParams = z.strictObject({
56
+ offer: PermitOfferJson,
57
+ });
58
+ /**
59
+ * Params for `permit_offer_declined`. The decline reason (if any) rides along
60
+ * inside `offer.decline_reason` — the DB stamps it on the offer row during
61
+ * decline, so a sibling `reason` field would just duplicate it.
62
+ */
63
+ export const PermitOfferDeclinedParams = z.strictObject({
64
+ offer: PermitOfferJson,
65
+ });
66
+ /**
67
+ * Params for `permit_offer_supersede`. Fires to the grantor's sockets when
68
+ * their pending offer is obsoleted — either by a sibling accept
69
+ * (`reason: 'sibling_accepted'`) or by revoke of the resulting permit
70
+ * (`reason: 'permit_revoked'`). `cause_id` points at the accepted offer id
71
+ * or the revoked permit id respectively.
72
+ */
73
+ export const PermitOfferSupersedeParams = z.strictObject({
74
+ offer: PermitOfferJson,
75
+ reason: z.enum(['sibling_accepted', 'permit_revoked']),
76
+ cause_id: UuidSchema,
77
+ });
78
+ /**
79
+ * Params for `permit_revoke`. Delivered to the revokee's sockets when one
80
+ * of their active permits is revoked. Flat wire shape — `revoked_by` is
81
+ * admin-UI-visible but deliberately omitted here (the revokee doesn't need
82
+ * to learn the admin's identity). Target account is implicit in the send
83
+ * target.
84
+ */
85
+ export const PermitRevokeParams = z.strictObject({
86
+ permit_id: UuidSchema,
87
+ role: RoleName,
88
+ scope_id: UuidSchema.nullable(),
89
+ reason: z.string().max(PERMIT_REVOKED_REASON_LENGTH_MAX).nullable(),
90
+ });
91
+ // -- Action specs -----------------------------------------------------------
92
+ export const permit_offer_received_notification_spec = {
93
+ method: PERMIT_OFFER_RECEIVED_NOTIFICATION_METHOD,
94
+ kind: 'remote_notification',
95
+ initiator: 'backend',
96
+ auth: null,
97
+ side_effects: true,
98
+ input: PermitOfferReceivedParams,
99
+ output: z.void(),
100
+ async: true,
101
+ description: 'A new permit offer arrived in the recipient’s inbox.',
102
+ };
103
+ export const permit_offer_retracted_notification_spec = {
104
+ method: PERMIT_OFFER_RETRACTED_NOTIFICATION_METHOD,
105
+ kind: 'remote_notification',
106
+ initiator: 'backend',
107
+ auth: null,
108
+ side_effects: true,
109
+ input: PermitOfferRetractedParams,
110
+ output: z.void(),
111
+ async: true,
112
+ description: 'A pending permit offer was retracted by its grantor.',
113
+ };
114
+ export const permit_offer_accepted_notification_spec = {
115
+ method: PERMIT_OFFER_ACCEPTED_NOTIFICATION_METHOD,
116
+ kind: 'remote_notification',
117
+ initiator: 'backend',
118
+ auth: null,
119
+ side_effects: true,
120
+ input: PermitOfferAcceptedParams,
121
+ output: z.void(),
122
+ async: true,
123
+ description: 'A pending permit offer was accepted by its recipient.',
124
+ };
125
+ export const permit_offer_declined_notification_spec = {
126
+ method: PERMIT_OFFER_DECLINED_NOTIFICATION_METHOD,
127
+ kind: 'remote_notification',
128
+ initiator: 'backend',
129
+ auth: null,
130
+ side_effects: true,
131
+ input: PermitOfferDeclinedParams,
132
+ output: z.void(),
133
+ async: true,
134
+ description: 'A pending permit offer was declined by its recipient.',
135
+ };
136
+ export const permit_offer_supersede_notification_spec = {
137
+ method: PERMIT_OFFER_SUPERSEDE_NOTIFICATION_METHOD,
138
+ kind: 'remote_notification',
139
+ initiator: 'backend',
140
+ auth: null,
141
+ side_effects: true,
142
+ input: PermitOfferSupersedeParams,
143
+ output: z.void(),
144
+ async: true,
145
+ description: 'A grantor’s pending permit offer was obsoleted by a sibling accept or by revoke of the resulting permit.',
146
+ };
147
+ export const permit_revoke_notification_spec = {
148
+ method: PERMIT_REVOKE_NOTIFICATION_METHOD,
149
+ kind: 'remote_notification',
150
+ initiator: 'backend',
151
+ auth: null,
152
+ side_effects: true,
153
+ input: PermitRevokeParams,
154
+ output: z.void(),
155
+ async: true,
156
+ description: 'An active permit on the revokee’s account was revoked.',
157
+ };
158
+ // -- EventSpec surface ------------------------------------------------------
159
+ /**
160
+ * SSE/WS event specs for the consentful-permits notification surface.
161
+ *
162
+ * Pass to `create_app_server`'s `event_specs` so the attack surface reflects
163
+ * them and DEV-mode `create_validated_broadcaster` catches payload drift.
164
+ */
165
+ export const PERMIT_OFFER_NOTIFICATION_SPECS = [
166
+ create_action_event_spec(permit_offer_received_notification_spec),
167
+ create_action_event_spec(permit_offer_retracted_notification_spec),
168
+ create_action_event_spec(permit_offer_accepted_notification_spec),
169
+ create_action_event_spec(permit_offer_declined_notification_spec),
170
+ create_action_event_spec(permit_offer_supersede_notification_spec),
171
+ create_action_event_spec(permit_revoke_notification_spec),
172
+ ];
173
+ // -- Notification builders --------------------------------------------------
174
+ export const build_permit_offer_received_notification = (params) => create_jsonrpc_notification(PERMIT_OFFER_RECEIVED_NOTIFICATION_METHOD, params);
175
+ export const build_permit_offer_retracted_notification = (params) => create_jsonrpc_notification(PERMIT_OFFER_RETRACTED_NOTIFICATION_METHOD, params);
176
+ export const build_permit_offer_accepted_notification = (params) => create_jsonrpc_notification(PERMIT_OFFER_ACCEPTED_NOTIFICATION_METHOD, params);
177
+ export const build_permit_offer_declined_notification = (params) => create_jsonrpc_notification(PERMIT_OFFER_DECLINED_NOTIFICATION_METHOD, params);
178
+ export const build_permit_offer_supersede_notification = (params) => create_jsonrpc_notification(PERMIT_OFFER_SUPERSEDE_NOTIFICATION_METHOD, params);
179
+ export const build_permit_revoke_notification = (params) => create_jsonrpc_notification(PERMIT_REVOKE_NOTIFICATION_METHOD, params);