@opengeni/api-router 3.0.1 → 3.0.2-canary.38894290271001

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 (546) hide show
  1. package/dist/access-grant-rls.d.ts +8 -1
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/app.d.ts +50 -3
  4. package/dist/app.js +10 -1
  5. package/dist/artifact-catalog-cursor.d.ts +1 -0
  6. package/dist/attached-browser-viewer.d.ts +11 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
  10. package/dist/auth/managed-auth.d.ts +72 -5
  11. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  12. package/dist/auth/new-signups-gate.d.ts +23 -0
  13. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  14. package/dist/azure-live.d.ts +28 -0
  15. package/dist/browser-action-fences.d.ts +13 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-lost-runtime-end.d.ts +24 -0
  19. package/dist/browser-state-authority.d.ts +1 -27
  20. package/dist/{chunk-AJ62T5QN.js → chunk-GBUJ2DYZ.js} +80507 -39878
  21. package/dist/chunk-GBUJ2DYZ.js.map +1 -0
  22. package/dist/chunk-OGQDXVXY.js +18 -0
  23. package/dist/chunk-OGQDXVXY.js.map +1 -0
  24. package/dist/claude-default-models.d.ts +19 -0
  25. package/dist/claude-subscription-core.d.ts +50 -0
  26. package/dist/claude-subscription-oauth.d.ts +36 -0
  27. package/dist/claude-subscription-profile.d.ts +9 -0
  28. package/dist/claude-subscription-usage.d.ts +6 -0
  29. package/dist/claude-workspace-connection.d.ts +15 -0
  30. package/dist/codemode.d.ts +40 -5
  31. package/dist/codex-realtime.d.ts +29 -3
  32. package/dist/codex-session-pointers.d.ts +19 -0
  33. package/dist/connection-ownership.d.ts +6 -3
  34. package/dist/controller-data-plane.d.ts +16 -0
  35. package/dist/credit-promotion-snapshot.d.ts +6 -0
  36. package/dist/editable-artifact-source-session.d.ts +3 -0
  37. package/dist/editable-artifact-websocket.d.ts +5 -3
  38. package/dist/fatal-process-boundary.d.ts +9 -1
  39. package/dist/github-access.d.ts +7 -1
  40. package/dist/github-browser-flow.d.ts +1 -1
  41. package/dist/http/acting-person.d.ts +36 -0
  42. package/dist/http/api-contract-compat.d.ts +19 -0
  43. package/dist/http/api-error.d.ts +50 -1
  44. package/dist/http/auth.d.ts +8 -1
  45. package/dist/http/cors.d.ts +12 -0
  46. package/dist/http/deprecation.d.ts +42 -0
  47. package/dist/http/keyed-admission.d.ts +12 -0
  48. package/dist/http/local-browser-boundary.d.ts +72 -0
  49. package/dist/http/metrics-listener.d.ts +22 -0
  50. package/dist/http/path-identifier.d.ts +17 -0
  51. package/dist/http/registered-route-label.d.ts +16 -0
  52. package/dist/http/rejection-telemetry.d.ts +34 -0
  53. package/dist/http/request-body.d.ts +27 -0
  54. package/dist/http/request-source.d.ts +41 -3
  55. package/dist/http/sse.d.ts +12 -1
  56. package/dist/http/unmatched-route.d.ts +18 -0
  57. package/dist/http/user-content.d.ts +36 -0
  58. package/dist/http/variable-sets-removed.d.ts +41 -0
  59. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  60. package/dist/index.js +1279 -108
  61. package/dist/index.js.map +1 -1
  62. package/dist/integration-connect-metrics.d.ts +35 -0
  63. package/dist/integration-endpoint-test.d.ts +20 -0
  64. package/dist/integrations/api-integrations.d.ts +2 -2
  65. package/dist/integrations/atlassian.d.ts +8 -3
  66. package/dist/integrations/fiken.d.ts +3 -1
  67. package/dist/integrations/github-lens-connect.d.ts +37 -66
  68. package/dist/integrations/google-drive.d.ts +2 -0
  69. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  70. package/dist/integrations/marketplace-plugin.d.ts +43 -43
  71. package/dist/integrations/oauth-client.d.ts +171 -12
  72. package/dist/integrations/oauth-profiles.d.ts +42 -13
  73. package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
  74. package/dist/integrations/slack-bot.d.ts +285 -7
  75. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  76. package/dist/integrations/slack-interactions.d.ts +89 -10
  77. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  78. package/dist/integrations/slack-routing.d.ts +1 -1
  79. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  80. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  81. package/dist/integrations/slack-tool-review.d.ts +5 -0
  82. package/dist/interaction-agent-access.d.ts +13 -8
  83. package/dist/interaction-agent-version.d.ts +21 -0
  84. package/dist/interaction-holder-heartbeat.d.ts +5 -0
  85. package/dist/interaction-metrics.d.ts +27 -2
  86. package/dist/interaction-route-stages.d.ts +25 -0
  87. package/dist/interaction-secrets-vault.d.ts +20 -0
  88. package/dist/interaction-secrets.d.ts +103 -0
  89. package/dist/mcp/action-catalog-types.d.ts +14 -0
  90. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  91. package/dist/mcp/action-descriptions.d.ts +4 -0
  92. package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
  93. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  94. package/dist/mcp/child-read-evidence.d.ts +9 -0
  95. package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
  96. package/dist/mcp/contract-input.d.ts +13 -0
  97. package/dist/mcp/documents.d.ts +2 -0
  98. package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
  99. package/dist/mcp/notification-tools.d.ts +26 -0
  100. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  101. package/dist/mcp/scheduled-task-input.d.ts +1309 -0
  102. package/dist/mcp/scheduled-task-view.d.ts +217 -3
  103. package/dist/mcp/secret-tools.d.ts +14 -0
  104. package/dist/mcp/server.d.ts +108 -5
  105. package/dist/mcp/session-admin-access-tools.d.ts +33 -0
  106. package/dist/mcp/session-event-errors.d.ts +28 -0
  107. package/dist/mcp/session-event-view.d.ts +62 -0
  108. package/dist/mcp/session-view.d.ts +15 -0
  109. package/dist/mcp/session-wait.d.ts +18 -0
  110. package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
  111. package/dist/mcp/site-data-tools.d.ts +22 -0
  112. package/dist/mcp/site-publication-tools.d.ts +19 -0
  113. package/dist/mcp/site-sql-tools.d.ts +27 -0
  114. package/dist/mcp-oauth.d.ts +37 -4
  115. package/dist/model-calls/chat-completions.d.ts +87 -0
  116. package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
  117. package/dist/model-calls/service.d.ts +36 -0
  118. package/dist/model-catalog.d.ts +9 -3
  119. package/dist/native-push-dispatch.d.ts +69 -0
  120. package/dist/observability.d.ts +3 -1
  121. package/dist/organization-mcp.d.ts +82 -0
  122. package/dist/prepared-mcp-actor.d.ts +77 -0
  123. package/dist/prepared-mcp-permissions.d.ts +8 -0
  124. package/dist/routes/analytics-consent.d.ts +26 -0
  125. package/dist/routes/api-integrations.d.ts +11 -0
  126. package/dist/routes/api-keys.d.ts +7 -7
  127. package/dist/routes/automations.d.ts +2 -0
  128. package/dist/routes/billing.d.ts +59 -0
  129. package/dist/routes/browser-sessions.d.ts +65 -2
  130. package/dist/routes/chat-completions.d.ts +11 -0
  131. package/dist/routes/claude-core-usage.d.ts +20 -0
  132. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  133. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  134. package/dist/routes/client-errors.d.ts +182 -0
  135. package/dist/routes/codex-core.d.ts +401 -0
  136. package/dist/routes/codex.d.ts +64 -2
  137. package/dist/routes/computer-sessions.d.ts +6 -1
  138. package/dist/routes/desktop-distribution.d.ts +32 -0
  139. package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
  140. package/dist/routes/github-browser-pages.d.ts +27 -0
  141. package/dist/routes/inbox.d.ts +13 -0
  142. package/dist/routes/insights-response-cache.d.ts +10 -0
  143. package/dist/routes/insights-usage.d.ts +12 -0
  144. package/dist/routes/insights.d.ts +28 -0
  145. package/dist/routes/interaction-placement-message.d.ts +7 -0
  146. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  147. package/dist/routes/model-account-choice.d.ts +13 -0
  148. package/dist/routes/model-account-settings.d.ts +19 -0
  149. package/dist/routes/native-app-auth.d.ts +12 -0
  150. package/dist/routes/organization-integration-policy.d.ts +8 -0
  151. package/dist/routes/organization-integrations.d.ts +6 -0
  152. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  153. package/dist/routes/organization-model-defaults.d.ts +9 -0
  154. package/dist/routes/organization-service-accounts.d.ts +3 -0
  155. package/dist/routes/personal-api-keys.d.ts +3 -0
  156. package/dist/routes/session-admin-access.d.ts +3 -0
  157. package/dist/routes/session-artifact-associations.d.ts +4 -0
  158. package/dist/routes/session-history-imports.d.ts +20 -0
  159. package/dist/routes/sessions.d.ts +38 -2
  160. package/dist/routes/site-data.d.ts +18 -0
  161. package/dist/routes/site-publishing.d.ts +5 -0
  162. package/dist/routes/site-runtime.d.ts +31 -0
  163. package/dist/routes/site-sql.d.ts +16 -0
  164. package/dist/routes/slack-bot-access.d.ts +3 -0
  165. package/dist/routes/subscription-account-pools.d.ts +21 -0
  166. package/dist/routes/subscription-core-http.d.ts +5 -0
  167. package/dist/routes/subscription-pool-access.d.ts +37 -0
  168. package/dist/routes/subscription-pool-core.d.ts +153 -0
  169. package/dist/routes/supergrok.d.ts +6 -6
  170. package/dist/routes/usage-allowances.d.ts +12 -0
  171. package/dist/routes/variable-sets-removed.d.ts +2 -0
  172. package/dist/routes/vault-providers.d.ts +34 -0
  173. package/dist/routes/vaults.d.ts +3 -0
  174. package/dist/routes/workspace-integrations.d.ts +35 -0
  175. package/dist/routes/workspace-model-providers.d.ts +4 -0
  176. package/dist/routes/workspaces.d.ts +11 -2
  177. package/dist/sandbox/agent-update.d.ts +64 -0
  178. package/dist/sandbox/auth-callout.d.ts +8 -0
  179. package/dist/sandbox/channel-a.d.ts +15 -1
  180. package/dist/sandbox/enrollment.d.ts +26 -4
  181. package/dist/sandbox/machine-audience.d.ts +29 -0
  182. package/dist/sandbox/machines.d.ts +15 -2
  183. package/dist/sandbox/metrics-ingestion.d.ts +6 -2
  184. package/dist/sandbox/screen-control.d.ts +85 -0
  185. package/dist/sandbox/viewer.d.ts +5 -1
  186. package/dist/sandbox-file-artifacts.d.ts +17 -1
  187. package/dist/scheduled-task-blockers.d.ts +39 -0
  188. package/dist/scheduled-task-deletion.d.ts +3 -4
  189. package/dist/scheduled-task-lifecycle.d.ts +14 -0
  190. package/dist/secret-answers.d.ts +40 -0
  191. package/dist/session-create-observability.d.ts +5 -0
  192. package/dist/session-event-view-36GO3IL7.js +528 -0
  193. package/dist/session-event-view-36GO3IL7.js.map +1 -0
  194. package/dist/signed-state-secret.d.ts +18 -0
  195. package/dist/site-agent-guard.d.ts +53 -0
  196. package/dist/site-data/operations.d.ts +103 -0
  197. package/dist/site-data/service.d.ts +203 -0
  198. package/dist/site-frame-guard.d.ts +32 -0
  199. package/dist/site-publishing/agent-data-tools.d.ts +84 -0
  200. package/dist/site-publishing/agent-model.d.ts +58 -0
  201. package/dist/site-publishing/agent-session.d.ts +16 -0
  202. package/dist/site-publishing/content-scanner.d.ts +31 -0
  203. package/dist/site-publishing/edge-sync.d.ts +48 -0
  204. package/dist/site-publishing/gateway-signature.d.ts +56 -0
  205. package/dist/site-publishing/limits.d.ts +63 -0
  206. package/dist/site-publishing/page-tool-authority.d.ts +30 -0
  207. package/dist/site-publishing/platform-usage.d.ts +113 -0
  208. package/dist/site-publishing/platform.d.ts +21 -0
  209. package/dist/site-publishing/readiness.d.ts +62 -0
  210. package/dist/site-publishing/runtime.d.ts +179 -0
  211. package/dist/site-publishing/service.d.ts +264 -0
  212. package/dist/site-publishing/session-events.d.ts +22 -0
  213. package/dist/site-publishing/session-views.d.ts +36 -0
  214. package/dist/site-publishing/viewer.d.ts +40 -0
  215. package/dist/site-session-origin.d.ts +31 -6
  216. package/dist/site-sql/format.d.ts +47 -0
  217. package/dist/site-sql/gateway.d.ts +50 -0
  218. package/dist/site-sql/service.d.ts +213 -0
  219. package/dist/temporal-schedule-sync.d.ts +26 -0
  220. package/dist/transcription/billing-refusal.d.ts +8 -0
  221. package/dist/transcription/normalize.d.ts +23 -0
  222. package/dist/transcription/providers/azure-mai.d.ts +12 -0
  223. package/dist/transcription/providers/azure-openai.d.ts +4 -0
  224. package/dist/transcription/providers/openai.d.ts +16 -0
  225. package/dist/transcription/providers/subscription-core.d.ts +39 -0
  226. package/dist/transcription/service.d.ts +10 -1
  227. package/dist/transcription/wav-duration.d.ts +8 -0
  228. package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
  229. package/dist/workspace-tool-gateway-observability.d.ts +16 -0
  230. package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
  231. package/dist/workspace-tool-gateway.d.ts +102 -6
  232. package/dist/workspace-tool-target-fence.d.ts +116 -0
  233. package/dist/workspace-tool-target.d.ts +225 -0
  234. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  235. package/dist/xai-subscription-core.d.ts +60 -0
  236. package/package.json +25 -20
  237. package/src/access-grant-rls.ts +64 -14
  238. package/src/admission-trace.ts +14 -0
  239. package/src/app.ts +1684 -252
  240. package/src/artifact-catalog-cursor.ts +1 -0
  241. package/src/attached-browser-viewer.ts +26 -0
  242. package/src/auth/managed-auth-attempt-context.ts +9 -0
  243. package/src/auth/managed-auth-rate-limits.ts +252 -0
  244. package/src/auth/managed-auth-session-adapter.ts +64 -29
  245. package/src/auth/managed-auth.ts +303 -35
  246. package/src/auth/managed-email.ts +18 -1
  247. package/src/auth/managed-sign-in-notifications.ts +81 -0
  248. package/src/auth/new-signups-gate.ts +49 -0
  249. package/src/auth/organization-user-setup.ts +3 -3
  250. package/src/auth/signup-funnel-metrics.ts +164 -0
  251. package/src/azure-live.ts +103 -0
  252. package/src/browser-action-fences.ts +45 -0
  253. package/src/browser-controller-authority.ts +1 -186
  254. package/src/browser-ephemeral.ts +39 -0
  255. package/src/browser-lost-runtime-end.ts +71 -0
  256. package/src/browser-state-authority.ts +1 -236
  257. package/src/claude-default-models.ts +37 -0
  258. package/src/claude-subscription-core.ts +154 -0
  259. package/src/claude-subscription-oauth.ts +352 -0
  260. package/src/claude-subscription-profile.ts +73 -0
  261. package/src/claude-subscription-usage.ts +51 -0
  262. package/src/claude-workspace-connection.ts +82 -0
  263. package/src/codemode.ts +236 -39
  264. package/src/codex-realtime.ts +181 -53
  265. package/src/codex-session-pointers.ts +80 -0
  266. package/src/company-brain-okf.ts +1 -1
  267. package/src/connected-machine-computer-access.ts +2 -1
  268. package/src/connection-ownership.ts +19 -13
  269. package/src/controller-data-plane.ts +34 -0
  270. package/src/credit-promotion-snapshot.ts +36 -0
  271. package/src/editable-artifact-production.ts +10 -0
  272. package/src/editable-artifact-source-session.ts +123 -0
  273. package/src/editable-artifact-websocket.ts +16 -3
  274. package/src/fatal-process-boundary.ts +67 -3
  275. package/src/gateway-realtime.ts +12 -8
  276. package/src/github-access.ts +31 -5
  277. package/src/github-browser-flow.ts +1 -1
  278. package/src/http/acting-person.ts +105 -0
  279. package/src/http/api-contract-compat.ts +49 -0
  280. package/src/http/api-error.ts +210 -2
  281. package/src/http/auth.ts +68 -4
  282. package/src/http/cors.ts +37 -5
  283. package/src/http/deprecation.ts +118 -0
  284. package/src/http/keyed-admission.ts +29 -0
  285. package/src/http/local-browser-boundary.ts +343 -0
  286. package/src/http/metrics-listener.ts +57 -0
  287. package/src/http/path-identifier.ts +54 -0
  288. package/src/http/registered-route-label.ts +34 -0
  289. package/src/http/rejection-telemetry.ts +120 -0
  290. package/src/http/request-body.ts +127 -0
  291. package/src/http/request-source.ts +154 -13
  292. package/src/http/sse.ts +88 -28
  293. package/src/http/unmatched-route.ts +60 -0
  294. package/src/http/user-content.ts +158 -0
  295. package/src/http/variable-sets-removed.ts +122 -0
  296. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  297. package/src/index.ts +107 -57
  298. package/src/integration-connect-metrics.ts +228 -0
  299. package/src/integration-endpoint-test.ts +291 -0
  300. package/src/integrations/api-integrations.ts +81 -7
  301. package/src/integrations/atlassian.ts +202 -83
  302. package/src/integrations/fiken.ts +66 -38
  303. package/src/integrations/github-app-connect.ts +64 -18
  304. package/src/integrations/github-lens-connect.ts +8 -29
  305. package/src/integrations/google-drive.ts +448 -152
  306. package/src/integrations/integration-commit-authority.ts +69 -0
  307. package/src/integrations/marketplace-plugin.ts +1 -1
  308. package/src/integrations/oauth-client.ts +733 -193
  309. package/src/integrations/oauth-profiles.ts +116 -45
  310. package/src/integrations/onepassword-vault-provider.ts +16 -0
  311. package/src/integrations/personal-github-repositories.ts +1 -1
  312. package/src/integrations/personal-github.ts +61 -35
  313. package/src/integrations/provider-oauth.ts +67 -85
  314. package/src/integrations/slack-app-home.ts +5 -5
  315. package/src/integrations/slack-bot.ts +893 -201
  316. package/src/integrations/slack-file-upload-flow.ts +147 -0
  317. package/src/integrations/slack-install.ts +7 -7
  318. package/src/integrations/slack-interactions.ts +1589 -299
  319. package/src/integrations/slack-mrkdwn.ts +193 -0
  320. package/src/integrations/slack-routing.ts +2 -2
  321. package/src/integrations/slack-session-defaults.ts +224 -0
  322. package/src/integrations/slack-task-file-upload.ts +323 -0
  323. package/src/integrations/slack-tool-review.ts +65 -0
  324. package/src/integrations/social-oauth.ts +90 -58
  325. package/src/interaction-agent-access.ts +40 -20
  326. package/src/interaction-agent-version.ts +85 -0
  327. package/src/interaction-holder-heartbeat.ts +24 -8
  328. package/src/interaction-metrics.ts +164 -2
  329. package/src/interaction-route-stages.ts +94 -0
  330. package/src/interaction-secrets-vault.ts +213 -0
  331. package/src/interaction-secrets.ts +426 -0
  332. package/src/mcp/action-catalog-types.ts +14 -0
  333. package/src/mcp/action-catalog.gen.ts +8014 -0
  334. package/src/mcp/action-descriptions.ts +299 -0
  335. package/src/mcp/action-schema-imports.gen.ts +304 -0
  336. package/src/mcp/capability-account-readiness.ts +17 -0
  337. package/src/mcp/child-read-evidence.ts +19 -0
  338. package/src/mcp/company-profile-agent-admin.ts +13 -0
  339. package/src/mcp/contract-input.ts +165 -0
  340. package/src/mcp/documents.ts +9 -2
  341. package/src/mcp/editable-artifacts.ts +29 -11
  342. package/src/mcp/files.ts +5 -1
  343. package/src/mcp/first-party-tool-permissions.ts +7 -285
  344. package/src/mcp/knowledge-entries.ts +108 -34
  345. package/src/mcp/notification-tools.ts +480 -0
  346. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  347. package/src/mcp/scheduled-task-input.ts +89 -0
  348. package/src/mcp/scheduled-task-view.ts +63 -3
  349. package/src/mcp/secret-tools.ts +185 -0
  350. package/src/mcp/server.ts +2213 -1116
  351. package/src/mcp/session-admin-access-tools.ts +163 -0
  352. package/src/mcp/session-event-errors.ts +123 -0
  353. package/src/mcp/session-event-view.ts +395 -13
  354. package/src/mcp/session-view.ts +3 -0
  355. package/src/mcp/session-wait.ts +67 -7
  356. package/src/mcp/site-agent-clamp-tools.ts +140 -0
  357. package/src/mcp/site-data-tools.ts +339 -0
  358. package/src/mcp/site-publication-tools.ts +201 -0
  359. package/src/mcp/site-sql-tools.ts +427 -0
  360. package/src/mcp-oauth.ts +635 -45
  361. package/src/model-calls/chat-completions.ts +352 -0
  362. package/src/model-calls/pending-usage-settlements.ts +125 -0
  363. package/src/model-calls/service.ts +694 -0
  364. package/src/model-catalog.ts +68 -17
  365. package/src/native-push-dispatch.ts +457 -0
  366. package/src/observability.ts +15 -1
  367. package/src/organization-mcp.ts +485 -0
  368. package/src/prepared-mcp-actor.ts +154 -0
  369. package/src/prepared-mcp-permissions.ts +38 -0
  370. package/src/routes/analytics-consent.ts +123 -0
  371. package/src/routes/api-integrations.ts +268 -9
  372. package/src/routes/api-keys.ts +164 -25
  373. package/src/routes/artifact-catalog.ts +111 -0
  374. package/src/routes/automations.ts +163 -90
  375. package/src/routes/billing.ts +535 -59
  376. package/src/routes/browser-sessions.ts +966 -342
  377. package/src/routes/canonical-human-identities.ts +61 -0
  378. package/src/routes/capabilities.ts +112 -5
  379. package/src/routes/channels.ts +4 -3
  380. package/src/routes/chat-completions.ts +235 -0
  381. package/src/routes/claude-core-usage.ts +147 -0
  382. package/src/routes/claude-subscription-accounts.ts +233 -0
  383. package/src/routes/claude-subscription-oauth.ts +175 -0
  384. package/src/routes/client-errors.ts +394 -0
  385. package/src/routes/codex-core.ts +687 -0
  386. package/src/routes/codex.ts +1277 -1119
  387. package/src/routes/company-brain.ts +4 -0
  388. package/src/routes/computer-sessions.ts +319 -85
  389. package/src/routes/connect.ts +277 -175
  390. package/src/routes/connections.ts +690 -363
  391. package/src/routes/desktop-distribution.ts +217 -0
  392. package/src/routes/documents.ts +13 -7
  393. package/src/routes/editable-artifacts.ts +74 -4
  394. package/src/routes/enrollments.ts +110 -16
  395. package/src/routes/external-identity-links.ts +13 -12
  396. package/src/routes/files.ts +41 -16
  397. package/src/routes/github-browser-fonts.gen.ts +12 -0
  398. package/src/routes/github-browser-pages.ts +258 -0
  399. package/src/routes/github.ts +200 -75
  400. package/src/routes/inbox.ts +353 -0
  401. package/src/routes/insights-response-cache.ts +83 -0
  402. package/src/routes/insights-usage.ts +345 -0
  403. package/src/routes/insights.ts +103 -8
  404. package/src/routes/install.ts +51 -10
  405. package/src/routes/integration-facets.ts +70 -28
  406. package/src/routes/interaction-placement-message.ts +12 -0
  407. package/src/routes/knowledge.ts +136 -27
  408. package/src/routes/machines.ts +189 -135
  409. package/src/routes/managed-auth-session-sets.ts +43 -10
  410. package/src/routes/managed-onboarding.ts +39 -19
  411. package/src/routes/managed-sign-in-methods.ts +433 -0
  412. package/src/routes/memory-slack-publications.ts +3 -2
  413. package/src/routes/model-account-choice.ts +194 -0
  414. package/src/routes/model-account-settings.ts +235 -0
  415. package/src/routes/model-connection-access.ts +210 -48
  416. package/src/routes/native-app-auth.ts +296 -0
  417. package/src/routes/organization-integration-policy.ts +116 -0
  418. package/src/routes/organization-integrations.ts +326 -0
  419. package/src/routes/organization-mcp-connections.ts +183 -0
  420. package/src/routes/organization-memberships.ts +205 -19
  421. package/src/routes/organization-model-defaults.ts +110 -0
  422. package/src/routes/organization-model-providers.ts +74 -3
  423. package/src/routes/organization-service-accounts.ts +128 -0
  424. package/src/routes/organization-sessions.ts +21 -5
  425. package/src/routes/personal-api-keys.ts +184 -0
  426. package/src/routes/personal-github-git-broker.ts +2 -2
  427. package/src/routes/personal-github.ts +9 -4
  428. package/src/routes/plugins.ts +46 -7
  429. package/src/routes/pr-review-github.ts +105 -118
  430. package/src/routes/pr-review.ts +88 -82
  431. package/src/routes/preference-registry.ts +18 -0
  432. package/src/routes/rigs.ts +48 -13
  433. package/src/routes/scheduled-tasks.ts +347 -27
  434. package/src/routes/session-admin-access.ts +271 -0
  435. package/src/routes/session-artifact-associations.ts +164 -0
  436. package/src/routes/session-history-imports.ts +305 -0
  437. package/src/routes/sessions.ts +1682 -363
  438. package/src/routes/site-data.ts +340 -0
  439. package/src/routes/site-publishing.ts +584 -0
  440. package/src/routes/site-runtime.ts +1944 -0
  441. package/src/routes/site-sql.ts +263 -0
  442. package/src/routes/skill-content.ts +72 -7
  443. package/src/routes/skills.ts +5 -4
  444. package/src/routes/slack-bot-access.ts +108 -0
  445. package/src/routes/social.ts +27 -15
  446. package/src/routes/subscription-account-pools.ts +209 -0
  447. package/src/routes/subscription-core-http.ts +18 -0
  448. package/src/routes/subscription-pool-access.ts +180 -0
  449. package/src/routes/subscription-pool-core.ts +552 -0
  450. package/src/routes/supergrok.ts +174 -655
  451. package/src/routes/transcription-recordings.ts +71 -4
  452. package/src/routes/transcriptions.ts +26 -2
  453. package/src/routes/usage-allowances.ts +381 -0
  454. package/src/routes/variable-sets-removed.ts +19 -0
  455. package/src/routes/vault-providers.ts +782 -0
  456. package/src/routes/vaults.ts +421 -0
  457. package/src/routes/video-generation.ts +30 -12
  458. package/src/routes/workspace-artifacts.ts +165 -53
  459. package/src/routes/workspace-integrations.ts +576 -0
  460. package/src/routes/workspace-model-providers.ts +148 -0
  461. package/src/routes/workspace-state.ts +4 -0
  462. package/src/routes/workspaces.ts +625 -117
  463. package/src/sandbox/agent-update.ts +315 -0
  464. package/src/sandbox/auth-callout.ts +104 -21
  465. package/src/sandbox/channel-a.ts +150 -49
  466. package/src/sandbox/enrollment.ts +131 -22
  467. package/src/sandbox/machine-audience.ts +192 -0
  468. package/src/sandbox/machines.ts +75 -31
  469. package/src/sandbox/metrics-ingestion.ts +133 -2
  470. package/src/sandbox/rematerialize.ts +51 -21
  471. package/src/sandbox/screen-control.ts +289 -0
  472. package/src/sandbox/viewer.ts +33 -58
  473. package/src/sandbox-file-artifacts.ts +53 -27
  474. package/src/scheduled-task-blockers.ts +293 -0
  475. package/src/scheduled-task-deletion.ts +13 -3
  476. package/src/scheduled-task-lifecycle.ts +84 -0
  477. package/src/secret-answers.ts +119 -0
  478. package/src/session-create-observability.ts +46 -0
  479. package/src/session-realtime-context.ts +26 -4
  480. package/src/signed-state-secret.ts +58 -0
  481. package/src/site-agent-guard.ts +261 -0
  482. package/src/site-data/operations.ts +777 -0
  483. package/src/site-data/service.ts +1043 -0
  484. package/src/site-frame-guard.ts +107 -0
  485. package/src/site-publishing/agent-data-tools.ts +250 -0
  486. package/src/site-publishing/agent-model.ts +127 -0
  487. package/src/site-publishing/agent-session.ts +148 -0
  488. package/src/site-publishing/content-scanner.ts +93 -0
  489. package/src/site-publishing/edge-sync.ts +148 -0
  490. package/src/site-publishing/gateway-signature.ts +198 -0
  491. package/src/site-publishing/limits.ts +315 -0
  492. package/src/site-publishing/page-tool-authority.ts +111 -0
  493. package/src/site-publishing/platform-usage.ts +479 -0
  494. package/src/site-publishing/platform.ts +98 -0
  495. package/src/site-publishing/readiness.ts +330 -0
  496. package/src/site-publishing/runtime.ts +831 -0
  497. package/src/site-publishing/service.ts +1282 -0
  498. package/src/site-publishing/session-events.ts +262 -0
  499. package/src/site-publishing/session-views.ts +262 -0
  500. package/src/site-publishing/viewer.ts +75 -0
  501. package/src/site-session-origin.ts +91 -6
  502. package/src/site-sql/format.ts +134 -0
  503. package/src/site-sql/gateway.ts +168 -0
  504. package/src/site-sql/service.ts +1636 -0
  505. package/src/site-uploads.ts +27 -5
  506. package/src/temporal-schedule-sync.ts +74 -0
  507. package/src/transcription/billing-refusal.ts +14 -0
  508. package/src/transcription/normalize.ts +77 -0
  509. package/src/transcription/providers/azure-mai.ts +98 -0
  510. package/src/transcription/providers/azure-openai.ts +16 -7
  511. package/src/transcription/providers/codex-subscription.ts +190 -67
  512. package/src/transcription/providers/openai.ts +79 -5
  513. package/src/transcription/providers/subscription-core.ts +125 -0
  514. package/src/transcription/providers/xai-subscription.ts +81 -83
  515. package/src/transcription/segmenter.ts +7 -1
  516. package/src/transcription/service.ts +239 -10
  517. package/src/transcription/wav-duration.ts +39 -0
  518. package/src/workspace-deletion.ts +25 -1
  519. package/src/workspace-tool-gateway-attestations.ts +133 -0
  520. package/src/workspace-tool-gateway-observability.ts +64 -0
  521. package/src/workspace-tool-gateway-secrets.ts +104 -0
  522. package/src/workspace-tool-gateway.ts +921 -103
  523. package/src/workspace-tool-target-fence.ts +380 -0
  524. package/src/workspace-tool-target.ts +554 -0
  525. package/src/workspace-webhook-dispatch.ts +225 -0
  526. package/src/xai-realtime.ts +85 -81
  527. package/src/xai-subscription-core.ts +172 -0
  528. package/dist/browser-auth-broker.d.ts +0 -20
  529. package/dist/chunk-AJ62T5QN.js.map +0 -1
  530. package/dist/connection-authority-owner.d.ts +0 -59
  531. package/dist/routes/connection-authorities.d.ts +0 -3
  532. package/dist/routes/environments.d.ts +0 -5
  533. package/dist/routes/host-mcp-bindings.d.ts +0 -5
  534. package/dist/routes/host-mcp-resolvers.d.ts +0 -3
  535. package/dist/routes/packs.d.ts +0 -3
  536. package/dist/session-event-view-MU3HMNV3.js +0 -264
  537. package/dist/session-event-view-MU3HMNV3.js.map +0 -1
  538. package/dist/xai-subscription-auth.d.ts +0 -23
  539. package/src/browser-auth-broker.ts +0 -155
  540. package/src/connection-authority-owner.ts +0 -61
  541. package/src/routes/connection-authorities.ts +0 -139
  542. package/src/routes/environments.ts +0 -388
  543. package/src/routes/host-mcp-bindings.ts +0 -122
  544. package/src/routes/host-mcp-resolvers.ts +0 -41
  545. package/src/routes/packs.ts +0 -784
  546. package/src/xai-subscription-auth.ts +0 -139
