@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
package/src/routes/github.ts
CHANGED
|
@@ -2,11 +2,13 @@ import {
|
|
|
2
2
|
GitHubActionPoliciesResponse,
|
|
3
3
|
GitHubActionPolicyActorState,
|
|
4
4
|
GitHubAppManifestCreate,
|
|
5
|
+
OrganizationIntegrationDeniedError,
|
|
5
6
|
UpdateGitHubActionPolicyRequest,
|
|
6
7
|
type AccessGrant,
|
|
7
8
|
type GitHubInstallationBindingCandidate,
|
|
8
9
|
} from "@opengeni/contracts";
|
|
9
10
|
import { PersonalGitHubConnectionMetadata } from "@opengeni/contracts/personal-github";
|
|
11
|
+
import { withOrganizationIntegrationAcquisition } from "@opengeni/db/organization-integration-policy";
|
|
10
12
|
import {
|
|
11
13
|
ListGitHubRepositoryBranchesQuery,
|
|
12
14
|
VerifyPublicGitHubRepositoryRefRequest,
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
GitHubPublicRepositoryVerificationError,
|
|
32
34
|
githubAppMissingSettings,
|
|
33
35
|
githubOAuthAuthorizeUrl,
|
|
36
|
+
inspectSignedState,
|
|
34
37
|
organizationAppManifestUrl,
|
|
35
38
|
personalAppManifestUrl,
|
|
36
39
|
readSignedState,
|
|
@@ -39,9 +42,10 @@ import {
|
|
|
39
42
|
type GitHubSignedStatePayload,
|
|
40
43
|
verifySignedState,
|
|
41
44
|
} from "@opengeni/github";
|
|
42
|
-
import type { Context, Hono } from "hono";
|
|
45
|
+
import type { Context, Hono, MiddlewareHandler } from "hono";
|
|
43
46
|
import { deleteCookie, setCookie } from "hono/cookie";
|
|
44
47
|
import { HTTPException } from "hono/http-exception";
|
|
48
|
+
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
|
45
49
|
import {
|
|
46
50
|
githubAppActionPolicyActor,
|
|
47
51
|
hasPermission,
|
|
@@ -71,22 +75,90 @@ import {
|
|
|
71
75
|
assertPersonalConnectionOwnerPrincipal,
|
|
72
76
|
requireLegacyOAuthActor,
|
|
73
77
|
} from "../connection-ownership";
|
|
78
|
+
import { workspaceIntegrationsPathForUntrusted } from "../integrations/oauth-client";
|
|
74
79
|
import { listPersonalGitHubConnections } from "../integrations/personal-github";
|
|
80
|
+
import {
|
|
81
|
+
integrationCommitGrant,
|
|
82
|
+
type IntegrationCommitGrant,
|
|
83
|
+
} from "../integrations/integration-commit-authority";
|
|
75
84
|
import {
|
|
76
85
|
isConsistentGitHubBindingCandidates,
|
|
77
86
|
isConsistentGitHubBindingProof,
|
|
78
87
|
} from "../integrations/github-installation-proof";
|
|
88
|
+
import {
|
|
89
|
+
githubConnectFailureHtml,
|
|
90
|
+
githubInstallationChooserHtml,
|
|
91
|
+
githubSetupPendingHtml,
|
|
92
|
+
githubOwnerApprovedHtml,
|
|
93
|
+
githubSetupSuccessHtml,
|
|
94
|
+
githubSuccessHtml,
|
|
95
|
+
type GitHubConnectFailure,
|
|
96
|
+
} from "./github-browser-pages";
|
|
79
97
|
import {
|
|
80
98
|
completeGitHubAppConnect,
|
|
81
99
|
isGitHubAppConnectState,
|
|
82
100
|
} from "../integrations/github-app-connect";
|
|
101
|
+
import { parseRequestJson } from "../http/request-body";
|
|
83
102
|
|
|
84
103
|
const githubStateCookie = "opengeni_github_state";
|
|
85
104
|
const githubBindingStateMaxAgeSeconds = 10 * 60;
|
|
86
105
|
const legacyInstallationChooserDisabledMessage =
|
|
87
106
|
"The legacy repository-admin GitHub installation chooser is disabled; use the GitHub owner-consent connect flow";
|
|
107
|
+
/**
|
|
108
|
+
* GitHub routes a browser navigates to (not the JSON API). A page-load link
|
|
109
|
+
* opened after it expired, GitHub's Cancel button, or a non-owner all land on
|
|
110
|
+
* one of these, so their failures render a readable page instead of JSON.
|
|
111
|
+
*/
|
|
112
|
+
const GITHUB_BROWSER_ROUTES = [
|
|
113
|
+
"/v1/workspaces/:workspaceId/github/connect",
|
|
114
|
+
"/v1/workspaces/:workspaceId/github/installations/select",
|
|
115
|
+
"/v1/workspaces/:workspaceId/github/installations/:installationId/configure",
|
|
116
|
+
"/v1/github/app-manifest/callback",
|
|
117
|
+
"/v1/github/setup",
|
|
118
|
+
"/v1/github/install/callback",
|
|
119
|
+
"/v1/github/oauth/callback",
|
|
120
|
+
] as const;
|
|
121
|
+
|
|
122
|
+
/** An HTTP failure that already knows which browser page explains it. */
|
|
123
|
+
class GitHubBrowserFailure extends HTTPException {
|
|
124
|
+
constructor(
|
|
125
|
+
status: 400 | 403,
|
|
126
|
+
message: string,
|
|
127
|
+
readonly failure: GitHubConnectFailure,
|
|
128
|
+
) {
|
|
129
|
+
super(status, { message });
|
|
130
|
+
this.name = "GitHubBrowserFailure";
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
88
134
|
export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
89
135
|
const { db, settings, githubStateSecret } = deps;
|
|
136
|
+
// Registered before the routes so it wraps them. The status code is kept, so
|
|
137
|
+
// automation still sees the same outcome; only the body becomes a page. Every
|
|
138
|
+
// failure is rendered, not only HTTP ones: an organization policy denial or an
|
|
139
|
+
// unexpected fault must not reach the browser as the JSON error envelope.
|
|
140
|
+
const browserFailurePage: MiddlewareHandler = async (c, next) => {
|
|
141
|
+
let failure: unknown;
|
|
142
|
+
let handledStatus: number | undefined;
|
|
143
|
+
try {
|
|
144
|
+
await next();
|
|
145
|
+
if (!c.error) return;
|
|
146
|
+
failure = c.error;
|
|
147
|
+
// The app error handler has already answered this failure.
|
|
148
|
+
handledStatus = c.res.status;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
failure = error;
|
|
151
|
+
}
|
|
152
|
+
c.res = c.html(
|
|
153
|
+
githubConnectFailureHtml(
|
|
154
|
+
githubBrowserFailureKind(failure),
|
|
155
|
+
githubFailureReturnUrl(deps, c),
|
|
156
|
+
githubBrowserFailureDetail(failure),
|
|
157
|
+
),
|
|
158
|
+
githubBrowserFailureStatus(failure, handledStatus) as ContentfulStatusCode,
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
for (const path of GITHUB_BROWSER_ROUTES) app.use(path, browserFailurePage);
|
|
90
162
|
|
|
91
163
|
app.get("/v1/workspaces/:workspaceId/github/app", async (c) => {
|
|
92
164
|
const workspaceId = c.req.param("workspaceId");
|
|
@@ -174,7 +246,7 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
174
246
|
|
|
175
247
|
app.patch("/v1/workspaces/:workspaceId/github/action-policies", async (c) => {
|
|
176
248
|
const workspaceId = c.req.param("workspaceId");
|
|
177
|
-
const payload =
|
|
249
|
+
const payload = await parseRequestJson(c, UpdateGitHubActionPolicyRequest);
|
|
178
250
|
const actor = payload.actor;
|
|
179
251
|
if (actor.kind === "workspace_app") {
|
|
180
252
|
const grant = await requireAccessGrant(c, deps, workspaceId, "github:manage");
|
|
@@ -228,7 +300,7 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
228
300
|
|
|
229
301
|
// Start with user authorization, not GitHub's install/configure selector.
|
|
230
302
|
// This lets an owner link an already-installed App without relying on
|
|
231
|
-
// GitHub's Configure page to preserve or return
|
|
303
|
+
// GitHub's Configure page to preserve or return Opengeni state.
|
|
232
304
|
app.get("/v1/workspaces/:workspaceId/github/connect", async (c) => {
|
|
233
305
|
const workspaceId = c.req.param("workspaceId");
|
|
234
306
|
const state = c.req.query("state");
|
|
@@ -308,7 +380,7 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
308
380
|
const workspaceId = c.req.param("workspaceId");
|
|
309
381
|
const grant = await requireAccessGrant(c, deps, workspaceId);
|
|
310
382
|
requirePublicGitHubRepositoryVerificationPermission(grant);
|
|
311
|
-
const request =
|
|
383
|
+
const request = await parseRequestJson(c, VerifyPublicGitHubRepositoryRefRequest);
|
|
312
384
|
let repository: ReturnType<typeof parseCanonicalGitHubRepositoryUrl>;
|
|
313
385
|
try {
|
|
314
386
|
repository = parseCanonicalGitHubRepositoryUrl(request.url);
|
|
@@ -431,7 +503,7 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
431
503
|
const access = await requireAccessGrantAuthorization(c, deps, workspaceId, "github:manage");
|
|
432
504
|
requireLegacyOAuthActor(access);
|
|
433
505
|
const grant = access.grant;
|
|
434
|
-
const payload =
|
|
506
|
+
const payload = await parseRequestJson(c, GitHubAppManifestCreate);
|
|
435
507
|
const baseUrl = (settings.githubAppManifestBaseUrl ?? new URL(c.req.url).origin).replace(
|
|
436
508
|
/\/+$/,
|
|
437
509
|
"",
|
|
@@ -441,7 +513,7 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
441
513
|
workspaceId: grant.workspaceId,
|
|
442
514
|
});
|
|
443
515
|
setGitHubStateCookie(c, deps, state);
|
|
444
|
-
const appName = payload.appName?.trim() || "
|
|
516
|
+
const appName = payload.appName?.trim() || "Opengeni";
|
|
445
517
|
const manifest = buildGitHubAppManifest({
|
|
446
518
|
appName,
|
|
447
519
|
baseUrl,
|
|
@@ -498,6 +570,16 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
498
570
|
);
|
|
499
571
|
});
|
|
500
572
|
if (!state) {
|
|
573
|
+
// An organization owner approving a member's request (or installing
|
|
574
|
+
// straight from GitHub) arrives with no Opengeni state. Nothing names a
|
|
575
|
+
// workspace, so nothing is connected: explain the remaining step instead
|
|
576
|
+
// of an "expired link" error. No provider or database call happens here.
|
|
577
|
+
if (
|
|
578
|
+
c.req.query("setup_action") === "install" &&
|
|
579
|
+
parsePositiveInteger(c.req.query("installation_id")) !== null
|
|
580
|
+
) {
|
|
581
|
+
return c.html(githubOwnerApprovedHtml(githubFailureReturnUrl(deps, c)));
|
|
582
|
+
}
|
|
501
583
|
throw new HTTPException(400, { message: "missing GitHub installation state" });
|
|
502
584
|
}
|
|
503
585
|
const statePayload = readSignedState(state, githubStateSecret);
|
|
@@ -519,7 +601,17 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
519
601
|
}
|
|
520
602
|
const setupAction = c.req.query("setup_action");
|
|
521
603
|
if (setupAction === "request") {
|
|
522
|
-
return c.html(
|
|
604
|
+
return c.html(
|
|
605
|
+
githubSetupPendingHtml(
|
|
606
|
+
openGeniReturnUrl(
|
|
607
|
+
settings,
|
|
608
|
+
c,
|
|
609
|
+
grant.workspaceId,
|
|
610
|
+
typeof statePayload.returnPath === "string" ? statePayload.returnPath : null,
|
|
611
|
+
"requested",
|
|
612
|
+
),
|
|
613
|
+
),
|
|
614
|
+
);
|
|
523
615
|
}
|
|
524
616
|
if (setupAction !== "install" && setupAction !== "update") {
|
|
525
617
|
throw new HTTPException(400, { message: "unsupported GitHub setup action" });
|
|
@@ -575,6 +667,9 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
575
667
|
});
|
|
576
668
|
const code = c.req.query("code");
|
|
577
669
|
const state = c.req.query("state");
|
|
670
|
+
if (c.req.query("error") === "access_denied") {
|
|
671
|
+
throw new GitHubBrowserFailure(400, "GitHub authorization was cancelled", "cancelled");
|
|
672
|
+
}
|
|
578
673
|
if (!code) {
|
|
579
674
|
throw new HTTPException(400, { message: "missing GitHub OAuth code" });
|
|
580
675
|
}
|
|
@@ -598,6 +693,7 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
598
693
|
message: "GitHub OAuth state does not match this workspace",
|
|
599
694
|
});
|
|
600
695
|
}
|
|
696
|
+
await withOrganizationIntegrationAcquisition(db, grant, ["github-app"], async () => {});
|
|
601
697
|
let candidates: GitHubInstallationBindingCandidate[] | null;
|
|
602
698
|
try {
|
|
603
699
|
candidates = deps.githubAppApi?.discoverInstallationBindingCandidates
|
|
@@ -652,6 +748,7 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
652
748
|
message: "GitHub OAuth state does not match this workspace",
|
|
653
749
|
});
|
|
654
750
|
}
|
|
751
|
+
await withOrganizationIntegrationAcquisition(db, grant, ["github-app"], async () => {});
|
|
655
752
|
let proof;
|
|
656
753
|
try {
|
|
657
754
|
proof = deps.githubAppApi?.authorizeInstallationBinding
|
|
@@ -681,22 +778,30 @@ export function registerGitHubRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
681
778
|
const expiresAt = new Date((statePayload.iat + githubBindingStateMaxAgeSeconds) * 1_000);
|
|
682
779
|
let bound;
|
|
683
780
|
try {
|
|
684
|
-
bound = await
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
781
|
+
bound = await withOrganizationIntegrationAcquisition(
|
|
782
|
+
db,
|
|
783
|
+
grant,
|
|
784
|
+
["github-app"],
|
|
785
|
+
async (tx) => {
|
|
786
|
+
await grant.authorizeCommit(tx);
|
|
787
|
+
return bindAuthorizedGitHubInstallationRepositories(tx, {
|
|
788
|
+
accountId: grant.accountId,
|
|
789
|
+
workspaceId: grant.workspaceId,
|
|
790
|
+
installationId,
|
|
791
|
+
githubAccountId: proof.installation.accountId,
|
|
792
|
+
accountLogin: proof.installation.accountLogin,
|
|
793
|
+
accountType: proof.installation.accountType,
|
|
794
|
+
linkedBySubjectId: grant.subjectId,
|
|
795
|
+
githubActorId: proof.actorId,
|
|
796
|
+
githubActorLogin: proof.actorLogin,
|
|
797
|
+
authorityKind: proof.authorityKind,
|
|
798
|
+
authorityCheckedAt,
|
|
799
|
+
authorityExpiresAt: expiresAt,
|
|
800
|
+
authorityNonce: statePayload.nonce,
|
|
801
|
+
repositoryIds,
|
|
802
|
+
});
|
|
803
|
+
},
|
|
804
|
+
);
|
|
700
805
|
} catch (error) {
|
|
701
806
|
if (error instanceof GitHubInstallationAuthorityCommitError) {
|
|
702
807
|
throw new HTTPException(409, { message: error.message });
|
|
@@ -913,18 +1018,32 @@ async function requireGitHubManageGrant(
|
|
|
913
1018
|
deps: ApiRouteDeps,
|
|
914
1019
|
workspaceId: string,
|
|
915
1020
|
expectedState: GitHubSignedStatePayload,
|
|
916
|
-
): Promise<
|
|
1021
|
+
): Promise<IntegrationCommitGrant> {
|
|
917
1022
|
try {
|
|
918
1023
|
const access = await requireAccessGrantAuthorization(c, deps, workspaceId, "github:manage");
|
|
919
1024
|
requireLegacyOAuthActor(access);
|
|
920
|
-
return access
|
|
1025
|
+
return integrationCommitGrant(access, ["github:manage"], {
|
|
1026
|
+
settings: deps.settings,
|
|
1027
|
+
authorizationHeader: c.req.header("authorization"),
|
|
1028
|
+
});
|
|
921
1029
|
} catch (error) {
|
|
922
1030
|
if (!(error instanceof HTTPException) || error.status !== 401) {
|
|
923
1031
|
throw error;
|
|
924
1032
|
}
|
|
925
1033
|
const grant = githubBrowserGrantFromState(deps.settings, expectedState, workspaceId);
|
|
926
1034
|
if (grant) {
|
|
927
|
-
return
|
|
1035
|
+
return {
|
|
1036
|
+
...grant,
|
|
1037
|
+
authorizeCommit: async () => {
|
|
1038
|
+
const current = githubBrowserGrantFromState(deps.settings, expectedState, workspaceId);
|
|
1039
|
+
if (
|
|
1040
|
+
!current ||
|
|
1041
|
+
current.accountId !== grant.accountId ||
|
|
1042
|
+
current.subjectId !== grant.subjectId
|
|
1043
|
+
)
|
|
1044
|
+
throw new HTTPException(403, { message: "GitHub browser handoff expired or changed" });
|
|
1045
|
+
},
|
|
1046
|
+
};
|
|
928
1047
|
}
|
|
929
1048
|
throw error;
|
|
930
1049
|
}
|
|
@@ -952,7 +1071,7 @@ function githubAuthorityHttpError(error: unknown): HTTPException {
|
|
|
952
1071
|
}
|
|
953
1072
|
if (error instanceof GitHubInstallationAuthorityError) {
|
|
954
1073
|
if (error.reason === "authority_denied") {
|
|
955
|
-
return new
|
|
1074
|
+
return new GitHubBrowserFailure(403, error.message, "not_owner");
|
|
956
1075
|
}
|
|
957
1076
|
if (error.reason === "installation_missing") {
|
|
958
1077
|
return new HTTPException(404, { message: error.message });
|
|
@@ -1022,39 +1141,6 @@ function isSecureRequest(c: Context, deps: ApiRouteDeps): boolean {
|
|
|
1022
1141
|
);
|
|
1023
1142
|
}
|
|
1024
1143
|
|
|
1025
|
-
function githubSuccessHtml(envLines: string[]): string {
|
|
1026
|
-
const envText = envLines.join("\n");
|
|
1027
|
-
const escaped = escapeHtml(envText);
|
|
1028
|
-
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>GitHub App Created</title><style>body{font-family:system-ui,sans-serif;margin:0;min-height:100vh;display:grid;place-items:center;background:#0b0b0d;color:#f4f4f5}main{width:min(760px,calc(100vw - 32px));border:1px solid #27272a;border-radius:8px;padding:28px;background:#111114}h1{margin:0 0 10px;font-size:24px;line-height:1.2}p{margin:0 0 18px;color:#d4d4d8}.env-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:22px 0 8px}.env-header h2{margin:0;font-size:13px;line-height:1.2;text-transform:uppercase;letter-spacing:.08em;color:#a1a1aa}pre{white-space:pre-wrap;word-break:break-word;max-height:380px;overflow:auto;background:#09090b;border:1px solid #27272a;border-radius:8px;padding:16px;font-size:13px;line-height:1.5}button{display:inline-flex;align-items:center;justify-content:center;min-height:36px;border-radius:6px;border:1px solid #3f3f46;padding:0 12px;background:#f4f4f5;color:#09090b;font:600 14px system-ui,sans-serif;cursor:pointer}button:disabled{cursor:not-allowed;opacity:.7}</style></head><body><main><h1>GitHub App created</h1><p>Add these values to .env, then restart API and worker.</p><div class="env-header"><h2>Environment variables</h2><button id="copy-env" type="button">Copy env</button></div><pre id="env-lines">${escaped}</pre><script>(()=>{const button=document.getElementById("copy-env");const env=document.getElementById("env-lines");async function copyText(text){if(navigator.clipboard&&window.isSecureContext){await navigator.clipboard.writeText(text);return;}const area=document.createElement("textarea");area.value=text;area.setAttribute("readonly","");area.style.position="fixed";area.style.inset="-9999px";document.body.append(area);area.select();document.execCommand("copy");area.remove();}button?.addEventListener("click",async()=>{try{await copyText(env?.textContent||"");button.textContent="Copied";setTimeout(()=>button.textContent="Copy env",1600);}catch{button.textContent="Copy failed";setTimeout(()=>button.textContent="Copy env",2200);}});})();</script></main></body></html>`;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
function githubSetupSuccessHtml(account: string, returnUrl: string): string {
|
|
1032
|
-
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>GitHub App Connected</title><style>body{font-family:system-ui,sans-serif;margin:0;min-height:100vh;display:grid;place-items:center;background:#0b0b0d;color:#f4f4f5}main{width:min(640px,calc(100vw - 32px));border:1px solid #27272a;border-radius:8px;padding:28px;background:#111114}h1{margin:0 0 10px;font-size:24px;line-height:1.2}p{margin:0 0 18px;color:#d4d4d8}.button{display:inline-flex;align-items:center;justify-content:center;min-height:36px;border-radius:6px;border:1px solid #3f3f46;padding:0 12px;background:#f4f4f5;color:#09090b;font:600 14px system-ui,sans-serif;text-decoration:none}</style></head><body><main><h1>GitHub App connected</h1><p>${escapeHtml(account)} is now available to this OpenGeni workspace through an explicit repository allowlist.</p><a class="button" href="${escapeHtml(returnUrl)}">Back to OpenGeni</a></main></body></html>`;
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
function githubInstallationChooserHtml(
|
|
1036
|
-
candidates: GitHubInstallationBindingCandidate[],
|
|
1037
|
-
state: string,
|
|
1038
|
-
workspaceId: string,
|
|
1039
|
-
baseUrl: string,
|
|
1040
|
-
): string {
|
|
1041
|
-
const action = `${baseUrl}/v1/workspaces/${encodeURIComponent(workspaceId)}/github/installations/select`;
|
|
1042
|
-
const options = candidates
|
|
1043
|
-
.map(({ installation, authorityKind }, index) => {
|
|
1044
|
-
const account = escapeHtml(
|
|
1045
|
-
installation.accountLogin ?? `installation ${installation.installationId}`,
|
|
1046
|
-
);
|
|
1047
|
-
const label = authorityKind === "personal_owner" ? "Personal account" : "Organization owner";
|
|
1048
|
-
return `<label class="option"><input type="radio" name="installation_id" value="${installation.installationId}" required${candidates.length === 1 && index === 0 ? " checked" : ""}><span><strong>${account}</strong><small>${label}</small></span></label>`;
|
|
1049
|
-
})
|
|
1050
|
-
.join("");
|
|
1051
|
-
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Choose GitHub installation</title><style>body{font-family:system-ui,sans-serif;margin:0;min-height:100vh;display:grid;place-items:center;background:#0b0b0d;color:#f4f4f5}main{width:min(640px,calc(100vw - 32px));border:1px solid #27272a;border-radius:12px;padding:28px;background:#111114}h1{margin:0 0 10px;font-size:24px}p{margin:0 0 18px;color:#d4d4d8}.options{display:grid;gap:8px;margin-bottom:18px}.option{display:flex;align-items:center;gap:12px;border:1px solid #3f3f46;border-radius:8px;padding:12px;cursor:pointer}.option span{display:grid;gap:2px}.option small{color:#a1a1aa}button{min-height:38px;border-radius:7px;border:1px solid #3f3f46;padding:0 14px;background:#f4f4f5;color:#09090b;font:600 14px system-ui,sans-serif;cursor:pointer}.secondary{margin-left:8px;background:transparent;color:#f4f4f5}</style></head><body><main><h1>Choose a GitHub account</h1><p>These accounts already have the OpenGeni GitHub App installed and GitHub proved you are the personal owner or an active organization owner.</p><form method="get" action="${escapeHtml(action)}"><input type="hidden" name="state" value="${escapeHtml(state)}"><div class="options">${options}</div><button type="submit">Connect selected</button><button class="secondary" type="submit" name="installation_id" value="new" formnovalidate>Install on another account</button></form></main></body></html>`;
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
function githubSetupPendingHtml(): string {
|
|
1055
|
-
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>GitHub App Requested</title><style>body{font-family:system-ui,sans-serif;margin:0;min-height:100vh;display:grid;place-items:center;background:#0b0b0d;color:#f4f4f5}main{width:min(640px,calc(100vw - 32px));border:1px solid #27272a;border-radius:8px;padding:28px;background:#111114}h1{margin:0 0 10px;font-size:24px;line-height:1.2}p{margin:0;color:#d4d4d8}</style></head><body><main><h1>GitHub App request sent</h1><p>A GitHub organization owner must approve the installation. OpenGeni has not created a workspace binding.</p></main></body></html>`;
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
1144
|
function parsePositiveInteger(value: string | undefined | null): number | null {
|
|
1059
1145
|
if (!value || !/^\d+$/.test(value)) {
|
|
1060
1146
|
return null;
|
|
@@ -1068,32 +1154,19 @@ function isFreshGitHubBindingState(payload: GitHubSignedStatePayload): boolean {
|
|
|
1068
1154
|
return age >= 0 && age < githubBindingStateMaxAgeSeconds;
|
|
1069
1155
|
}
|
|
1070
1156
|
|
|
1071
|
-
function escapeHtml(value: string): string {
|
|
1072
|
-
return value.replace(
|
|
1073
|
-
/[&<>"']/g,
|
|
1074
|
-
(char) =>
|
|
1075
|
-
({
|
|
1076
|
-
"&": "&",
|
|
1077
|
-
"<": "<",
|
|
1078
|
-
">": ">",
|
|
1079
|
-
'"': """,
|
|
1080
|
-
"'": "'",
|
|
1081
|
-
})[char] ?? char,
|
|
1082
|
-
);
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
1157
|
function openGeniReturnUrl(
|
|
1086
1158
|
settings: ApiRouteDeps["settings"],
|
|
1087
1159
|
c: Context,
|
|
1088
1160
|
workspaceId: string,
|
|
1089
1161
|
returnPath: string | null = null,
|
|
1162
|
+
outcome: "connected" | "requested" = "connected",
|
|
1090
1163
|
): string {
|
|
1091
1164
|
const baseUrl = openGeniBaseUrl(settings, c) || new URL(c.req.url).origin;
|
|
1092
1165
|
const safeReturnPath = githubSessionReturnPath(returnPath, workspaceId);
|
|
1093
1166
|
const url = safeReturnPath ? new URL(safeReturnPath, `${baseUrl}/`) : new URL(baseUrl);
|
|
1094
1167
|
if (safeReturnPath) {
|
|
1095
1168
|
url.searchParams.delete("capability_auth");
|
|
1096
|
-
url.searchParams.set("github",
|
|
1169
|
+
url.searchParams.set("github", outcome);
|
|
1097
1170
|
return url.toString();
|
|
1098
1171
|
}
|
|
1099
1172
|
url.searchParams.set("workspaceId", workspaceId);
|
|
@@ -1103,3 +1176,55 @@ function openGeniReturnUrl(
|
|
|
1103
1176
|
function openGeniBaseUrl(settings: ApiRouteDeps["settings"], c: Context): string {
|
|
1104
1177
|
return githubBrowserBaseUrl(settings, new URL(c.req.url).origin);
|
|
1105
1178
|
}
|
|
1179
|
+
|
|
1180
|
+
/** The status the app error handler gives this failure; the page keeps it. */
|
|
1181
|
+
function githubBrowserFailureStatus(error: unknown, handledStatus: number | undefined): number {
|
|
1182
|
+
if (error instanceof HTTPException) return error.status;
|
|
1183
|
+
if (error instanceof OrganizationIntegrationDeniedError) return 403;
|
|
1184
|
+
// An unexpected fault keeps whatever the error handler answered (500 by default).
|
|
1185
|
+
return handledStatus ?? 500;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
function githubBrowserFailureKind(error: unknown): GitHubConnectFailure {
|
|
1189
|
+
if (error instanceof OrganizationIntegrationDeniedError) return "policy_denied";
|
|
1190
|
+
if (!(error instanceof HTTPException)) return "failed";
|
|
1191
|
+
if (error instanceof GitHubBrowserFailure) return error.failure;
|
|
1192
|
+
if (error.status === 401) return "signed_out";
|
|
1193
|
+
if (error.status === 403) return "forbidden";
|
|
1194
|
+
// Every signed-state rejection names its state; they all mean "start again".
|
|
1195
|
+
if (error.status === 400 && /\bstate\b/iu.test(error.message)) return "expired";
|
|
1196
|
+
return "failed";
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
/**
|
|
1200
|
+
* Human-authored HTTP messages only; configuration errors carry a JSON
|
|
1201
|
+
* envelope. Anything else (an unexpected fault) shows no detail.
|
|
1202
|
+
*/
|
|
1203
|
+
function githubBrowserFailureDetail(error: unknown): string | null {
|
|
1204
|
+
if (!(error instanceof HTTPException)) return null;
|
|
1205
|
+
if (error instanceof GitHubBrowserFailure && error.failure === "cancelled") return null;
|
|
1206
|
+
try {
|
|
1207
|
+
const parsed = JSON.parse(error.message) as { message?: unknown };
|
|
1208
|
+
return typeof parsed?.message === "string" ? parsed.message : null;
|
|
1209
|
+
} catch {
|
|
1210
|
+
return error.message || null;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* The failure page links back to the workspace integrations page when the
|
|
1216
|
+
* request names a workspace (its path, or a correctly signed state even if it
|
|
1217
|
+
* aged out); otherwise to the Opengeni home. This is only a link target, so an
|
|
1218
|
+
* expired state is acceptable evidence of where the user came from.
|
|
1219
|
+
*/
|
|
1220
|
+
function githubFailureReturnUrl(deps: ApiRouteDeps, c: Context): string {
|
|
1221
|
+
const baseUrl = (
|
|
1222
|
+
deps.settings.webBaseUrl ??
|
|
1223
|
+
(openGeniBaseUrl(deps.settings, c) || new URL(c.req.url).origin)
|
|
1224
|
+
).replace(/\/+$/u, "");
|
|
1225
|
+
const rawState = c.req.query("state");
|
|
1226
|
+
const candidate =
|
|
1227
|
+
c.req.param("workspaceId") ??
|
|
1228
|
+
(rawState ? inspectSignedState(rawState, deps.githubStateSecret)?.workspaceId : undefined);
|
|
1229
|
+
return `${baseUrl}${workspaceIntegrationsPathForUntrusted(candidate) ?? "/"}`;
|
|
1230
|
+
}
|