@opengeni/api-router 0.30.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-grant-rls.d.ts +3 -0
- package/dist/admission-trace.d.ts +8 -0
- package/dist/api-websocket.d.ts +18 -0
- package/dist/app.d.ts +50 -2
- package/dist/app.js +12 -1
- package/dist/artifact-catalog-cursor.d.ts +27 -0
- package/dist/auth/managed-auth-attempt-context.d.ts +10 -0
- package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +6 -0
- package/dist/auth/managed-auth.d.ts +102 -3
- package/dist/auth/managed-email.d.ts +29 -0
- package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
- package/dist/auth/new-signups-gate.d.ts +23 -0
- package/dist/auth/organization-user-setup.d.ts +80 -0
- package/dist/auth/signup-funnel-metrics.d.ts +44 -0
- package/dist/browser-controller-authority.d.ts +1 -61
- package/dist/browser-ephemeral.d.ts +5 -0
- package/dist/browser-state-authority.d.ts +1 -27
- package/dist/chunk-6TZ5LG3O.js +123948 -0
- package/dist/chunk-6TZ5LG3O.js.map +1 -0
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.js.map +1 -0
- package/dist/claude-subscription-account-conflicts.d.ts +1 -0
- package/dist/claude-subscription-account-usage.d.ts +39 -0
- package/dist/claude-subscription-oauth.d.ts +25 -0
- package/dist/claude-subscription-profile.d.ts +9 -0
- package/dist/claude-subscription-usage.d.ts +44 -0
- package/dist/claude-workspace-connection.d.ts +15 -0
- package/dist/codemode.d.ts +32 -1
- package/dist/company-brain-okf.d.ts +24 -0
- package/dist/connected-machine-computer-access.d.ts +11 -0
- package/dist/connection-ownership.d.ts +54 -0
- package/dist/controller-data-plane.d.ts +32 -0
- package/dist/editable-artifact-source-session.d.ts +3 -0
- package/dist/editable-artifact-websocket.d.ts +10 -18
- package/dist/editable-artifact-workspace-files.d.ts +1 -1
- package/dist/fatal-process-boundary.d.ts +25 -0
- package/dist/github-access.d.ts +31 -2
- package/dist/http/acting-person.d.ts +24 -0
- package/dist/http/api-contract-compat.d.ts +19 -0
- package/dist/http/api-error.d.ts +27 -1
- package/dist/http/cors.d.ts +17 -0
- package/dist/http/deprecation.d.ts +42 -0
- package/dist/http/interaction-control-error.d.ts +13 -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/request-body.d.ts +27 -0
- package/dist/http/request-source.d.ts +52 -0
- package/dist/http/sse.d.ts +17 -6
- package/dist/http/unmatched-route.d.ts +18 -0
- package/dist/http/user-content.d.ts +36 -0
- package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.js +1091 -162
- package/dist/index.js.map +1 -1
- package/dist/integration-endpoint-test.d.ts +20 -0
- package/dist/integrations/api-integrations.d.ts +2 -2
- package/dist/integrations/atlassian.d.ts +29 -3
- package/dist/integrations/connect-authority.d.ts +1 -0
- package/dist/integrations/connect-callback-return.d.ts +6 -0
- package/dist/integrations/fiken.d.ts +16 -2
- package/dist/integrations/github-app-connect.d.ts +47 -0
- package/dist/integrations/github-installation-proof.d.ts +3 -0
- package/dist/integrations/github-lens-connect.d.ts +116 -0
- package/dist/integrations/github-skill-source.d.ts +1 -5
- package/dist/integrations/google-drive.d.ts +24 -0
- package/dist/integrations/integration-commit-authority.d.ts +13 -0
- package/dist/integrations/marketplace-plugin.d.ts +2691 -0
- package/dist/integrations/oauth-client.d.ts +178 -18
- package/dist/integrations/oauth-profiles.d.ts +222 -0
- package/dist/integrations/oauth-return-path.d.ts +1 -0
- package/dist/integrations/personal-github-repositories.d.ts +84 -0
- package/dist/integrations/personal-github.d.ts +42 -0
- package/dist/integrations/pr-review-provider.d.ts +22 -0
- package/dist/integrations/provider-oauth.d.ts +19 -1
- package/dist/integrations/slack-app-home.d.ts +24 -0
- package/dist/integrations/slack-bot.d.ts +367 -12
- package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
- package/dist/integrations/slack-install.d.ts +20 -0
- package/dist/integrations/slack-interactions.d.ts +107 -9
- package/dist/integrations/slack-mrkdwn.d.ts +41 -0
- package/dist/integrations/slack-routing.d.ts +120 -0
- package/dist/integrations/slack-session-defaults.d.ts +58 -0
- package/dist/integrations/slack-task-file-upload.d.ts +36 -0
- package/dist/integrations/social-oauth.d.ts +7 -0
- package/dist/interaction-agent-access.d.ts +15 -0
- package/dist/interaction-frame-proxy.d.ts +68 -0
- package/dist/interaction-metrics.d.ts +2 -0
- package/dist/mcp/action-catalog-types.d.ts +9 -0
- package/dist/mcp/action-catalog.gen.d.ts +2 -0
- package/dist/mcp/capability-account-readiness.d.ts +7 -0
- package/dist/mcp/child-read-evidence.d.ts +9 -0
- package/dist/mcp/command-read.d.ts +24 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
- package/dist/mcp/contract-input.d.ts +11 -0
- package/dist/mcp/documents.d.ts +7 -5
- package/dist/mcp/files.d.ts +2 -2
- package/dist/mcp/first-party-tool-permissions.d.ts +650 -0
- package/dist/mcp/knowledge-entries.d.ts +5 -0
- package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
- package/dist/mcp/receipts.d.ts +9 -0
- package/dist/mcp/request-abort.d.ts +19 -0
- package/dist/mcp/scheduled-task-input.d.ts +1189 -0
- package/dist/mcp/scheduled-task-view.d.ts +22 -4
- package/dist/mcp/server.d.ts +255 -3
- package/dist/mcp/session-event-view.d.ts +94 -0
- package/dist/mcp/session-view.d.ts +66 -2
- package/dist/mcp/session-wait.d.ts +174 -0
- package/dist/mcp-oauth.d.ts +52 -0
- package/dist/model-catalog.d.ts +11 -31
- package/dist/observability.d.ts +3 -1
- package/dist/organization-mcp.d.ts +52 -0
- package/dist/organization-recovery-notifications.d.ts +41 -0
- package/dist/routes/analytics-consent.d.ts +26 -0
- package/dist/routes/api-integrations.d.ts +25 -0
- package/dist/routes/api-keys.d.ts +17 -0
- package/dist/routes/artifact-catalog.d.ts +6 -0
- package/dist/routes/automations.d.ts +19 -0
- package/dist/routes/billing.d.ts +49 -0
- package/dist/routes/browser-sessions.d.ts +59 -2
- 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 +146 -0
- package/dist/routes/codex.d.ts +76 -2
- package/dist/routes/company-brain.d.ts +3 -0
- package/dist/routes/company-profile.d.ts +2 -1
- package/dist/routes/computer-sessions.d.ts +14 -0
- package/dist/routes/connect.d.ts +5 -0
- package/dist/routes/editable-artifacts.d.ts +2 -0
- package/dist/routes/external-identity-links.d.ts +6 -0
- package/dist/routes/feedback.d.ts +3 -0
- package/dist/routes/github-browser-pages.d.ts +12 -0
- package/dist/routes/github.d.ts +2 -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 +30 -1
- package/dist/routes/knowledge.d.ts +3 -0
- package/dist/routes/managed-auth-session-sets.d.ts +26 -0
- package/dist/routes/managed-onboarding.d.ts +29 -0
- package/dist/routes/managed-sign-in-methods.d.ts +6 -0
- package/dist/routes/model-connection-access.d.ts +3 -0
- package/dist/routes/organization-integration-policy.d.ts +3 -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-providers.d.ts +3 -0
- package/dist/routes/organization-recovery.d.ts +19 -0
- package/dist/routes/organization-service-accounts.d.ts +3 -0
- package/dist/routes/organization-sessions.d.ts +26 -0
- package/dist/routes/personal-github-git-broker.d.ts +29 -0
- package/dist/routes/personal-github.d.ts +3 -0
- package/dist/routes/pr-review-github.d.ts +3 -0
- package/dist/routes/pr-review.d.ts +3 -0
- package/dist/routes/session-artifact-associations.d.ts +4 -0
- package/dist/routes/session-history-imports.d.ts +9 -0
- package/dist/routes/sessions.d.ts +44 -6
- package/dist/routes/skill-content.d.ts +4 -0
- package/dist/routes/skill-install-authority.d.ts +6 -0
- package/dist/routes/subscription-account-pools.d.ts +34 -0
- package/dist/routes/subscription-pool-access.d.ts +16 -0
- package/dist/routes/supergrok.d.ts +6 -1
- package/dist/routes/usage-allowances.d.ts +12 -0
- package/dist/routes/user-resource-authorities.d.ts +3 -0
- package/dist/routes/workspace-artifacts.d.ts +2 -1
- package/dist/routes/workspace-capture.d.ts +10 -2
- package/dist/routes/workspace-integrations.d.ts +35 -0
- package/dist/routes/workspace-learning.d.ts +3 -0
- package/dist/routes/workspace-model-providers.d.ts +4 -0
- package/dist/routes/workspaces.d.ts +29 -0
- package/dist/sandbox/auth-callout.d.ts +8 -0
- package/dist/sandbox/channel-a.d.ts +19 -1
- package/dist/sandbox/connection-authority.d.ts +3 -0
- package/dist/sandbox/enrollment.d.ts +9 -1
- package/dist/sandbox/machines.d.ts +5 -2
- package/dist/sandbox/metrics-ingestion.d.ts +28 -20
- package/dist/sandbox/rematerialize.d.ts +2 -0
- package/dist/sandbox/session-attach-variable-sets.d.ts +30 -0
- package/dist/sandbox/viewer.d.ts +26 -1
- package/dist/sandbox-file-artifacts.d.ts +50 -0
- package/dist/scheduled-task-deletion.d.ts +13 -0
- package/dist/session-create-observability.d.ts +5 -0
- package/dist/session-event-view-MPS2OZD3.js +292 -0
- package/dist/session-event-view-MPS2OZD3.js.map +1 -0
- package/dist/site-session-origin.d.ts +13 -0
- package/dist/site-uploads.d.ts +41 -0
- package/dist/slack-reaction-files.d.ts +1 -1
- package/dist/temporal-schedule-cleanup.d.ts +1 -0
- package/dist/temporal-schedule-sync.d.ts +26 -0
- package/dist/transcription/providers/xai-subscription.d.ts +1 -0
- package/dist/transcription/service.d.ts +2 -1
- package/dist/work-discovery-observability.d.ts +33 -0
- package/dist/workspace-artifact-content.d.ts +28 -0
- package/dist/workspace-artifact-provenance.d.ts +7 -0
- package/dist/workspace-delete-observability.d.ts +10 -0
- package/dist/workspace-deletion.d.ts +6 -0
- package/dist/workspace-state-projection.d.ts +3 -5
- package/dist/workspace-tool-gateway-observability.d.ts +17 -0
- package/dist/workspace-tool-gateway.d.ts +123 -0
- package/dist/workspace-webhook-dispatch.d.ts +26 -0
- package/package.json +23 -19
- package/src/access-grant-rls.ts +75 -0
- package/src/admission-trace.ts +14 -0
- package/src/api-websocket.ts +23 -0
- package/src/app.ts +1967 -252
- package/src/artifact-catalog-cursor.ts +60 -0
- package/src/auth/managed-auth-attempt-context.ts +70 -0
- package/src/auth/managed-auth-rate-limits.ts +252 -0
- package/src/auth/managed-auth-session-adapter.ts +222 -0
- package/src/auth/managed-auth.ts +536 -60
- package/src/auth/managed-email.ts +174 -0
- 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 +307 -0
- package/src/auth/signup-funnel-metrics.ts +164 -0
- package/src/browser-controller-authority.ts +1 -186
- package/src/browser-ephemeral.ts +39 -0
- package/src/browser-state-authority.ts +1 -236
- package/src/claude-subscription-account-conflicts.ts +12 -0
- package/src/claude-subscription-account-usage.ts +48 -0
- package/src/claude-subscription-oauth.ts +362 -0
- package/src/claude-subscription-profile.ts +73 -0
- package/src/claude-subscription-usage.ts +97 -0
- package/src/claude-workspace-connection.ts +82 -0
- package/src/codemode.ts +194 -30
- package/src/codex-realtime.ts +8 -2
- package/src/company-brain-okf.ts +340 -0
- package/src/connected-machine-computer-access.ts +33 -0
- package/src/connection-ownership.ts +199 -0
- package/src/controller-data-plane.ts +81 -0
- package/src/editable-artifact-native-kernel.ts +26 -15
- package/src/editable-artifact-office-import.ts +28 -3
- package/src/editable-artifact-production.ts +23 -7
- package/src/editable-artifact-source-session.ts +123 -0
- package/src/editable-artifact-websocket.ts +27 -21
- package/src/editable-artifact-workspace-files.ts +31 -6
- package/src/fatal-process-boundary.ts +246 -0
- package/src/gateway-realtime.ts +1 -1
- package/src/github-access.ts +147 -5
- package/src/http/acting-person.ts +71 -0
- package/src/http/api-contract-compat.ts +49 -0
- package/src/http/api-error.ts +115 -1
- package/src/http/auth.ts +48 -0
- package/src/http/cors.ts +67 -0
- package/src/http/deprecation.ts +118 -0
- package/src/http/interaction-control-error.ts +164 -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/request-body.ts +127 -0
- package/src/http/request-source.ts +178 -0
- package/src/http/sse.ts +486 -132
- package/src/http/unmatched-route.ts +60 -0
- package/src/http/user-content.ts +158 -0
- package/src/http/websocket-upgrade-dispatch.ts +29 -0
- package/src/index.ts +157 -52
- package/src/integration-endpoint-test.ts +291 -0
- package/src/integrations/api-integrations.ts +98 -11
- package/src/integrations/atlassian.ts +474 -136
- package/src/integrations/connect-authority.ts +2 -0
- package/src/integrations/connect-callback-return.ts +86 -0
- package/src/integrations/fiken.ts +354 -64
- package/src/integrations/github-app-connect.ts +435 -0
- package/src/integrations/github-installation-proof.ts +60 -0
- package/src/integrations/github-lens-connect.ts +76 -0
- package/src/integrations/github-skill-source.ts +2 -142
- package/src/integrations/google-drive.ts +717 -225
- package/src/integrations/integration-commit-authority.ts +69 -0
- package/src/integrations/marketplace-plugin.ts +48 -0
- package/src/integrations/oauth-client.ts +1356 -459
- package/src/integrations/oauth-profiles.ts +537 -0
- package/src/integrations/oauth-return-path.ts +18 -0
- package/src/integrations/personal-github-repositories.ts +674 -0
- package/src/integrations/personal-github.ts +825 -0
- package/src/integrations/pr-review-provider.ts +246 -0
- package/src/integrations/provider-oauth.ts +250 -22
- package/src/integrations/slack-app-home.ts +300 -0
- package/src/integrations/slack-bot.ts +963 -239
- package/src/integrations/slack-file-upload-flow.ts +147 -0
- package/src/integrations/slack-install.ts +83 -0
- package/src/integrations/slack-interactions.ts +3167 -474
- package/src/integrations/slack-mrkdwn.ts +193 -0
- package/src/integrations/slack-routing.ts +337 -0
- package/src/integrations/slack-session-defaults.ts +224 -0
- package/src/integrations/slack-task-file-upload.ts +323 -0
- package/src/integrations/social-oauth.ts +213 -15
- package/src/interaction-agent-access.ts +48 -0
- package/src/interaction-frame-proxy.ts +409 -0
- package/src/interaction-metrics.ts +30 -0
- package/src/mcp/action-catalog-types.ts +9 -0
- package/src/mcp/action-catalog.gen.ts +6696 -0
- package/src/mcp/capability-account-readiness.ts +17 -0
- package/src/mcp/child-read-evidence.ts +19 -0
- package/src/mcp/command-read.ts +109 -0
- package/src/mcp/company-profile-agent-admin.ts +198 -0
- package/src/mcp/contract-input.ts +141 -0
- package/src/mcp/documents.ts +65 -377
- package/src/mcp/editable-artifacts.ts +12 -6
- package/src/mcp/files.ts +80 -43
- package/src/mcp/first-party-tool-permissions.ts +305 -0
- package/src/mcp/knowledge-entries.ts +322 -0
- package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
- package/src/mcp/receipts.ts +34 -0
- package/src/mcp/request-abort.ts +44 -0
- package/src/mcp/scheduled-task-input.ts +76 -0
- package/src/mcp/scheduled-task-view.ts +44 -3
- package/src/mcp/server.ts +3030 -1267
- package/src/mcp/session-event-view.ts +383 -0
- package/src/mcp/session-view.ts +84 -3
- package/src/mcp/session-wait.ts +665 -0
- package/src/mcp-oauth.ts +1123 -0
- package/src/model-catalog.ts +91 -333
- package/src/observability.ts +15 -1
- package/src/organization-mcp.ts +397 -0
- package/src/organization-recovery-notifications.ts +103 -0
- package/src/routes/analytics-consent.ts +123 -0
- package/src/routes/api-integrations.ts +364 -74
- package/src/routes/api-keys.ts +336 -10
- package/src/routes/artifact-catalog.ts +279 -0
- package/src/routes/automations.ts +768 -0
- package/src/routes/billing.ts +461 -46
- package/src/routes/browser-sessions.ts +780 -112
- package/src/routes/canonical-human-identities.ts +90 -14
- package/src/routes/capabilities.ts +107 -6
- package/src/routes/channels.ts +20 -3
- package/src/routes/claude-subscription-accounts.ts +334 -0
- package/src/routes/claude-subscription-oauth.ts +142 -0
- package/src/routes/client-errors.ts +362 -0
- package/src/routes/codex.ts +833 -116
- package/src/routes/company-brain.ts +322 -0
- package/src/routes/company-profile.ts +65 -1
- package/src/routes/computer-sessions.ts +557 -106
- package/src/routes/connect.ts +1938 -0
- package/src/routes/connections.ts +1039 -349
- package/src/routes/documents.ts +488 -287
- package/src/routes/editable-artifacts.ts +79 -9
- package/src/routes/enrollments.ts +135 -39
- package/src/routes/environments.ts +154 -58
- package/src/routes/external-identity-links.ts +201 -0
- package/src/routes/feedback.ts +113 -0
- package/src/routes/files.ts +267 -33
- package/src/routes/github-browser-pages.ts +162 -0
- package/src/routes/github.ts +446 -144
- package/src/routes/insights-response-cache.ts +83 -0
- package/src/routes/insights-usage.ts +345 -0
- package/src/routes/insights.ts +153 -19
- package/src/routes/install.ts +133 -38
- package/src/routes/integration-facets.ts +107 -33
- package/src/routes/interaction-resources.ts +30 -3
- package/src/routes/knowledge.ts +488 -0
- package/src/routes/machines.ts +313 -15
- package/src/routes/managed-auth-session-sets.ts +1218 -0
- package/src/routes/managed-onboarding.ts +337 -0
- package/src/routes/managed-sign-in-methods.ts +433 -0
- package/src/routes/memory-slack-publications.ts +3 -2
- package/src/routes/model-connection-access.ts +208 -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 +178 -0
- package/src/routes/organization-memberships.ts +1019 -27
- package/src/routes/organization-model-providers.ts +293 -0
- package/src/routes/organization-recovery.ts +325 -0
- package/src/routes/organization-service-accounts.ts +128 -0
- package/src/routes/organization-sessions.ts +350 -0
- package/src/routes/personal-github-git-broker.ts +785 -0
- package/src/routes/personal-github.ts +370 -0
- package/src/routes/plugins.ts +251 -22
- package/src/routes/pr-review-github.ts +881 -0
- package/src/routes/pr-review.ts +622 -0
- package/src/routes/preference-registry.ts +12 -93
- package/src/routes/rigs.ts +167 -50
- package/src/routes/scheduled-tasks.ts +346 -41
- package/src/routes/session-artifact-associations.ts +87 -0
- package/src/routes/session-history-imports.ts +280 -0
- package/src/routes/sessions.ts +2306 -264
- package/src/routes/skill-content.ts +297 -0
- package/src/routes/skill-install-authority.ts +64 -0
- package/src/routes/skills.ts +62 -9
- package/src/routes/social.ts +46 -18
- package/src/routes/subscription-account-pools.ts +436 -0
- package/src/routes/subscription-pool-access.ts +126 -0
- package/src/routes/supergrok.ts +219 -303
- package/src/routes/transcription-recordings.ts +38 -3
- package/src/routes/transcriptions.ts +4 -0
- package/src/routes/usage-allowances.ts +378 -0
- package/src/routes/user-resource-authorities.ts +138 -0
- package/src/routes/video-generation.ts +14 -10
- package/src/routes/workspace-artifacts.ts +275 -69
- package/src/routes/workspace-capture.ts +21 -0
- package/src/routes/workspace-integrations.ts +576 -0
- package/src/routes/workspace-learning.ts +159 -0
- package/src/routes/workspace-model-providers.ts +148 -0
- package/src/routes/workspace-state.ts +38 -25
- package/src/routes/workspaces.ts +1004 -127
- package/src/sandbox/auth-callout.ts +96 -19
- package/src/sandbox/channel-a.ts +323 -24
- package/src/sandbox/connection-authority.ts +3 -0
- package/src/sandbox/enrollment.ts +81 -6
- package/src/sandbox/machines.ts +218 -76
- package/src/sandbox/metrics-ingestion.ts +411 -62
- package/src/sandbox/rematerialize.ts +121 -19
- package/src/sandbox/session-attach-variable-sets.ts +131 -0
- package/src/sandbox/viewer.ts +280 -25
- package/src/sandbox-file-artifacts.ts +413 -0
- package/src/scheduled-task-deletion.ts +138 -0
- package/src/session-create-observability.ts +46 -0
- package/src/session-realtime-context.ts +6 -3
- package/src/site-session-origin.ts +48 -0
- package/src/site-uploads.ts +224 -0
- package/src/slack-reaction-files.ts +16 -5
- package/src/temporal-schedule-cleanup.ts +13 -0
- package/src/temporal-schedule-sync.ts +74 -0
- package/src/transcription/providers/codex-subscription.ts +2 -0
- package/src/transcription/providers/openai.ts +1 -0
- package/src/transcription/providers/xai-subscription.ts +49 -3
- package/src/transcription/segmenter.ts +8 -2
- package/src/transcription/service.ts +43 -6
- package/src/work-discovery-observability.ts +121 -0
- package/src/workspace-artifact-content.ts +144 -0
- package/src/workspace-artifact-provenance.ts +104 -0
- package/src/workspace-delete-observability.ts +75 -0
- package/src/workspace-deletion.ts +73 -0
- package/src/workspace-state-projection.ts +18 -148
- package/src/workspace-tool-gateway-observability.ts +100 -0
- package/src/workspace-tool-gateway.ts +870 -0
- package/src/workspace-webhook-dispatch.ts +190 -0
- package/src/xai-subscription-auth.ts +9 -2
- package/dist/chunk-WCXHI3FF.js +0 -49920
- package/dist/chunk-WCXHI3FF.js.map +0 -1
- package/dist/routes/packs.d.ts +0 -3
- package/src/routes/packs.ts +0 -729
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { withOrganizationIntegrationAcquisition } from "@opengeni/db/organization-integration-policy";
|
|
2
|
+
import { claimOAuthAcquisition, finishOAuthAcquisition } from "./oauth-client";
|
|
1
3
|
import { Buffer } from "node:buffer";
|
|
2
4
|
import { createHash, randomBytes } from "node:crypto";
|
|
3
5
|
|
|
@@ -18,15 +20,21 @@ import {
|
|
|
18
20
|
type ApiIntegrationOAuthStartRequest,
|
|
19
21
|
type ConnectionOwnership,
|
|
20
22
|
} from "@opengeni/contracts";
|
|
21
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
integrationKeyForConnectProvider,
|
|
25
|
+
requireEnvironmentEncryption,
|
|
26
|
+
type ApiRouteDeps,
|
|
27
|
+
} from "@opengeni/core";
|
|
28
|
+
import { ExternalActorContinuation } from "@opengeni/contracts/external-identities";
|
|
22
29
|
import {
|
|
23
30
|
consumeIntegrationOAuthStateNonce,
|
|
24
31
|
decryptEnvironmentValue,
|
|
25
32
|
encryptEnvironmentValue,
|
|
26
33
|
getConnectionMetadata,
|
|
27
|
-
getWorkspaceGrant,
|
|
28
34
|
loadConnectionCredentialForBroker,
|
|
29
35
|
persistProviderOAuthConnection,
|
|
36
|
+
getConnectAttempt,
|
|
37
|
+
finishConnectOperation,
|
|
30
38
|
} from "@opengeni/db";
|
|
31
39
|
import { createSignedState, readSignedState } from "@opengeni/github";
|
|
32
40
|
import {
|
|
@@ -36,11 +44,20 @@ import {
|
|
|
36
44
|
type FetchLike,
|
|
37
45
|
} from "@opengeni/network";
|
|
38
46
|
import { HTTPException } from "hono/http-exception";
|
|
47
|
+
import { requireConnectOwnerAuthority } from "./connect-authority";
|
|
39
48
|
|
|
49
|
+
import {
|
|
50
|
+
assertConnectionOwnershipAllowedForPrincipal,
|
|
51
|
+
personalOwnerStateAccepted,
|
|
52
|
+
personalOwnerVerifiedInState,
|
|
53
|
+
PERSONAL_OWNER_VERIFIED_STATE_CLAIM,
|
|
54
|
+
} from "../connection-ownership";
|
|
40
55
|
import {
|
|
41
56
|
integrationBaseUrl,
|
|
57
|
+
oauthStateFailureReturn,
|
|
42
58
|
oauthStateTtlMs,
|
|
43
59
|
requireIntegrationsStateSecret,
|
|
60
|
+
workspaceIntegrationsPath,
|
|
44
61
|
} from "./oauth-client";
|
|
45
62
|
|
|
46
63
|
const PROVIDER_OAUTH_CALLBACK_PATH = "/v1/integrations/provider-oauth/callback";
|
|
@@ -56,10 +73,13 @@ type ProviderOAuthClient = {
|
|
|
56
73
|
};
|
|
57
74
|
|
|
58
75
|
type ProviderOAuthState = {
|
|
76
|
+
connectAttemptId?: string;
|
|
77
|
+
externalContinuation?: ExternalActorContinuation;
|
|
59
78
|
accountId: string;
|
|
60
79
|
workspaceId: string;
|
|
61
80
|
subjectId: string;
|
|
62
81
|
ownership: ConnectionOwnership;
|
|
82
|
+
personalOwnerVerified: boolean;
|
|
63
83
|
definitionId: string;
|
|
64
84
|
definitionFingerprint: string;
|
|
65
85
|
providerDomain: string;
|
|
@@ -91,6 +111,7 @@ type ProviderIdentity = {
|
|
|
91
111
|
|
|
92
112
|
type ProviderOAuthFailureReason =
|
|
93
113
|
| "state_invalid"
|
|
114
|
+
| "state_expired"
|
|
94
115
|
| "state_replayed"
|
|
95
116
|
| "provider_denied"
|
|
96
117
|
| "missing_code"
|
|
@@ -117,11 +138,20 @@ export async function startApiIntegrationProviderOAuth(
|
|
|
117
138
|
accountId: string;
|
|
118
139
|
workspaceId: string;
|
|
119
140
|
subjectId: string;
|
|
141
|
+
/**
|
|
142
|
+
* False for every principal that cannot own a personal Connection (API
|
|
143
|
+
* keys, the configured key, services, agent attempts). Resolved by the
|
|
144
|
+
* route from the live authenticated principal, never inferred here.
|
|
145
|
+
*/
|
|
146
|
+
personalOwnershipAllowed: boolean;
|
|
147
|
+
externalContinuation?: ExternalActorContinuation;
|
|
148
|
+
connectAttemptId?: string;
|
|
120
149
|
requestUrl: string;
|
|
121
150
|
payload: ApiIntegrationOAuthStartRequest;
|
|
122
151
|
},
|
|
123
152
|
): Promise<OAuthStartResponse> {
|
|
124
153
|
const definition = requiredDefinition(input.payload.definitionId);
|
|
154
|
+
await withOrganizationIntegrationAcquisition(deps.db, input, [definition.id], async () => {});
|
|
125
155
|
const providerDomain = integrationDefinitionProviderDomain(definition);
|
|
126
156
|
const existing = input.payload.connectionId
|
|
127
157
|
? await getConnectionMetadata(
|
|
@@ -155,7 +185,16 @@ export async function startApiIntegrationProviderOAuth(
|
|
|
155
185
|
message: "The selected Connection ownership does not match this OAuth request",
|
|
156
186
|
});
|
|
157
187
|
}
|
|
158
|
-
|
|
188
|
+
// API callers choose ownership explicitly; reconnects preserve the saved choice.
|
|
189
|
+
const ownership = existingOwnership ?? input.payload.ownership ?? null;
|
|
190
|
+
if (ownership === null) {
|
|
191
|
+
throw new HTTPException(422, {
|
|
192
|
+
message:
|
|
193
|
+
'ownership is required: choose "workspace" to share this Connection with the workspace, ' +
|
|
194
|
+
'or "personal" to connect only for yourself',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
assertConnectionOwnershipAllowedForPrincipal(ownership, input.personalOwnershipAllowed);
|
|
159
198
|
const authorizeScopes = uniqueStrings([
|
|
160
199
|
...(existing?.grantedScopes ?? []),
|
|
161
200
|
...definition.authentication.scopes,
|
|
@@ -164,15 +203,18 @@ export async function startApiIntegrationProviderOAuth(
|
|
|
164
203
|
const verifier = randomBytes(48).toString("base64url");
|
|
165
204
|
const key = requireEnvironmentEncryption(deps.settings);
|
|
166
205
|
const baseUrl = integrationBaseUrl(deps.settings.publicBaseUrl, input.requestUrl);
|
|
167
|
-
const redirectUri = `${baseUrl}${
|
|
206
|
+
const redirectUri = `${baseUrl}${providerOAuthCallbackPath(definition)}`;
|
|
168
207
|
const returnPath = safeReturnPath(
|
|
169
|
-
input.payload.returnPath ??
|
|
208
|
+
input.payload.returnPath ?? workspaceIntegrationsPath(input.workspaceId),
|
|
170
209
|
);
|
|
171
210
|
const state = createSignedState(requireIntegrationsStateSecret(deps.settings), {
|
|
172
211
|
accountId: input.accountId,
|
|
173
212
|
workspaceId: input.workspaceId,
|
|
174
213
|
subjectId: input.subjectId,
|
|
175
214
|
ownership,
|
|
215
|
+
// Signed record that a live principal was checked; the callback has no
|
|
216
|
+
// principal of its own and enforces exactly this decision.
|
|
217
|
+
[PERSONAL_OWNER_VERIFIED_STATE_CLAIM]: input.personalOwnershipAllowed,
|
|
176
218
|
definitionId: definition.id,
|
|
177
219
|
definitionFingerprint: providerDefinitionFingerprint(definition),
|
|
178
220
|
providerDomain,
|
|
@@ -181,6 +223,15 @@ export async function startApiIntegrationProviderOAuth(
|
|
|
181
223
|
clientId: client.clientId,
|
|
182
224
|
tokenEndpointAuthMethod: client.tokenEndpointAuthMethod,
|
|
183
225
|
returnPath,
|
|
226
|
+
...(input.connectAttemptId ? { connectAttemptId: input.connectAttemptId } : {}),
|
|
227
|
+
...(input.externalContinuation
|
|
228
|
+
? {
|
|
229
|
+
encryptedExternalContinuation: encryptEnvironmentValue(
|
|
230
|
+
key,
|
|
231
|
+
JSON.stringify(ExternalActorContinuation.parse(input.externalContinuation)),
|
|
232
|
+
),
|
|
233
|
+
}
|
|
234
|
+
: {}),
|
|
184
235
|
...(existing
|
|
185
236
|
? {
|
|
186
237
|
connectionId: existing.id,
|
|
@@ -221,12 +272,42 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
221
272
|
error?: string | undefined;
|
|
222
273
|
requestUrl: string;
|
|
223
274
|
},
|
|
224
|
-
): Promise<{ redirectTo: string }> {
|
|
275
|
+
): Promise<{ redirectTo: string; exactReturn?: boolean }> {
|
|
225
276
|
const apiBaseUrl = integrationBaseUrl(deps.settings.publicBaseUrl, input.requestUrl);
|
|
226
277
|
const returnBaseUrl = deps.settings.webBaseUrl?.replace(/\/+$/, "") ?? apiBaseUrl;
|
|
227
278
|
let state: ProviderOAuthState | null = null;
|
|
279
|
+
let exactReturnUrl: string | undefined;
|
|
280
|
+
let connectOperation: { attemptId: string; operationId: string; inputDigest: string } | undefined;
|
|
228
281
|
try {
|
|
229
282
|
state = readProviderOAuthState(input.state, deps.settings);
|
|
283
|
+
if (state.connectAttemptId) {
|
|
284
|
+
const stored = await getConnectAttempt(deps.db, state, state.connectAttemptId);
|
|
285
|
+
if (
|
|
286
|
+
stored.attempt.providerId !== state.definitionId ||
|
|
287
|
+
stored.attempt.ownership !== state.ownership
|
|
288
|
+
)
|
|
289
|
+
throw new ProviderOAuthCallbackError("state_invalid");
|
|
290
|
+
exactReturnUrl = stored.returnUrl;
|
|
291
|
+
connectOperation = {
|
|
292
|
+
attemptId: state.connectAttemptId,
|
|
293
|
+
operationId: `oauth:${state.nonce}`,
|
|
294
|
+
inputDigest: createHash("sha256").update(input.state!).digest("hex"),
|
|
295
|
+
};
|
|
296
|
+
const claim = await claimOAuthAcquisition(
|
|
297
|
+
deps.db,
|
|
298
|
+
state,
|
|
299
|
+
{
|
|
300
|
+
...connectOperation,
|
|
301
|
+
expectedRevision: stored.attempt.revision,
|
|
302
|
+
authorize: (tx, _attempt, origin) =>
|
|
303
|
+
requireConnectOwnerAuthority(tx, state!, "connections:write", origin),
|
|
304
|
+
},
|
|
305
|
+
integrationKeyForConnectProvider(state.definitionId),
|
|
306
|
+
Boolean(input.code && !input.error),
|
|
307
|
+
);
|
|
308
|
+
if (claim.status === "replayed") return { redirectTo: exactReturnUrl, exactReturn: true };
|
|
309
|
+
}
|
|
310
|
+
requireProviderOAuthOwner(state);
|
|
230
311
|
await requireProviderOAuthGrant(deps, state);
|
|
231
312
|
const consumed = await consumeIntegrationOAuthStateNonce(deps.db, {
|
|
232
313
|
accountId: state.accountId,
|
|
@@ -237,11 +318,31 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
237
318
|
now: new Date(),
|
|
238
319
|
});
|
|
239
320
|
if (!consumed) throw new ProviderOAuthCallbackError("state_replayed");
|
|
321
|
+
if (connectOperation && (input.error || !input.code)) {
|
|
322
|
+
await finishConnectOperation(deps.db, state, {
|
|
323
|
+
...connectOperation,
|
|
324
|
+
authorize: (tx, _attempt, origin) =>
|
|
325
|
+
requireConnectOwnerAuthority(tx, state!, "connections:write", origin),
|
|
326
|
+
commit: async (_tx, current) => ({
|
|
327
|
+
...current,
|
|
328
|
+
revision: current.revision + 1,
|
|
329
|
+
state: input.error === "access_denied" ? "cancelled" : "failed",
|
|
330
|
+
nextAction: { type: "none" },
|
|
331
|
+
error: {
|
|
332
|
+
code: input.error ? "provider_denied" : "missing_code",
|
|
333
|
+
message: "Authorization was not completed. Start a new connection attempt.",
|
|
334
|
+
retryable: false,
|
|
335
|
+
},
|
|
336
|
+
}),
|
|
337
|
+
});
|
|
338
|
+
return { redirectTo: exactReturnUrl!, exactReturn: true };
|
|
339
|
+
}
|
|
240
340
|
if (input.error) throw new ProviderOAuthCallbackError("provider_denied");
|
|
241
341
|
if (!input.code) throw new ProviderOAuthCallbackError("missing_code");
|
|
242
342
|
|
|
243
343
|
const definition = integrationDefinitionById(state.definitionId);
|
|
244
344
|
if (!definition) throw new ProviderOAuthCallbackError("state_invalid");
|
|
345
|
+
await withOrganizationIntegrationAcquisition(deps.db, state, [definition.id], async () => {});
|
|
245
346
|
if (
|
|
246
347
|
state.definitionFingerprint !== providerDefinitionFingerprint(definition) ||
|
|
247
348
|
state.providerDomain !== integrationDefinitionProviderDomain(definition) ||
|
|
@@ -258,7 +359,7 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
258
359
|
}
|
|
259
360
|
const key = requireEnvironmentEncryption(deps.settings);
|
|
260
361
|
const verifier = decryptEnvironmentValue(key, state.encryptedPkceVerifier);
|
|
261
|
-
const redirectUri = `${apiBaseUrl}${
|
|
362
|
+
const redirectUri = `${apiBaseUrl}${providerOAuthCallbackPath(definition)}`;
|
|
262
363
|
const token = await exchangeProviderAuthorizationCode(deps, definition, client, {
|
|
263
364
|
code: input.code,
|
|
264
365
|
verifier,
|
|
@@ -267,7 +368,7 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
267
368
|
if (!providerScopesInclude(definition, token.scopes, state.authorizeScopes)) {
|
|
268
369
|
throw new ProviderOAuthCallbackError("scope_not_granted");
|
|
269
370
|
}
|
|
270
|
-
|
|
371
|
+
let grantedScopes = token.scopes.length > 0 ? token.scopes : state.authorizeScopes;
|
|
271
372
|
const identity = await verifyProviderIdentity(deps, definition, token);
|
|
272
373
|
if (
|
|
273
374
|
state.expectedProviderPrincipalId &&
|
|
@@ -307,6 +408,11 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
307
408
|
if (!refreshToken) {
|
|
308
409
|
throw new ProviderOAuthCallbackError("refresh_token_missing");
|
|
309
410
|
}
|
|
411
|
+
// Microsoft omits offline_access from access-token scopes. The new or
|
|
412
|
+
// previously verified refresh token proves this capability instead.
|
|
413
|
+
if (definition.provider.id === "microsoft") {
|
|
414
|
+
grantedScopes = uniqueStrings([...grantedScopes, "offline_access"]);
|
|
415
|
+
}
|
|
310
416
|
const credentialEncrypted = encryptEnvironmentValue(
|
|
311
417
|
key,
|
|
312
418
|
JSON.stringify({
|
|
@@ -339,7 +445,8 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
339
445
|
]),
|
|
340
446
|
verifiedAt: new Date().toISOString(),
|
|
341
447
|
});
|
|
342
|
-
const
|
|
448
|
+
const persistenceInput: import("@opengeni/db").PersistProviderOAuthConnectionInput = {
|
|
449
|
+
authorize: (tx: import("@opengeni/db").Database) => requireConnectOwnerAuthority(tx, state!),
|
|
343
450
|
accountId: state.accountId,
|
|
344
451
|
workspaceId: state.workspaceId,
|
|
345
452
|
subjectId: ownerSubjectId,
|
|
@@ -362,7 +469,46 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
362
469
|
requestedConnectionVersion: state.connectionVersion,
|
|
363
470
|
}
|
|
364
471
|
: {}),
|
|
365
|
-
}
|
|
472
|
+
};
|
|
473
|
+
const persist = (database: import("@opengeni/db").Database) =>
|
|
474
|
+
persistProviderOAuthConnection(database, persistenceInput);
|
|
475
|
+
if (connectOperation) {
|
|
476
|
+
await finishOAuthAcquisition(
|
|
477
|
+
deps.db,
|
|
478
|
+
state,
|
|
479
|
+
{
|
|
480
|
+
...connectOperation,
|
|
481
|
+
authorize: (tx, _attempt, origin) =>
|
|
482
|
+
requireConnectOwnerAuthority(tx, state!, "connections:write", origin),
|
|
483
|
+
commit: async (tx, current) => {
|
|
484
|
+
const connection = await persist(tx);
|
|
485
|
+
if (!connection) throw new ProviderOAuthCallbackError("connection_conflict");
|
|
486
|
+
return {
|
|
487
|
+
...current,
|
|
488
|
+
revision: current.revision + 1,
|
|
489
|
+
state: "connected_but_incomplete",
|
|
490
|
+
credentialsCommitted: true,
|
|
491
|
+
nextAction: { type: "none" },
|
|
492
|
+
account: {
|
|
493
|
+
id: connection.id,
|
|
494
|
+
providerId: current.providerId,
|
|
495
|
+
label: identity.displayName ?? identity.email ?? identity.principalId,
|
|
496
|
+
ownership: current.ownership,
|
|
497
|
+
status: "connected",
|
|
498
|
+
},
|
|
499
|
+
};
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
definition.id,
|
|
503
|
+
);
|
|
504
|
+
return { redirectTo: exactReturnUrl!, exactReturn: true };
|
|
505
|
+
}
|
|
506
|
+
const connection = await withOrganizationIntegrationAcquisition(
|
|
507
|
+
deps.db,
|
|
508
|
+
state,
|
|
509
|
+
[definition.id],
|
|
510
|
+
persist,
|
|
511
|
+
);
|
|
366
512
|
if (!connection) throw new ProviderOAuthCallbackError("connection_conflict");
|
|
367
513
|
return {
|
|
368
514
|
redirectTo: providerOAuthReturnUrl(returnBaseUrl, state.returnPath, "success", {
|
|
@@ -373,14 +519,19 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
373
519
|
}),
|
|
374
520
|
};
|
|
375
521
|
} catch (error) {
|
|
522
|
+
if (exactReturnUrl !== undefined) return { redirectTo: exactReturnUrl, exactReturn: true };
|
|
523
|
+
const reason = providerOAuthFailureReason(error);
|
|
524
|
+
// An unreadable state carries no return path; an authentic but aged one
|
|
525
|
+
// still names its workspace and is reported as expired.
|
|
526
|
+
const failure = state ? null : oauthStateFailureReturn(deps.settings, input.state);
|
|
376
527
|
return {
|
|
377
528
|
redirectTo: providerOAuthReturnUrl(
|
|
378
529
|
returnBaseUrl,
|
|
379
|
-
state?.returnPath ??
|
|
530
|
+
state?.returnPath ?? failure!.returnPath,
|
|
380
531
|
"error",
|
|
381
532
|
{
|
|
382
533
|
...(state?.definitionId ? { definitionId: state.definitionId } : {}),
|
|
383
|
-
reason:
|
|
534
|
+
reason: failure && reason === "state_invalid" ? failure.reason : reason,
|
|
384
535
|
},
|
|
385
536
|
),
|
|
386
537
|
};
|
|
@@ -393,6 +544,23 @@ function requiredDefinition(id: string): IntegrationDefinition {
|
|
|
393
544
|
return definition;
|
|
394
545
|
}
|
|
395
546
|
|
|
547
|
+
/** Configuration readiness only: consent and installation are still separate. */
|
|
548
|
+
export function curatedOAuthReadiness(
|
|
549
|
+
settings: Settings,
|
|
550
|
+
definition: IntegrationDefinition,
|
|
551
|
+
): { configured: boolean; ownership: ConnectionOwnership[] } {
|
|
552
|
+
const ownership: ConnectionOwnership[] = ["workspace", "personal"];
|
|
553
|
+
try {
|
|
554
|
+
if (!settings.integrationsEnabled) return { configured: false, ownership };
|
|
555
|
+
requireEnvironmentEncryption(settings);
|
|
556
|
+
requireIntegrationsStateSecret(settings);
|
|
557
|
+
providerClientForDefinition(settings, definition);
|
|
558
|
+
return { configured: true, ownership };
|
|
559
|
+
} catch {
|
|
560
|
+
return { configured: false, ownership };
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
396
564
|
function providerClientForDefinition(
|
|
397
565
|
settings: Settings,
|
|
398
566
|
definition: IntegrationDefinition,
|
|
@@ -434,6 +602,28 @@ function providerClientForDefinition(
|
|
|
434
602
|
};
|
|
435
603
|
}
|
|
436
604
|
|
|
605
|
+
export function isApiIntegrationProviderOAuthState(
|
|
606
|
+
value: string | undefined,
|
|
607
|
+
settings: Settings,
|
|
608
|
+
): boolean {
|
|
609
|
+
try {
|
|
610
|
+
readProviderOAuthState(value, settings);
|
|
611
|
+
return true;
|
|
612
|
+
} catch {
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
function providerOAuthCallbackPath(definition: IntegrationDefinition): string {
|
|
618
|
+
// Google definitions share the established MCP OAuth callback. The
|
|
619
|
+
// route distinguishes signed provider state from MCP state, while the
|
|
620
|
+
// separate google-drive callback remains available for the legacy Drive
|
|
621
|
+
// installation flow.
|
|
622
|
+
return definition.provider.id === "google"
|
|
623
|
+
? "/v1/integrations/oauth/callback"
|
|
624
|
+
: PROVIDER_OAUTH_CALLBACK_PATH;
|
|
625
|
+
}
|
|
626
|
+
|
|
437
627
|
function providerClientKeys(definition: IntegrationDefinition): string[] {
|
|
438
628
|
const authorization = new URL(definition.authentication.authorizationUrl);
|
|
439
629
|
const token = new URL(definition.authentication.tokenUrl);
|
|
@@ -500,9 +690,25 @@ function readProviderOAuthState(raw: string | undefined, settings: Settings): Pr
|
|
|
500
690
|
}
|
|
501
691
|
return {
|
|
502
692
|
accountId: requiredStateString(payload.accountId),
|
|
693
|
+
...(optionalString(payload.connectAttemptId)
|
|
694
|
+
? { connectAttemptId: optionalString(payload.connectAttemptId)! }
|
|
695
|
+
: {}),
|
|
696
|
+
...(typeof payload.encryptedExternalContinuation === "string"
|
|
697
|
+
? {
|
|
698
|
+
externalContinuation: ExternalActorContinuation.parse(
|
|
699
|
+
JSON.parse(
|
|
700
|
+
decryptEnvironmentValue(
|
|
701
|
+
requireEnvironmentEncryption(settings),
|
|
702
|
+
payload.encryptedExternalContinuation,
|
|
703
|
+
),
|
|
704
|
+
),
|
|
705
|
+
),
|
|
706
|
+
}
|
|
707
|
+
: {}),
|
|
503
708
|
workspaceId: requiredStateString(payload.workspaceId),
|
|
504
709
|
subjectId: requiredStateString(payload.subjectId),
|
|
505
710
|
ownership,
|
|
711
|
+
personalOwnerVerified: personalOwnerVerifiedInState(payload),
|
|
506
712
|
definitionId: requiredStateString(payload.definitionId),
|
|
507
713
|
definitionFingerprint: requiredStateString(payload.definitionFingerprint),
|
|
508
714
|
providerDomain: requiredStateString(payload.providerDomain),
|
|
@@ -645,14 +851,22 @@ async function providerFetch(
|
|
|
645
851
|
|
|
646
852
|
async function requireProviderOAuthGrant(
|
|
647
853
|
deps: ApiRouteDeps,
|
|
648
|
-
state: Pick<
|
|
854
|
+
state: Pick<
|
|
855
|
+
ProviderOAuthState,
|
|
856
|
+
"accountId" | "workspaceId" | "subjectId" | "personalOwnerVerified" | "externalContinuation"
|
|
857
|
+
>,
|
|
649
858
|
): Promise<void> {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
859
|
+
await deps.db.transaction((tx) => requireConnectOwnerAuthority(tx, state));
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* A state minted before the start-side principal fence existed can still be in
|
|
864
|
+
* flight for one `oauthStateTtlMs` window, and it carries no
|
|
865
|
+
* `personalOwnerVerified` claim. Such a state must not land a personal
|
|
866
|
+
* Connection.
|
|
867
|
+
*/
|
|
868
|
+
function requireProviderOAuthOwner(state: ProviderOAuthState): void {
|
|
869
|
+
if (!personalOwnerStateAccepted(state)) {
|
|
656
870
|
throw new ProviderOAuthCallbackError("connection_conflict");
|
|
657
871
|
}
|
|
658
872
|
}
|
|
@@ -686,10 +900,24 @@ function providerScopesInclude(
|
|
|
686
900
|
fallbackScopes: string[],
|
|
687
901
|
): boolean {
|
|
688
902
|
const effective = returnedScopes.length > 0 ? returnedScopes : fallbackScopes;
|
|
689
|
-
const normalize = (value: string) =>
|
|
690
|
-
definition.provider.id === "microsoft"
|
|
903
|
+
const normalize = (value: string) => {
|
|
904
|
+
if (definition.provider.id === "microsoft") return value.toLowerCase();
|
|
905
|
+
if (definition.provider.id === "google") {
|
|
906
|
+
if (value === "email" || value === "https://www.googleapis.com/auth/userinfo.email") {
|
|
907
|
+
return "email";
|
|
908
|
+
}
|
|
909
|
+
if (value === "profile" || value === "https://www.googleapis.com/auth/userinfo.profile") {
|
|
910
|
+
return "profile";
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
return value;
|
|
914
|
+
};
|
|
691
915
|
const granted = new Set(effective.map(normalize));
|
|
692
|
-
return definition.authentication.scopes.every(
|
|
916
|
+
return definition.authentication.scopes.every(
|
|
917
|
+
(scope) =>
|
|
918
|
+
(definition.provider.id === "microsoft" && normalize(scope) === "offline_access") ||
|
|
919
|
+
granted.has(normalize(scope)),
|
|
920
|
+
);
|
|
693
921
|
}
|
|
694
922
|
|
|
695
923
|
function providerOAuthReturnUrl(
|