@fuzdev/fuz_app 0.54.0 → 0.56.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 (348) hide show
  1. package/dist/actions/CLAUDE.md +214 -103
  2. package/dist/actions/action_bridge.d.ts +8 -5
  3. package/dist/actions/action_bridge.d.ts.map +1 -1
  4. package/dist/actions/action_bridge.js +1 -11
  5. package/dist/actions/action_codegen.d.ts +32 -0
  6. package/dist/actions/action_codegen.d.ts.map +1 -1
  7. package/dist/actions/action_codegen.js +35 -15
  8. package/dist/actions/action_registry.d.ts.map +1 -1
  9. package/dist/actions/action_registry.js +5 -2
  10. package/dist/actions/action_rpc.d.ts +141 -22
  11. package/dist/actions/action_rpc.d.ts.map +1 -1
  12. package/dist/actions/action_rpc.js +106 -187
  13. package/dist/actions/action_spec.d.ts +55 -16
  14. package/dist/actions/action_spec.d.ts.map +1 -1
  15. package/dist/actions/action_spec.js +16 -11
  16. package/dist/actions/action_types.d.ts +28 -60
  17. package/dist/actions/action_types.d.ts.map +1 -1
  18. package/dist/actions/action_types.js +13 -5
  19. package/dist/actions/broadcast_api.d.ts +2 -2
  20. package/dist/actions/broadcast_api.js +2 -2
  21. package/dist/actions/compile_action_registry.d.ts +50 -0
  22. package/dist/actions/compile_action_registry.d.ts.map +1 -0
  23. package/dist/actions/compile_action_registry.js +69 -0
  24. package/dist/actions/heartbeat.d.ts +8 -4
  25. package/dist/actions/heartbeat.d.ts.map +1 -1
  26. package/dist/actions/heartbeat.js +5 -4
  27. package/dist/actions/perform_action.d.ts +145 -0
  28. package/dist/actions/perform_action.d.ts.map +1 -0
  29. package/dist/actions/perform_action.js +258 -0
  30. package/dist/actions/register_action_ws.d.ts +46 -40
  31. package/dist/actions/register_action_ws.d.ts.map +1 -1
  32. package/dist/actions/register_action_ws.js +101 -159
  33. package/dist/actions/register_ws_endpoint.d.ts +15 -10
  34. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  35. package/dist/actions/register_ws_endpoint.js +54 -7
  36. package/dist/actions/transports.d.ts.map +1 -1
  37. package/dist/actions/transports.js +0 -4
  38. package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
  39. package/dist/actions/transports_ws_auth_guard.js +1 -1
  40. package/dist/actions/transports_ws_backend.d.ts +1 -1
  41. package/dist/actions/transports_ws_backend.js +1 -1
  42. package/dist/auth/CLAUDE.md +794 -410
  43. package/dist/auth/account_action_specs.d.ts +28 -7
  44. package/dist/auth/account_action_specs.d.ts.map +1 -1
  45. package/dist/auth/account_action_specs.js +7 -7
  46. package/dist/auth/account_actions.d.ts +7 -13
  47. package/dist/auth/account_actions.d.ts.map +1 -1
  48. package/dist/auth/account_actions.js +26 -35
  49. package/dist/auth/account_queries.d.ts +52 -16
  50. package/dist/auth/account_queries.d.ts.map +1 -1
  51. package/dist/auth/account_queries.js +87 -38
  52. package/dist/auth/account_routes.d.ts +9 -11
  53. package/dist/auth/account_routes.d.ts.map +1 -1
  54. package/dist/auth/account_routes.js +118 -46
  55. package/dist/auth/account_schema.d.ts +46 -35
  56. package/dist/auth/account_schema.d.ts.map +1 -1
  57. package/dist/auth/account_schema.js +21 -28
  58. package/dist/auth/admin_action_specs.d.ts +100 -32
  59. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  60. package/dist/auth/admin_action_specs.js +64 -33
  61. package/dist/auth/admin_actions.d.ts +13 -19
  62. package/dist/auth/admin_actions.d.ts.map +1 -1
  63. package/dist/auth/admin_actions.js +37 -41
  64. package/dist/auth/audit_emitter.d.ts +160 -0
  65. package/dist/auth/audit_emitter.d.ts.map +1 -0
  66. package/dist/auth/audit_emitter.js +83 -0
  67. package/dist/auth/audit_log_queries.d.ts +17 -48
  68. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  69. package/dist/auth/audit_log_queries.js +20 -56
  70. package/dist/auth/audit_log_routes.d.ts +1 -1
  71. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  72. package/dist/auth/audit_log_routes.js +7 -3
  73. package/dist/auth/audit_log_schema.d.ts +92 -32
  74. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  75. package/dist/auth/audit_log_schema.js +75 -46
  76. package/dist/auth/auth_guard_resolver.d.ts +44 -0
  77. package/dist/auth/auth_guard_resolver.d.ts.map +1 -0
  78. package/dist/auth/auth_guard_resolver.js +56 -0
  79. package/dist/auth/bearer_auth.d.ts +9 -7
  80. package/dist/auth/bearer_auth.d.ts.map +1 -1
  81. package/dist/auth/bearer_auth.js +13 -21
  82. package/dist/auth/bootstrap_account.d.ts +7 -7
  83. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  84. package/dist/auth/bootstrap_account.js +7 -7
  85. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  86. package/dist/auth/bootstrap_routes.js +11 -10
  87. package/dist/auth/cleanup.d.ts +20 -26
  88. package/dist/auth/cleanup.d.ts.map +1 -1
  89. package/dist/auth/cleanup.js +33 -42
  90. package/dist/auth/credential_type_schema.d.ts +115 -0
  91. package/dist/auth/credential_type_schema.d.ts.map +1 -0
  92. package/dist/auth/credential_type_schema.js +127 -0
  93. package/dist/auth/daemon_token_middleware.d.ts +23 -11
  94. package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
  95. package/dist/auth/daemon_token_middleware.js +28 -22
  96. package/dist/auth/ddl.d.ts +2 -2
  97. package/dist/auth/ddl.d.ts.map +1 -1
  98. package/dist/auth/ddl.js +6 -6
  99. package/dist/auth/deps.d.ts +7 -18
  100. package/dist/auth/deps.d.ts.map +1 -1
  101. package/dist/auth/grant_path_schema.d.ts +117 -0
  102. package/dist/auth/grant_path_schema.d.ts.map +1 -0
  103. package/dist/auth/grant_path_schema.js +137 -0
  104. package/dist/auth/invite_queries.d.ts +12 -1
  105. package/dist/auth/invite_queries.d.ts.map +1 -1
  106. package/dist/auth/invite_queries.js +12 -1
  107. package/dist/auth/invite_schema.d.ts +1 -1
  108. package/dist/auth/invite_schema.d.ts.map +1 -1
  109. package/dist/auth/invite_schema.js +1 -1
  110. package/dist/auth/middleware.d.ts.map +1 -1
  111. package/dist/auth/middleware.js +9 -4
  112. package/dist/auth/migrations.d.ts +37 -14
  113. package/dist/auth/migrations.d.ts.map +1 -1
  114. package/dist/auth/migrations.js +79 -32
  115. package/dist/auth/request_context.d.ts +331 -61
  116. package/dist/auth/request_context.d.ts.map +1 -1
  117. package/dist/auth/request_context.js +378 -95
  118. package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +163 -94
  119. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -0
  120. package/dist/auth/role_grant_offer_action_specs.js +262 -0
  121. package/dist/auth/role_grant_offer_actions.d.ts +104 -0
  122. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -0
  123. package/dist/auth/role_grant_offer_actions.js +473 -0
  124. package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +90 -70
  125. package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -0
  126. package/dist/auth/role_grant_offer_notifications.js +182 -0
  127. package/dist/auth/role_grant_offer_queries.d.ts +242 -0
  128. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
  129. package/dist/auth/role_grant_offer_queries.js +533 -0
  130. package/dist/auth/role_grant_offer_schema.d.ts +150 -0
  131. package/dist/auth/role_grant_offer_schema.d.ts.map +1 -0
  132. package/dist/auth/{permit_offer_schema.js → role_grant_offer_schema.js} +60 -36
  133. package/dist/auth/role_grant_queries.d.ts +231 -0
  134. package/dist/auth/role_grant_queries.d.ts.map +1 -0
  135. package/dist/auth/role_grant_queries.js +320 -0
  136. package/dist/auth/role_schema.d.ts +150 -40
  137. package/dist/auth/role_schema.d.ts.map +1 -1
  138. package/dist/auth/role_schema.js +144 -45
  139. package/dist/auth/scope_kind_schema.d.ts +96 -0
  140. package/dist/auth/scope_kind_schema.d.ts.map +1 -0
  141. package/dist/auth/scope_kind_schema.js +94 -0
  142. package/dist/auth/self_service_role_action_specs.d.ts +6 -1
  143. package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
  144. package/dist/auth/self_service_role_action_specs.js +3 -1
  145. package/dist/auth/self_service_role_actions.d.ts +34 -27
  146. package/dist/auth/self_service_role_actions.d.ts.map +1 -1
  147. package/dist/auth/self_service_role_actions.js +68 -48
  148. package/dist/auth/session_cookie.d.ts +43 -6
  149. package/dist/auth/session_cookie.d.ts.map +1 -1
  150. package/dist/auth/session_cookie.js +31 -5
  151. package/dist/auth/session_middleware.d.ts +37 -3
  152. package/dist/auth/session_middleware.d.ts.map +1 -1
  153. package/dist/auth/session_middleware.js +33 -7
  154. package/dist/auth/signup_routes.d.ts.map +1 -1
  155. package/dist/auth/signup_routes.js +48 -19
  156. package/dist/auth/standard_action_specs.d.ts +2 -2
  157. package/dist/auth/standard_action_specs.js +4 -4
  158. package/dist/auth/standard_rpc_actions.d.ts +23 -19
  159. package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
  160. package/dist/auth/standard_rpc_actions.js +12 -12
  161. package/dist/db/migrate.d.ts +12 -8
  162. package/dist/db/migrate.d.ts.map +1 -1
  163. package/dist/db/migrate.js +10 -7
  164. package/dist/dev/setup.d.ts +2 -2
  165. package/dist/dev/setup.d.ts.map +1 -1
  166. package/dist/dev/setup.js +9 -7
  167. package/dist/env/load.d.ts +1 -1
  168. package/dist/env/load.js +1 -1
  169. package/dist/hono_context.d.ts +64 -5
  170. package/dist/hono_context.d.ts.map +1 -1
  171. package/dist/hono_context.js +38 -2
  172. package/dist/http/CLAUDE.md +264 -87
  173. package/dist/http/auth_shape.d.ts +191 -0
  174. package/dist/http/auth_shape.d.ts.map +1 -0
  175. package/dist/http/auth_shape.js +237 -0
  176. package/dist/http/common_routes.js +3 -3
  177. package/dist/http/db_routes.d.ts +4 -0
  178. package/dist/http/db_routes.d.ts.map +1 -1
  179. package/dist/http/db_routes.js +44 -7
  180. package/dist/http/error_schemas.d.ts +132 -19
  181. package/dist/http/error_schemas.d.ts.map +1 -1
  182. package/dist/http/error_schemas.js +132 -40
  183. package/dist/http/jsonrpc_errors.d.ts +27 -2
  184. package/dist/http/jsonrpc_errors.d.ts.map +1 -1
  185. package/dist/http/jsonrpc_errors.js +26 -2
  186. package/dist/http/pending_effects.d.ts +71 -18
  187. package/dist/http/pending_effects.d.ts.map +1 -1
  188. package/dist/http/pending_effects.js +87 -18
  189. package/dist/http/proxy.d.ts +52 -5
  190. package/dist/http/proxy.d.ts.map +1 -1
  191. package/dist/http/proxy.js +92 -14
  192. package/dist/http/route_spec.d.ts +113 -41
  193. package/dist/http/route_spec.d.ts.map +1 -1
  194. package/dist/http/route_spec.js +130 -52
  195. package/dist/http/schema_helpers.d.ts +3 -2
  196. package/dist/http/schema_helpers.d.ts.map +1 -1
  197. package/dist/http/schema_helpers.js +9 -2
  198. package/dist/http/surface.d.ts +2 -1
  199. package/dist/http/surface.d.ts.map +1 -1
  200. package/dist/http/surface.js +1 -2
  201. package/dist/http/surface_query.d.ts +39 -35
  202. package/dist/http/surface_query.d.ts.map +1 -1
  203. package/dist/http/surface_query.js +79 -36
  204. package/dist/primitive_schemas.d.ts +39 -0
  205. package/dist/primitive_schemas.d.ts.map +1 -0
  206. package/dist/primitive_schemas.js +40 -0
  207. package/dist/realtime/sse_auth_guard.d.ts +5 -5
  208. package/dist/realtime/sse_auth_guard.js +9 -9
  209. package/dist/runtime/mock.d.ts +1 -1
  210. package/dist/runtime/mock.js +1 -1
  211. package/dist/server/app_backend.d.ts +14 -11
  212. package/dist/server/app_backend.d.ts.map +1 -1
  213. package/dist/server/app_backend.js +12 -8
  214. package/dist/server/app_server.d.ts +7 -7
  215. package/dist/server/app_server.d.ts.map +1 -1
  216. package/dist/server/app_server.js +36 -31
  217. package/dist/server/validate_nginx.d.ts +1 -1
  218. package/dist/server/validate_nginx.js +1 -1
  219. package/dist/testing/CLAUDE.md +73 -55
  220. package/dist/testing/admin_integration.d.ts +5 -6
  221. package/dist/testing/admin_integration.d.ts.map +1 -1
  222. package/dist/testing/admin_integration.js +100 -96
  223. package/dist/testing/adversarial_headers.js +1 -1
  224. package/dist/testing/app_server.d.ts +11 -14
  225. package/dist/testing/app_server.d.ts.map +1 -1
  226. package/dist/testing/app_server.js +18 -17
  227. package/dist/testing/assertions.d.ts.map +1 -1
  228. package/dist/testing/assertions.js +2 -1
  229. package/dist/testing/attack_surface.d.ts.map +1 -1
  230. package/dist/testing/attack_surface.js +15 -9
  231. package/dist/testing/audit_completeness.d.ts +2 -2
  232. package/dist/testing/audit_completeness.d.ts.map +1 -1
  233. package/dist/testing/audit_completeness.js +53 -39
  234. package/dist/testing/auth_apps.d.ts +5 -4
  235. package/dist/testing/auth_apps.d.ts.map +1 -1
  236. package/dist/testing/auth_apps.js +28 -22
  237. package/dist/testing/data_exposure.d.ts.map +1 -1
  238. package/dist/testing/data_exposure.js +5 -5
  239. package/dist/testing/db.d.ts +1 -1
  240. package/dist/testing/db.d.ts.map +1 -1
  241. package/dist/testing/db.js +4 -4
  242. package/dist/testing/db_entities.d.ts +22 -0
  243. package/dist/testing/db_entities.d.ts.map +1 -0
  244. package/dist/testing/db_entities.js +28 -0
  245. package/dist/testing/entities.d.ts +10 -8
  246. package/dist/testing/entities.d.ts.map +1 -1
  247. package/dist/testing/entities.js +22 -18
  248. package/dist/testing/integration.d.ts.map +1 -1
  249. package/dist/testing/integration.js +13 -14
  250. package/dist/testing/integration_helpers.d.ts +8 -6
  251. package/dist/testing/integration_helpers.d.ts.map +1 -1
  252. package/dist/testing/integration_helpers.js +29 -23
  253. package/dist/testing/middleware.d.ts +15 -11
  254. package/dist/testing/middleware.d.ts.map +1 -1
  255. package/dist/testing/middleware.js +75 -32
  256. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  257. package/dist/testing/rpc_attack_surface.js +40 -24
  258. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  259. package/dist/testing/rpc_helpers.js +3 -1
  260. package/dist/testing/rpc_round_trip.d.ts +1 -1
  261. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  262. package/dist/testing/rpc_round_trip.js +14 -13
  263. package/dist/testing/sse_round_trip.d.ts +3 -4
  264. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  265. package/dist/testing/sse_round_trip.js +7 -11
  266. package/dist/testing/standard.d.ts +1 -1
  267. package/dist/testing/stubs.d.ts +25 -0
  268. package/dist/testing/stubs.d.ts.map +1 -1
  269. package/dist/testing/stubs.js +43 -2
  270. package/dist/testing/surface_invariants.d.ts +2 -2
  271. package/dist/testing/ws_round_trip.d.ts +12 -13
  272. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  273. package/dist/testing/ws_round_trip.js +24 -12
  274. package/dist/ui/AdminAccounts.svelte +23 -20
  275. package/dist/ui/AdminOverview.svelte +15 -13
  276. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  277. package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
  278. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
  279. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
  280. package/dist/ui/BootstrapForm.svelte +1 -1
  281. package/dist/ui/CLAUDE.md +65 -59
  282. package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +37 -22
  283. package/dist/ui/RoleGrantOfferForm.svelte.d.ts +20 -0
  284. package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
  285. package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
  286. package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
  287. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
  288. package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
  289. package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
  290. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
  291. package/dist/ui/SignupForm.svelte +1 -1
  292. package/dist/ui/SurfaceExplorer.svelte +35 -15
  293. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  294. package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
  295. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  296. package/dist/ui/account_sessions_state.svelte.js +2 -3
  297. package/dist/ui/admin_accounts_state.svelte.d.ts +25 -18
  298. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  299. package/dist/ui/admin_accounts_state.svelte.js +28 -17
  300. package/dist/ui/admin_rpc_adapters.d.ts +20 -20
  301. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  302. package/dist/ui/admin_rpc_adapters.js +17 -17
  303. package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
  304. package/dist/ui/admin_sessions_state.svelte.js +2 -2
  305. package/dist/ui/audit_log_state.svelte.d.ts +7 -7
  306. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  307. package/dist/ui/audit_log_state.svelte.js +6 -6
  308. package/dist/ui/auth_state.svelte.d.ts +3 -3
  309. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  310. package/dist/ui/auth_state.svelte.js +6 -6
  311. package/dist/ui/format_scope.d.ts +2 -2
  312. package/dist/ui/format_scope.js +2 -2
  313. package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +39 -31
  314. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
  315. package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +25 -19
  316. package/dist/ui/ui_format.js +2 -2
  317. package/package.json +3 -3
  318. package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
  319. package/dist/auth/permit_offer_action_specs.js +0 -227
  320. package/dist/auth/permit_offer_actions.d.ts +0 -110
  321. package/dist/auth/permit_offer_actions.d.ts.map +0 -1
  322. package/dist/auth/permit_offer_actions.js +0 -452
  323. package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
  324. package/dist/auth/permit_offer_notifications.js +0 -182
  325. package/dist/auth/permit_offer_queries.d.ts +0 -183
  326. package/dist/auth/permit_offer_queries.d.ts.map +0 -1
  327. package/dist/auth/permit_offer_queries.js +0 -408
  328. package/dist/auth/permit_offer_schema.d.ts +0 -103
  329. package/dist/auth/permit_offer_schema.d.ts.map +0 -1
  330. package/dist/auth/permit_queries.d.ts +0 -210
  331. package/dist/auth/permit_queries.d.ts.map +0 -1
  332. package/dist/auth/permit_queries.js +0 -294
  333. package/dist/auth/require_keeper.d.ts +0 -20
  334. package/dist/auth/require_keeper.d.ts.map +0 -1
  335. package/dist/auth/require_keeper.js +0 -35
  336. package/dist/auth/route_guards.d.ts +0 -21
  337. package/dist/auth/route_guards.d.ts.map +0 -1
  338. package/dist/auth/route_guards.js +0 -32
  339. package/dist/auth/session_lifecycle.d.ts +0 -37
  340. package/dist/auth/session_lifecycle.d.ts.map +0 -1
  341. package/dist/auth/session_lifecycle.js +0 -29
  342. package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
  343. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
  344. package/dist/ui/PermitOfferForm.svelte.d.ts +0 -14
  345. package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
  346. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
  347. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
  348. package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
