@alneas/eaos-server 0.0.0-stage → 0.2.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 (360) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.ja.md +49 -0
  4. package/README.md +46 -2
  5. package/dist/agentic/agent-jobs.d.ts +333 -0
  6. package/dist/agentic/agent-jobs.js +15 -0
  7. package/dist/agentic/agent-jobs.js.map +1 -0
  8. package/dist/agentic/agent-node.d.ts +40 -0
  9. package/dist/agentic/agent-node.js +7 -0
  10. package/dist/agentic/agent-node.js.map +1 -0
  11. package/dist/agentic/agent-runner.d.ts +33 -0
  12. package/dist/agentic/agent-runner.js +7 -0
  13. package/dist/agentic/agent-runner.js.map +1 -0
  14. package/dist/agentic/ai-broker.d.ts +169 -0
  15. package/dist/agentic/ai-broker.js +8 -0
  16. package/dist/agentic/ai-broker.js.map +1 -0
  17. package/dist/agentic/atomic-checkpointer.d.ts +137 -0
  18. package/dist/agentic/atomic-checkpointer.js +9 -0
  19. package/dist/agentic/atomic-checkpointer.js.map +1 -0
  20. package/dist/agentic/autonomous-worker.d.ts +122 -0
  21. package/dist/agentic/autonomous-worker.js +10 -0
  22. package/dist/agentic/autonomous-worker.js.map +1 -0
  23. package/dist/agentic/event-bridge.d.ts +350 -0
  24. package/dist/agentic/event-bridge.js +9 -0
  25. package/dist/agentic/event-bridge.js.map +1 -0
  26. package/dist/agentic/executor.d.ts +91 -0
  27. package/dist/agentic/executor.js +12 -0
  28. package/dist/agentic/executor.js.map +1 -0
  29. package/dist/agentic/graph-projection.d.ts +119 -0
  30. package/dist/agentic/graph-projection.js +7 -0
  31. package/dist/agentic/graph-projection.js.map +1 -0
  32. package/dist/agentic/graph.d.ts +524 -0
  33. package/dist/agentic/graph.js +7 -0
  34. package/dist/agentic/graph.js.map +1 -0
  35. package/dist/agentic/index.d.ts +28 -0
  36. package/dist/agentic/index.js +87 -0
  37. package/dist/agentic/index.js.map +1 -0
  38. package/dist/agentic/local-runner.d.ts +106 -0
  39. package/dist/agentic/local-runner.js +7 -0
  40. package/dist/agentic/local-runner.js.map +1 -0
  41. package/dist/agentic/remote-executor.d.ts +67 -0
  42. package/dist/agentic/remote-executor.js +8 -0
  43. package/dist/agentic/remote-executor.js.map +1 -0
  44. package/dist/agentic/types.d.ts +157 -0
  45. package/dist/agentic/types.js +7 -0
  46. package/dist/agentic/types.js.map +1 -0
  47. package/dist/agentic/workflow-catalog.d.ts +152 -0
  48. package/dist/agentic/workflow-catalog.js +7 -0
  49. package/dist/agentic/workflow-catalog.js.map +1 -0
  50. package/dist/agentic/workflow-compiler.d.ts +44 -0
  51. package/dist/agentic/workflow-compiler.js +8 -0
  52. package/dist/agentic/workflow-compiler.js.map +1 -0
  53. package/dist/agentic/workflow-coordinator.d.ts +170 -0
  54. package/dist/agentic/workflow-coordinator.js +8 -0
  55. package/dist/agentic/workflow-coordinator.js.map +1 -0
  56. package/dist/agentic/workflow-manager.d.ts +91 -0
  57. package/dist/agentic/workflow-manager.js +7 -0
  58. package/dist/agentic/workflow-manager.js.map +1 -0
  59. package/dist/agentic/workflow-registry.d.ts +334 -0
  60. package/dist/agentic/workflow-registry.js +7 -0
  61. package/dist/agentic/workflow-registry.js.map +1 -0
  62. package/dist/artifacts-CteHmCMI.d.ts +614 -0
  63. package/dist/auth-hooks/api-key.d.ts +75 -0
  64. package/dist/auth-hooks/api-key.js +7 -0
  65. package/dist/auth-hooks/api-key.js.map +1 -0
  66. package/dist/auth-hooks/index.d.ts +80 -0
  67. package/dist/auth-hooks/index.js +28 -0
  68. package/dist/auth-hooks/index.js.map +1 -0
  69. package/dist/browser-auth/account-memberships.d.ts +213 -0
  70. package/dist/browser-auth/account-memberships.js +13 -0
  71. package/dist/browser-auth/account-memberships.js.map +1 -0
  72. package/dist/browser-auth/index.d.ts +8 -0
  73. package/dist/browser-auth/index.js +59 -0
  74. package/dist/browser-auth/index.js.map +1 -0
  75. package/dist/browser-auth/kratos-session.d.ts +37 -0
  76. package/dist/browser-auth/kratos-session.js +7 -0
  77. package/dist/browser-auth/kratos-session.js.map +1 -0
  78. package/dist/browser-auth/platform-session.d.ts +120 -0
  79. package/dist/browser-auth/platform-session.js +7 -0
  80. package/dist/browser-auth/platform-session.js.map +1 -0
  81. package/dist/browser-auth/public-memberships.d.ts +22 -0
  82. package/dist/browser-auth/public-memberships.js +7 -0
  83. package/dist/browser-auth/public-memberships.js.map +1 -0
  84. package/dist/cache/index.d.ts +181 -0
  85. package/dist/cache/index.js +197 -0
  86. package/dist/cache/index.js.map +1 -0
  87. package/dist/chunk-32746UQZ.js +131 -0
  88. package/dist/chunk-32746UQZ.js.map +1 -0
  89. package/dist/chunk-3NLSWP2Y.js +223 -0
  90. package/dist/chunk-3NLSWP2Y.js.map +1 -0
  91. package/dist/chunk-3P4XTTQH.js +346 -0
  92. package/dist/chunk-3P4XTTQH.js.map +1 -0
  93. package/dist/chunk-3VITSHN3.js +15 -0
  94. package/dist/chunk-3VITSHN3.js.map +1 -0
  95. package/dist/chunk-46UWPEW2.js +226 -0
  96. package/dist/chunk-46UWPEW2.js.map +1 -0
  97. package/dist/chunk-4BARRLJR.js +180 -0
  98. package/dist/chunk-4BARRLJR.js.map +1 -0
  99. package/dist/chunk-4VORUFKR.js +45 -0
  100. package/dist/chunk-4VORUFKR.js.map +1 -0
  101. package/dist/chunk-55D4ERWO.js +1 -0
  102. package/dist/chunk-55D4ERWO.js.map +1 -0
  103. package/dist/chunk-5TBBZIND.js +18 -0
  104. package/dist/chunk-5TBBZIND.js.map +1 -0
  105. package/dist/chunk-5WOZWPZA.js +211 -0
  106. package/dist/chunk-5WOZWPZA.js.map +1 -0
  107. package/dist/chunk-6CBVZ6CT.js +168 -0
  108. package/dist/chunk-6CBVZ6CT.js.map +1 -0
  109. package/dist/chunk-6XZXYNJR.js +74 -0
  110. package/dist/chunk-6XZXYNJR.js.map +1 -0
  111. package/dist/chunk-753HWDSC.js +222 -0
  112. package/dist/chunk-753HWDSC.js.map +1 -0
  113. package/dist/chunk-7AHSS7SO.js +81 -0
  114. package/dist/chunk-7AHSS7SO.js.map +1 -0
  115. package/dist/chunk-7FTJN4SA.js +1 -0
  116. package/dist/chunk-7FTJN4SA.js.map +1 -0
  117. package/dist/chunk-AVDMLTPF.js +24 -0
  118. package/dist/chunk-AVDMLTPF.js.map +1 -0
  119. package/dist/chunk-BKAHUEIT.js +95 -0
  120. package/dist/chunk-BKAHUEIT.js.map +1 -0
  121. package/dist/chunk-CJ7OFEF7.js +134 -0
  122. package/dist/chunk-CJ7OFEF7.js.map +1 -0
  123. package/dist/chunk-EJKWDZIU.js +111 -0
  124. package/dist/chunk-EJKWDZIU.js.map +1 -0
  125. package/dist/chunk-F2J6IQ6I.js +247 -0
  126. package/dist/chunk-F2J6IQ6I.js.map +1 -0
  127. package/dist/chunk-F3O7CELI.js +23 -0
  128. package/dist/chunk-F3O7CELI.js.map +1 -0
  129. package/dist/chunk-F4IITPGX.js +221 -0
  130. package/dist/chunk-F4IITPGX.js.map +1 -0
  131. package/dist/chunk-FD6VC2NA.js +66 -0
  132. package/dist/chunk-FD6VC2NA.js.map +1 -0
  133. package/dist/chunk-FRRRWAHO.js +14 -0
  134. package/dist/chunk-FRRRWAHO.js.map +1 -0
  135. package/dist/chunk-HCKAGLLB.js +17 -0
  136. package/dist/chunk-HCKAGLLB.js.map +1 -0
  137. package/dist/chunk-HVC7FG6B.js +191 -0
  138. package/dist/chunk-HVC7FG6B.js.map +1 -0
  139. package/dist/chunk-HXFVOR7Z.js +496 -0
  140. package/dist/chunk-HXFVOR7Z.js.map +1 -0
  141. package/dist/chunk-IJWYS2PF.js +122 -0
  142. package/dist/chunk-IJWYS2PF.js.map +1 -0
  143. package/dist/chunk-INCHXAFK.js +1395 -0
  144. package/dist/chunk-INCHXAFK.js.map +1 -0
  145. package/dist/chunk-JT6BRGQM.js +1 -0
  146. package/dist/chunk-JT6BRGQM.js.map +1 -0
  147. package/dist/chunk-L6PMAEMB.js +115 -0
  148. package/dist/chunk-L6PMAEMB.js.map +1 -0
  149. package/dist/chunk-LOUGW6MU.js +126 -0
  150. package/dist/chunk-LOUGW6MU.js.map +1 -0
  151. package/dist/chunk-LYPZPE53.js +129 -0
  152. package/dist/chunk-LYPZPE53.js.map +1 -0
  153. package/dist/chunk-NNCCN7JP.js +186 -0
  154. package/dist/chunk-NNCCN7JP.js.map +1 -0
  155. package/dist/chunk-PBC3MZUL.js +212 -0
  156. package/dist/chunk-PBC3MZUL.js.map +1 -0
  157. package/dist/chunk-R4ADP2DC.js +20 -0
  158. package/dist/chunk-R4ADP2DC.js.map +1 -0
  159. package/dist/chunk-RHN4Y6VS.js +44 -0
  160. package/dist/chunk-RHN4Y6VS.js.map +1 -0
  161. package/dist/chunk-SDJNYPYK.js +770 -0
  162. package/dist/chunk-SDJNYPYK.js.map +1 -0
  163. package/dist/chunk-UGNTCOVR.js +28 -0
  164. package/dist/chunk-UGNTCOVR.js.map +1 -0
  165. package/dist/chunk-VC2PCK2S.js +31 -0
  166. package/dist/chunk-VC2PCK2S.js.map +1 -0
  167. package/dist/chunk-VF5YDZJC.js +305 -0
  168. package/dist/chunk-VF5YDZJC.js.map +1 -0
  169. package/dist/chunk-VISRDVTK.js +675 -0
  170. package/dist/chunk-VISRDVTK.js.map +1 -0
  171. package/dist/chunk-W6O3LVBY.js +102 -0
  172. package/dist/chunk-W6O3LVBY.js.map +1 -0
  173. package/dist/chunk-WFEAKJLR.js +47 -0
  174. package/dist/chunk-WFEAKJLR.js.map +1 -0
  175. package/dist/chunk-XIEY2OF4.js +67 -0
  176. package/dist/chunk-XIEY2OF4.js.map +1 -0
  177. package/dist/chunk-XITLHDG3.js +37 -0
  178. package/dist/chunk-XITLHDG3.js.map +1 -0
  179. package/dist/chunk-XMWPYZWZ.js +61 -0
  180. package/dist/chunk-XMWPYZWZ.js.map +1 -0
  181. package/dist/chunk-XUP6CNOM.js +34 -0
  182. package/dist/chunk-XUP6CNOM.js.map +1 -0
  183. package/dist/chunk-YABTQZDJ.js +25 -0
  184. package/dist/chunk-YABTQZDJ.js.map +1 -0
  185. package/dist/chunk-YMHVRBUU.js +199 -0
  186. package/dist/chunk-YMHVRBUU.js.map +1 -0
  187. package/dist/chunk-YMJ7BRKU.js +510 -0
  188. package/dist/chunk-YMJ7BRKU.js.map +1 -0
  189. package/dist/chunk-ZC3XWU7B.js +28 -0
  190. package/dist/chunk-ZC3XWU7B.js.map +1 -0
  191. package/dist/chunk-ZHMTD5KV.js +90 -0
  192. package/dist/chunk-ZHMTD5KV.js.map +1 -0
  193. package/dist/chunk-ZWZDLOE7.js +160 -0
  194. package/dist/chunk-ZWZDLOE7.js.map +1 -0
  195. package/dist/db-package/db/local-first-sqlite-adapter.d.ts +432 -0
  196. package/dist/db-package/db/local-first-sqlite-adapter.js +7 -0
  197. package/dist/db-package/db/local-first-sqlite-adapter.js.map +1 -0
  198. package/dist/db-package/index.d.ts +7 -0
  199. package/dist/db-package/index.js +16 -0
  200. package/dist/db-package/index.js.map +1 -0
  201. package/dist/db-package/migration/aggregator.d.ts +86 -0
  202. package/dist/db-package/migration/aggregator.js +7 -0
  203. package/dist/db-package/migration/aggregator.js.map +1 -0
  204. package/dist/db-package/migration/index.d.ts +3 -0
  205. package/dist/db-package/migration/index.js +8 -0
  206. package/dist/db-package/migration/index.js.map +1 -0
  207. package/dist/engine.d.ts +205 -0
  208. package/dist/engine.js +20 -0
  209. package/dist/engine.js.map +1 -0
  210. package/dist/entitlements/index.d.ts +313 -0
  211. package/dist/entitlements/index.js +23 -0
  212. package/dist/entitlements/index.js.map +1 -0
  213. package/dist/execution/chat.d.ts +7 -0
  214. package/dist/execution/chat.js +7 -0
  215. package/dist/execution/chat.js.map +1 -0
  216. package/dist/execution/index.d.ts +342 -0
  217. package/dist/execution/index.js +66 -0
  218. package/dist/execution/index.js.map +1 -0
  219. package/dist/execution/tool-agent.d.ts +7 -0
  220. package/dist/execution/tool-agent.js +8 -0
  221. package/dist/execution/tool-agent.js.map +1 -0
  222. package/dist/extensions/index.d.ts +172 -0
  223. package/dist/extensions/index.js +95 -0
  224. package/dist/extensions/index.js.map +1 -0
  225. package/dist/health/index.d.ts +35 -0
  226. package/dist/health/index.js +7 -0
  227. package/dist/health/index.js.map +1 -0
  228. package/dist/index.d.ts +43 -0
  229. package/dist/index.js +161 -0
  230. package/dist/index.js.map +1 -0
  231. package/dist/lifecycle/index.d.ts +133 -0
  232. package/dist/lifecycle/index.js +13 -0
  233. package/dist/lifecycle/index.js.map +1 -0
  234. package/dist/lifecycle-engine/backend-migration.d.ts +2 -0
  235. package/dist/lifecycle-engine/backend-migration.js +11 -0
  236. package/dist/lifecycle-engine/backend-migration.js.map +1 -0
  237. package/dist/lifecycle-engine/baseline.d.ts +2 -0
  238. package/dist/lifecycle-engine/baseline.js +9 -0
  239. package/dist/lifecycle-engine/baseline.js.map +1 -0
  240. package/dist/lifecycle-engine/index.d.ts +1497 -0
  241. package/dist/lifecycle-engine/index.js +41 -0
  242. package/dist/lifecycle-engine/index.js.map +1 -0
  243. package/dist/lifecycle-engine/platform/artifacts.d.ts +4 -0
  244. package/dist/lifecycle-engine/platform/artifacts.js +7 -0
  245. package/dist/lifecycle-engine/platform/artifacts.js.map +1 -0
  246. package/dist/lifecycle-engine/platform/control-plane.d.ts +12 -0
  247. package/dist/lifecycle-engine/platform/control-plane.js +2 -0
  248. package/dist/lifecycle-engine/platform/control-plane.js.map +1 -0
  249. package/dist/lifecycle-engine/platform/database-router.d.ts +118 -0
  250. package/dist/lifecycle-engine/platform/database-router.js +7 -0
  251. package/dist/lifecycle-engine/platform/database-router.js.map +1 -0
  252. package/dist/lifecycle-engine/platform/deployment-placements.d.ts +464 -0
  253. package/dist/lifecycle-engine/platform/deployment-placements.js +16 -0
  254. package/dist/lifecycle-engine/platform/deployment-placements.js.map +1 -0
  255. package/dist/lifecycle-engine/platform/deployment.d.ts +4 -0
  256. package/dist/lifecycle-engine/platform/deployment.js +17 -0
  257. package/dist/lifecycle-engine/platform/deployment.js.map +1 -0
  258. package/dist/lifecycle-engine/platform/index.d.ts +737 -0
  259. package/dist/lifecycle-engine/platform/index.js +60 -0
  260. package/dist/lifecycle-engine/platform/index.js.map +1 -0
  261. package/dist/lifecycle-engine/platform/runtime.d.ts +80 -0
  262. package/dist/lifecycle-engine/platform/runtime.js +11 -0
  263. package/dist/lifecycle-engine/platform/runtime.js.map +1 -0
  264. package/dist/lifecycle-engine/platform/site-publication.d.ts +102 -0
  265. package/dist/lifecycle-engine/platform/site-publication.js +7 -0
  266. package/dist/lifecycle-engine/platform/site-publication.js.map +1 -0
  267. package/dist/lifecycle-engine/platform/user-directory.d.ts +139 -0
  268. package/dist/lifecycle-engine/platform/user-directory.js +13 -0
  269. package/dist/lifecycle-engine/platform/user-directory.js.map +1 -0
  270. package/dist/mcp.d.ts +92 -0
  271. package/dist/mcp.js +10 -0
  272. package/dist/mcp.js.map +1 -0
  273. package/dist/middleware/auth.d.ts +118 -0
  274. package/dist/middleware/auth.js +7 -0
  275. package/dist/middleware/auth.js.map +1 -0
  276. package/dist/middleware/error-handler.d.ts +35 -0
  277. package/dist/middleware/error-handler.js +7 -0
  278. package/dist/middleware/error-handler.js.map +1 -0
  279. package/dist/middleware/module-guard.d.ts +33 -0
  280. package/dist/middleware/module-guard.js +7 -0
  281. package/dist/middleware/module-guard.js.map +1 -0
  282. package/dist/platform-admin/index.d.ts +37 -0
  283. package/dist/platform-admin/index.js +11 -0
  284. package/dist/platform-admin/index.js.map +1 -0
  285. package/dist/platform-admin/store.d.ts +346 -0
  286. package/dist/platform-admin/store.js +7 -0
  287. package/dist/platform-admin/store.js.map +1 -0
  288. package/dist/plugin-data/annotations.d.ts +6 -0
  289. package/dist/plugin-data/annotations.js +12 -0
  290. package/dist/plugin-data/annotations.js.map +1 -0
  291. package/dist/plugin-data/atomic-context.d.ts +41 -0
  292. package/dist/plugin-data/atomic-context.js +9 -0
  293. package/dist/plugin-data/atomic-context.js.map +1 -0
  294. package/dist/plugin-data/atomic.d.ts +6 -0
  295. package/dist/plugin-data/atomic.js +26 -0
  296. package/dist/plugin-data/atomic.js.map +1 -0
  297. package/dist/plugin-data/audit.d.ts +6 -0
  298. package/dist/plugin-data/audit.js +12 -0
  299. package/dist/plugin-data/audit.js.map +1 -0
  300. package/dist/plugin-data/commands.d.ts +6 -0
  301. package/dist/plugin-data/commands.js +8 -0
  302. package/dist/plugin-data/commands.js.map +1 -0
  303. package/dist/plugin-data/composite.d.ts +6 -0
  304. package/dist/plugin-data/composite.js +8 -0
  305. package/dist/plugin-data/composite.js.map +1 -0
  306. package/dist/plugin-data/delivery.d.ts +6 -0
  307. package/dist/plugin-data/delivery.js +16 -0
  308. package/dist/plugin-data/delivery.js.map +1 -0
  309. package/dist/plugin-data/index.d.ts +2798 -0
  310. package/dist/plugin-data/index.js +102 -0
  311. package/dist/plugin-data/index.js.map +1 -0
  312. package/dist/plugin-data/json-documents.d.ts +6 -0
  313. package/dist/plugin-data/json-documents.js +16 -0
  314. package/dist/plugin-data/json-documents.js.map +1 -0
  315. package/dist/plugin-data/outbox.d.ts +6 -0
  316. package/dist/plugin-data/outbox.js +16 -0
  317. package/dist/plugin-data/outbox.js.map +1 -0
  318. package/dist/plugin-data/scoped-records.d.ts +6 -0
  319. package/dist/plugin-data/scoped-records.js +10 -0
  320. package/dist/plugin-data/scoped-records.js.map +1 -0
  321. package/dist/plugin-sdk.d.ts +41 -0
  322. package/dist/plugin-sdk.js +10 -0
  323. package/dist/plugin-sdk.js.map +1 -0
  324. package/dist/sql-lifecycle/index.d.ts +138 -0
  325. package/dist/sql-lifecycle/index.js +167 -0
  326. package/dist/sql-lifecycle/index.js.map +1 -0
  327. package/dist/storage/index.d.ts +2 -0
  328. package/dist/storage/index.js +13 -0
  329. package/dist/storage/index.js.map +1 -0
  330. package/dist/storage/s3-compatible.d.ts +139 -0
  331. package/dist/storage/s3-compatible.js +11 -0
  332. package/dist/storage/s3-compatible.js.map +1 -0
  333. package/dist/tenant.d.ts +108 -0
  334. package/dist/tenant.js +9 -0
  335. package/dist/tenant.js.map +1 -0
  336. package/dist/workspace-context.d.ts +119 -0
  337. package/dist/workspace-context.js +9 -0
  338. package/dist/workspace-context.js.map +1 -0
  339. package/docs/api.md +30560 -0
  340. package/docs/db/README.md +49 -0
  341. package/docs/db/docs/api.md +1613 -0
  342. package/docs/db/docs/guide.md +47 -0
  343. package/docs/entitlements.md +60 -0
  344. package/docs/guide.md +92 -0
  345. package/docs/index.md +57 -0
  346. package/docs/ja/db/README.md +46 -0
  347. package/docs/ja/db/docs/guide.md +53 -0
  348. package/docs/ja/guide.md +46 -0
  349. package/docs/ja/lifecycle/README.md +46 -0
  350. package/docs/ja/lifecycle/docs/guide.md +45 -0
  351. package/docs/ja/storage/README.md +46 -0
  352. package/docs/ja/storage/docs/guide.md +43 -0
  353. package/docs/lifecycle/README.md +49 -0
  354. package/docs/lifecycle/docs/api.md +3770 -0
  355. package/docs/lifecycle/docs/baseline.md +50 -0
  356. package/docs/lifecycle/docs/guide.md +47 -0
  357. package/docs/storage/README.md +49 -0
  358. package/docs/storage/docs/api.md +470 -0
  359. package/docs/storage/docs/guide.md +47 -0
  360. package/package.json +354 -4
