@antasphere/chassis-server 1.0.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 (798) hide show
  1. package/LICENSE +82 -0
  2. package/dist/accounts/deletion.d.ts +163 -0
  3. package/dist/accounts/deletion.d.ts.map +1 -0
  4. package/dist/accounts/deletion.js +360 -0
  5. package/dist/accounts/deletion.js.map +1 -0
  6. package/dist/accounts/erasure-log.d.ts +66 -0
  7. package/dist/accounts/erasure-log.d.ts.map +1 -0
  8. package/dist/accounts/erasure-log.js +117 -0
  9. package/dist/accounts/erasure-log.js.map +1 -0
  10. package/dist/accounts/index.d.ts +6 -0
  11. package/dist/accounts/index.d.ts.map +1 -0
  12. package/dist/accounts/index.js +6 -0
  13. package/dist/accounts/index.js.map +1 -0
  14. package/dist/accounts/mint-refusal.d.ts +47 -0
  15. package/dist/accounts/mint-refusal.d.ts.map +1 -0
  16. package/dist/accounts/mint-refusal.js +59 -0
  17. package/dist/accounts/mint-refusal.js.map +1 -0
  18. package/dist/accounts/signup-duplicate.d.ts +14 -0
  19. package/dist/accounts/signup-duplicate.d.ts.map +1 -0
  20. package/dist/accounts/signup-duplicate.js +25 -0
  21. package/dist/accounts/signup-duplicate.js.map +1 -0
  22. package/dist/accounts/superadmin.d.ts +27 -0
  23. package/dist/accounts/superadmin.d.ts.map +1 -0
  24. package/dist/accounts/superadmin.js +46 -0
  25. package/dist/accounts/superadmin.js.map +1 -0
  26. package/dist/api/apikeys.d.ts +14 -0
  27. package/dist/api/apikeys.d.ts.map +1 -0
  28. package/dist/api/apikeys.js +124 -0
  29. package/dist/api/apikeys.js.map +1 -0
  30. package/dist/api/audit.d.ts +4 -0
  31. package/dist/api/audit.d.ts.map +1 -0
  32. package/dist/api/audit.js +75 -0
  33. package/dist/api/audit.js.map +1 -0
  34. package/dist/api/break-glass.d.ts +48 -0
  35. package/dist/api/break-glass.d.ts.map +1 -0
  36. package/dist/api/break-glass.js +217 -0
  37. package/dist/api/break-glass.js.map +1 -0
  38. package/dist/api/cli-auth.d.ts +84 -0
  39. package/dist/api/cli-auth.d.ts.map +1 -0
  40. package/dist/api/cli-auth.js +177 -0
  41. package/dist/api/cli-auth.js.map +1 -0
  42. package/dist/api/create-api.d.ts +123 -0
  43. package/dist/api/create-api.d.ts.map +1 -0
  44. package/dist/api/create-api.js +1165 -0
  45. package/dist/api/create-api.js.map +1 -0
  46. package/dist/api/demo-passes.d.ts +45 -0
  47. package/dist/api/demo-passes.d.ts.map +1 -0
  48. package/dist/api/demo-passes.js +143 -0
  49. package/dist/api/demo-passes.js.map +1 -0
  50. package/dist/api/errors.d.ts +5 -0
  51. package/dist/api/errors.d.ts.map +1 -0
  52. package/dist/api/errors.js +5 -0
  53. package/dist/api/errors.js.map +1 -0
  54. package/dist/api/export.d.ts +63 -0
  55. package/dist/api/export.d.ts.map +1 -0
  56. package/dist/api/export.js +393 -0
  57. package/dist/api/export.js.map +1 -0
  58. package/dist/api/files.d.ts +40 -0
  59. package/dist/api/files.d.ts.map +1 -0
  60. package/dist/api/files.js +150 -0
  61. package/dist/api/files.js.map +1 -0
  62. package/dist/api/index.d.ts +17 -0
  63. package/dist/api/index.d.ts.map +1 -0
  64. package/dist/api/index.js +17 -0
  65. package/dist/api/index.js.map +1 -0
  66. package/dist/api/invitations.d.ts +50 -0
  67. package/dist/api/invitations.d.ts.map +1 -0
  68. package/dist/api/invitations.js +313 -0
  69. package/dist/api/invitations.js.map +1 -0
  70. package/dist/api/members.d.ts +25 -0
  71. package/dist/api/members.d.ts.map +1 -0
  72. package/dist/api/members.js +522 -0
  73. package/dist/api/members.js.map +1 -0
  74. package/dist/api/onboarding.d.ts +26 -0
  75. package/dist/api/onboarding.d.ts.map +1 -0
  76. package/dist/api/onboarding.js +23 -0
  77. package/dist/api/onboarding.js.map +1 -0
  78. package/dist/api/openapi-doc.d.ts +21 -0
  79. package/dist/api/openapi-doc.d.ts.map +1 -0
  80. package/dist/api/openapi-doc.js +25 -0
  81. package/dist/api/openapi-doc.js.map +1 -0
  82. package/dist/api/projects.d.ts +24 -0
  83. package/dist/api/projects.d.ts.map +1 -0
  84. package/dist/api/projects.js +624 -0
  85. package/dist/api/projects.js.map +1 -0
  86. package/dist/api/scope-routes.d.ts +12 -0
  87. package/dist/api/scope-routes.d.ts.map +1 -0
  88. package/dist/api/scope-routes.js +2 -0
  89. package/dist/api/scope-routes.js.map +1 -0
  90. package/dist/api/sso-connect.d.ts +70 -0
  91. package/dist/api/sso-connect.d.ts.map +1 -0
  92. package/dist/api/sso-connect.js +164 -0
  93. package/dist/api/sso-connect.js.map +1 -0
  94. package/dist/api/sso-logout.d.ts +41 -0
  95. package/dist/api/sso-logout.d.ts.map +1 -0
  96. package/dist/api/sso-logout.js +34 -0
  97. package/dist/api/sso-logout.js.map +1 -0
  98. package/dist/api/teams.d.ts +43 -0
  99. package/dist/api/teams.d.ts.map +1 -0
  100. package/dist/api/teams.js +447 -0
  101. package/dist/api/teams.js.map +1 -0
  102. package/dist/api/workspaces.d.ts +114 -0
  103. package/dist/api/workspaces.d.ts.map +1 -0
  104. package/dist/api/workspaces.js +462 -0
  105. package/dist/api/workspaces.js.map +1 -0
  106. package/dist/apikeys/index.d.ts +3 -0
  107. package/dist/apikeys/index.d.ts.map +1 -0
  108. package/dist/apikeys/index.js +3 -0
  109. package/dist/apikeys/index.js.map +1 -0
  110. package/dist/apikeys/peppers.d.ts +53 -0
  111. package/dist/apikeys/peppers.d.ts.map +1 -0
  112. package/dist/apikeys/peppers.js +97 -0
  113. package/dist/apikeys/peppers.js.map +1 -0
  114. package/dist/apikeys/service.d.ts +56 -0
  115. package/dist/apikeys/service.d.ts.map +1 -0
  116. package/dist/apikeys/service.js +196 -0
  117. package/dist/apikeys/service.js.map +1 -0
  118. package/dist/app.d.ts +65 -0
  119. package/dist/app.d.ts.map +1 -0
  120. package/dist/app.js +142 -0
  121. package/dist/app.js.map +1 -0
  122. package/dist/audit/filters.d.ts +38 -0
  123. package/dist/audit/filters.d.ts.map +1 -0
  124. package/dist/audit/filters.js +97 -0
  125. package/dist/audit/filters.js.map +1 -0
  126. package/dist/audit/index.d.ts +3 -0
  127. package/dist/audit/index.d.ts.map +1 -0
  128. package/dist/audit/index.js +3 -0
  129. package/dist/audit/index.js.map +1 -0
  130. package/dist/audit/service.d.ts +65 -0
  131. package/dist/audit/service.d.ts.map +1 -0
  132. package/dist/audit/service.js +103 -0
  133. package/dist/audit/service.js.map +1 -0
  134. package/dist/boot.d.ts +8 -0
  135. package/dist/boot.d.ts.map +1 -0
  136. package/dist/boot.js +822 -0
  137. package/dist/boot.js.map +1 -0
  138. package/dist/constant-time.d.ts +3 -0
  139. package/dist/constant-time.d.ts.map +1 -0
  140. package/dist/constant-time.js +10 -0
  141. package/dist/constant-time.js.map +1 -0
  142. package/dist/email/driver.d.ts +16 -0
  143. package/dist/email/driver.d.ts.map +1 -0
  144. package/dist/email/driver.js +136 -0
  145. package/dist/email/driver.js.map +1 -0
  146. package/dist/email/index.d.ts +4 -0
  147. package/dist/email/index.d.ts.map +1 -0
  148. package/dist/email/index.js +4 -0
  149. package/dist/email/index.js.map +1 -0
  150. package/dist/email/shell.d.ts +72 -0
  151. package/dist/email/shell.d.ts.map +1 -0
  152. package/dist/email/shell.js +146 -0
  153. package/dist/email/shell.js.map +1 -0
  154. package/dist/email/templates.d.ts +83 -0
  155. package/dist/email/templates.d.ts.map +1 -0
  156. package/dist/email/templates.js +96 -0
  157. package/dist/email/templates.js.map +1 -0
  158. package/dist/entitlements/check.d.ts +140 -0
  159. package/dist/entitlements/check.d.ts.map +1 -0
  160. package/dist/entitlements/check.js +276 -0
  161. package/dist/entitlements/check.js.map +1 -0
  162. package/dist/entitlements/clock-skew.d.ts +27 -0
  163. package/dist/entitlements/clock-skew.d.ts.map +1 -0
  164. package/dist/entitlements/clock-skew.js +58 -0
  165. package/dist/entitlements/clock-skew.js.map +1 -0
  166. package/dist/entitlements/gate.d.ts +113 -0
  167. package/dist/entitlements/gate.d.ts.map +1 -0
  168. package/dist/entitlements/gate.js +430 -0
  169. package/dist/entitlements/gate.js.map +1 -0
  170. package/dist/entitlements/hub-machine-token.d.ts +83 -0
  171. package/dist/entitlements/hub-machine-token.d.ts.map +1 -0
  172. package/dist/entitlements/hub-machine-token.js +175 -0
  173. package/dist/entitlements/hub-machine-token.js.map +1 -0
  174. package/dist/entitlements/hub-subject.d.ts +32 -0
  175. package/dist/entitlements/hub-subject.d.ts.map +1 -0
  176. package/dist/entitlements/hub-subject.js +68 -0
  177. package/dist/entitlements/hub-subject.js.map +1 -0
  178. package/dist/entitlements/index.d.ts +9 -0
  179. package/dist/entitlements/index.d.ts.map +1 -0
  180. package/dist/entitlements/index.js +9 -0
  181. package/dist/entitlements/index.js.map +1 -0
  182. package/dist/entitlements/poster.d.ts +81 -0
  183. package/dist/entitlements/poster.d.ts.map +1 -0
  184. package/dist/entitlements/poster.js +169 -0
  185. package/dist/entitlements/poster.js.map +1 -0
  186. package/dist/entitlements/profiles.d.ts +121 -0
  187. package/dist/entitlements/profiles.d.ts.map +1 -0
  188. package/dist/entitlements/profiles.js +212 -0
  189. package/dist/entitlements/profiles.js.map +1 -0
  190. package/dist/entitlements/slot.d.ts +33 -0
  191. package/dist/entitlements/slot.d.ts.map +1 -0
  192. package/dist/entitlements/slot.js +75 -0
  193. package/dist/entitlements/slot.js.map +1 -0
  194. package/dist/env.d.ts +293 -0
  195. package/dist/env.d.ts.map +1 -0
  196. package/dist/env.js +383 -0
  197. package/dist/env.js.map +1 -0
  198. package/dist/files/http.d.ts +23 -0
  199. package/dist/files/http.d.ts.map +1 -0
  200. package/dist/files/http.js +66 -0
  201. package/dist/files/http.js.map +1 -0
  202. package/dist/files/index.d.ts +5 -0
  203. package/dist/files/index.d.ts.map +1 -0
  204. package/dist/files/index.js +5 -0
  205. package/dist/files/index.js.map +1 -0
  206. package/dist/files/serve.d.ts +43 -0
  207. package/dist/files/serve.d.ts.map +1 -0
  208. package/dist/files/serve.js +71 -0
  209. package/dist/files/serve.js.map +1 -0
  210. package/dist/files/service.d.ts +69 -0
  211. package/dist/files/service.d.ts.map +1 -0
  212. package/dist/files/service.js +188 -0
  213. package/dist/files/service.js.map +1 -0
  214. package/dist/files/spool.d.ts +21 -0
  215. package/dist/files/spool.d.ts.map +1 -0
  216. package/dist/files/spool.js +47 -0
  217. package/dist/files/spool.js.map +1 -0
  218. package/dist/identity/better-auth.d.ts +3927 -0
  219. package/dist/identity/better-auth.d.ts.map +1 -0
  220. package/dist/identity/better-auth.js +896 -0
  221. package/dist/identity/better-auth.js.map +1 -0
  222. package/dist/identity/demo-pass-plugin.d.ts +29 -0
  223. package/dist/identity/demo-pass-plugin.d.ts.map +1 -0
  224. package/dist/identity/demo-pass-plugin.js +88 -0
  225. package/dist/identity/demo-pass-plugin.js.map +1 -0
  226. package/dist/identity/demo-pass-rules.d.ts +84 -0
  227. package/dist/identity/demo-pass-rules.d.ts.map +1 -0
  228. package/dist/identity/demo-pass-rules.js +223 -0
  229. package/dist/identity/demo-pass-rules.js.map +1 -0
  230. package/dist/identity/demo-pass.d.ts +159 -0
  231. package/dist/identity/demo-pass.d.ts.map +1 -0
  232. package/dist/identity/demo-pass.js +319 -0
  233. package/dist/identity/demo-pass.js.map +1 -0
  234. package/dist/identity/hub-grant.d.ts +182 -0
  235. package/dist/identity/hub-grant.d.ts.map +1 -0
  236. package/dist/identity/hub-grant.js +594 -0
  237. package/dist/identity/hub-grant.js.map +1 -0
  238. package/dist/identity/hub-jwt.d.ts +22 -0
  239. package/dist/identity/hub-jwt.d.ts.map +1 -0
  240. package/dist/identity/hub-jwt.js +77 -0
  241. package/dist/identity/hub-jwt.js.map +1 -0
  242. package/dist/identity/hub-live-gate.d.ts +17 -0
  243. package/dist/identity/hub-live-gate.d.ts.map +1 -0
  244. package/dist/identity/hub-live-gate.js +146 -0
  245. package/dist/identity/hub-live-gate.js.map +1 -0
  246. package/dist/identity/hub-logout.d.ts +88 -0
  247. package/dist/identity/hub-logout.d.ts.map +1 -0
  248. package/dist/identity/hub-logout.js +158 -0
  249. package/dist/identity/hub-logout.js.map +1 -0
  250. package/dist/identity/hub-projection.d.ts +103 -0
  251. package/dist/identity/hub-projection.d.ts.map +1 -0
  252. package/dist/identity/hub-projection.js +130 -0
  253. package/dist/identity/hub-projection.js.map +1 -0
  254. package/dist/identity/hub-reconcile.d.ts +151 -0
  255. package/dist/identity/hub-reconcile.d.ts.map +1 -0
  256. package/dist/identity/hub-reconcile.js +400 -0
  257. package/dist/identity/hub-reconcile.js.map +1 -0
  258. package/dist/identity/hub-sso.d.ts +363 -0
  259. package/dist/identity/hub-sso.d.ts.map +1 -0
  260. package/dist/identity/hub-sso.js +536 -0
  261. package/dist/identity/hub-sso.js.map +1 -0
  262. package/dist/identity/hub-user-client.d.ts +222 -0
  263. package/dist/identity/hub-user-client.d.ts.map +1 -0
  264. package/dist/identity/hub-user-client.js +406 -0
  265. package/dist/identity/hub-user-client.js.map +1 -0
  266. package/dist/identity/index.d.ts +13 -0
  267. package/dist/identity/index.d.ts.map +1 -0
  268. package/dist/identity/index.js +13 -0
  269. package/dist/identity/index.js.map +1 -0
  270. package/dist/identity/oauth-jwt.d.ts +32 -0
  271. package/dist/identity/oauth-jwt.d.ts.map +1 -0
  272. package/dist/identity/oauth-jwt.js +122 -0
  273. package/dist/identity/oauth-jwt.js.map +1 -0
  274. package/dist/identity/resolve-membership.d.ts +28 -0
  275. package/dist/identity/resolve-membership.d.ts.map +1 -0
  276. package/dist/identity/resolve-membership.js +69 -0
  277. package/dist/identity/resolve-membership.js.map +1 -0
  278. package/dist/identity/signing-key.d.ts +49 -0
  279. package/dist/identity/signing-key.d.ts.map +1 -0
  280. package/dist/identity/signing-key.js +144 -0
  281. package/dist/identity/signing-key.js.map +1 -0
  282. package/dist/index.d.ts +21 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +11 -0
  285. package/dist/index.js.map +1 -0
  286. package/dist/invitations/index.d.ts +2 -0
  287. package/dist/invitations/index.d.ts.map +1 -0
  288. package/dist/invitations/index.js +2 -0
  289. package/dist/invitations/index.js.map +1 -0
  290. package/dist/invitations/service.d.ts +36 -0
  291. package/dist/invitations/service.d.ts.map +1 -0
  292. package/dist/invitations/service.js +122 -0
  293. package/dist/invitations/service.js.map +1 -0
  294. package/dist/jobs/index.d.ts +3 -0
  295. package/dist/jobs/index.d.ts.map +1 -0
  296. package/dist/jobs/index.js +3 -0
  297. package/dist/jobs/index.js.map +1 -0
  298. package/dist/jobs/pgboss.d.ts +119 -0
  299. package/dist/jobs/pgboss.d.ts.map +1 -0
  300. package/dist/jobs/pgboss.js +521 -0
  301. package/dist/jobs/pgboss.js.map +1 -0
  302. package/dist/jobs/timers.d.ts +127 -0
  303. package/dist/jobs/timers.d.ts.map +1 -0
  304. package/dist/jobs/timers.js +228 -0
  305. package/dist/jobs/timers.js.map +1 -0
  306. package/dist/logger.d.ts +17 -0
  307. package/dist/logger.d.ts.map +1 -0
  308. package/dist/logger.js +64 -0
  309. package/dist/logger.js.map +1 -0
  310. package/dist/mcp/errors.d.ts +37 -0
  311. package/dist/mcp/errors.d.ts.map +1 -0
  312. package/dist/mcp/errors.js +77 -0
  313. package/dist/mcp/errors.js.map +1 -0
  314. package/dist/mcp/http.d.ts +35 -0
  315. package/dist/mcp/http.d.ts.map +1 -0
  316. package/dist/mcp/http.js +80 -0
  317. package/dist/mcp/http.js.map +1 -0
  318. package/dist/mcp/index.d.ts +8 -0
  319. package/dist/mcp/index.d.ts.map +1 -0
  320. package/dist/mcp/index.js +8 -0
  321. package/dist/mcp/index.js.map +1 -0
  322. package/dist/mcp/inputs.d.ts +19 -0
  323. package/dist/mcp/inputs.d.ts.map +1 -0
  324. package/dist/mcp/inputs.js +28 -0
  325. package/dist/mcp/inputs.js.map +1 -0
  326. package/dist/mcp/projects.d.ts +31 -0
  327. package/dist/mcp/projects.d.ts.map +1 -0
  328. package/dist/mcp/projects.js +315 -0
  329. package/dist/mcp/projects.js.map +1 -0
  330. package/dist/mcp/server.d.ts +52 -0
  331. package/dist/mcp/server.d.ts.map +1 -0
  332. package/dist/mcp/server.js +93 -0
  333. package/dist/mcp/server.js.map +1 -0
  334. package/dist/mcp/teams.d.ts +7 -0
  335. package/dist/mcp/teams.d.ts.map +1 -0
  336. package/dist/mcp/teams.js +62 -0
  337. package/dist/mcp/teams.js.map +1 -0
  338. package/dist/mcp/tool-kit.d.ts +67 -0
  339. package/dist/mcp/tool-kit.d.ts.map +1 -0
  340. package/dist/mcp/tool-kit.js +74 -0
  341. package/dist/mcp/tool-kit.js.map +1 -0
  342. package/dist/members/removal.d.ts +95 -0
  343. package/dist/members/removal.d.ts.map +1 -0
  344. package/dist/members/removal.js +143 -0
  345. package/dist/members/removal.js.map +1 -0
  346. package/dist/middleware/auth-body.d.ts +25 -0
  347. package/dist/middleware/auth-body.d.ts.map +1 -0
  348. package/dist/middleware/auth-body.js +55 -0
  349. package/dist/middleware/auth-body.js.map +1 -0
  350. package/dist/middleware/auth-context.d.ts +170 -0
  351. package/dist/middleware/auth-context.d.ts.map +1 -0
  352. package/dist/middleware/auth-context.js +251 -0
  353. package/dist/middleware/auth-context.js.map +1 -0
  354. package/dist/middleware/body-cap.d.ts +17 -0
  355. package/dist/middleware/body-cap.d.ts.map +1 -0
  356. package/dist/middleware/body-cap.js +31 -0
  357. package/dist/middleware/body-cap.js.map +1 -0
  358. package/dist/middleware/body-refusal.d.ts +20 -0
  359. package/dist/middleware/body-refusal.d.ts.map +1 -0
  360. package/dist/middleware/body-refusal.js +5 -0
  361. package/dist/middleware/body-refusal.js.map +1 -0
  362. package/dist/middleware/cross-site.d.ts +61 -0
  363. package/dist/middleware/cross-site.d.ts.map +1 -0
  364. package/dist/middleware/cross-site.js +59 -0
  365. package/dist/middleware/cross-site.js.map +1 -0
  366. package/dist/middleware/hub-managed.d.ts +45 -0
  367. package/dist/middleware/hub-managed.d.ts.map +1 -0
  368. package/dist/middleware/hub-managed.js +56 -0
  369. package/dist/middleware/hub-managed.js.map +1 -0
  370. package/dist/middleware/idempotency.d.ts +14 -0
  371. package/dist/middleware/idempotency.d.ts.map +1 -0
  372. package/dist/middleware/idempotency.js +222 -0
  373. package/dist/middleware/idempotency.js.map +1 -0
  374. package/dist/middleware/index.d.ts +12 -0
  375. package/dist/middleware/index.d.ts.map +1 -0
  376. package/dist/middleware/index.js +12 -0
  377. package/dist/middleware/index.js.map +1 -0
  378. package/dist/middleware/json-depth.d.ts +32 -0
  379. package/dist/middleware/json-depth.d.ts.map +1 -0
  380. package/dist/middleware/json-depth.js +80 -0
  381. package/dist/middleware/json-depth.js.map +1 -0
  382. package/dist/middleware/no-store.d.ts +21 -0
  383. package/dist/middleware/no-store.d.ts.map +1 -0
  384. package/dist/middleware/no-store.js +32 -0
  385. package/dist/middleware/no-store.js.map +1 -0
  386. package/dist/middleware/oauth-public.d.ts +16 -0
  387. package/dist/middleware/oauth-public.d.ts.map +1 -0
  388. package/dist/middleware/oauth-public.js +50 -0
  389. package/dist/middleware/oauth-public.js.map +1 -0
  390. package/dist/middleware/rate-limit.d.ts +182 -0
  391. package/dist/middleware/rate-limit.d.ts.map +1 -0
  392. package/dist/middleware/rate-limit.js +277 -0
  393. package/dist/middleware/rate-limit.js.map +1 -0
  394. package/dist/middleware/request-id.d.ts +10 -0
  395. package/dist/middleware/request-id.d.ts.map +1 -0
  396. package/dist/middleware/request-id.js +42 -0
  397. package/dist/middleware/request-id.js.map +1 -0
  398. package/dist/middleware/scopes.d.ts +33 -0
  399. package/dist/middleware/scopes.d.ts.map +1 -0
  400. package/dist/middleware/scopes.js +139 -0
  401. package/dist/middleware/scopes.js.map +1 -0
  402. package/dist/middleware/security-headers.d.ts +53 -0
  403. package/dist/middleware/security-headers.d.ts.map +1 -0
  404. package/dist/middleware/security-headers.js +96 -0
  405. package/dist/middleware/security-headers.js.map +1 -0
  406. package/dist/observability/index.d.ts +3 -0
  407. package/dist/observability/index.d.ts.map +1 -0
  408. package/dist/observability/index.js +3 -0
  409. package/dist/observability/index.js.map +1 -0
  410. package/dist/observability/metrics.d.ts +17 -0
  411. package/dist/observability/metrics.d.ts.map +1 -0
  412. package/dist/observability/metrics.js +82 -0
  413. package/dist/observability/metrics.js.map +1 -0
  414. package/dist/observability/otel.d.ts +20 -0
  415. package/dist/observability/otel.d.ts.map +1 -0
  416. package/dist/observability/otel.js +54 -0
  417. package/dist/observability/otel.js.map +1 -0
  418. package/dist/pagination.d.ts +57 -0
  419. package/dist/pagination.d.ts.map +1 -0
  420. package/dist/pagination.js +90 -0
  421. package/dist/pagination.js.map +1 -0
  422. package/dist/platform/edition.d.ts +57 -0
  423. package/dist/platform/edition.d.ts.map +1 -0
  424. package/dist/platform/edition.js +90 -0
  425. package/dist/platform/edition.js.map +1 -0
  426. package/dist/platform/entitlements.d.ts +26 -0
  427. package/dist/platform/entitlements.d.ts.map +1 -0
  428. package/dist/platform/entitlements.js +28 -0
  429. package/dist/platform/entitlements.js.map +1 -0
  430. package/dist/platform/events.d.ts +87 -0
  431. package/dist/platform/events.d.ts.map +1 -0
  432. package/dist/platform/events.js +32 -0
  433. package/dist/platform/events.js.map +1 -0
  434. package/dist/platform/index.d.ts +8 -0
  435. package/dist/platform/index.d.ts.map +1 -0
  436. package/dist/platform/index.js +8 -0
  437. package/dist/platform/index.js.map +1 -0
  438. package/dist/platform/local-identity.d.ts +39 -0
  439. package/dist/platform/local-identity.d.ts.map +1 -0
  440. package/dist/platform/local-identity.js +87 -0
  441. package/dist/platform/local-identity.js.map +1 -0
  442. package/dist/platform/registry.d.ts +23 -0
  443. package/dist/platform/registry.d.ts.map +1 -0
  444. package/dist/platform/registry.js +5 -0
  445. package/dist/platform/registry.js.map +1 -0
  446. package/dist/platform/usage.d.ts +11 -0
  447. package/dist/platform/usage.d.ts.map +1 -0
  448. package/dist/platform/usage.js +12 -0
  449. package/dist/platform/usage.js.map +1 -0
  450. package/dist/platform/workspaces.d.ts +25 -0
  451. package/dist/platform/workspaces.d.ts.map +1 -0
  452. package/dist/platform/workspaces.js +44 -0
  453. package/dist/platform/workspaces.js.map +1 -0
  454. package/dist/projects/access.d.ts +40 -0
  455. package/dist/projects/access.d.ts.map +1 -0
  456. package/dist/projects/access.js +133 -0
  457. package/dist/projects/access.js.map +1 -0
  458. package/dist/projects/index.d.ts +2 -0
  459. package/dist/projects/index.d.ts.map +1 -0
  460. package/dist/projects/index.js +2 -0
  461. package/dist/projects/index.js.map +1 -0
  462. package/dist/route-label.d.ts +23 -0
  463. package/dist/route-label.d.ts.map +1 -0
  464. package/dist/route-label.js +29 -0
  465. package/dist/route-label.js.map +1 -0
  466. package/dist/routes/health.d.ts +30 -0
  467. package/dist/routes/health.d.ts.map +1 -0
  468. package/dist/routes/health.js +54 -0
  469. package/dist/routes/health.js.map +1 -0
  470. package/dist/routes/index.d.ts +3 -0
  471. package/dist/routes/index.d.ts.map +1 -0
  472. package/dist/routes/index.js +3 -0
  473. package/dist/routes/index.js.map +1 -0
  474. package/dist/routes/wellknown.d.ts +11 -0
  475. package/dist/routes/wellknown.d.ts.map +1 -0
  476. package/dist/routes/wellknown.js +45 -0
  477. package/dist/routes/wellknown.js.map +1 -0
  478. package/dist/secret.d.ts +30 -0
  479. package/dist/secret.d.ts.map +1 -0
  480. package/dist/secret.js +97 -0
  481. package/dist/secret.js.map +1 -0
  482. package/dist/setup-transport.d.ts +23 -0
  483. package/dist/setup-transport.d.ts.map +1 -0
  484. package/dist/setup-transport.js +52 -0
  485. package/dist/setup-transport.js.map +1 -0
  486. package/dist/state.d.ts +21 -0
  487. package/dist/state.d.ts.map +1 -0
  488. package/dist/state.js +4 -0
  489. package/dist/state.js.map +1 -0
  490. package/dist/storage/driver.d.ts +38 -0
  491. package/dist/storage/driver.d.ts.map +1 -0
  492. package/dist/storage/driver.js +14 -0
  493. package/dist/storage/driver.js.map +1 -0
  494. package/dist/storage/factory.d.ts +4 -0
  495. package/dist/storage/factory.d.ts.map +1 -0
  496. package/dist/storage/factory.js +20 -0
  497. package/dist/storage/factory.js.map +1 -0
  498. package/dist/storage/index.d.ts +4 -0
  499. package/dist/storage/index.d.ts.map +1 -0
  500. package/dist/storage/index.js +4 -0
  501. package/dist/storage/index.js.map +1 -0
  502. package/dist/storage/local.d.ts +21 -0
  503. package/dist/storage/local.d.ts.map +1 -0
  504. package/dist/storage/local.js +88 -0
  505. package/dist/storage/local.js.map +1 -0
  506. package/dist/storage/s3.d.ts +29 -0
  507. package/dist/storage/s3.d.ts.map +1 -0
  508. package/dist/storage/s3.js +82 -0
  509. package/dist/storage/s3.js.map +1 -0
  510. package/dist/testing/fake-hub.d.ts +425 -0
  511. package/dist/testing/fake-hub.d.ts.map +1 -0
  512. package/dist/testing/fake-hub.js +1074 -0
  513. package/dist/testing/fake-hub.js.map +1 -0
  514. package/dist/testing/helpers.d.ts +124 -0
  515. package/dist/testing/helpers.d.ts.map +1 -0
  516. package/dist/testing/helpers.js +174 -0
  517. package/dist/testing/helpers.js.map +1 -0
  518. package/dist/testing/index.d.ts +12 -0
  519. package/dist/testing/index.d.ts.map +1 -0
  520. package/dist/testing/index.js +12 -0
  521. package/dist/testing/index.js.map +1 -0
  522. package/dist/testing/setup-origins.d.ts +21 -0
  523. package/dist/testing/setup-origins.d.ts.map +1 -0
  524. package/dist/testing/setup-origins.js +57 -0
  525. package/dist/testing/setup-origins.js.map +1 -0
  526. package/dist/testing/sso-helpers.d.ts +43 -0
  527. package/dist/testing/sso-helpers.d.ts.map +1 -0
  528. package/dist/testing/sso-helpers.js +159 -0
  529. package/dist/testing/sso-helpers.js.map +1 -0
  530. package/dist/tool-definition.d.ts +382 -0
  531. package/dist/tool-definition.d.ts.map +1 -0
  532. package/dist/tool-definition.js +46 -0
  533. package/dist/tool-definition.js.map +1 -0
  534. package/dist/util/index.d.ts +8 -0
  535. package/dist/util/index.d.ts.map +1 -0
  536. package/dist/util/index.js +8 -0
  537. package/dist/util/index.js.map +1 -0
  538. package/package.json +161 -0
  539. package/src/accounts/deletion.ts +389 -0
  540. package/src/accounts/erasure-log.ts +140 -0
  541. package/src/accounts/index.ts +5 -0
  542. package/src/accounts/mint-refusal.ts +67 -0
  543. package/src/accounts/signup-duplicate.ts +21 -0
  544. package/src/accounts/superadmin.ts +46 -0
  545. package/src/api/apikeys.ts +147 -0
  546. package/src/api/audit.ts +83 -0
  547. package/src/api/break-glass.ts +294 -0
  548. package/src/api/cli-auth.ts +308 -0
  549. package/src/api/create-api.ts +1403 -0
  550. package/src/api/demo-passes.ts +207 -0
  551. package/src/api/errors.ts +13 -0
  552. package/src/api/export.ts +482 -0
  553. package/src/api/files.ts +200 -0
  554. package/src/api/index.ts +29 -0
  555. package/src/api/invitations.ts +396 -0
  556. package/src/api/members.ts +617 -0
  557. package/src/api/onboarding.ts +50 -0
  558. package/src/api/openapi-doc.ts +34 -0
  559. package/src/api/projects.ts +788 -0
  560. package/src/api/scope-routes.ts +12 -0
  561. package/src/api/sso-connect.ts +246 -0
  562. package/src/api/sso-logout.ts +76 -0
  563. package/src/api/teams.ts +575 -0
  564. package/src/api/workspaces.ts +649 -0
  565. package/src/apikeys/index.ts +2 -0
  566. package/src/apikeys/peppers.ts +118 -0
  567. package/src/apikeys/service.ts +223 -0
  568. package/src/app.ts +228 -0
  569. package/src/audit/filters.ts +101 -0
  570. package/src/audit/index.ts +9 -0
  571. package/src/audit/service.ts +154 -0
  572. package/src/boot.ts +953 -0
  573. package/src/constant-time.ts +9 -0
  574. package/src/email/driver.ts +139 -0
  575. package/src/email/index.ts +26 -0
  576. package/src/email/shell.ts +201 -0
  577. package/src/email/templates.ts +184 -0
  578. package/src/entitlements/check.ts +435 -0
  579. package/src/entitlements/clock-skew.ts +58 -0
  580. package/src/entitlements/gate.ts +636 -0
  581. package/src/entitlements/hub-machine-token.ts +205 -0
  582. package/src/entitlements/hub-subject.ts +77 -0
  583. package/src/entitlements/index.ts +37 -0
  584. package/src/entitlements/poster.ts +265 -0
  585. package/src/entitlements/profiles.ts +303 -0
  586. package/src/entitlements/slot.ts +105 -0
  587. package/src/env.ts +456 -0
  588. package/src/files/http.ts +77 -0
  589. package/src/files/index.ts +4 -0
  590. package/src/files/serve.ts +115 -0
  591. package/src/files/service.ts +209 -0
  592. package/src/files/spool.ts +58 -0
  593. package/src/identity/better-auth.ts +1103 -0
  594. package/src/identity/demo-pass-plugin.ts +121 -0
  595. package/src/identity/demo-pass-rules.ts +229 -0
  596. package/src/identity/demo-pass.ts +390 -0
  597. package/src/identity/hub-grant.ts +704 -0
  598. package/src/identity/hub-jwt.ts +78 -0
  599. package/src/identity/hub-live-gate.ts +167 -0
  600. package/src/identity/hub-logout.ts +174 -0
  601. package/src/identity/hub-projection.ts +251 -0
  602. package/src/identity/hub-reconcile.ts +572 -0
  603. package/src/identity/hub-sso.ts +696 -0
  604. package/src/identity/hub-user-client.ts +554 -0
  605. package/src/identity/index.ts +56 -0
  606. package/src/identity/oauth-jwt.ts +128 -0
  607. package/src/identity/resolve-membership.ts +104 -0
  608. package/src/identity/signing-key.ts +164 -0
  609. package/src/index.ts +65 -0
  610. package/src/invitations/index.ts +1 -0
  611. package/src/invitations/service.ts +171 -0
  612. package/src/jobs/index.ts +25 -0
  613. package/src/jobs/pgboss.ts +594 -0
  614. package/src/jobs/timers.ts +287 -0
  615. package/src/logger.ts +67 -0
  616. package/src/mcp/errors.ts +111 -0
  617. package/src/mcp/http.ts +129 -0
  618. package/src/mcp/index.ts +28 -0
  619. package/src/mcp/inputs.ts +33 -0
  620. package/src/mcp/projects.ts +480 -0
  621. package/src/mcp/server.ts +174 -0
  622. package/src/mcp/teams.ts +97 -0
  623. package/src/mcp/tool-kit.ts +148 -0
  624. package/src/members/removal.ts +216 -0
  625. package/src/middleware/auth-body.ts +58 -0
  626. package/src/middleware/auth-context.ts +384 -0
  627. package/src/middleware/body-cap.ts +33 -0
  628. package/src/middleware/body-refusal.ts +23 -0
  629. package/src/middleware/cross-site.ts +122 -0
  630. package/src/middleware/hub-managed.ts +61 -0
  631. package/src/middleware/idempotency.ts +264 -0
  632. package/src/middleware/index.ts +33 -0
  633. package/src/middleware/json-depth.ts +74 -0
  634. package/src/middleware/no-store.ts +30 -0
  635. package/src/middleware/oauth-public.ts +54 -0
  636. package/src/middleware/rate-limit.ts +432 -0
  637. package/src/middleware/request-id.ts +54 -0
  638. package/src/middleware/scopes.ts +150 -0
  639. package/src/middleware/security-headers.ts +129 -0
  640. package/src/observability/index.ts +2 -0
  641. package/src/observability/metrics.ts +102 -0
  642. package/src/observability/otel.ts +79 -0
  643. package/src/pagination.ts +118 -0
  644. package/src/platform/edition.ts +140 -0
  645. package/src/platform/entitlements.ts +47 -0
  646. package/src/platform/events.ts +71 -0
  647. package/src/platform/index.ts +7 -0
  648. package/src/platform/local-identity.ts +90 -0
  649. package/src/platform/registry.ts +28 -0
  650. package/src/platform/usage.ts +13 -0
  651. package/src/platform/workspaces.ts +41 -0
  652. package/src/projects/access.ts +160 -0
  653. package/src/projects/index.ts +7 -0
  654. package/src/route-label.ts +29 -0
  655. package/src/routes/health.ts +79 -0
  656. package/src/routes/index.ts +2 -0
  657. package/src/routes/wellknown.ts +67 -0
  658. package/src/secret.ts +115 -0
  659. package/src/setup-transport.ts +46 -0
  660. package/src/state.ts +23 -0
  661. package/src/storage/driver.ts +48 -0
  662. package/src/storage/factory.ts +34 -0
  663. package/src/storage/index.ts +3 -0
  664. package/src/storage/local.ts +93 -0
  665. package/src/storage/s3.ts +109 -0
  666. package/src/testing/fake-hub.ts +1316 -0
  667. package/src/testing/helpers.ts +254 -0
  668. package/src/testing/index.ts +11 -0
  669. package/src/testing/setup-origins.ts +58 -0
  670. package/src/testing/sso-helpers.ts +178 -0
  671. package/src/tool-definition.ts +463 -0
  672. package/src/util/index.ts +17 -0
  673. package/test/fixtures/onboarding-backfill.sql +13 -0
  674. package/test/fixtures/operator-user-id-backfill.sql +18 -0
  675. package/test/host/dr-lib.sh +253 -0
  676. package/test/host/drizzle/0000_chassis_baseline.sql +438 -0
  677. package/test/host/drizzle/0001_last_owner_guard.sql +42 -0
  678. package/test/host/drizzle/meta/0000_snapshot.json +3566 -0
  679. package/test/host/drizzle/meta/_journal.json +20 -0
  680. package/test/host/drizzle.config.ts +17 -0
  681. package/test/host/identity.ts +41 -0
  682. package/test/host/minimal-host.ts +35 -0
  683. package/test/host/minimal-tool.ts +123 -0
  684. package/test/integration/account-oracle-uniformity.test.ts +284 -0
  685. package/test/integration/account-recovery.test.ts +236 -0
  686. package/test/integration/account.test.ts +120 -0
  687. package/test/integration/api-quota.test.ts +208 -0
  688. package/test/integration/apikey-expiry.test.ts +178 -0
  689. package/test/integration/apikey-pepper-rotation.test.ts +190 -0
  690. package/test/integration/boot-posture.test.ts +169 -0
  691. package/test/integration/break-glass.test.ts +484 -0
  692. package/test/integration/cloud-lifecycle.test.ts +233 -0
  693. package/test/integration/credential-boundaries.test.ts +195 -0
  694. package/test/integration/default-workspace.test.ts +414 -0
  695. package/test/integration/demo-pass-rules.test.ts +332 -0
  696. package/test/integration/demo-pass.test.ts +1222 -0
  697. package/test/integration/dr-verify-real-dump.test.ts +154 -0
  698. package/test/integration/edition.test.ts +868 -0
  699. package/test/integration/email-change.test.ts +394 -0
  700. package/test/integration/empty-tool.test.ts +267 -0
  701. package/test/integration/entitlements-null-hook.test.ts +187 -0
  702. package/test/integration/entitlements.test.ts +693 -0
  703. package/test/integration/export-entries.test.ts +321 -0
  704. package/test/integration/files.test.ts +320 -0
  705. package/test/integration/first-boot-claim.test.ts +131 -0
  706. package/test/integration/gdpr.test.ts +532 -0
  707. package/test/integration/helpers.ts +29 -0
  708. package/test/integration/hub-grant.test.ts +505 -0
  709. package/test/integration/hub-live-gate.test.ts +612 -0
  710. package/test/integration/hub-managed-membership.test.ts +559 -0
  711. package/test/integration/hub-org-selector.test.ts +281 -0
  712. package/test/integration/hub-reconcile.test.ts +646 -0
  713. package/test/integration/hub-sso.test.ts +704 -0
  714. package/test/integration/hub-teams.test.ts +771 -0
  715. package/test/integration/idempotency.test.ts +261 -0
  716. package/test/integration/invite-verification.test.ts +210 -0
  717. package/test/integration/last-owner-race.test.ts +263 -0
  718. package/test/integration/m9-fixes.test.ts +290 -0
  719. package/test/integration/mcp-projects.test.ts +463 -0
  720. package/test/integration/member-removal-race.test.ts +466 -0
  721. package/test/integration/member-removal.test.ts +794 -0
  722. package/test/integration/oauth-mcp.test.ts +477 -0
  723. package/test/integration/oauth-workspace.test.ts +371 -0
  724. package/test/integration/observability.test.ts +183 -0
  725. package/test/integration/onboarding.test.ts +268 -0
  726. package/test/integration/orphan-purge.test.ts +451 -0
  727. package/test/integration/pagination.test.ts +344 -0
  728. package/test/integration/platform-core.test.ts +305 -0
  729. package/test/integration/platform.test.ts +246 -0
  730. package/test/integration/pool-survives-restart.test.ts +80 -0
  731. package/test/integration/projects-cloud.test.ts +193 -0
  732. package/test/integration/projects.test.ts +1310 -0
  733. package/test/integration/security-fixes.test.ts +190 -0
  734. package/test/integration/setup-transport.test.ts +118 -0
  735. package/test/integration/signin-wall.test.ts +103 -0
  736. package/test/integration/signing-key-rotation.test.ts +349 -0
  737. package/test/integration/sso-helpers.ts +15 -0
  738. package/test/integration/sso-logout.test.ts +283 -0
  739. package/test/integration/teams-cloud.test.ts +194 -0
  740. package/test/integration/teams.test.ts +551 -0
  741. package/test/integration/timers.test.ts +377 -0
  742. package/test/integration/two-factor.test.ts +301 -0
  743. package/test/integration/usage-window.test.ts +161 -0
  744. package/test/integration/workspace-create-cloud.test.ts +523 -0
  745. package/test/integration/workspace-create.test.ts +510 -0
  746. package/test/integration/workspace-scoping.test.ts +530 -0
  747. package/test/integration/zz-adv-replay-owner.test.ts +205 -0
  748. package/test/unit/apikey-peppers.test.ts +110 -0
  749. package/test/unit/apikey-prefix.test.ts +34 -0
  750. package/test/unit/audit-filters.test.ts +135 -0
  751. package/test/unit/auth-origins.test.ts +92 -0
  752. package/test/unit/body-cap.test.ts +84 -0
  753. package/test/unit/clock-skew.test.ts +68 -0
  754. package/test/unit/cross-site.test.ts +166 -0
  755. package/test/unit/declared-credits.test.ts +13 -0
  756. package/test/unit/demo-pass-rules.test.ts +192 -0
  757. package/test/unit/email-driver.test.ts +127 -0
  758. package/test/unit/end-pool.test.ts +181 -0
  759. package/test/unit/entitlement-check.test.ts +492 -0
  760. package/test/unit/entitlement-gate.test.ts +1333 -0
  761. package/test/unit/entitlement-profiles.test.ts +289 -0
  762. package/test/unit/erasure-log.test.ts +72 -0
  763. package/test/unit/error-mapping.test.ts +89 -0
  764. package/test/unit/export-entries.test.ts +85 -0
  765. package/test/unit/export-sanitize.test.ts +27 -0
  766. package/test/unit/files-head-route.test.ts +155 -0
  767. package/test/unit/files-http.test.ts +97 -0
  768. package/test/unit/head-rewrite.test.ts +72 -0
  769. package/test/unit/hub-create-org.test.ts +181 -0
  770. package/test/unit/hub-jwt.test.ts +93 -0
  771. package/test/unit/hub-sso-params.test.ts +39 -0
  772. package/test/unit/hub-subject.test.ts +83 -0
  773. package/test/unit/idempotency-crypto.test.ts +45 -0
  774. package/test/unit/json-depth.test.ts +88 -0
  775. package/test/unit/logger-redaction.test.ts +66 -0
  776. package/test/unit/mcp-errors.test.ts +110 -0
  777. package/test/unit/mcp-inputs.test.ts +106 -0
  778. package/test/unit/mcp-project-hints.test.ts +26 -0
  779. package/test/unit/no-store.test.ts +49 -0
  780. package/test/unit/no-tool-migration-filename.test.ts +70 -0
  781. package/test/unit/observability.test.ts +64 -0
  782. package/test/unit/openapi-doc.test.ts +93 -0
  783. package/test/unit/rate-limit-consume-on.test.ts +76 -0
  784. package/test/unit/rate-limit.test.ts +39 -0
  785. package/test/unit/readyz-storage.test.ts +157 -0
  786. package/test/unit/request-quota.test.ts +146 -0
  787. package/test/unit/scopes.test.ts +66 -0
  788. package/test/unit/security-headers.test.ts +131 -0
  789. package/test/unit/serve-content-type.test.ts +74 -0
  790. package/test/unit/setup-transport.test.ts +29 -0
  791. package/test/unit/storage-local.test.ts +53 -0
  792. package/test/unit/superadmin.test.ts +32 -0
  793. package/test/unit/timers.test.ts +287 -0
  794. package/test/unit/tool-definition-guards.test.ts +166 -0
  795. package/test/unit/tool-entitlements-guard.test.ts +168 -0
  796. package/test/unit/usage-poster.test.ts +542 -0
  797. package/test/unit/usage-window.test.ts +48 -0
  798. package/test/unit/workspace-create-audit.test.ts +48 -0