@@ -13,12 +13,12 @@ import { Hono } from 'hono';
13
13
  import { Logger } from '@fuzdev/fuz_util/log.js';
14
14
  import { create_bearer_auth_middleware } from '../auth/bearer_auth.js';
15
15
  import { query_validate_api_token } from '../auth/api_token_queries.js';
16
- import { query_account_by_id, query_actor_by_account } from '../auth/account_queries.js';
17
- import { query_permit_find_active_for_actor } from '../auth/permit_queries.js';
16
+ import { query_account_by_id, query_actor_by_id, query_actors_by_account, } from '../auth/account_queries.js';
17
+ import { query_role_grant_find_active_for_actor } from '../auth/role_grant_queries.js';
18
18
  import { create_proxy_middleware, get_client_ip } from '../http/proxy.js';
19
19
  import { verify_request_source, parse_allowed_origins } from '../http/origin.js';
20
20
  import { REQUEST_CONTEXT_KEY } from '../auth/request_context.js';
21
- import { AUTH_API_TOKEN_ID_KEY, CREDENTIAL_TYPE_KEY } from '../hono_context.js';
21
+ import { ACCOUNT_ID_KEY, AUTH_API_TOKEN_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY, } from '../hono_context.js';
22
22
  import { ApiError } from '../http/error_schemas.js';
