@opengeni/api-router 3.0.1 → 3.1.2

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-OGQDXVXY.js +18 -0
  21. package/dist/chunk-OGQDXVXY.js.map +1 -0
  22. package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
  23. package/dist/chunk-OT56OY4V.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 +165 -55
  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,433 @@
1
+ import {
2
+ ManagedSignInMethods,
3
+ ManagedSignInPasswordMutation,
4
+ ManagedSignInProviderMutation,
5
+ ManagedSignInMutationResponse,
6
+ } from "@opengeni/contracts/managed-sign-in-methods";
7
+ import type { ApiRouteDeps } from "@opengeni/core";
8
+ import {
9
+ requireCanonicalHumanRequestIdentity,
10
+ getManagedAuthRequestActorLeaseStamp,
11
+ markManagedAuthRequestActorTransitionApplied,
12
+ } from "@opengeni/core/canonical-human-identities";
13
+ import {
14
+ MANAGED_AUTH_SESSION_SET_COOKIE,
15
+ managedAuthSha256,
16
+ managedAuthSecretRequestDigest,
17
+ requireManagedAuthMutationAdmission,
18
+ } from "@opengeni/core/managed-auth-session-sets";
19
+ import { getManagedAuthSessionSetSnapshot } from "@opengeni/db/managed-auth-session-sets";
20
+ import { getCanonicalHumanIdentityProjection } from "@opengeni/db/canonical-human-identities";
21
+ import { sql } from "drizzle-orm";
22
+ import type { Context, Hono } from "hono";
23
+ import { getCookie } from "hono/cookie";
24
+ import { HTTPException } from "hono/http-exception";
25
+ import { z } from "zod";
26
+ import {
27
+ isolatedManagedAuthOAuthCallbackRequest,
28
+ hashManagedAuthPassword,
29
+ verifyManagedAuthPassword,
30
+ } from "../auth/managed-auth";
31
+ import { runManagedSignInConnect } from "../auth/managed-auth-attempt-context";
32
+ import { deliverManagedSignInNotification } from "../auth/managed-sign-in-notifications";
33
+ import { managedAuthSelectedProofHeaders } from "../auth/managed-auth-session-adapter";
34
+ import { scrubManagedAuthProviderResponse } from "./managed-auth-session-sets";
35
+
36
+ const ConnectState = z.object({
37
+ opengeniSignInMethod: z.object({
38
+ intentId: z.string().uuid(),
39
+ provider: z.enum(["google", "github"]),
40
+ }),
41
+ link: z.object({ userId: z.string().min(1), email: z.string().email() }),
42
+ callbackURL: z.string().url(),
43
+ errorURL: z.string().url(),
44
+ });
45
+ const ConnectIntent = z.object({
46
+ authUserId: z.string().min(1),
47
+ authSessionId: z.string().min(1),
48
+ expectedIdentityId: z.string().uuid(),
49
+ actorFence: z
50
+ .object({
51
+ authorityHash: z.string().regex(/^[0-9a-f]{64}$/),
52
+ actorEpoch: z.string().regex(/^[1-9][0-9]*$/),
53
+ requestId: z.string().uuid(),
54
+ })
55
+ .optional(),
56
+ });
57
+
58
+ async function rows<T>(deps: ApiRouteDeps, query: ReturnType<typeof sql>): Promise<T[]> {
59
+ const result = await deps.db.execute(query);
60
+ return (Array.isArray(result) ? result : (result as { rows: T[] }).rows) as T[];
61
+ }
62
+
63
+ async function identity(context: Context, deps: ApiRouteDeps) {
64
+ return requireCanonicalHumanRequestIdentity(context, {
65
+ db: deps.db,
66
+ managedAuth: deps.managedAuth,
67
+ managedAuthSessionAdapter: deps.managedAuthSessionAdapter,
68
+ managedAuthSessionSetMode: deps.settings.managedAuthSessionSetMode,
69
+ });
70
+ }
71
+
72
+ export async function admitManagedSignInMutation(context: Context, deps: ApiRouteDeps) {
73
+ const origin = deps.settings.publicBaseUrl ? new URL(deps.settings.publicBaseUrl).origin : null;
74
+ if (
75
+ !origin ||
76
+ context.req.header("origin") !== origin ||
77
+ context.req.header("sec-fetch-site") !== "same-origin" ||
78
+ context.req.header("content-type")?.split(";", 1)[0] !== "application/json"
79
+ ) {
80
+ throw new HTTPException(403, { message: "Same-origin browser mutation required" });
81
+ }
82
+ const authority = getCookie(context, MANAGED_AUTH_SESSION_SET_COOKIE);
83
+ if (deps.settings.managedAuthSessionSetMode !== "legacy" && authority) {
84
+ const snapshot = await getManagedAuthSessionSetSnapshot(deps.db, {
85
+ authorityHash: managedAuthSha256(authority),
86
+ mode: deps.settings.managedAuthSessionSetMode,
87
+ readOnly: true,
88
+ });
89
+ if (!snapshot) throw new HTTPException(401);
90
+ try {
91
+ requireManagedAuthMutationAdmission({
92
+ request: context.req.raw,
93
+ allowedOrigins: [origin],
94
+ authority,
95
+ signingSecret: deps.settings.betterAuthSecret!,
96
+ expectedGeneration: snapshot.projection.generation,
97
+ });
98
+ } catch {
99
+ throw new HTTPException(403, { message: "Browser session-set CSRF validation failed" });
100
+ }
101
+ }
102
+ }
103
+
104
+ function configured(deps: ApiRouteDeps, provider: "credential" | "google" | "github") {
105
+ return (
106
+ provider === "credential" ||
107
+ (provider === "google"
108
+ ? Boolean(
109
+ deps.settings.managedAuthGoogleClientId && deps.settings.managedAuthGoogleClientSecret,
110
+ )
111
+ : Boolean(
112
+ deps.settings.managedAuthGithubClientId && deps.settings.managedAuthGithubClientSecret,
113
+ ))
114
+ );
115
+ }
116
+
117
+ function mutationError(context: Context, error: unknown): Response {
118
+ let candidate: unknown = error;
119
+ for (
120
+ let depth = 0;
121
+ depth < 5 && candidate instanceof Error;
122
+ depth++, candidate = candidate.cause
123
+ ) {
124
+ const code = candidate.message.match(/SIGN_IN_METHOD_[A-Z_]+/)?.[0];
125
+ if (code)
126
+ return context.json(
127
+ { code, message: code.toLowerCase().replaceAll("_", " ") },
128
+ code.includes("CONFLICT") ||
129
+ code.includes("REUSED") ||
130
+ code.includes("CHANGED") ||
131
+ code.includes("COLLISION") ||
132
+ code.includes("ALREADY")
133
+ ? 409
134
+ : 403,
135
+ );
136
+ }
137
+ throw error;
138
+ }
139
+
140
+ export function registerManagedSignInMethodRoutes(app: Hono, deps: ApiRouteDeps): void {
141
+ const base = "/v1/auth/sign-in-methods";
142
+ app.use(`${base}*`, async (context, next) => {
143
+ context.header("cache-control", "no-store");
144
+ await next();
145
+ });
146
+ app.get(base, async (context) => {
147
+ const actor = await identity(context, deps);
148
+ const projection = await getCanonicalHumanIdentityProjection(deps.db, actor.authUserId);
149
+ const [user] = await rows<{ email: string; emailVerified: boolean; fresh: boolean }>(
150
+ deps,
151
+ sql`
152
+ select u.email, u.email_verified as "emailVerified", s.created_at > clock_timestamp()-interval '5 minutes' as fresh
153
+ from auth_users u join auth_sessions s on s.user_id=u.id where u.id=${actor.authUserId} and s.id=${actor.authSessionId}`,
154
+ );
155
+ if (!user) throw new HTTPException(401);
156
+ const accounts = await rows<{ provider: string; usable: boolean }>(
157
+ deps,
158
+ sql`
159
+ select provider_id as provider, (provider_id <> 'credential' or length(password)>0) as usable from auth_identities where user_id=${actor.authUserId}`,
160
+ );
161
+ const connected = (provider: string) =>
162
+ accounts.some((a) => a.provider === provider && a.usable) &&
163
+ projection.loginBindings.some((b) => b.providerId === provider && b.status === "active");
164
+ const count = (["credential", "google", "github"] as const).filter(
165
+ (p) => connected(p) && configured(deps, p),
166
+ ).length;
167
+ return context.json(
168
+ ManagedSignInMethods.parse({
169
+ ...user,
170
+ identityId: projection.activeIdentity.id,
171
+ identityRevision: projection.activeIdentity.identityRevision,
172
+ freshAuthenticationRequired: !user.fresh,
173
+ methods: (["credential", "google", "github"] as const).map((provider) => ({
174
+ provider,
175
+ connected: connected(provider),
176
+ available: configured(deps, provider),
177
+ canDisconnect:
178
+ provider !== "credential" &&
179
+ connected(provider) &&
180
+ count - (configured(deps, provider) ? 1 : 0) > 0,
181
+ implicitRelinkingSuppressed:
182
+ !connected(provider) &&
183
+ projection.loginBindings.some(
184
+ (b) => b.providerId === provider && b.status !== "active",
185
+ ),
186
+ })),
187
+ }),
188
+ );
189
+ });
190
+ for (const kind of ["connect", "disconnect", "password"] as const) {
191
+ app.post(`${base}/${kind}`, async (context) => {
192
+ await admitManagedSignInMutation(context, deps);
193
+ const actor = await identity(context, deps);
194
+ const actorFence = getManagedAuthRequestActorLeaseStamp(context.req.raw);
195
+ if (deps.settings.managedAuthSessionSetMode !== "legacy" && !actorFence)
196
+ throw new HTTPException(409, { message: "Managed actor fence required" });
197
+ const schema =
198
+ kind === "password" ? ManagedSignInPasswordMutation : ManagedSignInProviderMutation;
199
+ const parsed = schema.safeParse(await context.req.json().catch(() => null));
200
+ if (!parsed.success)
201
+ throw new HTTPException(422, { message: "Invalid sign-in method request" });
202
+ const body = parsed.data;
203
+ const currentIdentity = await getCanonicalHumanIdentityProjection(deps.db, actor.authUserId);
204
+ if (currentIdentity.activeIdentity.id !== body.expectedIdentityId)
205
+ return context.json(
206
+ {
207
+ code: "SIGN_IN_METHOD_IDENTITY_CHANGED",
208
+ message: "The signed-in account changed; reload security settings",
209
+ },
210
+ 409,
211
+ );
212
+ const [user] = await rows<{ email: string; token: string }>(
213
+ deps,
214
+ sql`select u.email,s.token from auth_users u join auth_sessions s on s.user_id=u.id where u.id=${actor.authUserId} and s.id=${actor.authSessionId}`,
215
+ );
216
+ if (!user) throw new HTTPException(401);
217
+ const request: Record<string, unknown> = {
218
+ kind,
219
+ operationId: body.operationId,
220
+ requestDigest: managedAuthSecretRequestDigest(deps.settings.betterAuthSecret!, {
221
+ kind,
222
+ ...body,
223
+ }),
224
+ expectedIdentityRevision: body.expectedIdentityRevision,
225
+ expectedIdentityId: body.expectedIdentityId,
226
+ usableProviders: (["credential", "google", "github"] as const).filter((p) =>
227
+ configured(deps, p),
228
+ ),
229
+ ...(actorFence ? { actorFence } : {}),
230
+ };
231
+ try {
232
+ const [prior] = await rows<{ result: unknown }>(
233
+ deps,
234
+ sql`select replay_managed_sign_in_method(${actor.authUserId},${actor.authSessionId},${JSON.stringify(request)}::jsonb) result`,
235
+ );
236
+ if (prior?.result)
237
+ return context.json(
238
+ kind === "connect"
239
+ ? {
240
+ url: new URL(
241
+ "/settings/security?signInMethod=connected",
242
+ deps.settings.publicBaseUrl!,
243
+ ).toString(),
244
+ }
245
+ : ManagedSignInMutationResponse.parse(prior.result),
246
+ );
247
+ } catch (error) {
248
+ return mutationError(context, error);
249
+ }
250
+ // Per-human, cross-replica admission before password hashing or creating
251
+ // OAuth state. Successful committed-result replay does not spend a slot.
252
+ const [limit] = await rows<{ count: number }>(
253
+ deps,
254
+ sql`
255
+ insert into auth_rate_limits(id,key,count,last_request)
256
+ values(${`sign-in-methods:${actor.authUserId}`},${`sign-in-methods:${actor.authUserId}`},1,(extract(epoch from clock_timestamp())*1000)::bigint)
257
+ on conflict(key) do update set
258
+ count=case when auth_rate_limits.last_request < (extract(epoch from clock_timestamp())*1000)::bigint-60000 then 1 else least(auth_rate_limits.count+1,11) end,
259
+ last_request=case when auth_rate_limits.last_request < (extract(epoch from clock_timestamp())*1000)::bigint-60000 then (extract(epoch from clock_timestamp())*1000)::bigint else auth_rate_limits.last_request end
260
+ returning count`,
261
+ );
262
+ if (!limit || limit.count > 10)
263
+ return context.json(
264
+ {
265
+ code: "SIGN_IN_METHOD_RATE_LIMITED",
266
+ message: "Too many sign-in method attempts; try again in one minute",
267
+ },
268
+ 429,
269
+ );
270
+ if ("provider" in body) {
271
+ request.provider = body.provider;
272
+ if (kind === "connect" && !configured(deps, body.provider))
273
+ throw new HTTPException(409, { message: "Sign-in provider is not configured" });
274
+ } else {
275
+ const [credential] = await rows<{ password: string | null }>(
276
+ deps,
277
+ sql`select password from auth_identities where user_id=${actor.authUserId} and provider_id='credential'`,
278
+ );
279
+ if (
280
+ credential?.password &&
281
+ (!body.currentPassword ||
282
+ !(await verifyManagedAuthPassword(body.currentPassword, credential.password)))
283
+ ) {
284
+ return context.json(
285
+ {
286
+ code: "SIGN_IN_METHOD_CURRENT_PASSWORD_REQUIRED",
287
+ message: "Enter your current password",
288
+ },
289
+ 403,
290
+ );
291
+ }
292
+ request.expectedPasswordHash = credential?.password ?? null;
293
+ request.passwordHash = await hashManagedAuthPassword(body.newPassword);
294
+ }
295
+ try {
296
+ await rows(
297
+ deps,
298
+ sql`select mutate_managed_sign_in_method(${actor.authUserId},${actor.authSessionId},${JSON.stringify(request)}::jsonb)`,
299
+ );
300
+ if (kind === "connect" && "provider" in body) {
301
+ const headers = await managedAuthSelectedProofHeaders(deps.managedAuth!, user.token);
302
+ headers.set("origin", new URL(deps.settings.publicBaseUrl!).origin);
303
+ const callbackURL = new URL(
304
+ "/settings/security?signInMethod=connected",
305
+ deps.settings.publicBaseUrl!,
306
+ ).toString();
307
+ const errorCallbackURL = new URL(
308
+ "/settings/security?signInMethod=error",
309
+ deps.settings.publicBaseUrl!,
310
+ ).toString();
311
+ const result = await deps.managedAuth!.api.linkSocialAccount({
312
+ headers,
313
+ returnHeaders: true,
314
+ body: {
315
+ provider: body.provider,
316
+ callbackURL,
317
+ errorCallbackURL,
318
+ disableRedirect: true,
319
+ additionalData: {
320
+ opengeniSignInMethod: { intentId: body.operationId, provider: body.provider },
321
+ },
322
+ },
323
+ });
324
+ for (const cookie of result.headers.getSetCookie())
325
+ context.header("set-cookie", cookie, { append: true });
326
+ return context.json({ url: result.response.url });
327
+ }
328
+ if (actorFence) markManagedAuthRequestActorTransitionApplied(context.req.raw);
329
+ return context.json({
330
+ reauthenticationRequired: true,
331
+ notification: await deliverManagedSignInNotification(
332
+ deps.db,
333
+ deps.managedEmailTransport,
334
+ body.operationId,
335
+ ),
336
+ });
337
+ } catch (error) {
338
+ return mutationError(context, error);
339
+ }
340
+ });
341
+ }
342
+ }
343
+
344
+ /** Intercept only database-backed, product-issued explicit connect states. */
345
+ export async function handleManagedSignInConnectCallback(
346
+ context: Context,
347
+ deps: ApiRouteDeps,
348
+ provider: "google" | "github",
349
+ ): Promise<Response | null> {
350
+ const state = context.req.query("state");
351
+ if (!state || !deps.managedAuth) return null;
352
+ const verification = await (
353
+ await deps.managedAuth.$context
354
+ ).internalAdapter.findVerificationValue(state);
355
+ if (!verification?.value) return null;
356
+ let rawState: unknown;
357
+ try {
358
+ rawState = JSON.parse(verification.value);
359
+ } catch {
360
+ return null;
361
+ }
362
+ if (!rawState || typeof rawState !== "object" || !("opengeniSignInMethod" in rawState))
363
+ return null;
364
+ const parsed = ConnectState.safeParse(rawState);
365
+ if (!parsed.success)
366
+ throw new HTTPException(403, { message: "Invalid sign-in method OAuth proof" });
367
+ const value = parsed.data,
368
+ proof = value.opengeniSignInMethod;
369
+ if (
370
+ proof.provider !== provider ||
371
+ value.callbackURL !==
372
+ new URL(
373
+ "/settings/security?signInMethod=connected",
374
+ deps.settings.publicBaseUrl!,
375
+ ).toString() ||
376
+ value.errorURL !==
377
+ new URL("/settings/security?signInMethod=error", deps.settings.publicBaseUrl!).toString()
378
+ )
379
+ throw new HTTPException(403);
380
+ const [intent] = await rows<{ value: string }>(
381
+ deps,
382
+ sql`select value from auth_verifications where identifier=${`managed-sign-in:${proof.intentId}`} and expires_at>clock_timestamp()`,
383
+ );
384
+ if (!intent) throw new HTTPException(403, { message: "Sign-in method connection expired" });
385
+ const request = ConnectIntent.parse(JSON.parse(intent.value));
386
+ const authority = getCookie(context, MANAGED_AUTH_SESSION_SET_COOKIE);
387
+ if (!request.actorFence) {
388
+ const ambient = await deps.managedAuthSessionAdapter?.resolveAmbientSession(
389
+ context.req.raw.headers,
390
+ );
391
+ if (
392
+ !ambient ||
393
+ ambient.session.id !== request.authSessionId ||
394
+ ambient.user.id !== request.authUserId
395
+ ) {
396
+ return context.redirect(
397
+ new URL(
398
+ "/settings/security?signInMethod=error&error=SIGN_IN_METHOD_IDENTITY_CHANGED",
399
+ deps.settings.publicBaseUrl!,
400
+ ).toString(),
401
+ );
402
+ }
403
+ }
404
+ if (
405
+ request.actorFence &&
406
+ (!authority || managedAuthSha256(authority) !== request.actorFence.authorityHash)
407
+ )
408
+ throw new HTTPException(403);
409
+ if (value.link?.userId !== request.authUserId || value.link?.email === undefined)
410
+ throw new HTTPException(403);
411
+ const isolated = await isolatedManagedAuthOAuthCallbackRequest(deps.managedAuth, context.req.raw);
412
+ const response = await runManagedSignInConnect(proof.intentId, () =>
413
+ deps.managedAuth!.handler(isolated.request),
414
+ );
415
+ const [linked] = await rows<{ email: string }>(
416
+ deps,
417
+ sql`select u.email from auth_identities a join auth_users u on u.id=a.user_id where a.managed_link_intent_id=${proof.intentId}`,
418
+ );
419
+ if (linked)
420
+ await deliverManagedSignInNotification(deps.db, deps.managedEmailTransport, proof.intentId);
421
+ if (response.status >= 400 || !linked) {
422
+ return context.redirect(
423
+ new URL(
424
+ "/settings/security?signInMethod=error&error=SIGN_IN_METHOD_CONNECT_FAILED",
425
+ deps.settings.publicBaseUrl!,
426
+ ).toString(),
427
+ );
428
+ }
429
+ return scrubManagedAuthProviderResponse(response, {
430
+ replacementCookies: [],
431
+ preserveCookieNames: [isolated.stateCookieName],
432
+ });
433
+ }
@@ -25,6 +25,7 @@ import {
25
25
  import type { Hono } from "hono";
26
26
  import { HTTPException } from "hono/http-exception";
27
27
  import { createOpenGeniSlackBotInteractionClient } from "../integrations/slack-bot";
28
+ import { parseRequestJson } from "../http/request-body";
28
29
 
29
30
  export function registerMemorySlackPublicationRoutes(app: Hono, deps: ApiRouteDeps): void {
30
31
  const base = "/v1/workspaces/:workspaceId/memory-slack-publications";
@@ -45,7 +46,7 @@ export function registerMemorySlackPublicationRoutes(app: Hono, deps: ApiRouteDe
45
46
  app.put(`${base}/configuration`, async (c) => {
46
47
  const workspaceId = c.req.param("workspaceId");
47
48
  const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
48
- const payload = UpdateMemorySlackPublicationConfigurationRequest.parse(await c.req.json());
49
+ const payload = await parseRequestJson(c, UpdateMemorySlackPublicationConfigurationRequest);
49
50
  let slackTeamId: string | null = null;
50
51
  let channelName = payload.slackChannelName;
51
52
  if (payload.connectionId || payload.slackChannelId) {
@@ -179,7 +180,7 @@ export function registerMemorySlackPublicationRoutes(app: Hono, deps: ApiRouteDe
179
180
  app.post(`${base}/:publicationId/action`, async (c) => {
180
181
  const workspaceId = c.req.param("workspaceId");
181
182
  const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
182
- const payload = MemorySlackPublicationActionRequest.parse(await c.req.json());
183
+ const payload = await parseRequestJson(c, MemorySlackPublicationActionRequest);
183
184
  const publication = await actOnMemorySlackPublication(deps.db, {
184
185
  workspaceId,
185
186
  publicationId: c.req.param("publicationId"),
@@ -0,0 +1,194 @@
1
+ import {
2
+ ModelAccountPreferences,
3
+ SessionModelAccountChoiceResponse,
4
+ SetSessionModelAccountChoiceRequest,
5
+ SetSessionModelAccountChoiceResponse,
6
+ UpdateModelAccountPreferencesRequest,
7
+ } from "@opengeni/contracts";
8
+ import { requireAccessContext, requireAccessGrant, type ApiRouteDeps } from "@opengeni/core";
9
+ import {
10
+ chooseSubscriptionCoreSessionAccount,
11
+ deliverSubscriptionCoreProviderWakes,
12
+ readSubscriptionCoreSessionAccountChoice,
13
+ readSubscriptionPersonPreferences,
14
+ writeSubscriptionPersonPreferences,
15
+ } from "@opengeni/db";
16
+ import { publishDurableSessionEvents } from "@opengeni/events";
17
+ import type { Context, Hono } from "hono";
18
+ import { HTTPException } from "hono/http-exception";
19
+ import { z } from "zod";
20
+
21
+ import { ApiHttpError } from "../http/api-error";
22
+ import { isAgentActingAsPerson, requireFullAccessIfAgent } from "../http/acting-person";
23
+ import { requireSameOriginBrowserMutation } from "./codex";
24
+
25
+ const Uuid = z.string().uuid();
26
+
27
+ function parseId(value: string | undefined, what: string): string {
28
+ const parsed = Uuid.safeParse(value);
29
+ if (!parsed.success) throw new HTTPException(404, { message: `${what} not found` });
30
+ return parsed.data;
31
+ }
32
+
33
+ async function jsonBody(c: Context): Promise<unknown> {
34
+ return await c.req.json().catch(() => null);
35
+ }
36
+
37
+ /** The calling person in this organization (a human, or an agent acting as one). */
38
+ async function requireOrganizationPerson(
39
+ c: Context,
40
+ deps: ApiRouteDeps,
41
+ mutation: boolean,
42
+ ): Promise<{ organizationId: string; subjectId: string }> {
43
+ const organizationId = parseId(c.req.param("organizationId"), "organization");
44
+ if (mutation) {
45
+ requireSameOriginBrowserMutation(c, deps);
46
+ if (isAgentActingAsPerson(c)) requireFullAccessIfAgent(c, "Changing model account preferences");
47
+ }
48
+ const context = await requireAccessContext(c, deps);
49
+ const grant = context.accountGrants.find((each) => each.accountId === organizationId);
50
+ if (!grant || !context.subjectId.startsWith("user:")) {
51
+ throw new HTTPException(404, { message: "organization not found" });
52
+ }
53
+ return { organizationId, subjectId: context.subjectId };
54
+ }
55
+
56
+ /**
57
+ * Explicit model-account choice for a session and a person's own
58
+ * preferences, for every provider on the shared subscription core
59
+ * (SUB-SEL-02, SUB-SEL-04, SUB-ELIG-05, SUB-OWN-05, D-24, D-27, D-28).
60
+ *
61
+ * The session routes sit behind the session authorization middleware
62
+ * (`session.read` to read, the account-choice operation to write), so a
63
+ * private session is reachable only by its owner. The database enforces
64
+ * which account a session may use; these routes translate its outcome.
65
+ */
66
+ export function registerModelAccountChoiceRoutes(app: Hono, deps: ApiRouteDeps): void {
67
+ const sessionPath = "/v1/workspaces/:workspaceId/sessions/:sessionId/model-account";
68
+
69
+ app.get(sessionPath, async (c) => {
70
+ c.header("cache-control", "private, no-store");
71
+ const workspaceId = parseId(c.req.param("workspaceId"), "workspace");
72
+ const sessionId = parseId(c.req.param("sessionId"), "session");
73
+ await requireAccessGrant(c, deps, workspaceId, "sessions:read");
74
+ const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:read");
75
+ const choice = await readSubscriptionCoreSessionAccountChoice(deps.db, {
76
+ accountId: grant.accountId,
77
+ workspaceId,
78
+ sessionId,
79
+ subjectId: grant.subjectId,
80
+ });
81
+ if (!choice) throw new HTTPException(404, { message: "session not found" });
82
+ return c.json(
83
+ SessionModelAccountChoiceResponse.parse({
84
+ binding: choice.binding,
85
+ bindings: choice.bindings,
86
+ serving: choice.serving,
87
+ accounts: choice.connections,
88
+ personal: choice.personal,
89
+ }),
90
+ );
91
+ });
92
+
93
+ app.put(sessionPath, async (c) => {
94
+ const workspaceId = parseId(c.req.param("workspaceId"), "workspace");
95
+ const sessionId = parseId(c.req.param("sessionId"), "session");
96
+ const grant = await requireAccessGrant(c, deps, workspaceId, "sessions:control");
97
+ const parsed = SetSessionModelAccountChoiceRequest.safeParse(await jsonBody(c));
98
+ if (!parsed.success) {
99
+ throw new HTTPException(422, {
100
+ message: "connectionId must be an account id or null, with an optional provider",
101
+ });
102
+ }
103
+ const result = await chooseSubscriptionCoreSessionAccount(deps.db, {
104
+ accountId: grant.accountId,
105
+ workspaceId,
106
+ sessionId,
107
+ connectionId: parsed.data.connectionId,
108
+ provider: parsed.data.provider ?? null,
109
+ subjectId: grant.subjectId,
110
+ });
111
+ switch (result.outcome) {
112
+ case "not_found":
113
+ throw new HTTPException(404, { message: "session or account not found" });
114
+ case "refused":
115
+ throw new ApiHttpError(409, {
116
+ code: "conflict",
117
+ message: "this account cannot be used for this session",
118
+ retryable: false,
119
+ outcomeUnknown: false,
120
+ details: { reason: "account_not_eligible" },
121
+ });
122
+ case "conflict":
123
+ // The choice kept losing a deadlock to a concurrent placement after
124
+ // its bounded replay; nothing changed.
125
+ throw new ApiHttpError(409, {
126
+ code: "conflict",
127
+ message: "the session's account changed at the same time; try again",
128
+ retryable: true,
129
+ outcomeUnknown: false,
130
+ details: { reason: "binding_busy" },
131
+ });
132
+ case "changed":
133
+ // Waiters recheck on their own bounded timer; a lost wake only delays.
134
+ await deliverSubscriptionCoreProviderWakes(deps.db, result.wakes);
135
+ await publishDurableSessionEvents(deps.bus, workspaceId, sessionId, result.events);
136
+ break;
137
+ case "unchanged":
138
+ break;
139
+ }
140
+ return c.json(
141
+ SetSessionModelAccountChoiceResponse.parse({
142
+ changed: result.outcome === "changed",
143
+ appliedTo: result.appliedTo,
144
+ provider: result.provider,
145
+ connectionId: result.connectionId,
146
+ choice: parsed.data.connectionId === null ? "automatic" : "explicit",
147
+ }),
148
+ );
149
+ });
150
+
151
+ const preferencesPath = "/v1/organizations/:organizationId/me/model-account-preferences";
152
+
153
+ app.get(preferencesPath, async (c) => {
154
+ c.header("cache-control", "private, no-store");
155
+ const person = await requireOrganizationPerson(c, deps, false);
156
+ const preferences = await readSubscriptionPersonPreferences(deps.db, {
157
+ accountId: person.organizationId,
158
+ subjectId: person.subjectId,
159
+ });
160
+ if (!preferences) throw new HTTPException(404, { message: "organization not found" });
161
+ return c.json(ModelAccountPreferences.parse(preferences));
162
+ });
163
+
164
+ app.patch(preferencesPath, async (c) => {
165
+ const person = await requireOrganizationPerson(c, deps, true);
166
+ const parsed = UpdateModelAccountPreferencesRequest.safeParse(await jsonBody(c));
167
+ if (!parsed.success) {
168
+ throw new HTTPException(422, { message: "invalid model account preferences" });
169
+ }
170
+ const result = await writeSubscriptionPersonPreferences(deps.db, {
171
+ accountId: person.organizationId,
172
+ subjectId: person.subjectId,
173
+ personalFallbackOptIn: parsed.data.personalFallbackOptIn,
174
+ ...(parsed.data.expectedVersion === undefined
175
+ ? {}
176
+ : { expectedVersion: parsed.data.expectedVersion }),
177
+ });
178
+ if (result.outcome === "not_member") {
179
+ throw new HTTPException(404, { message: "organization not found" });
180
+ }
181
+ if (result.outcome === "conflict") {
182
+ throw new ApiHttpError(409, {
183
+ code: "conflict",
184
+ message: "your preferences changed in the meantime; reload and try again",
185
+ retryable: false,
186
+ outcomeUnknown: false,
187
+ details: { reason: "version_conflict", currentVersion: result.preferences.version },
188
+ });
189
+ }
190
+ // Waiters recheck on their own bounded timer; a lost wake only delays.
191
+ await deliverSubscriptionCoreProviderWakes(deps.db, result.wakes);
192
+ return c.json(ModelAccountPreferences.parse(result.preferences));
193
+ });
194
+ }