@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.
- package/dist/access-grant-rls.d.ts +8 -1
- package/dist/admission-trace.d.ts +8 -0
- package/dist/app.d.ts +50 -3
- package/dist/app.js +10 -1
- package/dist/artifact-catalog-cursor.d.ts +1 -0
- package/dist/attached-browser-viewer.d.ts +11 -0
- package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
- package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
- package/dist/auth/managed-auth.d.ts +72 -5
- package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
- package/dist/auth/new-signups-gate.d.ts +23 -0
- package/dist/auth/signup-funnel-metrics.d.ts +44 -0
- package/dist/azure-live.d.ts +28 -0
- package/dist/browser-action-fences.d.ts +13 -0
- package/dist/browser-controller-authority.d.ts +1 -61
- package/dist/browser-ephemeral.d.ts +5 -0
- package/dist/browser-lost-runtime-end.d.ts +24 -0
- package/dist/browser-state-authority.d.ts +1 -27
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.js.map +1 -0
- package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
- package/dist/chunk-OT56OY4V.js.map +1 -0
- package/dist/claude-default-models.d.ts +19 -0
- package/dist/claude-subscription-core.d.ts +50 -0
- package/dist/claude-subscription-oauth.d.ts +36 -0
- package/dist/claude-subscription-profile.d.ts +9 -0
- package/dist/claude-subscription-usage.d.ts +6 -0
- package/dist/claude-workspace-connection.d.ts +15 -0
- package/dist/codemode.d.ts +40 -5
- package/dist/codex-realtime.d.ts +29 -3
- package/dist/codex-session-pointers.d.ts +19 -0
- package/dist/connection-ownership.d.ts +6 -3
- package/dist/controller-data-plane.d.ts +16 -0
- package/dist/credit-promotion-snapshot.d.ts +6 -0
- package/dist/editable-artifact-source-session.d.ts +3 -0
- package/dist/editable-artifact-websocket.d.ts +5 -3
- package/dist/fatal-process-boundary.d.ts +9 -1
- package/dist/github-access.d.ts +7 -1
- package/dist/github-browser-flow.d.ts +1 -1
- package/dist/http/acting-person.d.ts +36 -0
- package/dist/http/api-contract-compat.d.ts +19 -0
- package/dist/http/api-error.d.ts +50 -1
- package/dist/http/auth.d.ts +8 -1
- package/dist/http/cors.d.ts +12 -0
- package/dist/http/deprecation.d.ts +42 -0
- package/dist/http/keyed-admission.d.ts +12 -0
- package/dist/http/local-browser-boundary.d.ts +72 -0
- package/dist/http/metrics-listener.d.ts +22 -0
- package/dist/http/path-identifier.d.ts +17 -0
- package/dist/http/registered-route-label.d.ts +16 -0
- package/dist/http/rejection-telemetry.d.ts +34 -0
- package/dist/http/request-body.d.ts +27 -0
- package/dist/http/request-source.d.ts +41 -3
- package/dist/http/sse.d.ts +12 -1
- package/dist/http/unmatched-route.d.ts +18 -0
- package/dist/http/user-content.d.ts +36 -0
- package/dist/http/variable-sets-removed.d.ts +41 -0
- package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
- package/dist/index.js +1279 -108
- package/dist/index.js.map +1 -1
- package/dist/integration-connect-metrics.d.ts +35 -0
- package/dist/integration-endpoint-test.d.ts +20 -0
- package/dist/integrations/api-integrations.d.ts +2 -2
- package/dist/integrations/atlassian.d.ts +8 -3
- package/dist/integrations/fiken.d.ts +3 -1
- package/dist/integrations/github-lens-connect.d.ts +37 -66
- package/dist/integrations/google-drive.d.ts +2 -0
- package/dist/integrations/integration-commit-authority.d.ts +13 -0
- package/dist/integrations/marketplace-plugin.d.ts +43 -43
- package/dist/integrations/oauth-client.d.ts +171 -12
- package/dist/integrations/oauth-profiles.d.ts +42 -13
- package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
- package/dist/integrations/slack-bot.d.ts +285 -7
- package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
- package/dist/integrations/slack-interactions.d.ts +89 -10
- package/dist/integrations/slack-mrkdwn.d.ts +41 -0
- package/dist/integrations/slack-routing.d.ts +1 -1
- package/dist/integrations/slack-session-defaults.d.ts +58 -0
- package/dist/integrations/slack-task-file-upload.d.ts +36 -0
- package/dist/integrations/slack-tool-review.d.ts +5 -0
- package/dist/interaction-agent-access.d.ts +13 -8
- package/dist/interaction-agent-version.d.ts +21 -0
- package/dist/interaction-holder-heartbeat.d.ts +5 -0
- package/dist/interaction-metrics.d.ts +27 -2
- package/dist/interaction-route-stages.d.ts +25 -0
- package/dist/interaction-secrets-vault.d.ts +20 -0
- package/dist/interaction-secrets.d.ts +103 -0
- package/dist/mcp/action-catalog-types.d.ts +14 -0
- package/dist/mcp/action-catalog.gen.d.ts +2 -0
- package/dist/mcp/action-descriptions.d.ts +4 -0
- package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
- package/dist/mcp/capability-account-readiness.d.ts +7 -0
- package/dist/mcp/child-read-evidence.d.ts +9 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
- package/dist/mcp/contract-input.d.ts +13 -0
- package/dist/mcp/documents.d.ts +2 -0
- package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
- package/dist/mcp/notification-tools.d.ts +26 -0
- package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
- package/dist/mcp/scheduled-task-input.d.ts +1309 -0
- package/dist/mcp/scheduled-task-view.d.ts +217 -3
- package/dist/mcp/secret-tools.d.ts +14 -0
- package/dist/mcp/server.d.ts +108 -5
- package/dist/mcp/session-admin-access-tools.d.ts +33 -0
- package/dist/mcp/session-event-errors.d.ts +28 -0
- package/dist/mcp/session-event-view.d.ts +62 -0
- package/dist/mcp/session-view.d.ts +15 -0
- package/dist/mcp/session-wait.d.ts +18 -0
- package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
- package/dist/mcp/site-data-tools.d.ts +22 -0
- package/dist/mcp/site-publication-tools.d.ts +19 -0
- package/dist/mcp/site-sql-tools.d.ts +27 -0
- package/dist/mcp-oauth.d.ts +37 -4
- package/dist/model-calls/chat-completions.d.ts +87 -0
- package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
- package/dist/model-calls/service.d.ts +36 -0
- package/dist/model-catalog.d.ts +9 -3
- package/dist/native-push-dispatch.d.ts +69 -0
- package/dist/observability.d.ts +3 -1
- package/dist/organization-mcp.d.ts +82 -0
- package/dist/prepared-mcp-actor.d.ts +77 -0
- package/dist/prepared-mcp-permissions.d.ts +8 -0
- package/dist/routes/analytics-consent.d.ts +26 -0
- package/dist/routes/api-integrations.d.ts +11 -0
- package/dist/routes/api-keys.d.ts +7 -7
- package/dist/routes/automations.d.ts +2 -0
- package/dist/routes/billing.d.ts +59 -0
- package/dist/routes/browser-sessions.d.ts +65 -2
- package/dist/routes/chat-completions.d.ts +11 -0
- package/dist/routes/claude-core-usage.d.ts +20 -0
- package/dist/routes/claude-subscription-accounts.d.ts +3 -0
- package/dist/routes/claude-subscription-oauth.d.ts +3 -0
- package/dist/routes/client-errors.d.ts +182 -0
- package/dist/routes/codex-core.d.ts +401 -0
- package/dist/routes/codex.d.ts +64 -2
- package/dist/routes/computer-sessions.d.ts +6 -1
- package/dist/routes/desktop-distribution.d.ts +32 -0
- package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
- package/dist/routes/github-browser-pages.d.ts +27 -0
- package/dist/routes/inbox.d.ts +13 -0
- package/dist/routes/insights-response-cache.d.ts +10 -0
- package/dist/routes/insights-usage.d.ts +12 -0
- package/dist/routes/insights.d.ts +28 -0
- package/dist/routes/interaction-placement-message.d.ts +7 -0
- package/dist/routes/managed-sign-in-methods.d.ts +6 -0
- package/dist/routes/model-account-choice.d.ts +13 -0
- package/dist/routes/model-account-settings.d.ts +19 -0
- package/dist/routes/native-app-auth.d.ts +12 -0
- package/dist/routes/organization-integration-policy.d.ts +8 -0
- package/dist/routes/organization-integrations.d.ts +6 -0
- package/dist/routes/organization-mcp-connections.d.ts +3 -0
- package/dist/routes/organization-model-defaults.d.ts +9 -0
- package/dist/routes/organization-service-accounts.d.ts +3 -0
- package/dist/routes/personal-api-keys.d.ts +3 -0
- package/dist/routes/session-admin-access.d.ts +3 -0
- package/dist/routes/session-artifact-associations.d.ts +4 -0
- package/dist/routes/session-history-imports.d.ts +20 -0
- package/dist/routes/sessions.d.ts +38 -2
- package/dist/routes/site-data.d.ts +18 -0
- package/dist/routes/site-publishing.d.ts +5 -0
- package/dist/routes/site-runtime.d.ts +31 -0
- package/dist/routes/site-sql.d.ts +16 -0
- package/dist/routes/slack-bot-access.d.ts +3 -0
- package/dist/routes/subscription-account-pools.d.ts +21 -0
- package/dist/routes/subscription-core-http.d.ts +5 -0
- package/dist/routes/subscription-pool-access.d.ts +37 -0
- package/dist/routes/subscription-pool-core.d.ts +153 -0
- package/dist/routes/supergrok.d.ts +6 -6
- package/dist/routes/usage-allowances.d.ts +12 -0
- package/dist/routes/variable-sets-removed.d.ts +2 -0
- package/dist/routes/vault-providers.d.ts +34 -0
- package/dist/routes/vaults.d.ts +3 -0
- package/dist/routes/workspace-integrations.d.ts +35 -0
- package/dist/routes/workspace-model-providers.d.ts +4 -0
- package/dist/routes/workspaces.d.ts +11 -2
- package/dist/sandbox/agent-update.d.ts +64 -0
- package/dist/sandbox/auth-callout.d.ts +8 -0
- package/dist/sandbox/channel-a.d.ts +15 -1
- package/dist/sandbox/enrollment.d.ts +26 -4
- package/dist/sandbox/machine-audience.d.ts +29 -0
- package/dist/sandbox/machines.d.ts +15 -2
- package/dist/sandbox/metrics-ingestion.d.ts +6 -2
- package/dist/sandbox/screen-control.d.ts +85 -0
- package/dist/sandbox/viewer.d.ts +5 -1
- package/dist/sandbox-file-artifacts.d.ts +17 -1
- package/dist/scheduled-task-blockers.d.ts +39 -0
- package/dist/scheduled-task-deletion.d.ts +3 -4
- package/dist/scheduled-task-lifecycle.d.ts +14 -0
- package/dist/secret-answers.d.ts +40 -0
- package/dist/session-create-observability.d.ts +5 -0
- package/dist/session-event-view-36GO3IL7.js +528 -0
- package/dist/session-event-view-36GO3IL7.js.map +1 -0
- package/dist/signed-state-secret.d.ts +18 -0
- package/dist/site-agent-guard.d.ts +53 -0
- package/dist/site-data/operations.d.ts +103 -0
- package/dist/site-data/service.d.ts +203 -0
- package/dist/site-frame-guard.d.ts +32 -0
- package/dist/site-publishing/agent-data-tools.d.ts +84 -0
- package/dist/site-publishing/agent-model.d.ts +58 -0
- package/dist/site-publishing/agent-session.d.ts +16 -0
- package/dist/site-publishing/content-scanner.d.ts +31 -0
- package/dist/site-publishing/edge-sync.d.ts +48 -0
- package/dist/site-publishing/gateway-signature.d.ts +56 -0
- package/dist/site-publishing/limits.d.ts +63 -0
- package/dist/site-publishing/page-tool-authority.d.ts +30 -0
- package/dist/site-publishing/platform-usage.d.ts +113 -0
- package/dist/site-publishing/platform.d.ts +21 -0
- package/dist/site-publishing/readiness.d.ts +62 -0
- package/dist/site-publishing/runtime.d.ts +179 -0
- package/dist/site-publishing/service.d.ts +264 -0
- package/dist/site-publishing/session-events.d.ts +22 -0
- package/dist/site-publishing/session-views.d.ts +36 -0
- package/dist/site-publishing/viewer.d.ts +40 -0
- package/dist/site-session-origin.d.ts +31 -6
- package/dist/site-sql/format.d.ts +47 -0
- package/dist/site-sql/gateway.d.ts +50 -0
- package/dist/site-sql/service.d.ts +213 -0
- package/dist/temporal-schedule-sync.d.ts +26 -0
- package/dist/transcription/billing-refusal.d.ts +8 -0
- package/dist/transcription/normalize.d.ts +23 -0
- package/dist/transcription/providers/azure-mai.d.ts +12 -0
- package/dist/transcription/providers/azure-openai.d.ts +4 -0
- package/dist/transcription/providers/openai.d.ts +16 -0
- package/dist/transcription/providers/subscription-core.d.ts +39 -0
- package/dist/transcription/service.d.ts +10 -1
- package/dist/transcription/wav-duration.d.ts +8 -0
- package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
- package/dist/workspace-tool-gateway-observability.d.ts +16 -0
- package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
- package/dist/workspace-tool-gateway.d.ts +102 -6
- package/dist/workspace-tool-target-fence.d.ts +116 -0
- package/dist/workspace-tool-target.d.ts +225 -0
- package/dist/workspace-webhook-dispatch.d.ts +26 -0
- package/dist/xai-subscription-core.d.ts +60 -0
- package/package.json +25 -20
- package/src/access-grant-rls.ts +64 -14
- package/src/admission-trace.ts +14 -0
- package/src/app.ts +1684 -252
- package/src/artifact-catalog-cursor.ts +1 -0
- package/src/attached-browser-viewer.ts +26 -0
- package/src/auth/managed-auth-attempt-context.ts +9 -0
- package/src/auth/managed-auth-rate-limits.ts +252 -0
- package/src/auth/managed-auth-session-adapter.ts +64 -29
- package/src/auth/managed-auth.ts +303 -35
- package/src/auth/managed-email.ts +18 -1
- package/src/auth/managed-sign-in-notifications.ts +81 -0
- package/src/auth/new-signups-gate.ts +49 -0
- package/src/auth/organization-user-setup.ts +3 -3
- package/src/auth/signup-funnel-metrics.ts +164 -0
- package/src/azure-live.ts +103 -0
- package/src/browser-action-fences.ts +45 -0
- package/src/browser-controller-authority.ts +1 -186
- package/src/browser-ephemeral.ts +39 -0
- package/src/browser-lost-runtime-end.ts +71 -0
- package/src/browser-state-authority.ts +1 -236
- package/src/claude-default-models.ts +37 -0
- package/src/claude-subscription-core.ts +154 -0
- package/src/claude-subscription-oauth.ts +352 -0
- package/src/claude-subscription-profile.ts +73 -0
- package/src/claude-subscription-usage.ts +51 -0
- package/src/claude-workspace-connection.ts +82 -0
- package/src/codemode.ts +236 -39
- package/src/codex-realtime.ts +181 -53
- package/src/codex-session-pointers.ts +80 -0
- package/src/company-brain-okf.ts +1 -1
- package/src/connected-machine-computer-access.ts +2 -1
- package/src/connection-ownership.ts +19 -13
- package/src/controller-data-plane.ts +34 -0
- package/src/credit-promotion-snapshot.ts +36 -0
- package/src/editable-artifact-production.ts +10 -0
- package/src/editable-artifact-source-session.ts +123 -0
- package/src/editable-artifact-websocket.ts +16 -3
- package/src/fatal-process-boundary.ts +67 -3
- package/src/gateway-realtime.ts +12 -8
- package/src/github-access.ts +31 -5
- package/src/github-browser-flow.ts +1 -1
- package/src/http/acting-person.ts +105 -0
- package/src/http/api-contract-compat.ts +49 -0
- package/src/http/api-error.ts +210 -2
- package/src/http/auth.ts +68 -4
- package/src/http/cors.ts +37 -5
- package/src/http/deprecation.ts +118 -0
- package/src/http/keyed-admission.ts +29 -0
- package/src/http/local-browser-boundary.ts +343 -0
- package/src/http/metrics-listener.ts +57 -0
- package/src/http/path-identifier.ts +54 -0
- package/src/http/registered-route-label.ts +34 -0
- package/src/http/rejection-telemetry.ts +120 -0
- package/src/http/request-body.ts +127 -0
- package/src/http/request-source.ts +154 -13
- package/src/http/sse.ts +88 -28
- package/src/http/unmatched-route.ts +60 -0
- package/src/http/user-content.ts +158 -0
- package/src/http/variable-sets-removed.ts +122 -0
- package/src/http/websocket-upgrade-dispatch.ts +29 -0
- package/src/index.ts +107 -57
- package/src/integration-connect-metrics.ts +228 -0
- package/src/integration-endpoint-test.ts +291 -0
- package/src/integrations/api-integrations.ts +81 -7
- package/src/integrations/atlassian.ts +202 -83
- package/src/integrations/fiken.ts +66 -38
- package/src/integrations/github-app-connect.ts +64 -18
- package/src/integrations/github-lens-connect.ts +8 -29
- package/src/integrations/google-drive.ts +448 -152
- package/src/integrations/integration-commit-authority.ts +69 -0
- package/src/integrations/marketplace-plugin.ts +1 -1
- package/src/integrations/oauth-client.ts +733 -193
- package/src/integrations/oauth-profiles.ts +116 -45
- package/src/integrations/onepassword-vault-provider.ts +16 -0
- package/src/integrations/personal-github-repositories.ts +1 -1
- package/src/integrations/personal-github.ts +61 -35
- package/src/integrations/provider-oauth.ts +67 -85
- package/src/integrations/slack-app-home.ts +5 -5
- package/src/integrations/slack-bot.ts +893 -201
- package/src/integrations/slack-file-upload-flow.ts +147 -0
- package/src/integrations/slack-install.ts +7 -7
- package/src/integrations/slack-interactions.ts +1589 -299
- package/src/integrations/slack-mrkdwn.ts +193 -0
- package/src/integrations/slack-routing.ts +2 -2
- package/src/integrations/slack-session-defaults.ts +224 -0
- package/src/integrations/slack-task-file-upload.ts +323 -0
- package/src/integrations/slack-tool-review.ts +65 -0
- package/src/integrations/social-oauth.ts +90 -58
- package/src/interaction-agent-access.ts +40 -20
- package/src/interaction-agent-version.ts +85 -0
- package/src/interaction-holder-heartbeat.ts +24 -8
- package/src/interaction-metrics.ts +164 -2
- package/src/interaction-route-stages.ts +94 -0
- package/src/interaction-secrets-vault.ts +213 -0
- package/src/interaction-secrets.ts +426 -0
- package/src/mcp/action-catalog-types.ts +14 -0
- package/src/mcp/action-catalog.gen.ts +8014 -0
- package/src/mcp/action-descriptions.ts +299 -0
- package/src/mcp/action-schema-imports.gen.ts +304 -0
- package/src/mcp/capability-account-readiness.ts +17 -0
- package/src/mcp/child-read-evidence.ts +19 -0
- package/src/mcp/company-profile-agent-admin.ts +13 -0
- package/src/mcp/contract-input.ts +165 -0
- package/src/mcp/documents.ts +9 -2
- package/src/mcp/editable-artifacts.ts +29 -11
- package/src/mcp/files.ts +5 -1
- package/src/mcp/first-party-tool-permissions.ts +7 -285
- package/src/mcp/knowledge-entries.ts +108 -34
- package/src/mcp/notification-tools.ts +480 -0
- package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
- package/src/mcp/scheduled-task-input.ts +89 -0
- package/src/mcp/scheduled-task-view.ts +63 -3
- package/src/mcp/secret-tools.ts +185 -0
- package/src/mcp/server.ts +2213 -1116
- package/src/mcp/session-admin-access-tools.ts +163 -0
- package/src/mcp/session-event-errors.ts +123 -0
- package/src/mcp/session-event-view.ts +395 -13
- package/src/mcp/session-view.ts +3 -0
- package/src/mcp/session-wait.ts +67 -7
- package/src/mcp/site-agent-clamp-tools.ts +140 -0
- package/src/mcp/site-data-tools.ts +339 -0
- package/src/mcp/site-publication-tools.ts +201 -0
- package/src/mcp/site-sql-tools.ts +427 -0
- package/src/mcp-oauth.ts +635 -45
- package/src/model-calls/chat-completions.ts +352 -0
- package/src/model-calls/pending-usage-settlements.ts +125 -0
- package/src/model-calls/service.ts +694 -0
- package/src/model-catalog.ts +68 -17
- package/src/native-push-dispatch.ts +457 -0
- package/src/observability.ts +15 -1
- package/src/organization-mcp.ts +485 -0
- package/src/prepared-mcp-actor.ts +154 -0
- package/src/prepared-mcp-permissions.ts +38 -0
- package/src/routes/analytics-consent.ts +123 -0
- package/src/routes/api-integrations.ts +268 -9
- package/src/routes/api-keys.ts +164 -25
- package/src/routes/artifact-catalog.ts +111 -0
- package/src/routes/automations.ts +163 -90
- package/src/routes/billing.ts +535 -59
- package/src/routes/browser-sessions.ts +966 -342
- package/src/routes/canonical-human-identities.ts +61 -0
- package/src/routes/capabilities.ts +112 -5
- package/src/routes/channels.ts +4 -3
- package/src/routes/chat-completions.ts +235 -0
- package/src/routes/claude-core-usage.ts +147 -0
- package/src/routes/claude-subscription-accounts.ts +233 -0
- package/src/routes/claude-subscription-oauth.ts +175 -0
- package/src/routes/client-errors.ts +394 -0
- package/src/routes/codex-core.ts +687 -0
- package/src/routes/codex.ts +1277 -1119
- package/src/routes/company-brain.ts +4 -0
- package/src/routes/computer-sessions.ts +319 -85
- package/src/routes/connect.ts +277 -175
- package/src/routes/connections.ts +690 -363
- package/src/routes/desktop-distribution.ts +217 -0
- package/src/routes/documents.ts +13 -7
- package/src/routes/editable-artifacts.ts +74 -4
- package/src/routes/enrollments.ts +110 -16
- package/src/routes/external-identity-links.ts +13 -12
- package/src/routes/files.ts +41 -16
- package/src/routes/github-browser-fonts.gen.ts +12 -0
- package/src/routes/github-browser-pages.ts +258 -0
- package/src/routes/github.ts +200 -75
- package/src/routes/inbox.ts +353 -0
- package/src/routes/insights-response-cache.ts +83 -0
- package/src/routes/insights-usage.ts +345 -0
- package/src/routes/insights.ts +103 -8
- package/src/routes/install.ts +51 -10
- package/src/routes/integration-facets.ts +70 -28
- package/src/routes/interaction-placement-message.ts +12 -0
- package/src/routes/knowledge.ts +136 -27
- package/src/routes/machines.ts +189 -135
- package/src/routes/managed-auth-session-sets.ts +43 -10
- package/src/routes/managed-onboarding.ts +39 -19
- package/src/routes/managed-sign-in-methods.ts +433 -0
- package/src/routes/memory-slack-publications.ts +3 -2
- package/src/routes/model-account-choice.ts +194 -0
- package/src/routes/model-account-settings.ts +235 -0
- package/src/routes/model-connection-access.ts +210 -48
- package/src/routes/native-app-auth.ts +296 -0
- package/src/routes/organization-integration-policy.ts +116 -0
- package/src/routes/organization-integrations.ts +326 -0
- package/src/routes/organization-mcp-connections.ts +183 -0
- package/src/routes/organization-memberships.ts +205 -19
- package/src/routes/organization-model-defaults.ts +110 -0
- package/src/routes/organization-model-providers.ts +74 -3
- package/src/routes/organization-service-accounts.ts +128 -0
- package/src/routes/organization-sessions.ts +21 -5
- package/src/routes/personal-api-keys.ts +184 -0
- package/src/routes/personal-github-git-broker.ts +2 -2
- package/src/routes/personal-github.ts +9 -4
- package/src/routes/plugins.ts +46 -7
- package/src/routes/pr-review-github.ts +105 -118
- package/src/routes/pr-review.ts +88 -82
- package/src/routes/preference-registry.ts +18 -0
- package/src/routes/rigs.ts +48 -13
- package/src/routes/scheduled-tasks.ts +347 -27
- package/src/routes/session-admin-access.ts +271 -0
- package/src/routes/session-artifact-associations.ts +164 -0
- package/src/routes/session-history-imports.ts +305 -0
- package/src/routes/sessions.ts +1682 -363
- package/src/routes/site-data.ts +340 -0
- package/src/routes/site-publishing.ts +584 -0
- package/src/routes/site-runtime.ts +1944 -0
- package/src/routes/site-sql.ts +263 -0
- package/src/routes/skill-content.ts +72 -7
- package/src/routes/skills.ts +5 -4
- package/src/routes/slack-bot-access.ts +108 -0
- package/src/routes/social.ts +27 -15
- package/src/routes/subscription-account-pools.ts +209 -0
- package/src/routes/subscription-core-http.ts +18 -0
- package/src/routes/subscription-pool-access.ts +180 -0
- package/src/routes/subscription-pool-core.ts +552 -0
- package/src/routes/supergrok.ts +174 -655
- package/src/routes/transcription-recordings.ts +71 -4
- package/src/routes/transcriptions.ts +26 -2
- package/src/routes/usage-allowances.ts +381 -0
- package/src/routes/variable-sets-removed.ts +19 -0
- package/src/routes/vault-providers.ts +782 -0
- package/src/routes/vaults.ts +421 -0
- package/src/routes/video-generation.ts +30 -12
- package/src/routes/workspace-artifacts.ts +165 -53
- package/src/routes/workspace-integrations.ts +576 -0
- package/src/routes/workspace-model-providers.ts +148 -0
- package/src/routes/workspace-state.ts +4 -0
- package/src/routes/workspaces.ts +625 -117
- package/src/sandbox/agent-update.ts +315 -0
- package/src/sandbox/auth-callout.ts +104 -21
- package/src/sandbox/channel-a.ts +165 -55
- package/src/sandbox/enrollment.ts +131 -22
- package/src/sandbox/machine-audience.ts +192 -0
- package/src/sandbox/machines.ts +75 -31
- package/src/sandbox/metrics-ingestion.ts +133 -2
- package/src/sandbox/rematerialize.ts +51 -21
- package/src/sandbox/screen-control.ts +289 -0
- package/src/sandbox/viewer.ts +33 -58
- package/src/sandbox-file-artifacts.ts +53 -27
- package/src/scheduled-task-blockers.ts +293 -0
- package/src/scheduled-task-deletion.ts +13 -3
- package/src/scheduled-task-lifecycle.ts +84 -0
- package/src/secret-answers.ts +119 -0
- package/src/session-create-observability.ts +46 -0
- package/src/session-realtime-context.ts +26 -4
- package/src/signed-state-secret.ts +58 -0
- package/src/site-agent-guard.ts +261 -0
- package/src/site-data/operations.ts +777 -0
- package/src/site-data/service.ts +1043 -0
- package/src/site-frame-guard.ts +107 -0
- package/src/site-publishing/agent-data-tools.ts +250 -0
- package/src/site-publishing/agent-model.ts +127 -0
- package/src/site-publishing/agent-session.ts +148 -0
- package/src/site-publishing/content-scanner.ts +93 -0
- package/src/site-publishing/edge-sync.ts +148 -0
- package/src/site-publishing/gateway-signature.ts +198 -0
- package/src/site-publishing/limits.ts +315 -0
- package/src/site-publishing/page-tool-authority.ts +111 -0
- package/src/site-publishing/platform-usage.ts +479 -0
- package/src/site-publishing/platform.ts +98 -0
- package/src/site-publishing/readiness.ts +330 -0
- package/src/site-publishing/runtime.ts +831 -0
- package/src/site-publishing/service.ts +1282 -0
- package/src/site-publishing/session-events.ts +262 -0
- package/src/site-publishing/session-views.ts +262 -0
- package/src/site-publishing/viewer.ts +75 -0
- package/src/site-session-origin.ts +91 -6
- package/src/site-sql/format.ts +134 -0
- package/src/site-sql/gateway.ts +168 -0
- package/src/site-sql/service.ts +1636 -0
- package/src/site-uploads.ts +27 -5
- package/src/temporal-schedule-sync.ts +74 -0
- package/src/transcription/billing-refusal.ts +14 -0
- package/src/transcription/normalize.ts +77 -0
- package/src/transcription/providers/azure-mai.ts +98 -0
- package/src/transcription/providers/azure-openai.ts +16 -7
- package/src/transcription/providers/codex-subscription.ts +190 -67
- package/src/transcription/providers/openai.ts +79 -5
- package/src/transcription/providers/subscription-core.ts +125 -0
- package/src/transcription/providers/xai-subscription.ts +81 -83
- package/src/transcription/segmenter.ts +7 -1
- package/src/transcription/service.ts +239 -10
- package/src/transcription/wav-duration.ts +39 -0
- package/src/workspace-deletion.ts +25 -1
- package/src/workspace-tool-gateway-attestations.ts +133 -0
- package/src/workspace-tool-gateway-observability.ts +64 -0
- package/src/workspace-tool-gateway-secrets.ts +104 -0
- package/src/workspace-tool-gateway.ts +921 -103
- package/src/workspace-tool-target-fence.ts +380 -0
- package/src/workspace-tool-target.ts +554 -0
- package/src/workspace-webhook-dispatch.ts +225 -0
- package/src/xai-realtime.ts +85 -81
- package/src/xai-subscription-core.ts +172 -0
- package/dist/browser-auth-broker.d.ts +0 -20
- package/dist/chunk-AJ62T5QN.js.map +0 -1
- package/dist/connection-authority-owner.d.ts +0 -59
- package/dist/routes/connection-authorities.d.ts +0 -3
- package/dist/routes/environments.d.ts +0 -5
- package/dist/routes/host-mcp-bindings.d.ts +0 -5
- package/dist/routes/host-mcp-resolvers.d.ts +0 -3
- package/dist/routes/packs.d.ts +0 -3
- package/dist/session-event-view-MU3HMNV3.js +0 -264
- package/dist/session-event-view-MU3HMNV3.js.map +0 -1
- package/dist/xai-subscription-auth.d.ts +0 -23
- package/src/browser-auth-broker.ts +0 -155
- package/src/connection-authority-owner.ts +0 -61
- package/src/routes/connection-authorities.ts +0 -139
- package/src/routes/environments.ts +0 -388
- package/src/routes/host-mcp-bindings.ts +0 -122
- package/src/routes/host-mcp-resolvers.ts +0 -41
- package/src/routes/packs.ts +0 -784
- 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 =
|
|
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 =
|
|
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
|
+
}
|