23
23
  // Mock the query modules so test cases can control return values.
24
24
  // vi.mock() is hoisted by vitest, so these run before any imports resolve.
@@ -27,10 +27,11 @@ vi.mock('../auth/api_token_queries.js', () => ({
27
27
  }));
28
28
  vi.mock('../auth/account_queries.js', () => ({
29
29
  query_account_by_id: vi.fn(),
30
- query_actor_by_account: vi.fn(),
30
+ query_actor_by_id: vi.fn(),
31
+ query_actors_by_account: vi.fn(),
31
32
  }));
32
- vi.mock('../auth/permit_queries.js', () => ({
33
- query_permit_find_active_for_actor: vi.fn(),
33
+ vi.mock('../auth/role_grant_queries.js', () => ({
34
+ query_role_grant_find_active_for_actor: vi.fn(),
34
35
  }));
35
36
  /** Stub `QueryDeps` for bearer auth tests (no real DB needed). */
36
37
  const STUB_DEPS = { db: {} };
@@ -38,32 +39,48 @@ const STUB_DEPS = { db: {} };
38
39
  * Create mock dependencies for `create_bearer_auth_middleware`, configured per test case.
39
40
  *
40
41
  * Configures the module-level mocks for `query_validate_api_token`,
41
- * `query_account_by_id`, `query_actor_by_account`, and `query_permit_find_active_for_actor`
42
+ * `query_account_by_id`, `query_actor_by_id`, and `query_role_grant_find_active_for_actor`
42
43
  * so each test case controls return values independently.
43
44
  *
44
45
  * @returns mocks bundle with spy references
45
46
  * @mutates module-level `vi.mock` registrations for `api_token_queries`,
46
- * `account_queries`, and `permit_queries` — each call resets and re-binds
47
+ * `account_queries`, and `role_grant_queries` — each call resets and re-binds
47
48
  * the four spies, so cases run in sequence without bleeding state.
48
49
  */
49
50
  export const create_bearer_auth_mocks = (tc) => {
50
51
  const mock_validate = vi.mocked(query_validate_api_token);
51
52
  const mock_find_by_id = vi.mocked(query_account_by_id);
52
- const mock_find_by_account = vi.mocked(query_actor_by_account);
53
- const mock_find_active_for_actor = vi.mocked(query_permit_find_active_for_actor);
53
+ const mock_find_actor_by_id = vi.mocked(query_actor_by_id);
54
+ const mock_find_actors_by_account = vi.mocked(query_actors_by_account);
55
+ const mock_find_active_for_actor = vi.mocked(query_role_grant_find_active_for_actor);
54
56
  mock_validate
55
57
  .mockReset()
56
58
  .mockImplementation(() => Promise.resolve(tc.mock_validate_result));
57
59
  mock_find_by_id
58
60
  .mockReset()
59
61
  .mockImplementation(() => Promise.resolve(tc.mock_find_by_id_result));
60
- mock_find_by_account
62
+ mock_find_actor_by_id
61
63
  .mockReset()
62
- .mockImplementation(() => Promise.resolve(tc.mock_find_by_account_result));
64
+ .mockImplementation(() => Promise.resolve(tc.mock_find_actor_by_id_result));
65
+ // `resolve_acting_actor` enumerates actors. Default: wrap the
66
+ // `mock_find_actor_by_id_result` in a single-element array so
67
+ // single-actor account scenarios resolve transparently; empty when
68
+ // the actor mock is undefined/null. Multi-actor scenarios should
69
+ // override this directly via `mockResolvedValue`.
70
+ mock_find_actors_by_account.mockReset().mockImplementation(() => {
71
+ const actor = tc.mock_find_actor_by_id_result;
72
+ return Promise.resolve(actor ? [actor] : []);
73
+ });
63
74
  mock_find_active_for_actor
64
75
  .mockReset()
65
- .mockImplementation(() => Promise.resolve(tc.mock_permits_result ?? []));
66
- return { mock_validate, mock_find_by_id, mock_find_by_account, mock_find_active_for_actor };
76
+ .mockImplementation(() => Promise.resolve(tc.mock_role_grants_result ?? []));
77
+ return {
78
+ mock_validate,
79
+ mock_find_by_id,
80
+ mock_find_actor_by_id,
81
+ mock_find_actors_by_account,
82
+ mock_find_active_for_actor,
83
+ };
67
84
  };
68
85
  /** Default client IP set by the proxy stub in test apps. */
69
86
  export const TEST_CLIENT_IP = '127.0.0.1';
@@ -77,11 +94,20 @@ export const create_bearer_auth_test_app = (tc, ip_rate_limiter = null) => {
77
94
  const mocks = create_bearer_auth_mocks(tc);
78
95
  const bearer_middleware = create_bearer_auth_middleware(STUB_DEPS, ip_rate_limiter, new Logger('test', { level: 'off' }));
79
96
  const app = new Hono();
80
- // inject pre-existing request context if the test case specifies one
97
+ // inject pre-existing session identity if the test case specifies one.
98
+ // `pre_context` simulates the session middleware having authenticated
99
+ // the caller — sets `ACCOUNT_ID_KEY` (the account-grain identity bearer
100
+ // auth checks) and pre-populates `REQUEST_CONTEXT_KEY` as a test
101
+ // escape-hatch (production bearer middleware is account-only and never
102
+ // sets this key — see `auth/CLAUDE.md` Production-middleware invariant)
103
+ // so consumer expectations on the full context shape stay testable.
81
104
  if (tc.pre_context) {
105
+ const pre_context = tc.pre_context;
82
106
  app.use('*', async (c, next) => {
83
- c.set(REQUEST_CONTEXT_KEY, tc.pre_context);
107
+ c.set(ACCOUNT_ID_KEY, pre_context.account.id);
108
+ c.set(REQUEST_CONTEXT_KEY, pre_context);
84
109
  c.set(CREDENTIAL_TYPE_KEY, 'session');
110
+ c.set(TEST_CONTEXT_PRESET_KEY, true);
85
111
  await next();
86
112
  });
87
113
  }
@@ -91,19 +117,22 @@ export const create_bearer_auth_test_app = (tc, ip_rate_limiter = null) => {
91
117
  await next();
92
118
  });
93
119
  app.use('/api/*', bearer_middleware);
94
- // route handler echoes full context state for assertions
120
+ // route handler echoes the account-grain identity the middleware writes
121
+ // (bearer auth sets `ACCOUNT_ID_KEY` + `CREDENTIAL_TYPE_KEY` +
122
+ // `AUTH_API_TOKEN_ID_KEY`; it never builds the full request context —
123
+ // that is the dispatcher's authorization phase). `request_context_set`
124
+ // is only true when a test pre-populates it via `pre_context`.
95
125
  app.get('/api/test', (c) => {
96
- const ctx = c.get(REQUEST_CONTEXT_KEY);
126
+ const account_id = c.get(ACCOUNT_ID_KEY);
97
127
  const cred = c.get(CREDENTIAL_TYPE_KEY);
98
128
  const api_token_id = c.get(AUTH_API_TOKEN_ID_KEY);
129
+ const ctx = c.get(REQUEST_CONTEXT_KEY);
99
130
  return c.json({
100
131
  ok: true,
101
- has_context: ctx != null,
132
+ account_id: account_id ?? null,
102
133
  credential_type: cred ?? null,
103
- account_id: ctx?.account.id ?? null,
104
- actor_id: ctx?.actor.id ?? null,
105
- permit_count: ctx?.permits.length ?? 0,
106
134
  api_token_id: api_token_id ?? null,
135
+ request_context_set: ctx != null,
107
136
  });
108
137
  });
109
138
  return { app, mocks };
@@ -141,15 +170,18 @@ export const describe_bearer_auth_cases = (suite_name, cases, ip_rate_limiter =
141
170
  else {
142
171
  assert.ok(mocks.mock_validate.mock.calls.length > 0, 'validate should have been called');
143
172
  }
144
- if (tc.assert_context_set) {
145
- assert.strictEqual(body.has_context, true, 'REQUEST_CONTEXT_KEY should be set');
173
+ if (tc.assert_account_set) {
174
+ assert.ok(body.account_id, 'ACCOUNT_ID_KEY should be set');
175
+ if (tc.expected_account_id !== undefined) {
176
+ assert.strictEqual(body.account_id, tc.expected_account_id, 'ACCOUNT_ID_KEY should match the validated api_token.account_id');
177
+ }
146
178
  assert.strictEqual(body.credential_type, 'api_token', 'CREDENTIAL_TYPE_KEY should be api_token');
147
179
  }
148
180
  if (tc.expected_api_token_id !== undefined) {
149
181
  assert.strictEqual(body.api_token_id, tc.expected_api_token_id, 'AUTH_API_TOKEN_ID_KEY should match the validated api_token.id');
150
182
  }
151
183
  if (tc.assert_context_preserved) {
152
- assert.strictEqual(body.has_context, true, 'original context should be preserved');
184
+ assert.ok(body.account_id, 'pre-existing account_id should be preserved');
153
185
  assert.strictEqual(body.credential_type, 'session', 'credential type should remain session');
154
186
  }
155
187
  if (tc.assert_mocks) {
@@ -177,11 +209,13 @@ export const create_test_middleware_stack_app = (options) => {
177
209
  const allowed_origins_str = options?.allowed_origins ?? 'https://app.example.com';
178
210
  const mock_validate = vi.mocked(query_validate_api_token);
179
211
  const mock_find_by_id = vi.mocked(query_account_by_id);
180
- const mock_find_by_account = vi.mocked(query_actor_by_account);
181
- const mock_find_active_for_actor = vi.mocked(query_permit_find_active_for_actor);
212
+ const mock_find_actor_by_id = vi.mocked(query_actor_by_id);
213
+ const mock_find_actors_by_account = vi.mocked(query_actors_by_account);
214
+ const mock_find_active_for_actor = vi.mocked(query_role_grant_find_active_for_actor);
182
215
  mock_validate.mockReset().mockImplementation(() => Promise.resolve(undefined));
183
216
  mock_find_by_id.mockReset().mockImplementation(() => Promise.resolve(undefined));
184
- mock_find_by_account.mockReset().mockImplementation(() => Promise.resolve(undefined));
217
+ mock_find_actor_by_id.mockReset().mockImplementation(() => Promise.resolve(undefined));
218
+ mock_find_actors_by_account.mockReset().mockImplementation(() => Promise.resolve([]));
185
219
  mock_find_active_for_actor.mockReset().mockImplementation(() => Promise.resolve([]));
186
220
  const get_connection_ip = typeof options?.connection_ip === 'function'
187
221
  ? options.connection_ip
@@ -197,14 +231,23 @@ export const create_test_middleware_stack_app = (options) => {
197
231
  app.use('*', proxy_mw);
198
232
  app.use('/api/*', origin_mw);
199
233
  app.use('/api/*', bearer_mw);
200
- // echo route for assertions
234
+ // echo route for assertions — exposes the account-grain identity bearer
235
+ // auth writes (`ACCOUNT_ID_KEY`); the full request context is the
236
+ // dispatcher's authorization phase concern, not middleware.
201
237
  app.get(TEST_MIDDLEWARE_PATH, (c) => {
202
- const ctx = c.get(REQUEST_CONTEXT_KEY);
238
+ const account_id = c.get(ACCOUNT_ID_KEY);
203
239
  return c.json({
204
240
  ok: true,
205
241
  client_ip: get_client_ip(c),
206
- has_context: ctx != null,
242
+ account_id: account_id ?? null,
207
243
  });
208
244
  });
209
- return { app, mock_validate, mock_find_by_id, mock_find_by_account, mock_find_active_for_actor };
245
+ return {
246
+ app,
247
+ mock_validate,
248
+ mock_find_by_id,
249
+ mock_find_actor_by_id,
250
+ mock_find_actors_by_account,
251
+ mock_find_active_for_actor,
252
+ };
210
253
  };
@@ -1 +1 @@
1
- {"version":3,"file":"rpc_attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAA6C,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAoBnG,uDAAuD;AACvD,MAAM,WAAW,uBAAuB;IACvC,+FAA+F;IAC/F,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACrB;AAodD;;;;;;;;;GASG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,uBAAuB,KAAG,IAOpF,CAAC"}
1
+ {"version":3,"file":"rpc_attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAA6C,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAqBnG,uDAAuD;AACvD,MAAM,WAAW,uBAAuB;IACvC,+FAA+F;IAC/F,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACrB;AA0dD;;;;;;;;;GASG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,uBAAuB,KAAG,IAOpF,CAAC"}
@@ -13,18 +13,23 @@ import './assert_dev_env.js';
13
13
  * @module
14
14
  */
15
15
  import { test, assert, describe } from 'vitest';
16
+ import { is_keeper_auth, is_public_auth, is_role_auth } from '../http/auth_shape.js';
16
17
  import { JSONRPC_ERROR_CODES } from '../http/jsonrpc_errors.js';
17
18
  import { create_auth_test_apps, create_test_app_from_specs, create_test_request_context, select_auth_app, } from './auth_apps.js';
18
19
  import { generate_input_test_cases } from './adversarial_input.js';
20
+ import { generate_valid_body } from './schema_generators.js';
19
21
  import { ERROR_INVALID_JSON_BODY } from '../http/error_schemas.js';
20
22
  import { create_rpc_post_init, create_rpc_get_url, assert_jsonrpc_error_response, } from './rpc_helpers.js';
21
23
  // --- Helpers ---
22
24
  /** Filter RPC methods that require any form of authentication. */
23
- const filter_protected_rpc_methods = (endpoint) => endpoint.methods.filter((m) => m.auth.type !== 'none');
24
- /** Filter RPC methods that require a specific role. */
25
- const filter_role_rpc_methods = (endpoint) => endpoint.methods.filter((m) => m.auth.type === 'role');
26
- /** Filter RPC methods that require keeper auth (daemon_token + keeper role). */
27
- const filter_keeper_rpc_methods = (endpoint) => endpoint.methods.filter((m) => m.auth.type === 'keeper');
25
+ const filter_protected_rpc_methods = (endpoint) => endpoint.methods.filter((m) => !is_public_auth(m.auth));
26
+ /** Filter RPC methods that declare a role gate (`auth.roles?.length`). */
27
+ const filter_role_rpc_methods = (endpoint) => endpoint.methods.filter((m) => is_role_auth(m.auth));
28
+ /**
29
+ * Filter RPC methods that require daemon-token credentials. Today this
30
+ * is the keeper bucket; future credential gates will widen the filter.
31
+ */
32
+ const filter_keeper_rpc_methods = (endpoint) => endpoint.methods.filter((m) => is_keeper_auth(m.auth));
28
33
  /** Find the `RpcAction` source spec for a surface method. */
29
34
  const find_rpc_action = (rpc_endpoint_specs, endpoint_path, method_name) => {
30
35
  const ep = rpc_endpoint_specs.find((e) => e.path === endpoint_path);
@@ -47,7 +52,7 @@ const find_rpc_action = (rpc_endpoint_specs, endpoint_path, method_name) => {
47
52
  */
48
53
  const describe_rpc_auth = (options) => {
49
54
  const { build, roles } = options;
50
- const { surface, route_specs } = build();
55
+ const { surface, route_specs, rpc_endpoints: rpc_endpoint_specs } = build();
51
56
  if (surface.rpc_endpoints.length === 0)
52
57
  return;
53
58
  const apps = create_auth_test_apps(route_specs, roles);
@@ -71,13 +76,18 @@ const describe_rpc_auth = (options) => {
71
76
  if (role_methods.length > 0) {
72
77
  describe('wrong role → forbidden', () => {
73
78
  for (const method of role_methods) {
74
- const wrong_roles = roles.filter((r) => r !== method.auth.role);
79
+ const required_roles = method.auth.roles ?? [];
80
+ const wrong_roles = roles.filter((r) => !required_roles.includes(r));
75
81
  for (const wrong_role of wrong_roles) {
76
- test(`${method.name} (${wrong_role} instead of ${method.auth.role})`, async () => {
82
+ test(`${method.name} (${wrong_role} instead of ${required_roles.join('|')})`, async () => {
77
83
  const app = apps.by_role.get(wrong_role);
78
84
  if (!app)
79
85
  throw new Error(`No test app for role '${wrong_role}'`);
80
- const res = await app.request(endpoint.path, create_rpc_post_init(method.name));
86
+ // Send valid params so we trip the role gate (403), not input
87
+ // validation (400). Dispatcher ordering: 401 → 400 → 403.
88
+ const action = find_rpc_action(rpc_endpoint_specs, endpoint.path, method.name);
89
+ const params = action ? generate_valid_body(action.spec.input) : undefined;
90
+ const res = await app.request(endpoint.path, create_rpc_post_init(method.name, params));
81
91
  assert.strictEqual(res.status, 403, `${method.name} should return 403`);
82
92
  const body = await res.json();
83
93
  assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
@@ -87,8 +97,12 @@ const describe_rpc_auth = (options) => {
87
97
  });
88
98
  describe('authenticated without role → forbidden', () => {
89
99
  for (const method of role_methods) {
90
- test(`${method.name} (${method.auth.role})`, async () => {
91
- const res = await apps.authed.request(endpoint.path, create_rpc_post_init(method.name));
100
+ test(`${method.name} (${(method.auth.roles ?? []).join('|')})`, async () => {
101
+ // Send valid params so we trip the role gate (403), not input
102
+ // validation (400).
103
+ const action = find_rpc_action(rpc_endpoint_specs, endpoint.path, method.name);
104
+ const params = action ? generate_valid_body(action.spec.input) : undefined;
105
+ const res = await apps.authed.request(endpoint.path, create_rpc_post_init(method.name, params));
92
106
  assert.strictEqual(res.status, 403, `${method.name} should return 403`);
93
107
  const body = await res.json();
94
108
  assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
@@ -102,14 +116,16 @@ const describe_rpc_auth = (options) => {
102
116
  const session_app = create_test_app_from_specs(route_specs, create_test_request_context('keeper'), 'session');
103
117
  const api_token_app = create_test_app_from_specs(route_specs, create_test_request_context('keeper'), 'api_token');
104
118
  for (const method of keeper_methods) {
119
+ const action = find_rpc_action(rpc_endpoint_specs, endpoint.path, method.name);
120
+ const valid_params = action ? generate_valid_body(action.spec.input) : undefined;
105
121
  test(`${method.name} rejects session credential`, async () => {
106
- const res = await session_app.request(endpoint.path, create_rpc_post_init(method.name));
122
+ const res = await session_app.request(endpoint.path, create_rpc_post_init(method.name, valid_params));
107
123
  assert.strictEqual(res.status, 403, `${method.name} should reject session credential`);
108
124
  const body = await res.json();
109
125
  assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
110
126
  });
111
127
  test(`${method.name} rejects api_token credential`, async () => {
112
- const res = await api_token_app.request(endpoint.path, create_rpc_post_init(method.name));
128
+ const res = await api_token_app.request(endpoint.path, create_rpc_post_init(method.name, valid_params));
113
129
  assert.strictEqual(res.status, 403, `${method.name} should reject api_token credential`);
114
130
  const body = await res.json();
115
131
  assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
@@ -279,7 +295,7 @@ const describe_rpc_adversarial_envelopes = (options) => {
279
295
  return;
280
296
  // valid JSON but not an object — hits dispatcher's params validation
281
297
  const res = await apps.public.request(`${endpoint.path}?method=${read_method.name}&id=test&params=42`);
282
- // should reject: either invalid_params (step 4) or auth error (step 3)
298
+ // should reject: either invalid_params (validation) or auth error
283
299
  assert.ok(res.status >= 400, `expected error status for non-object params, got ${res.status}`);
284
300
  const body = await res.json();
285
301
  assert_jsonrpc_error_response(body);
@@ -362,16 +378,16 @@ const describe_rpc_adversarial_params = (options) => {
362
378
  // --- Helpers (formatting) ---
363
379
  /** Format a `RouteAuth` as a human-readable label. */
364
380
  const format_auth = (auth) => {
365
- switch (auth.type) {
366
- case 'none':
367
- return 'public';
368
- case 'authenticated':
369
- return 'authenticated';
370
- case 'role':
371
- return `role: ${auth.role}`;
372
- case 'keeper':
373
- return 'keeper';
374
- }
381
+ if (is_public_auth(auth))
382
+ return 'public';
383
+ const parts = [];
384
+ parts.push(`account:${auth.account}`);
385
+ parts.push(`actor:${auth.actor}`);
386
+ if (auth.roles?.length)
387
+ parts.push(`roles:${auth.roles.join('|')}`);
388
+ if (auth.credential_types?.length)
389
+ parts.push(`creds:${auth.credential_types.join('|')}`);
390
+ return parts.join(' ');
375
391
  };
376
392
  // --- Public API ---
377
393
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"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"}
@@ -119,7 +119,9 @@ export const assert_jsonrpc_success_response = (body, output_schema) => {
119
119
  assert.ok(result.success, `not a valid JSON-RPC success response: ${JSON.stringify(body)}`);
120
120
  if (output_schema) {
121
121
  const output_result = output_schema.safeParse(result.data.result);
122
- assert.ok(output_result.success, `JSON-RPC result does not match output schema: ${JSON.stringify(output_result.error?.issues)}`);
122
+ if (!output_result.success) {
123
+ assert.fail(`JSON-RPC result does not match output schema: ${JSON.stringify(output_result.error.issues)}`);
124
+ }
123
125
  }
124
126
  };
125
127
  /** Adapt a `Hono`-style app into an `RpcTestTransport`. */
@@ -27,7 +27,7 @@ export interface RpcRoundTripTestOptions {
27
27
  app_options?: SuiteAppOptions;
28
28
  /** Database factories to run tests against. Default: pglite only. */
29
29
  db_factories?: Array<DbFactory>;
30
- /** Methods to skip, by name (e.g., `'tx_plan'`). */
30
+ /** Methods to skip, by name (e.g., `'zap_plan'`). */
31
31
  skip_methods?: Array<string>;
32
32
  /** Override generated params for specific methods (method name → params). */
33
33
  input_overrides?: Map<string, Record<string, unknown>>;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAEN,KAAK,eAAe,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAM9D,OAAO,EAMN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAE1B,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACvC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;;;;;;;;OAUG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,oDAAoD;IACpD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AA2BD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,uBAAuB,KAAG,IA8IhF,CAAC"}
1
+ {"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAEN,KAAK,eAAe,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAO9D,OAAO,EAMN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAE1B,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACvC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;;;;;;;;OAUG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,qDAAqD;IACrD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AA2BD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,uBAAuB,KAAG,IA8IhF,CAAC"}
@@ -16,25 +16,26 @@ import { create_pglite_factory } from './db.js';
16
16
  import { generate_valid_body } from './schema_generators.js';
17
17
  import { run_migrations } from '../db/migrate.js';
18
18
  import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
19
+ import { is_public_auth } from '../http/auth_shape.js';
19
20
  import { create_rpc_post_init, create_rpc_get_url, assert_jsonrpc_error_response, assert_jsonrpc_success_response, resolve_rpc_endpoints_for_setup, } from './rpc_helpers.js';
20
21
  /**
21
22
  * Pick auth headers matching an RPC method's auth requirement.
22
23
  */
23
24
  const pick_rpc_auth_headers = (method, test_app, authed_account, admin_account) => {
24
- switch (method.auth.type) {
25
- case 'none':
26
- return { host: 'localhost', origin: 'http://localhost:5173' };
27
- case 'authenticated':
28
- return authed_account.create_session_headers();
29
- case 'role':
30
- if (method.auth.role === ROLE_ADMIN) {
31
- return admin_account.create_session_headers();
32
- }
33
- // keeper role uses the bootstrapped account
34
- return test_app.create_session_headers();
35
- case 'keeper':
36
- return test_app.create_daemon_token_headers();
25
+ const { auth } = method;
26
+ if (is_public_auth(auth)) {
27
+ return { host: 'localhost', origin: 'http://localhost:5173' };
37
28
  }
29
+ if (auth.credential_types?.includes('daemon_token')) {
30
+ return test_app.create_daemon_token_headers();
31
+ }
32
+ if (auth.roles?.length) {
33
+ if (auth.roles.includes(ROLE_ADMIN)) {
34
+ return admin_account.create_session_headers();
35
+ }
36
+ return test_app.create_session_headers();
37
+ }
38
+ return authed_account.create_session_headers();
38
39
  };
39
40
  /**
40
41
  * Run schema-driven round-trip validation for RPC endpoints.
@@ -9,7 +9,7 @@ import { type DbFactory } from './db.js';
9
9
  import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
10
10
  /** Config for a single SSE route under test. */
11
11
  export interface SseRouteTestSpec {
12
- /** Full HTTP path of the SSE endpoint (e.g., `'/api/tx/subscribe'`). */
12
+ /** Full HTTP path of the SSE endpoint (e.g., `'/api/zap/subscribe'`). */
13
13
  path: string;
14
14
  /**
15
15
  * Fire an event matching one of the declared `event_specs` that should
@@ -51,9 +51,8 @@ export interface SseRouteTestOptions {
51
51
  on_audit_event?: (event: AuditLogEvent) => void;
52
52
  /**
53
53
  * RPC endpoint specs — required so the close-on-revoke assertion can
54
- * dispatch `account_session_revoke_all` via RPC (the former REST route
55
- * `POST /api/account/sessions/revoke-all` was removed in the 2026-04-23
56
- * migration). Hard-fails via `require_rpc_endpoint_path` on setup.
54
+ * dispatch `account_session_revoke_all` via RPC (there is no REST
55
+ * equivalent). Hard-fails via `require_rpc_endpoint_path` on setup.
57
56
  *
58
57
  * Accepts either an array (eager) or a factory
59
58
  * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` — the factory form
@@ -1 +1 @@
1
- {"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAmB7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAwB,KAAK,SAAS,EAAuB,MAAM,oBAAoB,CAAC;AAE/F,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAE9D,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAM1B,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAChC,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,qDAAqD;IACrD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;;;;;;;;OAaG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,8BAA8B;IAC9B,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;CAChC;AAyHD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,mBAAmB,KAAG,IA2HvE,CAAC"}
1
+ {"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAmB7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAwB,KAAK,SAAS,EAAuB,MAAM,oBAAoB,CAAC;AAE/F,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAE9D,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAM1B,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,qDAAqD;IACrD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;;;;;;;OAYG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,8BAA8B;IAC9B,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;CAChC;AAyHD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,mBAAmB,KAAG,IA2HvE,CAAC"}
@@ -229,18 +229,14 @@ export const describe_sse_route_tests = (options) => {
229
229
  * (keeper, other roles) uses the bootstrapped keeper account.
230
230
  */
231
231
  const pick_account_for_auth = (spec, test_app, authed_account, admin_account) => {
232
- switch (spec.auth.type) {
233
- case 'authenticated':
234
- return authed_account;
235
- case 'role':
236
- if (spec.auth.role === ROLE_ADMIN)
237
- return admin_account;
238
- // keeper role — bootstrapped account is the keeper; model it as a TestAccount
239
- return bootstrap_as_account(test_app);
240
- case 'keeper':
241
- case 'none':
242
- return bootstrap_as_account(test_app);
232
+ const { auth } = spec;
233
+ if (auth.roles?.includes(ROLE_ADMIN))
234
+ return admin_account;
235
+ if (auth.account === 'required' && !auth.roles?.length && !auth.credential_types?.length) {
236
+ return authed_account;
243
237
  }
238
+ // keeper / other-role / public — bootstrapped account
239
+ return bootstrap_as_account(test_app);
244
240
  };
245
241
  /**
246
242
  * Treat the bootstrapped `TestApp` account as a `TestAccount` for revocation.
@@ -36,7 +36,7 @@ export interface StandardTestOptions {
36
36
  /**
37
37
  * RPC endpoint specs — required. The standard integration tests drive
38
38
  * `account_verify`, `account_session_*`, `account_token_*` through the
39
- * RPC surface (and admin tests, when wired, drive permit grant/revoke
39
+ * RPC surface (and admin tests, when wired, drive role_grant grant/revoke
40
40
  * through it too).
41
41
  *
42
42
  * Accepts either an array (eager) or a factory
@@ -3,11 +3,13 @@ import type { z } from 'zod';
3
3
  import type { SessionOptions } from '../auth/session_cookie.js';
4
4
  import type { MiddlewareSpec } from '../http/middleware_spec.js';
5
5
  import type { AppDeps } from '../auth/deps.js';
6
+ import type { AuditEmitter } from '../auth/audit_emitter.js';
6
7
  import type { AppServerContext } from '../server/app_server.js';
7
8
  import { Db } from '../db/db.js';
8
9
  import { type RouteSpec } from '../http/route_spec.js';
9
10
  import { type AppSurfaceSpec, type RpcEndpointSpec } from '../http/surface.js';
10
11
  import type { EventSpec } from '../realtime/sse.js';
12
+ import { type AuditLogSse } from '../realtime/sse_auth_guard.js';
11
13
  /**
12
14
  * Create a Proxy that throws descriptive errors on any property access or method call.
13
15
  *
@@ -51,6 +53,29 @@ export declare const create_stub_db: () => Db;
51
53
  export declare const stub_handler: () => Response;
52
54
  /** Stub middleware that passes through. */
53
55
  export declare const stub_mw: (_c: any, next: any) => Promise<void>;
56
+ /**
57
+ * Build a no-op `AuditEmitter` for tests that don't assert on audit fan-out.
58
+ *
59
+ * `emit` / `emit_role_grant_target` are no-ops; `emit_pool` resolves
60
+ * immediately; `notify` is a no-op; `on_event_chain` is a frozen empty
61
+ * array — pushing onto it throws at runtime, so a test that wires a
62
+ * listener fails loudly instead of silently never firing. Tests asserting
63
+ * on real audit-row persistence (or on listener fan-out) build a real
64
+ * emitter via `create_audit_emitter` against a stub or real DB —
65
+ * `create_test_app` already does this on the test backend.
66
+ */
67
+ export declare const create_test_audit_emitter: () => AuditEmitter;
68
+ /**
69
+ * Build a no-op `AuditLogSse` for tests that wire `audit_sse` into the
70
+ * surface helper but don't assert on SSE fan-out or subscriber state.
71
+ *
72
+ * `subscribe` returns a no-op cleanup; `on_audit_event` is a no-op; the
73
+ * `registry` is a fresh `SubscriberRegistry` instance (call sites that
74
+ * inspect `.size` or call `.close_*` see a real registry, so writes are
75
+ * isolated per test). Tests that need real SSE plumbing build it via
76
+ * `create_audit_log_sse` against `create_test_app`.
77
+ */
78
+ export declare const create_stub_audit_sse: () => AuditLogSse;
54
79
  /** Stub `AppDeps` for auth surface tests — throws on any method access. */
55
80
  export declare const stub_app_deps: AppDeps;
56
81
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE/D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAC/B,OAAO,EAAqB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAGzE,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAKlD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,GAAG,GAAG,EAAE,OAAO,MAAM,KAAG,CAqBtD,CAAC;AAET;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,GAAG,GAAG,EAAE,QAAQ,MAAM,EAAE,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,CAOxF,CAAC;AAET,iEAAiE;AACjE,eAAO,MAAM,IAAI,EAAE,GAAkC,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,QAAO,EAI/B,CAAC;AAEJ,gDAAgD;AAChD,eAAO,MAAM,YAAY,QAAO,QAAgC,CAAC;AAEjE,2CAA2C;AAC3C,eAAO,MAAM,OAAO,GAAU,IAAI,GAAG,EAAE,MAAM,GAAG,KAAG,OAAO,CAAC,IAAI,CAAW,CAAC;AAI3E,2EAA2E;AAC3E,eAAO,MAAM,aAAa,EAAE,OAS3B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAO,OAStC,CAAC;AAEH,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,GAAI,UAAU;IACpD,iDAAiD;IACjD,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAC/B,KAAG,KAAK,CAAC,cAAc,CAqBvB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,GAC1C,iBAAiB,cAAc,CAAC,MAAM,CAAC,KACrC,gBAqBF,CAAC;AAEF,kDAAkD;AAClD,MAAM,WAAW,+BAA+B;IAC/C,6DAA6D;IAC7D,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,qFAAqF;IACrF,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,oEAAoE;IACpE,UAAU,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACzB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAC7F,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,KAAK,CAAC,cAAc,CAAC,CAAC;IAC/E,0DAA0D;IAC1D,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,GACxC,SAAS,+BAA+B,KACtC,cA2CF,CAAC"}
1
+ {"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"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"}