@@ -0,0 +1,80 @@
1
+ import * as hono_types from 'hono/types';
2
+ import { Context, Hono } from 'hono';
3
+ export { ApiKeyLookup, resolveApiKey } from './api-key.js';
4
+ import '@alneas/eaos-core';
5
+
6
+ /**
7
+ * Creates a body-limited registration endpoint that verifies the caller before parsing JSON.
8
+ * @typeParam T - Validated registration input returned by parse and passed unchanged to register.
9
+ * @param options - Host callbacks: verify receives the request context before parsing and must return a rejection Response or no value to continue; parse synchronously validates unknown JSON; register receives the parsed input and context and resolves the final response.
10
+ * @returns A Hono router serving POST /registration with a 128 KiB body limit; JSON or parser failures return 400.
11
+ * @throws Request handling propagates verify and register rejections; parse exceptions become 400 responses.
12
+ * @remarks The host owns authentication, registration persistence, duplicate handling, and transactional behavior. Body size enforcement precedes verify.
13
+ * @example
14
+ * ```typescript
15
+ * import type { Context } from "hono";
16
+ * import { createRegistrationHook } from "@alneas/eaos-server/auth-hooks";
17
+ * export function registrationRouter(
18
+ * verify: (context: Context) => Promise<Response | void>,
19
+ * register: (input: { email: string }, context: Context) => Promise<Response>,
20
+ * ) {
21
+ * return createRegistrationHook({ verify, register, parse(body: unknown) {
22
+ * if (!body || typeof body !== "object" || !("email" in body) || typeof body.email !== "string") {
23
+ * throw new Error("email is required");
24
+ * }
25
+ * return { email: body.email };
26
+ * } });
27
+ * }
28
+ * ```
29
+ */
30
+ declare function createRegistrationHook<T>(options: {
31
+ /**
32
+ * Verifies the caller before request JSON is parsed.
33
+ * @param c - Hono request context containing the headers/credentials to verify.
34
+ * @returns A rejection Response, or no value to continue registration.
35
+ * @throws Host verification failures propagate through request handling.
36
+ * @example
37
+ * ```typescript
38
+ * import { createRegistrationHook } from '@alneas/eaos-server/auth-hooks';
39
+ * import type { Context } from 'hono';
40
+ * export async function verifyCaller(options: Parameters<typeof createRegistrationHook>[0], context: Context) {
41
+ * return options.verify(context);
42
+ * }
43
+ * ```
44
+ */
45
+ verify(c: Context): Promise<Response | void>;
46
+ /**
47
+ * Synchronously validates parsed JSON and produces the registration input.
48
+ * @param body - Unknown JSON value from the request body.
49
+ * @returns Validated registration data passed unchanged to register.
50
+ * @throws Validation errors are converted to a 400 Invalid registration payload response.
51
+ * @example
52
+ * ```typescript
53
+ * import { createRegistrationHook } from '@alneas/eaos-server/auth-hooks';
54
+ * export function parseRegistration(options: Parameters<typeof createRegistrationHook>[0], body: unknown) {
55
+ * return options.parse(body);
56
+ * }
57
+ * ```
58
+ */
59
+ parse(body: unknown): T;
60
+ /**
61
+ * Performs host registration after caller verification and input parsing.
62
+ * @param input - Validated parser result, passed unchanged from parse.
63
+ * @param c - Same Hono request context used for caller verification.
64
+ * @returns The final host registration response.
65
+ * @throws Host persistence/registration failures propagate; earlier external effects may already have occurred.
66
+ * @example
67
+ * ```typescript
68
+ * import { createRegistrationHook } from '@alneas/eaos-server/auth-hooks';
69
+ * import type { Context } from 'hono';
70
+ * export async function registerValidated(options: Parameters<typeof createRegistrationHook>[0], body: unknown, context: Context) {
71
+ * const denied = await options.verify(context);
72
+ * if (denied) return denied;
73
+ * return options.register(options.parse(body), context);
74
+ * }
75
+ * ```
76
+ */
77
+ register(input: T, c: Context): Promise<Response>;
78
+ }): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
79
+
80
+ export { createRegistrationHook };
@@ -0,0 +1,28 @@
1
+ import {
2
+ resolveApiKey
3
+ } from "../chunk-ZC3XWU7B.js";
4
+
5
+ // src/auth-hooks/index.ts
6
+ import { Hono } from "hono";
7
+ import { bodyLimit } from "hono/body-limit";
8
+ function createRegistrationHook(options) {
9
+ const app = new Hono();
10
+ app.use("*", bodyLimit({ maxSize: 128 * 1024 }));
11
+ app.post("/registration", async (c) => {
12
+ const denied = await options.verify(c);
13
+ if (denied) return denied;
14
+ let input;
15
+ try {
16
+ input = options.parse(await c.req.json());
17
+ } catch {
18
+ return c.json({ error: "Invalid registration payload" }, 400);
19
+ }
20
+ return options.register(input, c);
21
+ });
22
+ return app;
23
+ }
24
+ export {
25
+ createRegistrationHook,
26
+ resolveApiKey
27
+ };
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/auth-hooks/index.ts"],"sourcesContent":["import { Hono, type Context } from 'hono'\nimport { bodyLimit } from 'hono/body-limit'\nexport * from './api-key'\n/**\n * Creates a body-limited registration endpoint that verifies the caller before parsing JSON.\n * @typeParam T - Validated registration input returned by parse and passed unchanged to register.\n * @param options - Host callbacks: verify receives the request context before parsing and must return a rejection Response or no value to continue; parse synchronously validates unknown JSON; register receives the parsed input and context and resolves the final response.\n * @returns A Hono router serving POST /registration with a 128 KiB body limit; JSON or parser failures return 400.\n * @throws Request handling propagates verify and register rejections; parse exceptions become 400 responses.\n * @remarks The host owns authentication, registration persistence, duplicate handling, and transactional behavior. Body size enforcement precedes verify.\n * @example\n * ```typescript\n * import type { Context } from \"hono\";\n * import { createRegistrationHook } from \"@alneas/eaos-server/auth-hooks\";\n * export function registrationRouter(\n * verify: (context: Context) => Promise<Response | void>,\n * register: (input: { email: string }, context: Context) => Promise<Response>,\n * ) {\n * return createRegistrationHook({ verify, register, parse(body: unknown) {\n * if (!body || typeof body !== \"object\" || !(\"email\" in body) || typeof body.email !== \"string\") {\n * throw new Error(\"email is required\");\n * }\n * return { email: body.email };\n * } });\n * }\n * ```\n */\nexport function createRegistrationHook<T>(options: {\n /**\n * Verifies the caller before request JSON is parsed.\n * @param c - Hono request context containing the headers/credentials to verify.\n * @returns A rejection Response, or no value to continue registration.\n * @throws Host verification failures propagate through request handling.\n * @example\n * ```typescript\n * import { createRegistrationHook } from '@alneas/eaos-server/auth-hooks';\n * import type { Context } from 'hono';\n * export async function verifyCaller(options: Parameters<typeof createRegistrationHook>[0], context: Context) {\n * return options.verify(context);\n * }\n * ```\n */\n \n verify(c: Context): Promise<Response | void>\n /**\n * Synchronously validates parsed JSON and produces the registration input.\n * @param body - Unknown JSON value from the request body.\n * @returns Validated registration data passed unchanged to register.\n * @throws Validation errors are converted to a 400 Invalid registration payload response.\n * @example\n * ```typescript\n * import { createRegistrationHook } from '@alneas/eaos-server/auth-hooks';\n * export function parseRegistration(options: Parameters<typeof createRegistrationHook>[0], body: unknown) {\n * return options.parse(body);\n * }\n * ```\n */\n parse(body: unknown): T\n /**\n * Performs host registration after caller verification and input parsing.\n * @param input - Validated parser result, passed unchanged from parse.\n * @param c - Same Hono request context used for caller verification.\n * @returns The final host registration response.\n * @throws Host persistence/registration failures propagate; earlier external effects may already have occurred.\n * @example\n * ```typescript\n * import { createRegistrationHook } from '@alneas/eaos-server/auth-hooks';\n * import type { Context } from 'hono';\n * export async function registerValidated(options: Parameters<typeof createRegistrationHook>[0], body: unknown, context: Context) {\n * const denied = await options.verify(context);\n * if (denied) return denied;\n * return options.register(options.parse(body), context);\n * }\n * ```\n */\n register(input: T, c: Context): Promise<Response>\n}) {\n const app = new Hono()\n app.use('*', bodyLimit({ maxSize: 128 * 1024 }))\n app.post('/registration', async c => {\n const denied = await options.verify(c); if (denied) return denied\n let input: T\n try { input = options.parse(await c.req.json()) } catch { return c.json({ error: 'Invalid registration payload' }, 400) }\n return options.register(input, c)\n })\n return app\n}\n"],"mappings":";;;;;AAAA,SAAS,YAA0B;AACnC,SAAS,iBAAiB;AA0BnB,SAAS,uBAA0B,SAiDvC;AACF,QAAM,MAAM,IAAI,KAAK;AACrB,MAAI,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,KAAK,CAAC,CAAC;AAC/C,MAAI,KAAK,iBAAiB,OAAM,MAAK;AACpC,UAAM,SAAS,MAAM,QAAQ,OAAO,CAAC;AAAG,QAAI,OAAQ,QAAO;AAC3D,QAAI;AACJ,QAAI;AAAE,cAAQ,QAAQ,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC;AAAA,IAAE,QAAQ;AAAE,aAAO,EAAE,KAAK,EAAE,OAAO,+BAA+B,GAAG,GAAG;AAAA,IAAE;AACxH,WAAO,QAAQ,SAAS,OAAO,CAAC;AAAA,EACjC,CAAC;AACD,SAAO;AACR;","names":[]}
@@ -0,0 +1,213 @@
1
+ import { AccountMemberships } from '@alneas/eaos-server/platform';
2
+
3
+ /**
4
+ * Provider metadata field updated by a membership migration; public metadata is visible to its account holder.
5
+ * @see applyAccountMembershipChange.
6
+ */
7
+ type AccountMetadataField = 'metadata_public' | 'metadata_admin';
8
+ /**
9
+ * Provider identity snapshot used for optimistic checks and metadata-preserving writes.
10
+ * @see planAccountMembershipPublication.
11
+ */
12
+ interface ManagedIdentity {
13
+ /** Provider identity ID. */
14
+ id: string;
15
+ /** Provider lifecycle state; membership operations require active. */
16
+ state: string;
17
+ /** Optional editable traits; never used as membership authority here. */
18
+ traits?: Record<string, unknown>;
19
+ /** Public provider metadata; published membership fields are user-visible. */
20
+ metadata_public?: Record<string, unknown>;
21
+ /** Private administrator metadata; legacy membership migration defaults to this field. */
22
+ metadata_admin?: Record<string, unknown>;
23
+ }
24
+ /**
25
+ * Reviewed membership replacement bound to a hash of the selected metadata snapshot.
26
+ * @see applyAccountMembershipChange.
27
+ */
28
+ interface MembershipMigrationPlan {
29
+ /** Identity whose metadata is being changed. */
30
+ identityId: string;
31
+ /** metadataHash of the selected metadata field before the change. */
32
+ beforeMetadataHash: string;
33
+ /** Validated target membership claims; all membership fields are replaced. */
34
+ memberships: AccountMemberships;
35
+ /** Metadata destination; omitted preserves the metadata_admin migration contract. */
36
+ metadataField?: AccountMetadataField;
37
+ }
38
+ /**
39
+ * Hashes metadata after recursively sorting object keys while preserving array order.
40
+ * @param metadata - JSON-serializable metadata; null/undefined at the root are normalized to an empty object.
41
+ * @returns Lower-case SHA-256 hexadecimal digest of canonicalized JSON.
42
+ * @throws For cyclic, BigInt, or other values that JSON serialization cannot encode.
43
+ * @remarks This is an optimistic snapshot comparison, not a signature or authentication mechanism.
44
+ * @example
45
+ * ```typescript
46
+ * import { metadataHash } from "@alneas/eaos-server/browser-auth/account-memberships";
47
+ * console.log(metadataHash({ b: 2, a: 1 }) === metadataHash({ a: 1, b: 2 })); // true
48
+ * ```
49
+ */
50
+ declare function metadataHash(metadata: unknown): string;
51
+ /**
52
+ * Durable mutation lock and audit boundary for account metadata updates.
53
+ * @remarks A failed or uncertain update retains its lock. The host must reconcile it rather than auto-expire or blindly retry.
54
+ * @see applyAccountMembershipChange.
55
+ */
56
+ interface AccountMutationStore {
57
+ /**
58
+ * Acquires an exclusive durable mutation lock before provider reads/writes.
59
+ * @param identityId - Provider identity being changed.
60
+ * @param token - Fresh mutation token generated for this attempt.
61
+ * @param actor - Nonblank authenticated operator identity.
62
+ * @returns No value; resolves only when the lock is held.
63
+ * @throws Rejects conflicting or unavailable persistence; provider work will not start.
64
+
65
+ * @example
66
+ * ```typescript
67
+ * import type { AccountMutationStore } from "@alneas/eaos-server/browser-auth";
68
+ * export async function lockReviewedIdentity(
69
+ * store: AccountMutationStore, identityId: string, freshMutationToken: string, authenticatedActor: string,
70
+ * ) {
71
+ * await store.acquire(identityId, freshMutationToken, authenticatedActor);
72
+ * // Keep the token until verified completion; uncertain writes require reconciliation.
73
+ * }
74
+ * ```
75
+ */
76
+ acquire(identityId: string, token: string, actor: string): Promise<void>;
77
+ /**
78
+ * Records verified completion and finalizes the durable lock/audit state.
79
+ * @param identityId - Changed provider identity.
80
+ * @param token - Token acquired for this attempt; enforce ownership in the host store.
81
+ * @param actor - Authenticated operator identity.
82
+ * @param beforeHash - Reviewed pre-change snapshot hash.
83
+ * @param afterHash - Hash read back and verified after the update.
84
+ * @returns No value; resolves when completion is durably recorded.
85
+ * @throws Persistence errors propagate after the provider may already have changed.
86
+
87
+ * @example
88
+ * ```typescript
89
+ * import type { AccountMutationStore } from "@alneas/eaos-server/browser-auth";
90
+ * export async function finishVerifiedIdentityMutation(
91
+ * store: AccountMutationStore, identityId: string, ownedToken: string, authenticatedActor: string,
92
+ * reviewedBeforeHash: string, verifiedAfterHash: string,
93
+ * ) {
94
+ * // Call only after reading back and verifying the actual provider metadata update.
95
+ * await store.complete(identityId, ownedToken, authenticatedActor, reviewedBeforeHash, verifiedAfterHash);
96
+ * }
97
+ * ```
98
+ */
99
+ complete(identityId: string, token: string, actor: string, beforeHash: string, afterHash: string): Promise<void>;
100
+ }
101
+ /**
102
+ * Host-authorized provider administration used by account membership operations.
103
+ * @see publishAccountMemberships.
104
+ */
105
+ interface AccountAdminPort {
106
+ /**
107
+ * Reads the authoritative current provider identity, including both metadata fields.
108
+ * @param identityId - Provider identity ID.
109
+ * @returns Current identity snapshot used for lifecycle and hash checks.
110
+ * @throws Provider errors propagate and retain any acquired durable lock.
111
+
112
+ * @example
113
+ * ```typescript
114
+ * import type { AccountAdminPort } from "@alneas/eaos-server/browser-auth";
115
+ * export async function readAuthoritativeIdentity(admin: AccountAdminPort, identityId: string) {
116
+ * // The host supplies an authorized provider-admin connection.
117
+ * const identity = await admin.read(identityId);
118
+ * return { id: identity.id, state: identity.state };
119
+ * }
120
+ * ```
121
+ */
122
+ read(identityId: string): Promise<ManagedIdentity>;
123
+ /**
124
+ * Writes selected metadata while preserving unrelated identity fields.
125
+ * @param identity - Authoritative identity snapshot; publication supplies both changed metadata fields and requires the port to PUT both in one provider request.
126
+ * @param metadata - Complete replacement value for the selected metadata field.
127
+ * @param field - Selected destination field.
128
+ * @returns No value; resolves when the provider acknowledges the write, before independent readback verification.
129
+ * @throws Provider failures propagate; the provider outcome may be uncertain and the durable lock must remain held.
130
+
131
+ * @example
132
+ * ```typescript
133
+ * import type { AccountAdminPort } from "@alneas/eaos-server/browser-auth";
134
+ * export async function writeReviewedIdentityMetadata(
135
+ * admin: AccountAdminPort,
136
+ * currentIdentity: Parameters<AccountAdminPort["write"]>[0],
137
+ * reviewedMetadata: Parameters<AccountAdminPort["write"]>[1],
138
+ * reviewedField: Parameters<AccountAdminPort["write"]>[2],
139
+ * ) {
140
+ * // Host workflow acquires the mutation lock and checks the reviewed snapshot first.
141
+ * await admin.write(currentIdentity, reviewedMetadata, reviewedField);
142
+ * // Read back through admin.read before recording durable mutation completion.
143
+ * }
144
+ * ```
145
+ */
146
+ write(identity: ManagedIdentity, metadata: Record<string, unknown>, field: AccountMetadataField): Promise<void>;
147
+ }
148
+ /**
149
+ * Replaces membership fields under a durable lock and verifies provider readback before recording completion.
150
+ * @param plan - Reviewed target claims, metadata field, and expected pre-change field hash.
151
+ * @param actor - Nonblank authenticated operator identity; authorization is host-owned.
152
+ * @param store - Durable exclusive lock and completion audit implementation.
153
+ * @param admin - Trusted provider read/write implementation.
154
+ * @returns No value; resolves after verified provider update and durable completion. Unrelated metadata keys are retained and absent defaultTenantId is written as null.
155
+ * @throws Rejects invalid actor/metadata field/claims, stale or inactive identity, failed readback, or propagated lock/provider/completion errors.
156
+ * @remarks A failed/uncertain mutation retains its durable lock. Reconcile; never auto-expire or blindly retry. This function does not roll back provider changes. Defaults to metadata_admin; explicitly selecting metadata_public exposes claims to the account holder.
157
+ * @example
158
+ * ```typescript
159
+ * import { applyAccountMembershipChange, type MembershipMigrationPlan, type AccountMutationStore, type AccountAdminPort } from "@alneas/eaos-server/browser-auth/account-memberships";
160
+ * export async function applyReviewedPlan(plan: MembershipMigrationPlan, actor: string, store: AccountMutationStore, admin: AccountAdminPort) {
161
+ * await applyAccountMembershipChange(plan, actor, store, admin);
162
+ * }
163
+ * ```
164
+ */
165
+ declare function applyAccountMembershipChange(plan: MembershipMigrationPlan, actor: string, store: AccountMutationStore, admin: AccountAdminPort): Promise<void>;
166
+ /**
167
+ * Reviewed plan moving existing private membership fields into public metadata without changing claims.
168
+ * @see planAccountMembershipPublication.
169
+ */
170
+ interface MembershipPublicationPlan {
171
+ /** Active identity whose memberships will become public. */
172
+ identityId: string;
173
+ /** Combined public/admin metadata snapshot hash used to detect stale plans. */
174
+ beforeMetadataHash: string;
175
+ /** Validated claims copied from private membership fields. */
176
+ memberships: AccountMemberships;
177
+ }
178
+ /**
179
+ * Plans moving existing administrator membership claims into public identity metadata.
180
+ * @param identity - Active authoritative identity snapshot containing private membership fields and no public membership fields.
181
+ * @returns A new publication plan binding parsed claims to the combined public/admin metadata hash; no writes occur.
182
+ * @throws For inactive identity, missing private memberships, existing public membership fields, invalid claims, or unhashable metadata.
183
+ * @remarks Review the returned plan before publication: membership fields become visible to the account holder.
184
+ * @example
185
+ * ```typescript
186
+ * import { planAccountMembershipPublication, type AccountAdminPort } from "@alneas/eaos-server/browser-auth/account-memberships";
187
+ * export async function reviewPlan(admin: AccountAdminPort, identityId: string) {
188
+ * return planAccountMembershipPublication(await admin.read(identityId));
189
+ * }
190
+ * ```
191
+ */
192
+ declare function planAccountMembershipPublication(identity: ManagedIdentity): MembershipPublicationPlan;
193
+ /**
194
+ * Moves reviewed membership fields from administrator to public metadata in one provider write and verifies readback.
195
+ * @param plan - Reviewed publication plan; current private claims must still match exactly.
196
+ * @param actor - Nonblank authenticated operator identity.
197
+ * @param store - Durable exclusive mutation lock and completion audit.
198
+ * @param admin - Provider port that must write both metadata fields from the supplied identity in one request.
199
+ * @returns No value; resolves after verified readback and durable completion, retaining unrelated public/private metadata.
200
+ * @throws Rejects invalid actor/claims, stale snapshot, changed memberships, failed provider verification, or propagated store/provider failures.
201
+ * @remarks The durable lock remains on any failed or uncertain outcome; reconcile instead of blind retry. This function does not roll back or independently authenticate the operator. Atomicity of the two-field update depends on the host port honoring its single-request contract.
202
+ * @example
203
+ * ```typescript
204
+ * import { publishAccountMemberships, type MembershipPublicationPlan, type AccountMutationStore, type AccountAdminPort } from "@alneas/eaos-server/browser-auth/account-memberships";
205
+ * export async function publishReviewedPlan(plan: MembershipPublicationPlan, actor: string, store: AccountMutationStore, admin: AccountAdminPort) {
206
+ * await publishAccountMemberships(plan, actor, store, admin);
207
+ * }
208
+ * ```
209
+ */
210
+ declare function publishAccountMemberships(plan: MembershipPublicationPlan, actor: string, store: AccountMutationStore, admin: AccountAdminPort): Promise<void>;
211
+
212
+ export { applyAccountMembershipChange, metadataHash, planAccountMembershipPublication, publishAccountMemberships };
213
+ export type { AccountAdminPort, AccountMetadataField, AccountMutationStore, ManagedIdentity, MembershipMigrationPlan, MembershipPublicationPlan };
@@ -0,0 +1,13 @@
1
+ import {
2
+ applyAccountMembershipChange,
3
+ metadataHash,
4
+ planAccountMembershipPublication,
5
+ publishAccountMemberships
6
+ } from "../chunk-XMWPYZWZ.js";
7
+ export {
8
+ applyAccountMembershipChange,
9
+ metadataHash,
10
+ planAccountMembershipPublication,
11
+ publishAccountMemberships
12
+ };
13
+ //# sourceMappingURL=account-memberships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,8 @@
1
+ import 'hono/types';
2
+ import 'hono';
3
+ export { createKratosSessionVerifier } from './kratos-session.js';
4
+ export { B as BrowserSession, Membership, c as createBrowserSessionRouter, createPlatformSessionResolver } from './platform-session.js';
5
+ export { publicAccountMemberships } from './public-memberships.js';
6
+ export { AccountAdminPort, AccountMetadataField, AccountMutationStore, ManagedIdentity, MembershipMigrationPlan, MembershipPublicationPlan, applyAccountMembershipChange, metadataHash, planAccountMembershipPublication, publishAccountMemberships } from './account-memberships.js';
7
+ import '@alneas/eaos-server/lifecycle-engine';
8
+ import '@alneas/eaos-server/platform';
@@ -0,0 +1,59 @@
1
+ import {
2
+ applyAccountMembershipChange,
3
+ metadataHash,
4
+ planAccountMembershipPublication,
5
+ publishAccountMemberships
6
+ } from "../chunk-XMWPYZWZ.js";
7
+ import {
8
+ createKratosSessionVerifier
9
+ } from "../chunk-F3O7CELI.js";
10
+ import {
11
+ createPlatformSessionResolver
12
+ } from "../chunk-XUP6CNOM.js";
13
+ import {
14
+ publicAccountMemberships
15
+ } from "../chunk-FRRRWAHO.js";
16
+
17
+ // src/browser-auth/index.ts
18
+ import { Hono } from "hono";
19
+ function createBrowserSessionRouter(options) {
20
+ const router = new Hono();
21
+ router.use("*", async (c, next) => {
22
+ c.header("Cache-Control", "no-store");
23
+ c.header("Vary", "Cookie, Authorization, X-Tenant-Id");
24
+ await next();
25
+ });
26
+ router.get("/config", (c) => {
27
+ try {
28
+ const v = options.configuration();
29
+ if (!v.publicUrl || !v.provider || !Array.isArray(v.redirectOrigins)) throw new Error("Unconfigured");
30
+ return c.json({ publicUrl: v.publicUrl, provider: v.provider, ...v.returnTo ? { returnTo: v.returnTo } : {}, redirectOrigins: v.redirectOrigins });
31
+ } catch {
32
+ return c.json({ error: "Authentication is not configured" }, 503);
33
+ }
34
+ });
35
+ router.get("/session", async (c) => {
36
+ try {
37
+ const value = await options.resolveSession(c);
38
+ if (!value) return c.json({ error: "Authentication required" }, 401);
39
+ if (options.tenantId && value.tenantId !== options.tenantId) return c.json({ error: "Tenant unavailable" }, 403);
40
+ if (typeof value.userId !== "string" || !value.userId.trim() || typeof value.tenantId !== "string" || !value.tenantId.trim() || !Array.isArray(value.roles) || !Array.isArray(value.enabledModules) || [...value.roles, ...value.enabledModules].some((v) => typeof v !== "string" || !v.trim())) throw new Error("Invalid session");
41
+ return c.json(value);
42
+ } catch (error) {
43
+ const status = error?.status;
44
+ return c.json({ error: "Authenticated membership unavailable" }, status === 401 ? 401 : status === 403 ? 403 : 503);
45
+ }
46
+ });
47
+ return router;
48
+ }
49
+ export {
50
+ applyAccountMembershipChange,
51
+ createBrowserSessionRouter,
52
+ createKratosSessionVerifier,
53
+ createPlatformSessionResolver,
54
+ metadataHash,
55
+ planAccountMembershipPublication,
56
+ publicAccountMemberships,
57
+ publishAccountMemberships
58
+ };
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/browser-auth/index.ts"],"sourcesContent":["import { Hono, type Context } from 'hono'\nexport * from './kratos-session'\nexport * from './platform-session'\nexport * from './public-memberships'\n/**\n * Verified browser identity and membership serialized by {@link createBrowserSessionRouter}.\n */\nexport interface BrowserSession {\n /** Nonblank authenticated identity ID. */\n userId: string\n /** Nonblank selected authorized tenant ID. */\n tenantId: string\n /** Verified nonblank role names; empty arrays are accepted. */\n roles: string[]\n /** Verified nonblank module entitlement names; empty arrays are accepted. */\n enabledModules: string[]\n}\n/**\n * Exposes browser-safe provider configuration and verified session data with no-store response headers.\n * @typeParam T - Host session shape extending required identity/membership fields; additional fields are serialized in full.\n * @param options - configuration synchronously supplies publicUrl/provider/redirectOrigins and optional returnTo for GET /config; resolveSession receives Hono context for GET /session and resolves a verified session or null; optional tenantId restricts returned sessions to one tenant.\n * @returns A router with GET /config and /session. Configuration failure returns 503; absent session returns 401, tenant mismatch returns 403, and resolver failures map status 401/403 or otherwise 503.\n * @remarks The host owns IdP settings and membership lookup. No identity creation, default roles, or token minting occurs. Configuration output whitelists fields, but session output serializes all T fields: do not place secrets in a session. Responses set Cache-Control: no-store and Vary: Cookie, Authorization, X-Tenant-Id.\n * @example\n * ```typescript\n * import type { Context } from \"hono\";\n * import { createBrowserSessionRouter, type BrowserSession } from \"@alneas/eaos-server/browser-auth\";\n * export function authRouter(resolveSession: (context: Context) => Promise<BrowserSession | null>) {\n * return createBrowserSessionRouter({\n * configuration: () => ({ publicUrl: \"https://identity.example.com\", provider: \"kratos\", redirectOrigins: [\"https://app.example.com\"] }),\n * resolveSession,\n * });\n * }\n * ```\n */\nexport function createBrowserSessionRouter<T extends BrowserSession>(options: {\n /**\n * Synchronous public IdP configuration callback evaluated on each /config request; failures become 503 and only explicitly selected fields are serialized.\n */\n configuration: () => {\n /**\n * Nonempty public identity-provider URL returned to the browser; the router does not validate its URL syntax.\n */\n publicUrl: string;\n /**\n * Nonempty provider label returned to the browser.\n */\n provider: string;\n /**\n * Optional post-authentication return URL included only when truthy; host configuration must validate redirect policy.\n */\n returnTo?: string;\n /**\n * Host redirect-origin list serialized to the browser; the router checks only that it is an array.\n */\n redirectOrigins: string[] }\n /**\n * Per-request host verifier resolving a trusted session or null for 401; thrown statuses 401/403 are preserved and other failures become 503.\n */\n resolveSession: (context: Context) => Promise<T | null>\n /**\n * Optional dedicated-backend tenant restriction; a session selecting another tenant returns 403.\n */\n tenantId?: string\n}) {\n const router = new Hono()\n router.use('*', async (c, next) => { c.header('Cache-Control', 'no-store'); c.header('Vary', 'Cookie, Authorization, X-Tenant-Id'); await next() })\n router.get('/config', c => {\n try {\n const v = options.configuration()\n // Explicit fields only: secrets in host configuration cannot be serialized accidentally.\n if (!v.publicUrl || !v.provider || !Array.isArray(v.redirectOrigins)) throw new Error('Unconfigured')\n return c.json({ publicUrl: v.publicUrl, provider: v.provider, ...(v.returnTo ? { returnTo: v.returnTo } : {}), redirectOrigins: v.redirectOrigins })\n } catch { return c.json({ error: 'Authentication is not configured' }, 503) }\n })\n router.get('/session', async c => {\n try {\n const value = await options.resolveSession(c)\n if (!value) return c.json({ error: 'Authentication required' }, 401)\n if (options.tenantId && value.tenantId !== options.tenantId) return c.json({ error: 'Tenant unavailable' }, 403)\n if (typeof value.userId !== 'string' || !value.userId.trim() || typeof value.tenantId !== 'string' || !value.tenantId.trim() || !Array.isArray(value.roles) || !Array.isArray(value.enabledModules) || [...value.roles, ...value.enabledModules].some(v => typeof v !== 'string' || !v.trim())) throw new Error('Invalid session')\n return c.json(value)\n } catch (error) {\n const status = (error as { status?: number })?.status\n return c.json({ error: 'Authenticated membership unavailable' }, status === 401 ? 401 : status === 403 ? 403 : 503)\n }\n })\n return router\n}\n\nexport { applyAccountMembershipChange, metadataHash, planAccountMembershipPublication, publishAccountMemberships, type ManagedIdentity, type AccountMetadataField, type MembershipMigrationPlan, type MembershipPublicationPlan, type AccountMutationStore, type AccountAdminPort } from './account-memberships'\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,YAA0B;AAmC5B,SAAS,2BAAqD,SA6BlE;AACD,QAAM,SAAS,IAAI,KAAK;AACxB,SAAO,IAAI,KAAK,OAAO,GAAG,SAAS;AAAE,MAAE,OAAO,iBAAiB,UAAU;AAAG,MAAE,OAAO,QAAQ,oCAAoC;AAAG,UAAM,KAAK;AAAA,EAAE,CAAC;AAClJ,SAAO,IAAI,WAAW,OAAK;AACzB,QAAI;AACF,YAAM,IAAI,QAAQ,cAAc;AAEhC,UAAI,CAAC,EAAE,aAAa,CAAC,EAAE,YAAY,CAAC,MAAM,QAAQ,EAAE,eAAe,EAAG,OAAM,IAAI,MAAM,cAAc;AACpG,aAAO,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,UAAU,EAAE,UAAU,GAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC,GAAI,iBAAiB,EAAE,gBAAgB,CAAC;AAAA,IACrJ,QAAQ;AAAE,aAAO,EAAE,KAAK,EAAE,OAAO,mCAAmC,GAAG,GAAG;AAAA,IAAE;AAAA,EAC9E,CAAC;AACD,SAAO,IAAI,YAAY,OAAM,MAAK;AAChC,QAAI;AACF,YAAM,QAAQ,MAAM,QAAQ,eAAe,CAAC;AAC5C,UAAI,CAAC,MAAO,QAAO,EAAE,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;AACnE,UAAI,QAAQ,YAAY,MAAM,aAAa,QAAQ,SAAU,QAAO,EAAE,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;AAC/G,UAAI,OAAO,MAAM,WAAW,YAAY,CAAC,MAAM,OAAO,KAAK,KAAK,OAAO,MAAM,aAAa,YAAY,CAAC,MAAM,SAAS,KAAK,KAAK,CAAC,MAAM,QAAQ,MAAM,KAAK,KAAK,CAAC,MAAM,QAAQ,MAAM,cAAc,KAAK,CAAC,GAAG,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,KAAK,OAAK,OAAO,MAAM,YAAY,CAAC,EAAE,KAAK,CAAC,EAAG,OAAM,IAAI,MAAM,iBAAiB;AACjU,aAAO,EAAE,KAAK,KAAK;AAAA,IACrB,SAAS,OAAO;AACd,YAAM,SAAU,OAA+B;AAC/C,aAAO,EAAE,KAAK,EAAE,OAAO,uCAAuC,GAAG,WAAW,MAAM,MAAM,WAAW,MAAM,MAAM,GAAG;AAAA,IACpH;AAAA,EACF,CAAC;AACD,SAAO;AACT;","names":[]}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Creates a public Kratos whoami verifier without using the Admin API or minting sessions.
3
+ * @param options - publicUrl is an HTTP(S) origin with root path and no embedded credentials/query/fragment; fetch defaults to global fetch and timeoutMs to 10000 milliseconds.
4
+ * @returns An async verifier accepting cookie/sessionToken credentials and resolving userId plus provider identity, or null for absent credentials, 401/403 responses, inactive sessions, or missing identity IDs. sessionToken takes precedence over cookie.
5
+ * @throws Synchronously for an invalid provider URL. Verification rejects transport, abort, invalid timeout, non-OK provider responses other than 401/403, and JSON parsing failures.
6
+ * @remarks Credentials are forwarded only to the configured origin with redirects disabled and no-store caching. The host must trust this origin and separately resolve memberships and tenant lifecycle. This verifier creates no listeners or background work.
7
+ * @example
8
+ * ```typescript
9
+ * import { createKratosSessionVerifier } from "@alneas/eaos-server/browser-auth/kratos-session";
10
+ * const verify = createKratosSessionVerifier({ publicUrl: "https://identity.example.com" });
11
+ * export async function authenticate(cookie: string | undefined) {
12
+ * return verify({ cookie });
13
+ * }
14
+ * ```
15
+ */
16
+ declare function createKratosSessionVerifier(options: {
17
+ /**
18
+ * Trusted HTTP(S) Kratos origin with a root path and no embedded credentials, query, or fragment.
19
+ */
20
+ publicUrl: string;
21
+ /**
22
+ * Host transport for public whoami calls; defaults to global fetch, with redirects disabled and no-store caching.
23
+ */
24
+ fetch?: typeof fetch;
25
+ /**
26
+ * AbortSignal timeout in milliseconds for each whoami request; defaults to 10000 and invalid values fail when invoked.
27
+ */
28
+ timeoutMs?: number;
29
+ }): (credentials: {
30
+ cookie?: string;
31
+ sessionToken?: string;
32
+ }) => Promise<{
33
+ userId: string;
34
+ identity: Record<string, unknown>;
35
+ } | null>;
36
+
37
+ export { createKratosSessionVerifier };
@@ -0,0 +1,7 @@
1
+ import {
2
+ createKratosSessionVerifier
3
+ } from "../chunk-F3O7CELI.js";
4
+ export {
5
+ createKratosSessionVerifier
6
+ };
7
+ //# sourceMappingURL=kratos-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,120 @@
1
+ import * as hono_types from 'hono/types';
2
+ import { Context, Hono } from 'hono';
3
+ import { createKratosSessionVerifier } from './kratos-session.js';
4
+ import './public-memberships.js';
5
+ import './account-memberships.js';
6
+ import { LifecycleStore, BackendTarget } from '@alneas/eaos-server/lifecycle-engine';
7
+ import '@alneas/eaos-server/platform';
8
+
9
+ /**
10
+ * Verified tenant membership candidate supplied to {@link createPlatformSessionResolver}.
11
+ */
12
+ interface Membership {
13
+ /** Tenant ID matching the selected header, if provided; validated as a 1–128-character scope identifier. */
14
+ tenantId: string;
15
+ /** Verified role names, each a nonempty string. */
16
+ roles: string[];
17
+ /** Verified entitlement names, each a nonempty string. */
18
+ enabledModules: string[];
19
+ }
20
+ /**
21
+ * Combines a verified Kratos identity, unambiguous membership, active tenant, and expected backend placement.
22
+ * @param options - verify checks credentials; memberships receives verified userId, optional selected tenant ID, and provider identity and resolves candidate memberships; store supplies lifecycle state; targetFor synchronously resolves the expected backend for a selected tenant.
23
+ * @returns A resolver accepting Hono context and optional refresh flag. It resolves a BrowserSession or null for invalid credentials/selection, ambiguous membership, or inactive tenant. Each context caches the in-flight/result Promise unless refresh is true.
24
+ * @throws The resolver rejects verifier, membership, store, and targetFor errors, malformed membership fields, or backend placement mismatch. Rejected Promises are cached until refresh.
25
+ * @remarks Authorization accepts only the exact Bearer syntax with one space and a nonwhitespace token. Bearer token takes precedence over X-Session-Token; the verifier gives session tokens precedence over cookies. X-Tenant-Id selects a candidate but never grants membership. No default tenant or role is invented. The WeakMap cache is per resolver/context; refresh starts another lookup without cancelling previous work.
26
+ * @example
27
+ * ```typescript
28
+ * import { createPlatformSessionResolver } from "@alneas/eaos-server/browser-auth/platform-session";
29
+ * export function hostSessionResolver(options: Parameters<typeof createPlatformSessionResolver>[0]) {
30
+ * // Supply verified membership reads, lifecycle store, and backend routing.
31
+ * return createPlatformSessionResolver(options);
32
+ * }
33
+ * ```
34
+ */
35
+ declare function createPlatformSessionResolver(options: {
36
+ /**
37
+ * Server whoami verifier receiving cookie/session-token credentials; token transport takes precedence over cookies.
38
+ */
39
+ verify: ReturnType<typeof createKratosSessionVerifier>;
40
+ /**
41
+ * Host callback receiving verified user ID, optional requested tenant, and provider identity; must resolve exactly one authorized membership or resolution returns null.
42
+ */
43
+ memberships: (userId: string, tenantId: string | undefined, identity: Record<string, unknown>) => Promise<Membership[]>;
44
+ /**
45
+ * Authoritative lifecycle store used to require an active tenant and its expected backend placement.
46
+ */
47
+ store: LifecycleStore;
48
+ /**
49
+ * Synchronous host backend selector for the verified membership tenant; an ID differing from lifecycle placement rejects resolution.
50
+ */
51
+ targetFor: (tenantId: string) => BackendTarget;
52
+ }): (context: Context, resolution?: {
53
+ refresh?: boolean;
54
+ }) => Promise<BrowserSession | null>;
55
+
56
+ /**
57
+ * Verified browser identity and membership serialized by {@link createBrowserSessionRouter}.
58
+ */
59
+ interface BrowserSession {
60
+ /** Nonblank authenticated identity ID. */
61
+ userId: string;
62
+ /** Nonblank selected authorized tenant ID. */
63
+ tenantId: string;
64
+ /** Verified nonblank role names; empty arrays are accepted. */
65
+ roles: string[];
66
+ /** Verified nonblank module entitlement names; empty arrays are accepted. */
67
+ enabledModules: string[];
68
+ }
69
+ /**
70
+ * Exposes browser-safe provider configuration and verified session data with no-store response headers.
71
+ * @typeParam T - Host session shape extending required identity/membership fields; additional fields are serialized in full.
72
+ * @param options - configuration synchronously supplies publicUrl/provider/redirectOrigins and optional returnTo for GET /config; resolveSession receives Hono context for GET /session and resolves a verified session or null; optional tenantId restricts returned sessions to one tenant.
73
+ * @returns A router with GET /config and /session. Configuration failure returns 503; absent session returns 401, tenant mismatch returns 403, and resolver failures map status 401/403 or otherwise 503.
74
+ * @remarks The host owns IdP settings and membership lookup. No identity creation, default roles, or token minting occurs. Configuration output whitelists fields, but session output serializes all T fields: do not place secrets in a session. Responses set Cache-Control: no-store and Vary: Cookie, Authorization, X-Tenant-Id.
75
+ * @example
76
+ * ```typescript
77
+ * import type { Context } from "hono";
78
+ * import { createBrowserSessionRouter, type BrowserSession } from "@alneas/eaos-server/browser-auth";
79
+ * export function authRouter(resolveSession: (context: Context) => Promise<BrowserSession | null>) {
80
+ * return createBrowserSessionRouter({
81
+ * configuration: () => ({ publicUrl: "https://identity.example.com", provider: "kratos", redirectOrigins: ["https://app.example.com"] }),
82
+ * resolveSession,
83
+ * });
84
+ * }
85
+ * ```
86
+ */
87
+ declare function createBrowserSessionRouter<T extends BrowserSession>(options: {
88
+ /**
89
+ * Synchronous public IdP configuration callback evaluated on each /config request; failures become 503 and only explicitly selected fields are serialized.
90
+ */
91
+ configuration: () => {
92
+ /**
93
+ * Nonempty public identity-provider URL returned to the browser; the router does not validate its URL syntax.
94
+ */
95
+ publicUrl: string;
96
+ /**
97
+ * Nonempty provider label returned to the browser.
98
+ */
99
+ provider: string;
100
+ /**
101
+ * Optional post-authentication return URL included only when truthy; host configuration must validate redirect policy.
102
+ */
103
+ returnTo?: string;
104
+ /**
105
+ * Host redirect-origin list serialized to the browser; the router checks only that it is an array.
106
+ */
107
+ redirectOrigins: string[];
108
+ };
109
+ /**
110
+ * Per-request host verifier resolving a trusted session or null for 401; thrown statuses 401/403 are preserved and other failures become 503.
111
+ */
112
+ resolveSession: (context: Context) => Promise<T | null>;
113
+ /**
114
+ * Optional dedicated-backend tenant restriction; a session selecting another tenant returns 403.
115
+ */
116
+ tenantId?: string;
117
+ }): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
118
+
119
+ export { createBrowserSessionRouter as c, createPlatformSessionResolver };
120
+ export type { BrowserSession as B, Membership };
@@ -0,0 +1,7 @@
1
+ import {
2
+ createPlatformSessionResolver
3
+ } from "../chunk-XUP6CNOM.js";
4
+ export {
5
+ createPlatformSessionResolver
6
+ };
7
+ //# sourceMappingURL=platform-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,22 @@
1
+ import { AccountMemberships } from '@alneas/eaos-server/platform';
2
+
3
+ /**
4
+ * Parses account membership claims exclusively from an active identity's public metadata.
5
+ * @param identity - Identity returned by a server-verified Kratos session; state must equal active.
6
+ * @returns Parsed memberships and optional defaultTenantId; absent/null public metadata supplies an empty membership list.
7
+ * @throws For inactive identities, malformed public metadata, or invalid membership claims rejected by the platform parser.
8
+ * @remarks Never pass editable traits or unverified client JSON. There is no fallback to private metadata or SQL membership lookup, and parsing does not authenticate the identity.
9
+ * @example
10
+ * ```typescript
11
+ * import { publicAccountMemberships } from "@alneas/eaos-server/browser-auth/public-memberships";
12
+ * import { createKratosSessionVerifier } from "@alneas/eaos-server/browser-auth/kratos-session";
13
+ * const verify = createKratosSessionVerifier({ publicUrl: "https://identity.example.com" });
14
+ * export async function memberships(cookie: string | undefined) {
15
+ * const session = await verify({ cookie });
16
+ * return session ? publicAccountMemberships(session.identity) : null;
17
+ * }
18
+ * ```
19
+ */
20
+ declare function publicAccountMemberships(identity: Record<string, unknown>): AccountMemberships;
21
+
22
+ export { publicAccountMemberships };