@@ -0,0 +1,93 @@
1
+ import type { Settings } from "@opengeni/config";
2
+
3
+ /**
4
+ * Pluggable content scanning for published Sites. `none` is the default; the
5
+ * Google Web Risk scanner runs only with OPENGENI_SITES_WEB_RISK_API_KEY. A
6
+ * scan looks up the absolute URLs found in a Site's HTML when it is published
7
+ * and records findings for moderation. It never blocks publishing, and a
8
+ * disabled or failing scanner records nothing that blocks either.
9
+ */
10
+
11
+ export type SiteContentScanFinding = { url: string; threatTypes: string[] };
12
+ export type SiteContentScanResult = {
13
+ status: "none" | "clean" | "flagged" | "error";
14
+ findings: SiteContentScanFinding[];
15
+ };
16
+
17
+ export type SiteContentScanner = {
18
+ readonly name: "none" | "web_risk";
19
+ scanHtml(html: string): Promise<SiteContentScanResult>;
20
+ };
21
+
22
+ /** Most distinct URLs one scan looks up (bounds cost per publish). */
23
+ export const SITE_SCAN_MAX_URLS = 20;
24
+
25
+ /** Distinct absolute http(s) URLs in the HTML, first seen first, at most `limit`. */
26
+ export function siteHtmlUrls(html: string, limit = SITE_SCAN_MAX_URLS): string[] {
27
+ const found = new Set<string>();
28
+ for (const match of html.matchAll(/https?:\/\/[^\s"'<>`()\\]{1,2000}/giu)) {
29
+ let url: URL;
30
+ try {
31
+ url = new URL(match[0]);
32
+ } catch {
33
+ continue;
34
+ }
35
+ found.add(url.toString());
36
+ if (found.size >= limit) break;
37
+ }
38
+ return [...found];
39
+ }
40
+
41
+ export const noneSiteContentScanner: SiteContentScanner = Object.freeze({
42
+ name: "none" as const,
43
+ scanHtml: async () => ({ status: "none" as const, findings: [] }),
44
+ });
45
+
46
+ const WEB_RISK_THREATS = ["MALWARE", "SOCIAL_ENGINEERING", "UNWANTED_SOFTWARE"];
47
+
48
+ export function createWebRiskSiteContentScanner(
49
+ apiKey: string,
50
+ options: { fetch?: typeof fetch } = {},
51
+ ): SiteContentScanner {
52
+ const fetchImpl = options.fetch ?? fetch;
53
+ return {
54
+ name: "web_risk",
55
+ async scanHtml(html) {
56
+ const urls = siteHtmlUrls(html);
57
+ if (urls.length === 0) return { status: "clean", findings: [] };
58
+ const findings: SiteContentScanFinding[] = [];
59
+ try {
60
+ for (const url of urls) {
61
+ const query = new URLSearchParams();
62
+ for (const threat of WEB_RISK_THREATS) query.append("threatTypes", threat);
63
+ query.set("uri", url);
64
+ query.set("key", apiKey);
65
+ const response = await fetchImpl(
66
+ `https://webrisk.googleapis.com/v1/uris:search?${query.toString()}`,
67
+ { method: "GET" },
68
+ );
69
+ if (!response.ok) throw new Error(`Web Risk lookup failed with ${response.status}`);
70
+ const body = (await response.json().catch(() => ({}))) as {
71
+ threat?: { threatTypes?: unknown };
72
+ };
73
+ const types = Array.isArray(body.threat?.threatTypes)
74
+ ? body.threat.threatTypes.filter((type): type is string => typeof type === "string")
75
+ : [];
76
+ if (types.length > 0) findings.push({ url, threatTypes: types });
77
+ }
78
+ } catch {
79
+ return { status: "error", findings };
80
+ }
81
+ return { status: findings.length > 0 ? "flagged" : "clean", findings };
82
+ },
83
+ };
84
+ }
85
+
86
+ export function createSiteContentScanner(
87
+ settings: Pick<Settings, "sitesWebRiskApiKey">,
88
+ options: { fetch?: typeof fetch } = {},
89
+ ): SiteContentScanner {
90
+ return settings.sitesWebRiskApiKey
91
+ ? createWebRiskSiteContentScanner(settings.sitesWebRiskApiKey, options)
92
+ : noneSiteContentScanner;
93
+ }
@@ -0,0 +1,148 @@
1
+ import { SiteHostMapRecord, siteHostMapKey } from "@opengeni/contracts";
2
+ import type { Settings } from "@opengeni/config";
3
+
4
+ /**
5
+ * Optional Cloudflare edge sync for published Sites. Postgres is the source
6
+ * of truth; the KV host map and the edge cache are rebuildable copies. With
7
+ * no Cloudflare settings every call is a no-op.
8
+ *
9
+ * Writes go through the Cloudflare REST API with plain fetch (no SDK, each
10
+ * call bounded by a 10 s timeout) and never block the database write: callers
11
+ * schedule them after commit, each is retried a few times and then logged.
12
+ * The caller reads what a hostname should hold in a short transaction under
13
+ * the hostname's lock and commits before any of these calls, so no database
14
+ * transaction or lock waits on Cloudflare; after writing it re-reads the
15
+ * hostname and writes again if it moved meanwhile. One process runs at most
16
+ * one sync per hostname at a time. A writer never replaces a newer
17
+ * generation (read, compare, write; KV has no compare-and-set, so writers in
18
+ * two processes racing within one round trip can still land out of order,
19
+ * until the entry's TTL ends it). Generations come from one database
20
+ * sequence shared by every hostname, so a later change to a label (a move,
21
+ * an unpublish tombstone, a takedown) always carries a higher generation
22
+ * than anything written before.
23
+ *
24
+ * Staleness bound: the API itself refuses a suspended or unpublished Site on
25
+ * the very next site-runtime call (it re-checks publication status and access
26
+ * every time). The edge copies lag behind: Cloudflare KV propagates a write
27
+ * to other locations within about 60 s, every KV entry expires after
28
+ * `sitesHostMapTtlSeconds` (default 300 s), and the gateway caches host
29
+ * lookups for up to 60 s and access checks for 30 s. A takedown also purges
30
+ * the host's edge cache when a zone id is configured. The after-commit sync
31
+ * runs in process, so a restart can lose a pending write; the next signed
32
+ * host lookup for that label re-syncs a stale record, and the TTL bounds the
33
+ * rest. A missed sync is therefore corrected within TTL + 60 s at worst.
34
+ */
35
+
36
+ export type SiteEdgeSyncSettings = Pick<
37
+ Settings,
38
+ | "sitesCloudflareApiToken"
39
+ | "sitesCloudflareAccountId"
40
+ | "sitesCloudflareKvNamespaceId"
41
+ | "sitesCloudflareZoneId"
42
+ | "sitesHostMapTtlSeconds"
43
+ >;
44
+
45
+ export type SiteEdgeSync = {
46
+ readonly kvEnabled: boolean;
47
+ readonly purgeEnabled: boolean;
48
+ /** Write the host-map record unless the edge already holds a newer generation. */
49
+ putHostRecord(record: SiteHostMapRecord): Promise<"written" | "skipped_newer" | "disabled">;
50
+ /** Purge the edge cache for one hostname. */
51
+ purgeHost(hostname: string): Promise<"purged" | "disabled">;
52
+ };
53
+
54
+ export type SiteEdgeSyncOptions = {
55
+ fetch?: typeof fetch;
56
+ attempts?: number;
57
+ backoffMs?: number;
58
+ };
59
+
60
+ const API = "https://api.cloudflare.com/client/v4";
61
+ const FETCH_TIMEOUT_MS = 10_000;
62
+
63
+ async function withRetries<T>(attempts: number, backoffMs: number, run: () => Promise<T>) {
64
+ let last: unknown;
65
+ for (let attempt = 0; attempt < attempts; attempt += 1) {
66
+ try {
67
+ return await run();
68
+ } catch (error) {
69
+ last = error;
70
+ if (attempt < attempts - 1)
71
+ await new Promise((resolve) => setTimeout(resolve, backoffMs * 2 ** attempt));
72
+ }
73
+ }
74
+ throw last;
75
+ }
76
+
77
+ export function createSiteEdgeSync(
78
+ settings: SiteEdgeSyncSettings,
79
+ options: SiteEdgeSyncOptions = {},
80
+ ): SiteEdgeSync {
81
+ const fetchImpl = options.fetch ?? fetch;
82
+ const attempts = Math.max(1, options.attempts ?? 3);
83
+ const backoffMs = Math.max(0, options.backoffMs ?? 250);
84
+ const token = settings.sitesCloudflareApiToken;
85
+ const account = settings.sitesCloudflareAccountId;
86
+ const namespace = settings.sitesCloudflareKvNamespaceId;
87
+ const zone = settings.sitesCloudflareZoneId;
88
+ const kvEnabled = Boolean(token && account && namespace);
89
+ const purgeEnabled = Boolean(token && zone);
90
+ const headers = { authorization: `Bearer ${token ?? ""}` };
91
+ const valueUrl = (key: string) =>
92
+ `${API}/accounts/${encodeURIComponent(account ?? "")}/storage/kv/namespaces/${encodeURIComponent(
93
+ namespace ?? "",
94
+ )}/values/${encodeURIComponent(key)}`;
95
+
96
+ return {
97
+ kvEnabled,
98
+ purgeEnabled,
99
+ async putHostRecord(record) {
100
+ if (!kvEnabled) return "disabled";
101
+ const parsed = SiteHostMapRecord.parse(record);
102
+ const key = siteHostMapKey(parsed.hostname);
103
+ return await withRetries(attempts, backoffMs, async () => {
104
+ const current = await fetchImpl(valueUrl(key), {
105
+ method: "GET",
106
+ headers,
107
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
108
+ });
109
+ if (current.ok) {
110
+ const existing = SiteHostMapRecord.safeParse(await current.json().catch(() => null));
111
+ if (existing.success && existing.data.generation > parsed.generation)
112
+ return "skipped_newer" as const;
113
+ } else if (current.status !== 404) {
114
+ throw new Error(`Cloudflare KV read failed with ${current.status}`);
115
+ } else {
116
+ await current.body?.cancel().catch(() => undefined);
117
+ }
118
+ const ttl = Math.max(60, settings.sitesHostMapTtlSeconds);
119
+ const written = await fetchImpl(`${valueUrl(key)}?expiration_ttl=${ttl}`, {
120
+ method: "PUT",
121
+ headers: { ...headers, "content-type": "application/json" },
122
+ body: JSON.stringify(parsed),
123
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
124
+ });
125
+ if (!written.ok) throw new Error(`Cloudflare KV write failed with ${written.status}`);
126
+ await written.body?.cancel().catch(() => undefined);
127
+ return "written" as const;
128
+ });
129
+ },
130
+ async purgeHost(hostname) {
131
+ if (!purgeEnabled) return "disabled";
132
+ return await withRetries(attempts, backoffMs, async () => {
133
+ const response = await fetchImpl(
134
+ `${API}/zones/${encodeURIComponent(zone ?? "")}/purge_cache`,
135
+ {
136
+ method: "POST",
137
+ headers: { ...headers, "content-type": "application/json" },
138
+ body: JSON.stringify({ hosts: [hostname.toLowerCase()] }),
139
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
140
+ },
141
+ );
142
+ if (!response.ok) throw new Error(`Cloudflare cache purge failed with ${response.status}`);
143
+ await response.body?.cancel().catch(() => undefined);
144
+ return "purged" as const;
145
+ });
146
+ },
147
+ };
148
+ }
@@ -0,0 +1,198 @@
1
+ import { createHash, createHmac, timingSafeEqual } from "node:crypto";
2
+ import {
3
+ siteGatewayCanonicalString,
4
+ SITE_GATEWAY_BODY_SHA256_HEADER,
5
+ SITE_GATEWAY_CLIENT_IP_HEADER,
6
+ SITE_GATEWAY_HOST_HEADER,
7
+ SITE_GATEWAY_HUMAN_HEADER,
8
+ SITE_GATEWAY_MAX_SKEW_SECONDS,
9
+ SITE_GATEWAY_SESSION_HEADER,
10
+ SITE_GATEWAY_SIGNATURE_HEADER,
11
+ SITE_GATEWAY_SIGNATURE_VERSION,
12
+ SITE_GATEWAY_TIMESTAMP_HEADER,
13
+ SITE_GATEWAY_VISITOR_HEADER,
14
+ } from "@opengeni/contracts";
15
+
16
+ /**
17
+ * Verification of gateway-signed site-runtime requests. The gateway HMACs
18
+ * `siteGatewayCanonicalString` with the shared secret; the API accepts the
19
+ * current or the previous secret (rotation), within 30 s of its clock. The
20
+ * signed body hash travels in its own header, so the signature is checked
21
+ * from the headers alone, before the body is read; the route then hashes the
22
+ * body as it reads it and refuses a body that does not match. Nothing else
23
+ * about the request is trusted before this passes.
24
+ */
25
+
26
+ export type SiteGatewayFields = {
27
+ host: string;
28
+ session: string;
29
+ visitor: string;
30
+ clientIp: string;
31
+ human: boolean;
32
+ };
33
+
34
+ export type SiteGatewayVerification =
35
+ | {
36
+ ok: true;
37
+ fields: SiteGatewayFields;
38
+ /** The signed hex SHA-256 the body read afterwards must match. */
39
+ bodySha256: string;
40
+ }
41
+ | {
42
+ ok: false;
43
+ reason:
44
+ | "not_configured"
45
+ | "missing_headers"
46
+ | "bad_timestamp"
47
+ | "skew"
48
+ | "bad_body_hash"
49
+ | "bad_signature"
50
+ | "body_mismatch"
51
+ | "credentials";
52
+ };
53
+
54
+ const SHA256_HEX = /^[0-9a-f]{64}$/u;
55
+
56
+ /** Request headers that carry Opengeni app credentials; site-runtime refuses them. */
57
+ export const SITE_RUNTIME_REFUSED_HEADERS: readonly string[] = Object.freeze([
58
+ "authorization",
59
+ "proxy-authorization",
60
+ "cookie",
61
+ "x-api-key",
62
+ "x-opengeni-external-actor",
63
+ ]);
64
+
65
+ export function sha256Hex(bytes: Uint8Array): string {
66
+ return createHash("sha256").update(bytes).digest("hex");
67
+ }
68
+
69
+ export function siteGatewaySignature(secret: string, canonical: string): string {
70
+ return `${SITE_GATEWAY_SIGNATURE_VERSION}=${createHmac("sha256", secret)
71
+ .update(canonical, "utf8")
72
+ .digest("base64url")}`;
73
+ }
74
+
75
+ function sameText(expected: string, presented: string): boolean {
76
+ const a = Buffer.from(expected, "utf8");
77
+ const b = Buffer.from(presented, "utf8");
78
+ // Equal-length compare; a length mismatch still spends a compare.
79
+ if (a.length !== b.length) {
80
+ timingSafeEqual(a, a);
81
+ return false;
82
+ }
83
+ return timingSafeEqual(a, b);
84
+ }
85
+
86
+ /** Bounded header value: the gateway never sends long values here. */
87
+ function header(headers: Headers, name: string, max = 512): string | null {
88
+ const value = headers.get(name);
89
+ if (value === null) return null;
90
+ return value.length > max ? null : value;
91
+ }
92
+
93
+ /**
94
+ * Verify a signed request from its headers alone; the body is not needed.
95
+ * On success the caller reads the body (capped) and checks it against
96
+ * `bodySha256` with `sameSha256Hex`, refusing a mismatch as `body_mismatch`.
97
+ */
98
+ export function verifySiteGatewayRequest(input: {
99
+ method: string;
100
+ pathWithQuery: string;
101
+ headers: Headers;
102
+ secrets: readonly (string | undefined)[];
103
+ nowMs?: number;
104
+ }): SiteGatewayVerification {
105
+ const secrets = input.secrets.filter((secret): secret is string => Boolean(secret));
106
+ if (secrets.length === 0) return { ok: false, reason: "not_configured" };
107
+ const signature = header(input.headers, SITE_GATEWAY_SIGNATURE_HEADER, 128);
108
+ const timestampText = header(input.headers, SITE_GATEWAY_TIMESTAMP_HEADER, 16);
109
+ const host = header(input.headers, SITE_GATEWAY_HOST_HEADER, 253);
110
+ const bodySha256 = input.headers.get(SITE_GATEWAY_BODY_SHA256_HEADER);
111
+ if (!signature || !timestampText || !host || bodySha256 === null)
112
+ return { ok: false, reason: "missing_headers" };
113
+ if (!/^\d{1,12}$/u.test(timestampText)) return { ok: false, reason: "bad_timestamp" };
114
+ const timestamp = Number(timestampText);
115
+ const now = Math.floor((input.nowMs ?? Date.now()) / 1000);
116
+ if (Math.abs(now - timestamp) > SITE_GATEWAY_MAX_SKEW_SECONDS)
117
+ return { ok: false, reason: "skew" };
118
+ // The hash must be lowercase hex, exactly as the gateway signs it.
119
+ if (!SHA256_HEX.test(bodySha256)) return { ok: false, reason: "bad_body_hash" };
120
+ const session = header(input.headers, SITE_GATEWAY_SESSION_HEADER) ?? "";
121
+ const visitor = header(input.headers, SITE_GATEWAY_VISITOR_HEADER) ?? "";
122
+ const clientIp = header(input.headers, SITE_GATEWAY_CLIENT_IP_HEADER, 64) ?? "";
123
+ const human = header(input.headers, SITE_GATEWAY_HUMAN_HEADER, 8) ?? "";
124
+ const canonical = siteGatewayCanonicalString({
125
+ method: input.method,
126
+ host,
127
+ pathWithQuery: input.pathWithQuery,
128
+ timestamp,
129
+ bodySha256,
130
+ session,
131
+ visitor,
132
+ clientIp,
133
+ human,
134
+ });
135
+ // Check every configured secret, so timing does not reveal which one matched.
136
+ let matched = false;
137
+ for (const secret of secrets)
138
+ matched = sameText(siteGatewaySignature(secret, canonical), signature) || matched;
139
+ if (!matched) return { ok: false, reason: "bad_signature" };
140
+ // Signed requests never carry app credentials; a request that does is refused.
141
+ if (SITE_RUNTIME_REFUSED_HEADERS.some((name) => input.headers.has(name)))
142
+ return { ok: false, reason: "credentials" };
143
+ return {
144
+ ok: true,
145
+ fields: { host: host.toLowerCase(), session, visitor, clientIp, human: human === "1" },
146
+ bodySha256,
147
+ };
148
+ }
149
+
150
+ /** Whether two hex digests are equal, compared in constant time. */
151
+ export function sameSha256Hex(actual: string, signed: string): boolean {
152
+ return sameText(actual, signed);
153
+ }
154
+
155
+ /** Sign a request as the gateway does (tests and local tools). */
156
+ export function signSiteGatewayRequest(input: {
157
+ secret: string;
158
+ method: string;
159
+ pathWithQuery: string;
160
+ host: string;
161
+ body?: Uint8Array | string;
162
+ session?: string;
163
+ visitor?: string;
164
+ clientIp?: string;
165
+ human?: boolean;
166
+ nowMs?: number;
167
+ }): Record<string, string> {
168
+ const body =
169
+ typeof input.body === "string"
170
+ ? new TextEncoder().encode(input.body)
171
+ : (input.body ?? new Uint8Array());
172
+ const timestamp = Math.floor((input.nowMs ?? Date.now()) / 1000);
173
+ const fields = {
174
+ session: input.session ?? "",
175
+ visitor: input.visitor ?? "",
176
+ clientIp: input.clientIp ?? "",
177
+ human: input.human ? "1" : "",
178
+ };
179
+ const bodySha256 = sha256Hex(body);
180
+ const canonical = siteGatewayCanonicalString({
181
+ method: input.method,
182
+ host: input.host,
183
+ pathWithQuery: input.pathWithQuery,
184
+ timestamp,
185
+ bodySha256,
186
+ ...fields,
187
+ });
188
+ return {
189
+ [SITE_GATEWAY_BODY_SHA256_HEADER]: bodySha256,
190
+ [SITE_GATEWAY_TIMESTAMP_HEADER]: String(timestamp),
191
+ [SITE_GATEWAY_SIGNATURE_HEADER]: siteGatewaySignature(input.secret, canonical),
192
+ [SITE_GATEWAY_HOST_HEADER]: input.host,
193
+ ...(fields.session ? { [SITE_GATEWAY_SESSION_HEADER]: fields.session } : {}),
194
+ ...(fields.visitor ? { [SITE_GATEWAY_VISITOR_HEADER]: fields.visitor } : {}),
195
+ ...(fields.clientIp ? { [SITE_GATEWAY_CLIENT_IP_HEADER]: fields.clientIp } : {}),
196
+ ...(fields.human ? { [SITE_GATEWAY_HUMAN_HEADER]: fields.human } : {}),
197
+ };
198
+ }