@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,55 @@
1
+ import { hasNulDeep } from '@antasphere/chassis-contract';
2
+ import { apiError } from '../api/errors.js';
3
+ /** Matches better-call's / Hono's JSON content-type test (the json-depth regex). */
4
+ const JSON_CONTENT_TYPE = /^application\/([a-z0-9.+-]*\+)?json/i;
5
+ /**
6
+ * Pre-validates JSON bodies bound for the Better Auth mount (AF-1 + the
7
+ * update-user half of SL-B4, PRDCT-1358).
8
+ *
9
+ * The load-bearing half is NUL: Better Auth's free-text sinks (`/update-user`'s
10
+ * `name`) are outside the contract, so a NUL rode through to Postgres (SQLSTATE
11
+ * 22021) and surfaced as Better Auth's OWN 500 — a response `app.onError` never
12
+ * sees, so the app-level 22021 backstop cannot reach `/auth/*`. Refusing it
13
+ * here, before the mount, is the only complete place.
14
+ *
15
+ * The malformed/empty-JSON half is defence in depth and a wire-shape
16
+ * normalizer: on the pinned Better Auth (better-call ≥ 1.3.7) a JSON parse
17
+ * error already answers 400 (`BAD_REQUEST`), not a 500 — but with better-call's
18
+ * own error code, not this API's. Answering `invalid_json` here keeps the auth
19
+ * surface's parse errors in the same envelope as every other route, and guards
20
+ * a future dependency change that reverts to a 500.
21
+ *
22
+ * A body under a JSON content-type must parse and carry no NUL anywhere;
23
+ * non-JSON content types pass untouched (the OAuth token endpoint is
24
+ * form-encoded), as do bodyless requests. The body is read from a clone — the
25
+ * mount consumes the original.
26
+ */
27
+ export function authBodyGuard() {
28
+ return async (c, next) => {
29
+ const raw = c.req.raw;
30
+ if (!raw.body)
31
+ return next();
32
+ if (!JSON_CONTENT_TYPE.test(raw.headers.get('content-type') ?? ''))
33
+ return next();
34
+ let text;
35
+ try {
36
+ text = await raw.clone().text();
37
+ }
38
+ catch {
39
+ // Unreadable body — let the mount produce its own error.
40
+ return next();
41
+ }
42
+ let parsed;
43
+ try {
44
+ parsed = JSON.parse(text);
45
+ }
46
+ catch {
47
+ return apiError(c, 400, 'invalid_json', 'Request body is not valid JSON');
48
+ }
49
+ if (hasNulDeep(parsed)) {
50
+ return apiError(c, 400, 'invalid_characters', 'Request contains characters that cannot be stored (e.g. a NUL byte)');
51
+ }
52
+ return next();
53
+ };
54
+ }
55
+ //# sourceMappingURL=auth-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-body.js","sourceRoot":"","sources":["../../src/middleware/auth-body.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,oFAAoF;AACpF,MAAM,iBAAiB,GAAG,sCAAsC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,IAAI;YAAE,OAAO,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAClF,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;YACzD,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,gCAAgC,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,OAAO,QAAQ,CACb,CAAC,EACD,GAAG,EACH,oBAAoB,EACpB,qEAAqE,CACtE,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,170 @@
1
+ import type { Context, MiddlewareHandler } from 'hono';
2
+ import type { RateLimiterAbstract } from 'rate-limiter-flexible';
3
+ import { type Principal } from '@antasphere/chassis-contract';
4
+ import type { PlatformRegistry } from '../platform/registry.js';
5
+ import { type ClientIpFn, type RequestQuotaService } from './rate-limit.js';
6
+ declare module 'hono' {
7
+ interface ContextVariableMap {
8
+ principal: Principal | null;
9
+ /** The tool's `guest_forbidden` sentence, set by `authContext` for `requireNonGuest()` to answer with. */
10
+ guestForbiddenMessage: string;
11
+ /** Demo sign-in: the pass that opened this request's session, when one did (the audit mark). */
12
+ demoPassId?: string;
13
+ }
14
+ }
15
+ export declare function isPublicApiPath(path: string): boolean;
16
+ /**
17
+ * An edition's post-resolution verdict on an otherwise-valid principal.
18
+ * `ok` with a `role` means "the caller's authoritative role just changed —
19
+ * run THIS request under it"; `ok` with a `workspace` means "the person's
20
+ * DEFAULT workspace just moved (the pass this request ran read it off the
21
+ * hub) — run THIS request there", which the gate says only for a request
22
+ * that selected nothing (`request.selector` null) on a credential that pins
23
+ * nothing (PRDCT-2958, F2: the command that runs the pass used to land in
24
+ * the old default, the one after it in the new); a refusal carries the
25
+ * exact wire error. The seam exists for the cloud edition's hub gates (org
26
+ * suspension + hub membership re-assertion, internal/federation.md P4); oss
27
+ * never wires one. The gate also sees WHAT is being asked (`request`), so a
28
+ * policy can exempt specific surfaces (e.g. suspension keeping GET /me
29
+ * readable — the visible-but-blocked posture); implementations may ignore
30
+ * it.
31
+ */
32
+ export type PrincipalGateResult = {
33
+ ok: true;
34
+ role?: Principal['role'];
35
+ workspace?: GateWorkspace;
36
+ } | {
37
+ ok: false;
38
+ status: 401 | 403;
39
+ code: string;
40
+ message: string;
41
+ };
42
+ /** The membership a gate re-resolved for the request: the fields of the principal it replaces. */
43
+ export interface GateWorkspace {
44
+ workspaceId: string;
45
+ role: Principal['role'];
46
+ origin: Principal['origin'];
47
+ accountRef: string | null;
48
+ }
49
+ export interface PrincipalGateRequest {
50
+ path: string;
51
+ method: string;
52
+ /** The request's own workspace selector (the X-Workspace-Id header), null when it named none. */
53
+ selector: string | null;
54
+ }
55
+ export type PrincipalGate = (principal: Principal, request: PrincipalGateRequest) => Promise<PrincipalGateResult>;
56
+ /** The gate's verdict applied: the principal to run the request as, or the exact wire refusal. */
57
+ export type AdmitResult = {
58
+ ok: true;
59
+ principal: Principal;
60
+ } | {
61
+ ok: false;
62
+ status: 401 | 403;
63
+ code: string;
64
+ message: string;
65
+ };
66
+ /**
67
+ * The session half of the credential resolver: the identity provider's live
68
+ * resolve of the request's cookie (membership re-checked, the selection rule
69
+ * applied). One home for the call, shared by `authContext` and the
70
+ * zero-state re-admission of `GET /me`.
71
+ */
72
+ export declare function resolveSessionPrincipal(c: Context, registry: PlatformRegistry): Promise<Principal | null>;
73
+ /**
74
+ * The edition gate on a resolved principal, with a freshly synced hub role
75
+ * applied to THIS request (D11): a demoted admin loses admin surfaces now, a
76
+ * promoted member gains them now. No gate (oss) admits the principal as it
77
+ * is. One home for the step, shared by `authContext` and the zero-state
78
+ * re-admission of `GET /me`.
79
+ */
80
+ export declare function admitPrincipal(c: Context, principal: Principal, principalGate: PrincipalGate | undefined): Promise<AdmitResult>;
81
+ export interface AuthContextDeps {
82
+ registry: PlatformRegistry;
83
+ /**
84
+ * Resolves `Bearer <prefix>_...` API keys under the user-scoped selection
85
+ * rule — `requested` is the request's X-Workspace-Id (or null). May throw
86
+ * WorkspaceMismatchError for a valid PINNED key whose pin differs from the
87
+ * header. Absent = keys rejected.
88
+ */
89
+ resolveApiKey?: (token: string, requested: string | null) => Promise<Principal | null>;
90
+ /** Resolves OAuth Bearer JWTs (local JWKS verify + live membership selection). */
91
+ resolveOauthJwt?: (token: string, requested: string | null) => Promise<Principal | null>;
92
+ /** Distinguishes an API-key credential from other bearers. */
93
+ isApiKeyToken: (token: string) => boolean;
94
+ /** Failed key verifications consume from this bucket (per IP) — brute-force wall. */
95
+ keyFailureLimiter?: RateLimiterAbstract;
96
+ /** Client identity (socket address unless TRUST_PROXY opts into XFF). */
97
+ clientIp: ClientIpFn;
98
+ /** General per-principal request quota (I3). Absent = no general limit. */
99
+ requestQuota?: RequestQuotaService;
100
+ /**
101
+ * Post-resolution principal veto (cloud edition only). Runs here — in the
102
+ * single credential resolver — rather than inside any one identity path,
103
+ * so sessions, API keys, AND OAuth bearers all pass the same gate
104
+ * (internal/decisions/016). Absent (oss) = zero overhead, zero hub surface.
105
+ */
106
+ principalGate?: PrincipalGate | undefined;
107
+ /**
108
+ * Demo sign-in (present only while DEMO_SIGN_IN is on, self-hosted): judges
109
+ * a resolved SESSION against the demo pass that opened it, if one did.
110
+ * `ended` = the pass has expired or was revoked and the session is gone:
111
+ * the request goes on signed out. Here, in the single credential resolver,
112
+ * so no route can be reached with a session its pass no longer backs.
113
+ */
114
+ demoSession?: ((headers: Headers) => Promise<{
115
+ passId: string;
116
+ sessionId: string;
117
+ } | 'ended' | null>) | undefined;
118
+ /**
119
+ * The composed fail-closed scope allowlist (`createScopeAllowlist` in
120
+ * scopes.ts: the chassis rules, then the tool's). `null` = the endpoint is
121
+ * not open to machine principals. Required: a tool must state its list.
122
+ */
123
+ requiredScopeFor: (path: string, method: string) => string | null;
124
+ /**
125
+ * The tool's `guest_forbidden` sentence (`copy.guestForbidden`). Carried on
126
+ * the request so `requireNonGuest()` keeps its argument-less call sites, in
127
+ * the chassis and in the tool alike. Required: the chassis has no wording.
128
+ */
129
+ guestForbiddenMessage: string;
130
+ }
131
+ /**
132
+ * The single credential resolver: every /api/v1 request passes through here
133
+ * and comes out with c.get('principal') set (or a 401/403 for bad machine
134
+ * credentials). Three paths, one output shape:
135
+ *
136
+ * - session cookie → IdentityProvider.resolve (live membership re-check)
137
+ * - Bearer API key → O(1) key lookup (M2)
138
+ * - Bearer JWT → OAuth access token this instance minted: local JWKS
139
+ * verification + live membership re-check (M6)
140
+ *
141
+ * Machine principals additionally pass the fail-closed scope allowlist:
142
+ * endpoints not consciously listed in scopes.ts are unreachable with a key
143
+ * or token, whatever the underlying user's role is.
144
+ */
145
+ export declare function authContext({ registry, resolveApiKey, resolveOauthJwt, isApiKeyToken, keyFailureLimiter, clientIp, requestQuota, principalGate, demoSession, requiredScopeFor, guestForbiddenMessage }: AuthContextDeps): MiddlewareHandler;
146
+ /** Route guard: 401 when unauthenticated. */
147
+ export declare function requireAuth(): MiddlewareHandler;
148
+ /**
149
+ * Route guard (D2, internal/federation.md P6): an `origin='guest'` membership
150
+ * belongs to an EXTERNAL per-resource collaborator — it exists so the platform
151
+ * can resolve them to a principal at all, not to make them a workspace
152
+ * actor. Guests keep every ADR 013 per-resource surface their grant opens
153
+ * (read, version push, share tokens, annotations on THAT resource) but are
154
+ * refused resource creation and workspace-level surfaces on BOTH editions.
155
+ * Judges the resolved principal, so sessions, API keys, and OAuth bearers
156
+ * all pass the same gate. 403 — the surfaces this guards are flat,
157
+ * documented workspace surfaces, not probeable per-grant resources, so the
158
+ * ADR 013 hide-existence 404 posture does not apply here (same stance as
159
+ * requireRole).
160
+ */
161
+ export declare function requireNonGuest(): MiddlewareHandler;
162
+ declare const ROLE_RANK: {
163
+ readonly member: 0;
164
+ readonly admin: 1;
165
+ readonly owner: 2;
166
+ };
167
+ /** Route guard: 403 below the required role. */
168
+ export declare function requireRole(min: keyof typeof ROLE_RANK): MiddlewareHandler;
169
+ export {};
170
+ //# sourceMappingURL=auth-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-context.d.ts","sourceRoot":"","sources":["../../src/middleware/auth-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,251 @@
1
+ import { ACTIVE_WORKSPACE_HEADER } from '@antasphere/chassis-contract';
2
+ import { WorkspaceMismatchError } from '../apikeys/service.js';
3
+ import { apiError } from '../api/errors.js';
4
+ import { quotaHeaderEntries } from './rate-limit.js';
5
+ import { looksLikeJwt } from './scopes.js';
6
+ /** Paths under /api/v1 that are reachable without any credential. */
7
+ const PUBLIC_API_PATHS = new Set([
8
+ '/api/v1/instance',
9
+ '/api/v1/setup',
10
+ '/api/v1/openapi.json',
11
+ // CLI email-OTP sign-in (api/cli-auth.ts): pre-auth by definition — the
12
+ // flow exists to OBTAIN a credential. Both are rate-limited in api/index.ts.
13
+ '/api/v1/cli/auth/request',
14
+ '/api/v1/cli/auth/complete',
15
+ // CLI cross-tool connect (api/sso-connect.ts, cloud edition): pre-auth by
16
+ // the same definition — the hub-minted exchange JWT in the body IS the
17
+ // credential, verified hard by the handler. Rate-limited in api/index.ts.
18
+ // The entry is inert on oss: the route is never registered there, so the
19
+ // path falls through to the JSON 404 terminator for every caller.
20
+ '/api/v1/sso/cli-connect'
21
+ ]);
22
+ export function isPublicApiPath(path) {
23
+ return PUBLIC_API_PATHS.has(path) || path.startsWith('/api/v1/auth/');
24
+ }
25
+ /**
26
+ * The session half of the credential resolver: the identity provider's live
27
+ * resolve of the request's cookie (membership re-checked, the selection rule
28
+ * applied). One home for the call, shared by `authContext` and the
29
+ * zero-state re-admission of `GET /me`.
30
+ */
31
+ export function resolveSessionPrincipal(c, registry) {
32
+ return registry.identity.resolve({
33
+ headers: c.req.raw.headers,
34
+ path: c.req.path,
35
+ method: c.req.method,
36
+ requestId: c.get('requestId')
37
+ });
38
+ }
39
+ /**
40
+ * The edition gate on a resolved principal, with a freshly synced hub role
41
+ * applied to THIS request (D11): a demoted admin loses admin surfaces now, a
42
+ * promoted member gains them now. No gate (oss) admits the principal as it
43
+ * is. One home for the step, shared by `authContext` and the zero-state
44
+ * re-admission of `GET /me`.
45
+ */
46
+ export async function admitPrincipal(c, principal, principalGate) {
47
+ if (!principalGate)
48
+ return { ok: true, principal };
49
+ const verdict = await principalGate(principal, {
50
+ path: c.req.path,
51
+ method: c.req.method,
52
+ selector: c.req.header(ACTIVE_WORKSPACE_HEADER)?.trim() || null
53
+ });
54
+ if (!verdict.ok)
55
+ return verdict;
56
+ let admitted = principal;
57
+ if (verdict.workspace && verdict.workspace.workspaceId !== principal.workspaceId) {
58
+ const { accountRef, ...rest } = verdict.workspace;
59
+ const { accountRef: _previous, ...withoutRef } = admitted;
60
+ admitted = { ...withoutRef, ...rest, ...(accountRef ? { accountRef } : {}) };
61
+ }
62
+ if (verdict.role !== undefined && verdict.role !== admitted.role) {
63
+ admitted = { ...admitted, role: verdict.role };
64
+ }
65
+ return { ok: true, principal: admitted };
66
+ }
67
+ /**
68
+ * The single credential resolver: every /api/v1 request passes through here
69
+ * and comes out with c.get('principal') set (or a 401/403 for bad machine
70
+ * credentials). Three paths, one output shape:
71
+ *
72
+ * - session cookie → IdentityProvider.resolve (live membership re-check)
73
+ * - Bearer API key → O(1) key lookup (M2)
74
+ * - Bearer JWT → OAuth access token this instance minted: local JWKS
75
+ * verification + live membership re-check (M6)
76
+ *
77
+ * Machine principals additionally pass the fail-closed scope allowlist:
78
+ * endpoints not consciously listed in scopes.ts are unreachable with a key
79
+ * or token, whatever the underlying user's role is.
80
+ */
81
+ export function authContext({ registry, resolveApiKey, resolveOauthJwt, isApiKeyToken, keyFailureLimiter, clientIp, requestQuota, principalGate, demoSession, requiredScopeFor, guestForbiddenMessage }) {
82
+ return async (c, next) => {
83
+ c.set('principal', null);
84
+ c.set('guestForbiddenMessage', guestForbiddenMessage);
85
+ if (isPublicApiPath(c.req.path)) {
86
+ return next();
87
+ }
88
+ const authHeader = c.req.header('authorization')?.trim() ?? '';
89
+ const bearer = /^Bearer\s+(.+)$/i.exec(authHeader)?.[1]?.trim() ?? null;
90
+ // The universal per-request workspace selector (user-scoped credential
91
+ // model): EVERY credential kind resolves it through the shared
92
+ // resolveMembership rule — sessions inside the identity provider,
93
+ // machine credentials via the threaded `requested` below. A PINNED API
94
+ // key is the one exception: it always resolves its pin, and a header
95
+ // naming a different workspace is rejected loudly (403 below) instead of
96
+ // being silently served the pinned one.
97
+ const requested = c.req.header(ACTIVE_WORKSPACE_HEADER)?.trim() || null;
98
+ let principal = null;
99
+ if (bearer && looksLikeJwt(bearer)) {
100
+ if (!resolveOauthJwt) {
101
+ return apiError(c, 401, 'oauth_not_enabled', 'OAuth bearer tokens are not enabled on this instance');
102
+ }
103
+ principal = await resolveOauthJwt(bearer, requested);
104
+ if (!principal) {
105
+ return apiError(c, 401, 'invalid_token', 'OAuth bearer token is invalid, expired, or revoked');
106
+ }
107
+ }
108
+ else if (bearer && isApiKeyToken(bearer)) {
109
+ if (!resolveApiKey) {
110
+ return apiError(c, 401, 'invalid_api_key', 'API key not recognized');
111
+ }
112
+ const ip = clientIp(c);
113
+ if (keyFailureLimiter) {
114
+ const bucket = await keyFailureLimiter.get(ip).catch(() => null);
115
+ if (bucket && bucket.remainingPoints <= 0 && bucket.msBeforeNext > 0) {
116
+ return apiError(c, 429, 'rate_limited', 'Too many failed API key attempts');
117
+ }
118
+ }
119
+ try {
120
+ principal = await resolveApiKey(bearer, requested);
121
+ }
122
+ catch (cause) {
123
+ // A VALID pinned key + a mismatching selector: a client bug or a
124
+ // confused-deputy attempt — loud 403, and no failure-limiter charge
125
+ // (the credential itself verified fine).
126
+ if (cause instanceof WorkspaceMismatchError) {
127
+ return apiError(c, 403, 'workspace_mismatch', 'This credential is pinned to a different workspace');
128
+ }
129
+ throw cause;
130
+ }
131
+ if (!principal) {
132
+ if (keyFailureLimiter)
133
+ await keyFailureLimiter.consume(ip).catch(() => { });
134
+ return apiError(c, 401, 'invalid_api_key', 'API key not recognized');
135
+ }
136
+ }
137
+ else if (bearer) {
138
+ return apiError(c, 401, 'unsupported_credential', 'Unrecognized bearer credential format');
139
+ }
140
+ else {
141
+ principal = await resolveSessionPrincipal(c, registry);
142
+ // Fail-closed: a judge that throws refuses the session for this
143
+ // request rather than letting a dead pass's session through.
144
+ if (principal && demoSession) {
145
+ const verdict = await demoSession(c.req.raw.headers);
146
+ if (verdict === 'ended')
147
+ principal = null;
148
+ else if (verdict)
149
+ c.set('demoPassId', verdict.passId);
150
+ }
151
+ }
152
+ // General per-principal request quota (I3), consumed BEFORE the scope
153
+ // gate so even fail-closed 403 hammering is bounded — once a credential
154
+ // resolves, the quota is the outermost cost control. The bucket key is
155
+ // derived from the principal (see principalBucketKey), never a header.
156
+ // Sessions are included: the default quota is far above any dashboard's
157
+ // request rate, and a hijacked/scripted session is the same cost vector.
158
+ let quota = null;
159
+ if (principal && requestQuota) {
160
+ quota = await requestQuota.consume(principal);
161
+ if (quota && !quota.ok) {
162
+ for (const [name, value] of quotaHeaderEntries(quota))
163
+ c.header(name, value);
164
+ c.header('Retry-After', String(quota.retryAfterSeconds ?? Math.max(1, quota.resetSeconds)));
165
+ return apiError(c, 429, 'rate_limited', 'API request quota exceeded, slow down');
166
+ }
167
+ }
168
+ // Edition principal gate (cloud: hub org-status + membership
169
+ // re-assertion, internal/federation.md P4). AFTER the quota — hammering a
170
+ // suspended org stays rate-bounded — and BEFORE the scope gate, so a
171
+ // definitive hub refusal wins over any per-endpoint outcome. Cache-first
172
+ // inside; the hub is never a hard round-trip in the hot path.
173
+ if (principal && principalGate) {
174
+ const admitted = await admitPrincipal(c, principal, principalGate);
175
+ if (!admitted.ok) {
176
+ return apiError(c, admitted.status, admitted.code, admitted.message);
177
+ }
178
+ principal = admitted.principal;
179
+ }
180
+ // Fail-closed scope gate for machine principals only.
181
+ if (principal?.scopes) {
182
+ const needed = requiredScopeFor(c.req.path, c.req.method);
183
+ if (!needed) {
184
+ return apiError(c, 403, 'endpoint_not_allowed', 'This endpoint is not available to this credential');
185
+ }
186
+ if (!principal.scopes.has(needed)) {
187
+ return apiError(c, 403, 'insufficient_scope', `This credential was not granted "${needed}"`);
188
+ }
189
+ }
190
+ c.set('principal', principal);
191
+ if (!quota)
192
+ return next();
193
+ // Success path: stamp the quota headers on whatever response the route
194
+ // produced (set on c.res so streamed/raw Response bodies get them too),
195
+ // letting well-behaved agents self-throttle before hitting 429s.
196
+ await next();
197
+ for (const [name, value] of quotaHeaderEntries(quota))
198
+ c.res.headers.set(name, value);
199
+ return;
200
+ };
201
+ }
202
+ /** Route guard: 401 when unauthenticated. */
203
+ export function requireAuth() {
204
+ return async (c, next) => {
205
+ if (!c.get('principal')) {
206
+ return apiError(c, 401, 'unauthenticated', 'Authentication required');
207
+ }
208
+ return next();
209
+ };
210
+ }
211
+ /**
212
+ * Route guard (D2, internal/federation.md P6): an `origin='guest'` membership
213
+ * belongs to an EXTERNAL per-resource collaborator — it exists so the platform
214
+ * can resolve them to a principal at all, not to make them a workspace
215
+ * actor. Guests keep every ADR 013 per-resource surface their grant opens
216
+ * (read, version push, share tokens, annotations on THAT resource) but are
217
+ * refused resource creation and workspace-level surfaces on BOTH editions.
218
+ * Judges the resolved principal, so sessions, API keys, and OAuth bearers
219
+ * all pass the same gate. 403 — the surfaces this guards are flat,
220
+ * documented workspace surfaces, not probeable per-grant resources, so the
221
+ * ADR 013 hide-existence 404 posture does not apply here (same stance as
222
+ * requireRole).
223
+ */
224
+ export function requireNonGuest() {
225
+ return async (c, next) => {
226
+ const principal = c.get('principal');
227
+ if (!principal) {
228
+ return apiError(c, 401, 'unauthenticated', 'Authentication required');
229
+ }
230
+ if (principal.origin === 'guest') {
231
+ // A principal only ever comes out of `authContext`, which set the sentence first.
232
+ return apiError(c, 403, 'guest_forbidden', c.get('guestForbiddenMessage'));
233
+ }
234
+ return next();
235
+ };
236
+ }
237
+ const ROLE_RANK = { member: 0, admin: 1, owner: 2 };
238
+ /** Route guard: 403 below the required role. */
239
+ export function requireRole(min) {
240
+ return async (c, next) => {
241
+ const principal = c.get('principal');
242
+ if (!principal) {
243
+ return apiError(c, 401, 'unauthenticated', 'Authentication required');
244
+ }
245
+ if (ROLE_RANK[principal.role] < ROLE_RANK[min]) {
246
+ return apiError(c, 403, 'forbidden', `Requires ${min} role`);
247
+ }
248
+ return next();
249
+ };
250
+ }
251
+ //# sourceMappingURL=auth-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-context.js","sourceRoot":"","sources":["../../src/middleware/auth-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Context, MiddlewareHandler } from 'hono';
2
+ import type { BodyCap } from '../tool-definition.js';
3
+ /**
4
+ * A body-size cap that DEFERS its declared-size refusal to the entitlement
5
+ * gate (PRDCT-2632). Built once per `BodyCap` from hono's `bodyLimit` (a
6
+ * declared Content-Length over the cap is refused before a byte is read; an
7
+ * undeclared body is counted and cut at the cap), with one difference: when
8
+ * the request's matched route carries a gate that judges a plan limit
9
+ * (`isDeferring`), a declared oversize body is not refused HERE — the
10
+ * refusal is parked on the context (`bodyRefusal`) for the gate to fire
11
+ * after the plan check, and the request is rebuilt WITHOUT a body, so
12
+ * nothing downstream can read a byte of it whatever the middleware order.
13
+ * A metered account thus meets 403 `plan_required` with its upgrade link at
14
+ * any size, and the cap's 413 only when the plan allows the size.
15
+ */
16
+ export declare function deferrableBodyCap(cap: BodyCap, isDeferring: (c: Context) => boolean): MiddlewareHandler;
17
+ //# sourceMappingURL=body-cap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-cap.d.ts","sourceRoot":"","sources":["../../src/middleware/body-cap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAEvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,GAAG,iBAAiB,CAevG"}
@@ -0,0 +1,31 @@
1
+ import { bodyLimit } from 'hono/body-limit';
2
+ /**
3
+ * A body-size cap that DEFERS its declared-size refusal to the entitlement
4
+ * gate (PRDCT-2632). Built once per `BodyCap` from hono's `bodyLimit` (a
5
+ * declared Content-Length over the cap is refused before a byte is read; an
6
+ * undeclared body is counted and cut at the cap), with one difference: when
7
+ * the request's matched route carries a gate that judges a plan limit
8
+ * (`isDeferring`), a declared oversize body is not refused HERE — the
9
+ * refusal is parked on the context (`bodyRefusal`) for the gate to fire
10
+ * after the plan check, and the request is rebuilt WITHOUT a body, so
11
+ * nothing downstream can read a byte of it whatever the middleware order.
12
+ * A metered account thus meets 403 `plan_required` with its upgrade link at
13
+ * any size, and the cap's 413 only when the plan allows the size.
14
+ */
15
+ export function deferrableBodyCap(cap, isDeferring) {
16
+ const streamCap = bodyLimit({ maxSize: cap.maxBytes, onError: cap.onError });
17
+ return (c, next) => {
18
+ const declared = Number(c.req.header('content-length') ?? '');
19
+ if (Number.isFinite(declared) && declared > cap.maxBytes && isDeferring(c)) {
20
+ c.set('bodyRefusal', () => cap.onError(c));
21
+ // Rebuilt from the URL, the method and the headers: a `body: null`
22
+ // in a Request init keeps the input's body (the Fetch spec), so the
23
+ // drop must be a request that never had one.
24
+ const raw = c.req.raw;
25
+ c.req.raw = new Request(raw.url, { method: raw.method, headers: raw.headers, signal: raw.signal });
26
+ return next();
27
+ }
28
+ return streamCap(c, next);
29
+ };
30
+ }
31
+ //# sourceMappingURL=body-cap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-cap.js","sourceRoot":"","sources":["../../src/middleware/body-cap.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAY,EAAE,WAAoC;IAClF,MAAM,SAAS,GAAG,SAAS,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;QACjB,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,mEAAmE;YACnE,oEAAoE;YACpE,6CAA6C;YAC7C,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;YACtB,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACnG,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QACD,OAAO,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Context } from 'hono';
2
+ declare module 'hono' {
3
+ interface ContextVariableMap {
4
+ /**
5
+ * A body-size refusal the size cap DEFERRED (PRDCT-2632): the request
6
+ * declared a Content-Length over the tool's cap on a route whose gate
7
+ * judges a plan limit, so the gate must see the declared size first (a
8
+ * metered account meets 403 `plan_required` with the upgrade link at any
9
+ * size, never the instance-cap 413 in its place). The cap DROPS the
10
+ * request's body when it defers (`c.req.raw` is rebuilt without one), so
11
+ * nothing downstream can read a byte of it by construction; the gate
12
+ * fires the refusal right after the plan check, or before anything else
13
+ * when no plan applies. Undefined otherwise.
14
+ */
15
+ bodyRefusal: (() => Response) | undefined;
16
+ }
17
+ }
18
+ /** The pending deferred refusal of this request, if any. */
19
+ export declare function pendingBodyRefusal(c: Context): (() => Response) | undefined;
20
+ //# sourceMappingURL=body-refusal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-refusal.d.ts","sourceRoot":"","sources":["../../src/middleware/body-refusal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B;;;;;;;;;;WAUG;QACH,WAAW,EAAE,CAAC,MAAM,QAAQ,CAAC,GAAG,SAAS,CAAC;KAC3C;CACF;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,GAAG,SAAS,CAE3E"}
@@ -0,0 +1,5 @@
1
+ /** The pending deferred refusal of this request, if any. */
2
+ export function pendingBodyRefusal(c) {
3
+ return c.get('bodyRefusal');
4
+ }
5
+ //# sourceMappingURL=body-refusal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-refusal.js","sourceRoot":"","sources":["../../src/middleware/body-refusal.ts"],"names":[],"mappings":"AAmBA,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAAC,CAAU;IAC3C,OAAO,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC9B,CAAC"}