@@ -0,0 +1,536 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { and, eq, ne } from 'drizzle-orm';
3
+ import { account, user as userTable, userOnboarding } from '@antasphere/chassis-db';
4
+ import { HubJwtVerifier } from './hub-jwt.js';
5
+ /**
6
+ * "Sign in with Antasphere" — the cloud edition's SSO entrance
7
+ * (internal/federation.md, user-scoped federation). This module owns everything
8
+ * hub-SSO:
9
+ *
10
+ * - the relying-party provider config for better-auth's `genericOAuth`
11
+ * plugin (registered by identity/better-auth.ts ONLY when the instance
12
+ * boots EDITION=cloud — an oss boot never constructs this class);
13
+ * - `HubJwtVerifier`: remote-JWKS verification of hub-minted JWTs (hard
14
+ * iss/aud pinning, RS256 allowlist, cached keys + one forced refresh);
15
+ * - the per-login ASSERTION handoff (an AsyncLocalStorage scope spanning
16
+ * the callback request — see `runWithLoginScope`);
17
+ * - the per-login work better-auth does not know about: identity guard,
18
+ * D10 email re-sync, and the FAIL-CLOSED login reconcile (the org
19
+ * projection) — a cloud login whose reconcile pass fails must not exist.
20
+ *
21
+ * Identity comes from the ID TOKEN ONLY (aud = HUB_CLIENT_ID). The access
22
+ * token is never claim-bearing for the tool: the SSO code exchange sends
23
+ * RFC 8707 `resource = <hub>/mcp` (the `tokenResource` seam constant shared
24
+ * with hub-grant.ts), so the callback access token is HUB-audienced — a
25
+ * bearer for the hub's own `/api/v1`, which the login-time reconcile uses
26
+ * to read the user's org list AS THE USER. Org claims are gone from the
27
+ * login path entirely; the hub's caller-scoped `GET /orgs` is the ONE
28
+ * source of org/membership truth. Refresh + between-logins reads live in
29
+ * hub-grant.ts / hub-user-client.ts; SSO scopes carry `offline_access
30
+ * account:read` so the grant persists on the account row, plus
31
+ * `orgs:create` (HUB_SSO_SCOPES below) for the one write the tool makes at
32
+ * the hub as the user.
33
+ */
34
+ /**
35
+ * providerId of the hub relying party — the discovery method name in
36
+ * `/api/v1/instance`, the better-auth callback path segment
37
+ * (`/api/v1/auth/oauth2/callback/antasphere` — the redirect URI in the
38
+ * hub's TOOL_REGISTRY entry), and the D9 trusted-provider key.
39
+ */
40
+ export const HUB_SSO_PROVIDER_ID = 'antasphere';
41
+ /**
42
+ * A login failure the after-hook converts into a clean, session-less
43
+ * redirect back to /login?error=<code>. Codes are stable (the dashboard
44
+ * maps them to copy); anything unexpected becomes `sso_login_failed`.
45
+ * `/sso/cli-connect` reuses the same errors as 403 bodies —
46
+ * `sso_link_refused` is its trusted-link refusal (never thrown on the
47
+ * browser login path, where better-auth's own linking gate answers first).
48
+ */
49
+ export class HubSsoLoginError extends Error {
50
+ code;
51
+ constructor(code, message) {
52
+ super(message);
53
+ this.code = code;
54
+ this.name = 'HubSsoLoginError';
55
+ }
56
+ }
57
+ const loginScope = new AsyncLocalStorage();
58
+ /**
59
+ * The scopes the tool requests at hub sign-in — the ONE statement of the
60
+ * list (the provider entry below spreads it; tests import it).
61
+ *
62
+ * - `openid profile email`: the id_token identity.
63
+ * - `offline_access account:read`: the stored grant and its as-the-user
64
+ * `GET /orgs` reads (hub-grant.ts, hub-user-client.ts).
65
+ * - `orgs:create` (PRDCT-2443): the hub's DEDICATED scope for `POST /orgs`
66
+ * — it opens that one route, to a tool-registry client only.
67
+ * `account:write` does NOT open it and is deliberately not requested: a
68
+ * tool holds the narrowest write it needs, nothing account-wide.
69
+ *
70
+ * DEPLOY ORDER — THE HUB FIRST. The hub's authorize endpoint
71
+ * (@better-auth/oauth-provider) validates every requested scope against the
72
+ * CLIENT's registered scopes (its tool registry seeds them) and answers
73
+ * `error=invalid_scope` for an unknown one — the WHOLE sign-in fails, for
74
+ * every user, not just workspace creation. A hub that does not yet list
75
+ * `orgs:create` for this client must never meet a tool that requests
76
+ * it. A grant minted BEFORE this shipped simply lacks the scope: the hub
77
+ * answers 403 `insufficient_scope` on create, which the route maps to 401
78
+ * `hub_reauth_required` — one sign-in heals it.
79
+ */
80
+ export const HUB_SSO_SCOPES = [
81
+ 'openid',
82
+ 'profile',
83
+ 'email',
84
+ 'offline_access',
85
+ 'account:read',
86
+ 'orgs:create'
87
+ ];
88
+ /**
89
+ * Strict whitelist for per-call authorize params (the SL-1 silent-connect
90
+ * seam): the dashboard's silent auto-connect passes
91
+ * `additionalData: { prompt: 'none' }` on `POST /sign-in/oauth2`, and the
92
+ * ONLY thing that may ever reach the hub's authorize URL from that
93
+ * caller-controlled blob is the literal `prompt=none` pair — anything else
94
+ * (other prompt values, extra keys) is dropped. Verified on better-auth
95
+ * 1.6.15 (re-verify on ANY bump): `authorizationUrlParams` may be a
96
+ * FUNCTION of the endpoint ctx (generic-oauth/types.d.mts), the sign-in
97
+ * body carries `additionalData` (generic-oauth/routes.mjs — also threaded
98
+ * into the state blob), and the function's return is applied to the
99
+ * authorization URL via `createAuthorizationURL`'s `additionalParams`.
100
+ */
101
+ export function ssoAuthorizationUrlParams(body) {
102
+ const additionalData = body?.additionalData;
103
+ const prompt = additionalData?.prompt;
104
+ return prompt === 'none' ? { prompt: 'none' } : {};
105
+ }
106
+ export class HubSsoService {
107
+ opts;
108
+ verifier;
109
+ reconciler = null;
110
+ constructor(opts) {
111
+ this.opts = opts;
112
+ this.verifier = new HubJwtVerifier(opts.issuerUrl);
113
+ }
114
+ /** Boot binds the reconciler once it exists (see LoginReconciler). */
115
+ bindReconciler(reconciler) {
116
+ this.reconciler = reconciler;
117
+ }
118
+ /**
119
+ * Establish the per-request login scope. api/index.ts wraps EVERY
120
+ * /api/v1/auth/* request on cloud — an empty object store is free, and
121
+ * wrapping unconditionally keeps the seam independent of better-auth's
122
+ * internal routing.
123
+ */
124
+ runWithLoginScope(fn) {
125
+ return loginScope.run({}, fn);
126
+ }
127
+ /** One-shot read of the assertion the current request's getUserInfo verified. */
128
+ takeAssertion() {
129
+ const scope = loginScope.getStore();
130
+ const assertion = scope?.assertion;
131
+ if (scope)
132
+ delete scope.assertion;
133
+ return assertion;
134
+ }
135
+ /** The account site's address (the hub issuer, no trailing slash): where a refusal sends the person. */
136
+ accountUrl() {
137
+ return this.opts.issuerUrl.replace(/\/+$/, '');
138
+ }
139
+ /** Where a failed SSO login lands — the login page with a stable error code. */
140
+ loginErrorUrl(code) {
141
+ return `${this.opts.publicBaseUrl.replace(/\/+$/, '')}/login?error=${encodeURIComponent(code)}`;
142
+ }
143
+ logLoginFailure(err, localUserId) {
144
+ this.opts.logger.warn({ err, localUserId }, 'hub SSO login failed after callback — session revoked, redirecting with error');
145
+ }
146
+ /**
147
+ * The genericOAuth provider entry for the hub. Notes that are POSTURE,
148
+ * not accident:
149
+ *
150
+ * - `scopes` (HUB_SSO_SCOPES) carry `offline_access account:read`: the
151
+ * grant IS the between-logins credential — better-auth persists the
152
+ * refresh token on the account row (encrypted; identity/better-auth.ts),
153
+ * and hub-grant.ts keeps it alive — and `orgs:create`, the hub's
154
+ * DEDICATED scope for `POST /orgs` (PRDCT-2443).
155
+ * - `tokenUrlParams.resource` (RFC 8707) is `tokenResource` — `<hub>/mcp`
156
+ * — so the minted access token is a bearer for the HUB's own API (the
157
+ * login reconcile + every between-logins read), never for ours.
158
+ * - `disableSignUp` stays UNSET: SSO IS the sanctioned signup entrance
159
+ * on cloud — the deliberate FOURTH switch next to the three
160
+ * closed-signup switches (CLAUDE.md invariant, internal/federation.md).
161
+ * - `getUserInfo` replaces the plugin's default entirely, so IT owns the
162
+ * emailVerified mapping — set from the hub's verified `email_verified`
163
+ * claim, never defaulted.
164
+ */
165
+ providerConfig() {
166
+ return {
167
+ providerId: HUB_SSO_PROVIDER_ID,
168
+ discoveryUrl: this.opts.issuerUrl.replace(/\/+$/, '') + '/.well-known/openid-configuration',
169
+ clientId: this.opts.clientId,
170
+ clientSecret: this.opts.clientSecret,
171
+ scopes: [...HUB_SSO_SCOPES],
172
+ pkce: true,
173
+ ...(this.opts.tokenResource ? { tokenUrlParams: { resource: this.opts.tokenResource } } : {}),
174
+ // Per-call prompt=none passthrough for the silent auto-connect — the
175
+ // strict whitelist above; nothing else from the caller's
176
+ // additionalData ever reaches the hub authorize URL.
177
+ authorizationUrlParams: (ctx) => ssoAuthorizationUrlParams(ctx.body),
178
+ getUserInfo: (tokens) => this.getUserInfo(tokens)
179
+ };
180
+ }
181
+ /**
182
+ * Verify the callback id_token and extract the USER assertion. Returning
183
+ * null makes the plugin fail the login with a clean error redirect — the
184
+ * fail-closed path for every bad token (wrong iss/aud, expired, bad
185
+ * signature, malformed claims). The access token is NOT verified here —
186
+ * it is hub-audienced, never claim-bearing for us; it rides the login
187
+ * scope as the reconcile's bearer, and the HUB verifies it on use.
188
+ */
189
+ async getUserInfo(tokens) {
190
+ try {
191
+ if (!tokens.idToken)
192
+ throw new Error('token response carried no id_token (openid is always scoped)');
193
+ if (!tokens.accessToken)
194
+ throw new Error('token response carried no access token');
195
+ const idClaims = await this.verifier.verify(tokens.idToken, this.opts.clientId);
196
+ const assertion = buildUserAssertion(idClaims);
197
+ const scope = loginScope.getStore();
198
+ if (scope) {
199
+ scope.assertion = {
200
+ ...assertion,
201
+ accessToken: tokens.accessToken,
202
+ accessTokenExpiresAt: tokens.accessTokenExpiresAt ?? null
203
+ };
204
+ }
205
+ else {
206
+ // No scope means the auth mount was not wrapped — the after-hook
207
+ // will fail this login closed (sso_assertion_missing). Say why.
208
+ this.opts.logger.error('hub SSO: getUserInfo ran outside a login scope — the callback after-hook will refuse this login');
209
+ }
210
+ return {
211
+ id: assertion.sub,
212
+ email: assertion.email,
213
+ name: assertion.name,
214
+ emailVerified: assertion.emailVerified
215
+ };
216
+ }
217
+ catch (err) {
218
+ this.opts.logger.warn({ err }, 'hub SSO: callback token rejected');
219
+ return null;
220
+ }
221
+ }
222
+ /**
223
+ * The per-login work (after-hook, newSession-gated, JIT and returning
224
+ * users alike), in fail-closed order:
225
+ *
226
+ * 1. single-hub-identity guard — undo an email-match link that would
227
+ * merge two hub subjects into one local user;
228
+ * 2. email re-sync (D10) with the explicit duplicate-email collision
229
+ * path (fail the login, corrupt nothing);
230
+ * 3. the FAIL-CLOSED login reconcile: one forced pass reading the user's
231
+ * org list from the hub with the callback access token — reconcile IS
232
+ * the projection now. A pass that does not definitively succeed
233
+ * throws `sso_projection_failed` (session revoked, error redirect):
234
+ * a cloud login without its projection must not exist.
235
+ *
236
+ * Throws HubSsoLoginError; the caller revokes the just-minted session and
237
+ * redirects. Any other throw is mapped to the generic failure code there.
238
+ */
239
+ async assertLogin(localUserId, assertion) {
240
+ await this.guardSingleHubIdentity(localUserId, assertion.sub);
241
+ await this.syncEmail(localUserId, assertion);
242
+ if (!this.reconciler) {
243
+ // Boot always binds on cloud; a missing binding is a wiring bug and
244
+ // must fail the login closed, never mint an unprojected session.
245
+ throw new HubSsoLoginError('sso_projection_failed', 'no login reconciler bound (boot wiring bug)');
246
+ }
247
+ const outcome = await this.reconciler.forceReconcile(localUserId, {
248
+ accessToken: assertion.accessToken,
249
+ expiresAt: assertion.accessTokenExpiresAt
250
+ });
251
+ if (outcome !== 'ok') {
252
+ throw new HubSsoLoginError('sso_projection_failed', `login reconcile pass failed (${outcome})`);
253
+ }
254
+ // SL-6: lazily mark the first login for the tool-local onboarding seam.
255
+ // AFTER the reconcile 'ok' (a revoked login must not leave a row) and
256
+ // strictly BEST-EFFORT: this write is NEVER a login failure mode — a
257
+ // failed insert just means the row appears on the NEXT login, and the
258
+ // banner semantics (`NOT EXISTS dismissed row` = welcome owed) already
259
+ // show the welcome without any row at all. ON CONFLICT DO NOTHING keeps
260
+ // returning logins from touching an existing (possibly dismissed) row.
261
+ try {
262
+ await this.opts.db.insert(userOnboarding).values({ userId: localUserId }).onConflictDoNothing();
263
+ }
264
+ catch (err) {
265
+ this.opts.logger.warn({ err, localUserId }, 'onboarding first-login insert failed — retry-safe (the welcome stays owed), login unaffected');
266
+ }
267
+ }
268
+ /**
269
+ * Verify a hub-minted exchange JWT (`POST /sso/cli-connect`, the H3
270
+ * counterpart — internal/federation.md P5) and extract its assertion. The
271
+ * chain, every link fail-closed:
272
+ *
273
+ * 1. `HubJwtVerifier.verify` — hub JWKS signature, `iss` pinned to the
274
+ * hub, `aud` pinned to OUR resource URL (a token minted for another
275
+ * tool dies here; a tool-minted MCP token dies on `iss`),
276
+ * RS256 allowlist, expiry (5 s tolerance).
277
+ * 2. `exp` REQUIRED — jose only validates expiry when the claim exists,
278
+ * and the replay ledger needs a bound; a token without one is a
279
+ * contract break, refused.
280
+ * 3. `purpose === 'sso-connect'` REQUIRED — a hub ACCESS token carries
281
+ * no purpose claim and dies here even if iss/aud ever matched.
282
+ * 4. `jti` REQUIRED (bounded) — the caller consumes it one-time-use.
283
+ *
284
+ * The token's TRANSITIONAL org claims (workspace_id/role/workspace_name,
285
+ * kept by the hub through the compat window) are deliberately NOT read —
286
+ * org truth comes from the connect-time reconcile, never a claim.
287
+ *
288
+ * Throws on any failure; the route maps every throw to one uniform 401
289
+ * (no oracle distinguishing replay from expiry from a foreign audience).
290
+ */
291
+ async verifyConnectToken(token) {
292
+ const claims = await this.verifier.verify(token, this.opts.resourceUrl);
293
+ if (typeof claims.exp !== 'number')
294
+ throw new Error('exchange token carries no exp');
295
+ if (claims.purpose !== 'sso-connect') {
296
+ throw new Error('token is not an sso-connect exchange token (purpose claim)');
297
+ }
298
+ const jti = claims.jti;
299
+ if (typeof jti !== 'string' || !jti || jti.length > 256) {
300
+ throw new Error('exchange token carries no usable jti');
301
+ }
302
+ const sub = claims.sub;
303
+ if (typeof sub !== 'string' || !sub)
304
+ throw new Error('exchange token carries no sub');
305
+ const email = claims.email;
306
+ if (typeof email !== 'string' || !email.includes('@')) {
307
+ throw new Error('exchange token carries no usable email claim');
308
+ }
309
+ const normalizedEmail = email.toLowerCase();
310
+ return {
311
+ sub,
312
+ email: normalizedEmail,
313
+ // The hub mints exchange tokens only for a live, authenticated hub
314
+ // user — an identity whose email the hub itself verified (H3 re-reads
315
+ // emailVerified LIVE at mint). The H3 contract carries no
316
+ // email_verified or name claim, so the honest mirror of the SSO
317
+ // id_token's `email_verified: true` is asserted here, and the display
318
+ // name falls back exactly like an SSO login with a blank profile name.
319
+ emailVerified: true,
320
+ name: normalizedEmail.split('@')[0],
321
+ jti,
322
+ expiresAt: new Date(claims.exp * 1000)
323
+ };
324
+ }
325
+ /**
326
+ * JIT-provision for `/sso/cli-connect`: resolve-or-create the local user
327
+ * for a VERIFIED connect assertion, then run the USER half of the
328
+ * per-login work — identity guard, D10 email sync. NO org projection
329
+ * happens here: the route stores the H3 grant (`acquireFromConnect`) and
330
+ * runs the same fail-closed reconcile as a browser login — the reconcile
331
+ * IS the projection, on the connect path too. User resolution mirrors
332
+ * better-auth's own OAuth linking exactly (oauth2/link-account.mjs on the
333
+ * pinned 1.6.15):
334
+ *
335
+ * 1. account row (providerId='antasphere', accountId=sub) → that user;
336
+ * 2. else a local user holding the asserted email → TRUSTED LINK (D9),
337
+ * but only onto a VERIFIED local email (requireLocalEmailVerified —
338
+ * an attacker-parked unverified account can never be taken over);
339
+ * 3. else create user + account through the internal adapter's
340
+ * `createOAuthUser` — the genericOAuth JIT call, so the
341
+ * databaseHooks.user.create.after seam (`user.created` → collaborator
342
+ * grant sweep) fires exactly as it would for a browser SSO signup.
343
+ *
344
+ * Two concurrent first-connects race the create; the loser's unique-email
345
+ * violation is caught and resolved by re-running the lookup (the Phase 5
346
+ * duplicate-account lesson).
347
+ */
348
+ async provisionConnect(auth, assertion) {
349
+ let userId = await this.resolveConnectUser(auth, assertion, true);
350
+ if (userId === null) {
351
+ // Lost the create race: the winner's rows are committed now (the
352
+ // adapter's transaction passthrough) — one retry must resolve.
353
+ userId = await this.resolveConnectUser(auth, assertion, false);
354
+ if (userId === null) {
355
+ throw new HubSsoLoginError('sso_login_failed', 'user provisioning raced and re-lookup failed');
356
+ }
357
+ }
358
+ await this.guardSingleHubIdentity(userId, assertion.sub);
359
+ await this.syncEmail(userId, assertion);
360
+ // Re-read AFTER the D10 sync may have just rewritten the email; the
361
+ // response must carry what the database now holds.
362
+ const [row] = await this.opts.db
363
+ .select({ id: userTable.id, email: userTable.email, name: userTable.name })
364
+ .from(userTable)
365
+ .where(eq(userTable.id, userId))
366
+ .limit(1);
367
+ if (!row)
368
+ throw new HubSsoLoginError('sso_login_failed', 'user row missing after provisioning');
369
+ return { user: row };
370
+ }
371
+ /**
372
+ * The connect path's fail-closed projection pass: one forced reconcile
373
+ * reading the user's org list AS THE USER with their freshly stored (or
374
+ * pre-existing) grant. Returns the pass's own outcome — the route mints a
375
+ * key ONLY on 'ok' (never a born-dead key).
376
+ */
377
+ async reconcileConnect(localUserId) {
378
+ if (!this.reconciler) {
379
+ // Boot always binds on cloud; a missing binding is a wiring bug and
380
+ // must refuse the connect, never mint an unprojected key.
381
+ throw new HubSsoLoginError('sso_projection_failed', 'no login reconciler bound (boot wiring bug)');
382
+ }
383
+ return this.reconciler.forceReconcile(localUserId);
384
+ }
385
+ /**
386
+ * One resolution pass (see provisionConnect). Returns the local user id,
387
+ * or null when `mayCreate` and the create lost a uniqueness race —
388
+ * signalling the caller to re-run with the winner's rows visible.
389
+ */
390
+ async resolveConnectUser(auth, assertion, mayCreate) {
391
+ const db = this.opts.db;
392
+ const [linked] = await db
393
+ .select({ userId: account.userId })
394
+ .from(account)
395
+ .where(and(eq(account.providerId, HUB_SSO_PROVIDER_ID), eq(account.accountId, assertion.sub)))
396
+ .limit(1);
397
+ if (linked)
398
+ return linked.userId;
399
+ const [existing] = await db
400
+ .select({ id: userTable.id, emailVerified: userTable.emailVerified })
401
+ .from(userTable)
402
+ .where(eq(userTable.email, assertion.email))
403
+ .limit(1);
404
+ const authCtx = await auth.$context;
405
+ if (existing) {
406
+ if (!existing.emailVerified) {
407
+ // requireLocalEmailVerified, mirrored: linking a trusted provider
408
+ // onto an UNVERIFIED local account is the classic pre-registration
409
+ // takeover — refuse, exactly like the browser SSO path does.
410
+ throw new HubSsoLoginError('sso_link_refused', 'a local account holds this email but its address is unverified — refusing the trusted link');
411
+ }
412
+ await authCtx.internalAdapter.linkAccount({
413
+ providerId: HUB_SSO_PROVIDER_ID,
414
+ accountId: assertion.sub,
415
+ userId: existing.id
416
+ });
417
+ return existing.id;
418
+ }
419
+ if (!mayCreate)
420
+ return null;
421
+ try {
422
+ const created = await authCtx.internalAdapter.createOAuthUser({ email: assertion.email, name: assertion.name, emailVerified: assertion.emailVerified }, { providerId: HUB_SSO_PROVIDER_ID, accountId: assertion.sub });
423
+ return created.user.id;
424
+ }
425
+ catch (err) {
426
+ // The only expected failure is the unique-email (or duplicate-link)
427
+ // violation from a concurrent first-connect — resolvable by retry.
428
+ this.opts.logger.warn({ err }, 'sso cli-connect: JIT create raced — retrying resolution');
429
+ return null;
430
+ }
431
+ }
432
+ /**
433
+ * A local user may hold AT MOST ONE hub identity. The dangerous path:
434
+ * hub user B's email was changed (hub-side, verified there) to an address
435
+ * some local user A still carries because A's projection is stale — B's
436
+ * first login then finds no account row, matches A by email, and the D9
437
+ * trusted link merges B onto A's local user (and A's resources). Detect the
438
+ * second `antasphere` accountId, DELETE the NEWEST link row, and fail the
439
+ * login. The conflict clears when A next logs in (their email re-syncs
440
+ * away) or an operator intervenes.
441
+ *
442
+ * The undo keys on RECENCY, not on the current login's `sub`. On the
443
+ * normal conflict they are the same row (the trusted link just inserted
444
+ * it). They differ only in residue states where TWO rows pre-exist — a
445
+ * crash between better-auth's link and this hook, or a second identity
446
+ * linked via the explicit /oauth2/link flow (which mints no session, so
447
+ * this guard never saw it). Deleting the current-sub row there would let
448
+ * the ESTABLISHED identity's own login destroy itself (and two
449
+ * concurrent conflicting logins destroy BOTH rows, stranding the user);
450
+ * the newest row is always the intruding link, never the long-standing
451
+ * identity, so the user self-heals on retry.
452
+ */
453
+ async guardSingleHubIdentity(localUserId, sub) {
454
+ const rows = await this.opts.db
455
+ .select({ accountId: account.accountId, createdAt: account.createdAt })
456
+ .from(account)
457
+ .where(and(eq(account.userId, localUserId), eq(account.providerId, HUB_SSO_PROVIDER_ID)));
458
+ if (!rows.some((r) => r.accountId !== sub))
459
+ return;
460
+ const newest = [...rows].sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime() || b.accountId.localeCompare(a.accountId))[0];
461
+ await this.opts.db
462
+ .delete(account)
463
+ .where(and(eq(account.userId, localUserId), eq(account.providerId, HUB_SSO_PROVIDER_ID), eq(account.accountId, newest.accountId)));
464
+ throw new HubSsoLoginError('sso_identity_conflict', `hub subject ${sub} maps to a local user already linked to a different hub subject — newest link undone`);
465
+ }
466
+ /**
467
+ * D10: the hub is the identity source on cloud, so the local email FOLLOWS
468
+ * the (verified) hub email at every login — email-keyed features (the
469
+ * collaborator grant sweep) must see the current address. A collision with
470
+ * another local user's email fails the login cleanly; the unique
471
+ * constraint on user.email backstops the read-then-write race.
472
+ */
473
+ async syncEmail(localUserId, assertion) {
474
+ const email = assertion.email.toLowerCase();
475
+ const [row] = await this.opts.db
476
+ .select({ email: userTable.email, emailVerified: userTable.emailVerified })
477
+ .from(userTable)
478
+ .where(eq(userTable.id, localUserId))
479
+ .limit(1);
480
+ if (!row)
481
+ throw new HubSsoLoginError('sso_login_failed', 'user row missing after callback');
482
+ const emailChanged = row.email !== email;
483
+ // For an UNCHANGED address, emailVerified is a LATCH: once this instance
484
+ // holds the address as verified, a weaker hub assertion never flips it
485
+ // back — break-glass (api/break-glass.ts) refuses unverified users, so a
486
+ // downward sync could close the operator door if the hub's posture ever
487
+ // allowed an unverified login. A CHANGED address takes the hub's
488
+ // asserted state honestly (the new mailbox is unproven). Mirrors
489
+ // better-auth's own overrideUserInfo semantics.
490
+ const emailVerified = emailChanged
491
+ ? assertion.emailVerified
492
+ : row.emailVerified || assertion.emailVerified;
493
+ if (!emailChanged && row.emailVerified === emailVerified)
494
+ return;
495
+ if (emailChanged) {
496
+ const [holder] = await this.opts.db
497
+ .select({ id: userTable.id })
498
+ .from(userTable)
499
+ .where(and(eq(userTable.email, email), ne(userTable.id, localUserId)))
500
+ .limit(1);
501
+ if (holder) {
502
+ throw new HubSsoLoginError('sso_email_conflict', `hub-asserted email is already held by another local user — refusing to sync`);
503
+ }
504
+ }
505
+ try {
506
+ await this.opts.db
507
+ .update(userTable)
508
+ .set({ email, emailVerified, updatedAt: new Date() })
509
+ .where(eq(userTable.id, localUserId));
510
+ }
511
+ catch {
512
+ // Concurrent claim of the same address between check and write.
513
+ throw new HubSsoLoginError('sso_email_conflict', 'email sync lost a uniqueness race');
514
+ }
515
+ }
516
+ }
517
+ /** The SSO-login user assertion, from the VERIFIED id_token ONLY. */
518
+ function buildUserAssertion(idClaims) {
519
+ const sub = idClaims.sub;
520
+ if (typeof sub !== 'string' || !sub)
521
+ throw new Error('id_token carries no sub');
522
+ const email = idClaims.email;
523
+ if (typeof email !== 'string' || !email.includes('@')) {
524
+ throw new Error('id_token carries no usable email claim');
525
+ }
526
+ const normalizedEmail = email.toLowerCase();
527
+ const rawName = idClaims.name;
528
+ const name = typeof rawName === 'string' && rawName.trim() ? rawName : normalizedEmail.split('@')[0];
529
+ return {
530
+ sub,
531
+ email: normalizedEmail,
532
+ emailVerified: idClaims.email_verified === true,
533
+ name
534
+ };
535
+ }
536
+ //# sourceMappingURL=hub-sso.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-sso.js","sourceRoot":"","sources":["../../src/identity/hub-sso.ts"],"names":[],"mappings":"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"}