@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,246 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
2
+ import type { StartedPostgreSqlContainer } from '@testcontainers/postgresql';
3
+ import pg from 'pg';
4
+ import { eq } from 'drizzle-orm';
5
+ import { runMigrations } from '@antasphere/chassis-db/migrate';
6
+ import { workspaceMembers } from '@antasphere/chassis-db';
7
+ import { existsSync } from 'node:fs';
8
+ import {
9
+ createDatabase,
10
+ createTestApp,
11
+ extractCookie,
12
+ readJson,
13
+ startPostgres,
14
+ type TestApp,
15
+ host
16
+ } from './helpers.js';
17
+
18
+ const OWNER = {
19
+ email: 'owner@example.com',
20
+ name: 'Owner One',
21
+ password: 'a-long-owner-password-123'
22
+ };
23
+
24
+ let container: StartedPostgreSqlContainer;
25
+ let app: TestApp;
26
+
27
+ // The host's own history, the folder its boot applies (the chassis's fixture
28
+ // here, the tool's packages/db/drizzle under the tool's host).
29
+ const migrationsFolder = host.migrationsDir;
30
+ if (!existsSync(migrationsFolder)) throw new Error(`migrations not found at ${migrationsFolder}`);
31
+
32
+ beforeAll(async () => {
33
+ container = await startPostgres();
34
+ app = await createTestApp(container.getConnectionUri());
35
+ });
36
+
37
+ afterAll(async () => {
38
+ await app?.stop();
39
+ await container?.stop();
40
+ });
41
+
42
+ describe('migrations', () => {
43
+ it('is idempotent: a second run applies nothing', async () => {
44
+ // Boot already migrated. Run the migrator again and compare the journal.
45
+ const client = new pg.Client({ connectionString: container.getConnectionUri() });
46
+ await client.connect();
47
+ const before = await client.query('SELECT count(*)::int AS n FROM drizzle.__drizzle_migrations');
48
+ await runMigrations({ connectionString: container.getConnectionUri(), migrationsFolder });
49
+ const after = await client.query('SELECT count(*)::int AS n FROM drizzle.__drizzle_migrations');
50
+ await client.end();
51
+ expect(after.rows[0].n).toBe(before.rows[0].n);
52
+ expect(before.rows[0].n).toBeGreaterThan(0);
53
+ });
54
+
55
+ it('ships an image where pgvector is installable (products run CREATE EXTENSION — ADR 004)', async () => {
56
+ const client = new pg.Client({ connectionString: container.getConnectionUri() });
57
+ await client.connect();
58
+ const res = await client.query(
59
+ `SELECT count(*)::int AS n FROM pg_available_extensions WHERE name = 'vector'`
60
+ );
61
+ await client.end();
62
+ expect(res.rows[0].n).toBe(1);
63
+ });
64
+ });
65
+
66
+ describe('first-boot setup', () => {
67
+ it('reports setupRequired before setup', async () => {
68
+ const res = await app.app.request('/api/v1/instance');
69
+ expect(res.status).toBe(200);
70
+ const body = await readJson(res);
71
+ expect(body.setupRequired).toBe(true);
72
+ expect(body.instanceId).toBeNull();
73
+ expect(body.auth.methods).toContain('password');
74
+ });
75
+
76
+ it('creates owner + workspace, then flips setupRequired', async () => {
77
+ const res = await app.app.request('/api/v1/setup', {
78
+ method: 'POST',
79
+ headers: { 'content-type': 'application/json' },
80
+ body: JSON.stringify({
81
+ setupToken: 'integration-test-setup-token',
82
+ instanceName: 'Test Instance',
83
+ owner: OWNER
84
+ })
85
+ });
86
+ expect(res.status).toBe(201);
87
+ const body = await readJson(res);
88
+ expect(body.workspaceId).toBeTruthy();
89
+ expect(body.ownerUserId).toBeTruthy();
90
+ expect(body.instanceId).toMatch(/^[0-9A-HJKMNP-TV-Z]{26}$/); // ULID
91
+
92
+ const inst = await app.app.request('/api/v1/instance');
93
+ const instBody = await readJson(inst);
94
+ expect(instBody.setupRequired).toBe(false);
95
+ expect(instBody.name).toBe('Test Instance');
96
+ });
97
+
98
+ it('returns 410 on a second setup attempt', async () => {
99
+ const res = await app.app.request('/api/v1/setup', {
100
+ method: 'POST',
101
+ headers: { 'content-type': 'application/json' },
102
+ body: JSON.stringify({
103
+ setupToken: 'integration-test-setup-token',
104
+ instanceName: 'Again',
105
+ owner: { ...OWNER, email: 'other@example.com' }
106
+ })
107
+ });
108
+ expect(res.status).toBe(410);
109
+ const body = await readJson(res);
110
+ expect(body.error.code).toBe('already_setup');
111
+ });
112
+ });
113
+
114
+ describe('authentication + /me', () => {
115
+ let cookie: string;
116
+
117
+ it('signs in the owner with password and gets a session cookie', async () => {
118
+ const res = await app.app.request('/api/v1/auth/sign-in/email', {
119
+ method: 'POST',
120
+ headers: { 'content-type': 'application/json' },
121
+ body: JSON.stringify({ email: OWNER.email, password: OWNER.password })
122
+ });
123
+ expect(res.status).toBe(200);
124
+ cookie = extractCookie(res);
125
+ expect(cookie).toContain('better-auth');
126
+ });
127
+
128
+ it('resolves /me with the session cookie (role owner, via session)', async () => {
129
+ const res = await app.app.request('/api/v1/me', { headers: { cookie } });
130
+ expect(res.status).toBe(200);
131
+ const body = await readJson(res);
132
+ expect(body.user.email).toBe(OWNER.email);
133
+ expect(body.role).toBe('owner');
134
+ expect(body.via).toBe('session');
135
+ expect(body.scopes).toBeNull();
136
+ expect(body.workspace.name).toBe('Test Instance');
137
+ });
138
+
139
+ it('401s without credentials', async () => {
140
+ const res = await app.app.request('/api/v1/me');
141
+ expect(res.status).toBe(401);
142
+ });
143
+
144
+ it('401s a JWT-shaped bearer that this instance never minted', async () => {
145
+ const res = await app.app.request('/api/v1/me', {
146
+ headers: { authorization: 'Bearer aaa.bbb.ccc' }
147
+ });
148
+ expect(res.status).toBe(401);
149
+ const body = await readJson(res);
150
+ expect(body.error.code).toBe('invalid_token');
151
+ });
152
+
153
+ it('revokes instantly: deactivating the membership kills the live session', async () => {
154
+ const me = await app.app.request('/api/v1/me', { headers: { cookie } });
155
+ const body = await readJson(me);
156
+ // The last-owner trigger (migration 0009) forbids deactivating the sole
157
+ // owner, so seed a throwaway sibling owner first — this test is about the
158
+ // live re-check killing the subject's session, not the last-owner rule.
159
+ const siblingUserId = `sibling-${body.user.id}`;
160
+ await app.db.pool.query(
161
+ `INSERT INTO "user" (id, name, email, email_verified) VALUES ($1, 'Sibling Owner', $2, true)`,
162
+ [siblingUserId, `sibling-${Date.now()}@revoke.test`]
163
+ );
164
+ await app.db.pool.query(
165
+ `INSERT INTO workspace_members (workspace_id, user_id, role, is_active) VALUES ($1, $2, 'owner', true)`,
166
+ [body.workspace.id, siblingUserId]
167
+ );
168
+ try {
169
+ await app.db.db
170
+ .update(workspaceMembers)
171
+ .set({ isActive: false })
172
+ .where(eq(workspaceMembers.userId, body.user.id));
173
+
174
+ // The live re-check kills WORKSPACE access instantly: a real
175
+ // workspace endpoint 401s (no active membership resolves).
176
+ const denied = await app.app.request(host.probeRoute, { headers: { cookie } });
177
+ expect(denied.status).toBe(401);
178
+ // /me itself now answers the zero-membership zero state (200, empty
179
+ // list) rather than a 401 — the user is signed in but belongs to no
180
+ // workspace (user-scoped credential model); the dashboard renders the
181
+ // no-organization page instead of bouncing to login.
182
+ const after = await app.app.request('/api/v1/me', { headers: { cookie } });
183
+ expect(after.status).toBe(200);
184
+ const afterBody = await readJson(after);
185
+ expect(afterBody.workspaces).toEqual([]);
186
+ expect(afterBody.activeWorkspaceId).toBeNull();
187
+ } finally {
188
+ // restore even when the assertion fails — later suites need the owner
189
+ await app.db.db
190
+ .update(workspaceMembers)
191
+ .set({ isActive: true })
192
+ .where(eq(workspaceMembers.userId, body.user.id));
193
+ // drop the sibling (owner still active, so the trigger is satisfied)
194
+ await app.db.pool.query(`DELETE FROM workspace_members WHERE user_id = $1`, [siblingUserId]);
195
+ await app.db.pool.query(`DELETE FROM "user" WHERE id = $1`, [siblingUserId]);
196
+ }
197
+ });
198
+
199
+ it('blocks public HTTP sign-up (accounts enter via setup or invitations)', async () => {
200
+ const res = await app.app.request('/api/v1/auth/sign-up/email', {
201
+ method: 'POST',
202
+ headers: { 'content-type': 'application/json' },
203
+ body: JSON.stringify({ email: 'squatter@example.com', password: 'x'.repeat(16), name: 'Squatter' })
204
+ });
205
+ expect(res.status).toBe(403);
206
+ });
207
+ });
208
+
209
+ describe('setup token', () => {
210
+ it('enforces SETUP_TOKEN when configured (403 wrong, 201 right)', async () => {
211
+ const url = await createDatabase(container, 'setup_token_test');
212
+ const tokenApp = await createTestApp(url, { SETUP_TOKEN: 'super-setup-token' });
213
+ try {
214
+ const wrong = await tokenApp.app.request('/api/v1/setup', {
215
+ method: 'POST',
216
+ headers: { 'content-type': 'application/json' },
217
+ body: JSON.stringify({ instanceName: 'T', owner: OWNER, setupToken: 'nope-wrong-token' })
218
+ });
219
+ expect(wrong.status).toBe(403);
220
+
221
+ const right = await tokenApp.app.request('/api/v1/setup', {
222
+ method: 'POST',
223
+ headers: { 'content-type': 'application/json' },
224
+ body: JSON.stringify({ instanceName: 'T', owner: OWNER, setupToken: 'super-setup-token' })
225
+ });
226
+ expect(right.status).toBe(201);
227
+ } finally {
228
+ await tokenApp.stop();
229
+ }
230
+ });
231
+ });
232
+
233
+ describe('openapi + health', () => {
234
+ it('serves a generated OpenAPI document', async () => {
235
+ const res = await app.app.request('/api/v1/openapi.json');
236
+ expect(res.status).toBe(200);
237
+ const doc = await readJson(res);
238
+ expect(doc.openapi).toBe('3.1.0');
239
+ expect(Object.keys(doc.paths)).toEqual(expect.arrayContaining(['/instance', '/setup', '/me']));
240
+ });
241
+
242
+ it('reports ready after boot', async () => {
243
+ const res = await app.app.request('/readyz');
244
+ expect(res.status).toBe(200);
245
+ });
246
+ });
@@ -0,0 +1,80 @@
1
+ import { createDb } from '@antasphere/chassis-db';
2
+ import type { StartedPostgreSqlContainer } from '@testcontainers/postgresql';
3
+ import pg from 'pg';
4
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
5
+ import { endPool, startPostgres } from '../../src/testing/helpers.js';
6
+
7
+ /**
8
+ * The production pool survives what a Postgres restart does to it (lane A's
9
+ * verifier, F5). node-postgres emits `error` on the POOL when an idle client's
10
+ * connection ends on the server's side; with no listener that event is an
11
+ * uncaught exception and the process dies with 57P01. `createDb` listens, so
12
+ * the cost of a restart is one reconnect.
13
+ *
14
+ * The backends are ended with `pg_terminate_backend`, from a connection of its
15
+ * own: exactly what a restart, a failover or an administrator does.
16
+ */
17
+ let container: StartedPostgreSqlContainer;
18
+
19
+ beforeAll(async () => {
20
+ container = await startPostgres();
21
+ }, 120_000);
22
+
23
+ afterAll(async () => {
24
+ await container?.stop();
25
+ });
26
+
27
+ /** Ends every other backend of this database, the way a restart would. */
28
+ async function terminateOtherBackends(url: string): Promise<number> {
29
+ const admin = new pg.Client({ connectionString: url });
30
+ await admin.connect();
31
+ try {
32
+ const res = await admin.query<{ ended: boolean }>(
33
+ `select pg_terminate_backend(pid) as ended from pg_stat_activity
34
+ where datname = current_database() and pid <> pg_backend_pid()`
35
+ );
36
+ return res.rows.filter((r) => r.ended).length;
37
+ } finally {
38
+ await admin.end();
39
+ }
40
+ }
41
+
42
+ describe('createDb: an idle pooled connection ended by the server', () => {
43
+ it('reaches the listener, never the process, and the next query gets a new connection', async () => {
44
+ const url = container.getConnectionUri();
45
+ const seen: Array<{ code?: string }> = [];
46
+ const uncaught: unknown[] = [];
47
+ const onUncaught = (err: unknown) => uncaught.push(err);
48
+ process.on('uncaughtException', onUncaught);
49
+
50
+ const { pool } = createDb(url, {}, { onIdleError: (err) => seen.push(err as { code?: string }) });
51
+ try {
52
+ // three IDLE clients: checked out together, then all released
53
+ const clients = await Promise.all([pool.connect(), pool.connect(), pool.connect()]);
54
+ for (const c of clients) c.release();
55
+ expect(pool.idleCount).toBe(3);
56
+
57
+ expect(await terminateOtherBackends(url)).toBe(3);
58
+ await expect.poll(() => seen.length, { timeout: 10_000 }).toBe(3);
59
+
60
+ expect(seen.map((e) => e.code)).toEqual(['57P01', '57P01', '57P01']);
61
+ expect(uncaught).toEqual([]);
62
+ // the dead clients left the pool, and the pool still serves
63
+ expect(pool.totalCount).toBe(0);
64
+ const res = await pool.query<{ one: number }>('select 1 as one');
65
+ expect(res.rows[0]?.one).toBe(1);
66
+ } finally {
67
+ process.off('uncaughtException', onUncaught);
68
+ await endPool(pool);
69
+ }
70
+ });
71
+
72
+ it('listens even when the caller gives no callback: the bare handle is safe too', async () => {
73
+ const { pool } = createDb(container.getConnectionUri(), {});
74
+ try {
75
+ expect(pool.listenerCount('error')).toBeGreaterThanOrEqual(1);
76
+ } finally {
77
+ await endPool(pool);
78
+ }
79
+ });
80
+ });
@@ -0,0 +1,193 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
2
+ import type { StartedPostgreSqlContainer } from '@testcontainers/postgresql';
3
+ import { and, eq } from 'drizzle-orm';
4
+ import { projectMembers, workspaceMembers } from '@antasphere/chassis-db';
5
+ import { createDatabase, createTestApp, readJson, startPostgres, type TestApp, host } from './helpers.js';
6
+ import { FakeHub, type HubUserFixture } from '@antasphere/chassis-server/testing';
7
+ import * as sso from './sso-helpers.js';
8
+
9
+ /**
10
+ * Project membership is the tool's own ON BOTH EDITIONS: never behind the
11
+ * hub-managed gate. On `EDITION=cloud`, in a HUB-ORIGIN (projected) workspace,
12
+ * where every local membership mutation answers 403 `hub_managed`
13
+ * (hub-managed-membership.test.ts), a project is created and its members are
14
+ * added, changed and removed locally. Nothing here can diverge from the hub:
15
+ * members are picked among the workspace's existing members, and no
16
+ * invitation, claim or account is minted.
17
+ *
18
+ * The second half is the other side of the same coin: when the hub's
19
+ * reconcile sweeps a membership, the grants that rode on it go with it.
20
+ */
21
+ const ORG = '26260000-aaaa-4bbb-8ccc-000000000001';
22
+ /** A second org of the member's, so their session keeps resolving while ORG is swept. */
23
+ const ORG_OTHER = '26260000-aaaa-4bbb-8ccc-000000000002';
24
+
25
+ const DIALS = {
26
+ reconcileTtlMs: 120,
27
+ reconcileStaleMaxMs: 60_000,
28
+ retryMs: 250,
29
+ orgsTimeoutMs: 400,
30
+ tokenTimeoutMs: 2_000
31
+ };
32
+ const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
33
+ /** Let the per-user reconcile cache expire so the next request runs a fresh pass. */
34
+ const expireTtl = () => sleep(DIALS.reconcileTtlMs + 40);
35
+
36
+ const hubOwner: HubUserFixture = {
37
+ sub: 'hub-owner-projects',
38
+ email: 'hub-owner@projects-cloud.test',
39
+ name: 'Hub Owner',
40
+ workspaceId: ORG,
41
+ role: 'owner',
42
+ workspaceName: 'Org Projects'
43
+ };
44
+ const hubMember: HubUserFixture = {
45
+ sub: 'hub-member-projects',
46
+ email: 'hub-member@projects-cloud.test',
47
+ name: 'Hub Member',
48
+ workspaceId: ORG,
49
+ role: 'member',
50
+ workspaceName: 'Org Projects'
51
+ };
52
+
53
+ let container: StartedPostgreSqlContainer;
54
+ let hub: FakeHub;
55
+ let app: TestApp;
56
+ let ownerCookie = '';
57
+ let memberCookie = '';
58
+ let workspaceId = '';
59
+ let memberUserId = '';
60
+
61
+ let ipCounter = 0;
62
+ const nextIp = () => `10.78.0.${(ipCounter++ % 250) + 1}`;
63
+
64
+ const send = (method: string, path: string, cookie: string, body?: unknown) =>
65
+ app.app.request(`/api/v1${path}`, {
66
+ method,
67
+ headers: {
68
+ cookie,
69
+ 'x-workspace-id': workspaceId,
70
+ 'x-forwarded-for': nextIp(),
71
+ ...(body !== undefined ? { 'content-type': 'application/json' } : {})
72
+ },
73
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {})
74
+ });
75
+
76
+ beforeAll(async () => {
77
+ [container, hub] = await Promise.all([startPostgres(), FakeHub.start({ clientId: host.hubClientId })]);
78
+ app = await createTestApp(
79
+ await createDatabase(container, 'projects_cloud'),
80
+ {
81
+ EDITION: 'cloud',
82
+ HUB_ISSUER_URL: hub.issuer,
83
+ HUB_CLIENT_ID: host.hubClientId,
84
+ HUB_CLIENT_SECRET: 'integration-test-hub-secret-projects'
85
+ },
86
+ { hubDials: DIALS }
87
+ );
88
+ const setup = await app.app.request('/api/v1/setup', {
89
+ method: 'POST',
90
+ headers: { 'content-type': 'application/json', 'x-forwarded-for': nextIp() },
91
+ body: JSON.stringify({
92
+ setupToken: 'integration-test-setup-token',
93
+ instanceName: 'Projects Cloud',
94
+ owner: { email: 'operator@projects-cloud.test', name: 'Operator', password: 'operator-pass-projects-1' }
95
+ })
96
+ });
97
+ expect(setup.status).toBe(201);
98
+
99
+ ownerCookie = await sso.ssoLogin(app, hub, hubOwner);
100
+ const me = await readJson(await app.app.request('/api/v1/me', { headers: { cookie: ownerCookie } }));
101
+ workspaceId = me.activeWorkspaceId;
102
+ expect(me.workspace.hubOrigin).toBe(true);
103
+ memberCookie = await sso.ssoLogin(app, hub, hubMember);
104
+ const memberMe = await readJson(await app.app.request('/api/v1/me', { headers: { cookie: memberCookie } }));
105
+ expect(memberMe.activeWorkspaceId).toBe(workspaceId);
106
+ memberUserId = memberMe.user.id;
107
+ }, 180_000);
108
+
109
+ afterAll(async () => {
110
+ await app?.stop();
111
+ await Promise.all([container?.stop(), hub?.stop()]);
112
+ });
113
+
114
+ describe('cloud edition, hub-origin workspace', () => {
115
+ let projectId = '';
116
+
117
+ it('a project member is added locally (201) while POST /invitations answers 403 hub_managed', async () => {
118
+ const created = await send('POST', '/projects', ownerCookie, { name: 'Cloud project' });
119
+ expect(created.status).toBe(201);
120
+ projectId = (await readJson(created)).id;
121
+
122
+ const added = await send('POST', `/projects/${projectId}/members`, ownerCookie, {
123
+ email: hubMember.email,
124
+ role: 'editor'
125
+ });
126
+ expect(added.status).toBe(201);
127
+ expect(await readJson(added)).toMatchObject({ userId: memberUserId, role: 'editor' });
128
+
129
+ const invite = await send('POST', '/invitations', ownerCookie, {
130
+ email: 'newcomer@projects-cloud.test',
131
+ role: 'member'
132
+ });
133
+ expect(invite.status).toBe(403);
134
+ expect((await readJson(invite)).error.code).toBe('hub_managed');
135
+ });
136
+
137
+ it('a plain hub member creates a project of their own, and every other project mutation stays local too', async () => {
138
+ const own = await send('POST', '/projects', memberCookie, { name: 'A member’s own' });
139
+ expect(own.status).toBe(201);
140
+
141
+ const role = await send('PATCH', `/projects/${projectId}/members/${memberUserId}`, ownerCookie, {
142
+ role: 'viewer'
143
+ });
144
+ expect(role.status).toBe(200);
145
+ expect((await send('PATCH', `/projects/${projectId}`, ownerCookie, { name: 'Renamed' })).status).toBe(
146
+ 200
147
+ );
148
+ expect((await send('POST', `/projects/${projectId}/archive`, ownerCookie)).status).toBe(200);
149
+ expect((await send('POST', `/projects/${projectId}/unarchive`, ownerCookie)).status).toBe(200);
150
+ expect((await send('DELETE', `/projects/${projectId}/members/${memberUserId}`, ownerCookie)).status).toBe(
151
+ 200
152
+ );
153
+ });
154
+
155
+ it('a membership the hub sweeps loses its project grants, and a re-add at the hub starts with none', async () => {
156
+ const back = await send('POST', `/projects/${projectId}/members`, ownerCookie, {
157
+ userId: memberUserId,
158
+ role: 'editor'
159
+ });
160
+ expect(back.status).toBe(201);
161
+ expect((await send('GET', `/projects/${projectId}`, memberCookie)).status).toBe(200);
162
+ const membership = async () => {
163
+ const [row] = await app.db.db
164
+ .select({ id: workspaceMembers.id, isActive: workspaceMembers.isActive })
165
+ .from(workspaceMembers)
166
+ .where(and(eq(workspaceMembers.userId, memberUserId), eq(workspaceMembers.workspaceId, workspaceId)));
167
+ return row!;
168
+ };
169
+ const before = await membership();
170
+
171
+ // Removed from the org at the hub. The reconcile DEACTIVATES the local
172
+ // row, it never deletes it, so the foreign key's cascade does not fire:
173
+ // the sweep itself takes the grants.
174
+ hub.setUserOrg(hubMember.sub, ORG_OTHER, { name: 'Another Org', role: 'member' });
175
+ hub.removeUserOrg(hubMember.sub, ORG);
176
+ await expireTtl();
177
+ await app.app.request('/api/v1/me', { headers: { cookie: memberCookie } });
178
+ expect(await membership()).toEqual({ id: before.id, isActive: false });
179
+ expect(
180
+ await app.db.db.select().from(projectMembers).where(eq(projectMembers.memberId, before.id))
181
+ ).toEqual([]);
182
+
183
+ // Added back at the hub: the SAME row comes back to life, with no grant.
184
+ hub.setUserOrg(hubMember.sub, ORG, { name: 'Org Projects', role: 'member' });
185
+ await expireTtl();
186
+ await app.app.request('/api/v1/me', { headers: { cookie: memberCookie } });
187
+ expect(await membership()).toEqual({ id: before.id, isActive: true });
188
+ const gone = await send('GET', `/projects/${projectId}`, memberCookie);
189
+ expect(gone.status).toBe(404);
190
+ const listed = await readJson(await send('GET', '/projects?archived=all', memberCookie));
191
+ expect(listed.projects.map((p: { id: string }) => p.id)).not.toContain(projectId);
192
+ });
193
+ });