@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/auth/managed-auth.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { canonicalPublicOrigin, type Settings } from "@opengeni/config";
|
|
1
|
+
import { canonicalPublicOrigin, managedUserEmailAllowed, type Settings } from "@opengeni/config";
|
|
2
|
+
import { MANAGED_AUTH_NEW_SIGNUPS_PAUSED_CODE } from "@opengeni/contracts";
|
|
2
3
|
import {
|
|
4
|
+
configureManagedUserAdmission,
|
|
5
|
+
recordManagedAuthLoggedFailure,
|
|
3
6
|
type ManagedAuth,
|
|
4
7
|
type ManagedEmailMessage,
|
|
5
8
|
type ManagedEmailTransport,
|
|
@@ -12,20 +15,37 @@ import {
|
|
|
12
15
|
getCanonicalHumanExactLoginBindingForAuthUser,
|
|
13
16
|
synchronizeCanonicalHumanLoginBindings,
|
|
14
17
|
} from "@opengeni/db/canonical-human-identities";
|
|
18
|
+
import type { Observability } from "@opengeni/observability";
|
|
15
19
|
import { betterAuth } from "better-auth";
|
|
16
|
-
import { createEmailVerificationToken } from "better-auth/api";
|
|
17
|
-
import { hashPassword } from "better-auth/crypto";
|
|
20
|
+
import { APIError, createEmailVerificationToken } from "better-auth/api";
|
|
21
|
+
import { hashPassword, verifyPassword } from "better-auth/crypto";
|
|
18
22
|
import { sql } from "drizzle-orm";
|
|
19
|
-
import { Pool } from "pg";
|
|
23
|
+
import { Pool, type PoolConfig } from "pg";
|
|
20
24
|
|
|
25
|
+
import { TRUSTED_CLIENT_ADDRESS_HEADER } from "../http/request-source";
|
|
21
26
|
import { decideCanonicalHumanSessionAdmission } from "./canonical-human-session-admission";
|
|
27
|
+
import {
|
|
28
|
+
createManagedAuthEmailThrottleHook,
|
|
29
|
+
MANAGED_AUTH_CLIENT_RATE_LIMIT_RULES,
|
|
30
|
+
} from "./managed-auth-rate-limits";
|
|
31
|
+
import { deliverManagedSignInNotification } from "./managed-sign-in-notifications";
|
|
32
|
+
import {
|
|
33
|
+
createManagedAuthNewSignupsGate,
|
|
34
|
+
type ManagedAuthNewSignupsGate,
|
|
35
|
+
} from "./new-signups-gate";
|
|
36
|
+
import { createSignupFunnelMetrics } from "./signup-funnel-metrics";
|
|
22
37
|
import {
|
|
23
38
|
currentManagedAuthProviderId,
|
|
24
39
|
currentManagedAuthAttemptId,
|
|
25
40
|
recordCurrentManagedAuthSession,
|
|
26
41
|
shouldDiscardCurrentManagedAuthProviderSession,
|
|
42
|
+
currentManagedSignInConnectIntent,
|
|
27
43
|
} from "./managed-auth-attempt-context";
|
|
28
44
|
|
|
45
|
+
// Only used when no Better Auth secret is configured (local development);
|
|
46
|
+
// the email throttle key is a content-free digest either way.
|
|
47
|
+
const MANAGED_AUTH_EMAIL_THROTTLE_FALLBACK_KEY = "opengeni:managed-auth:email-throttle:local";
|
|
48
|
+
|
|
29
49
|
// `ManagedAuth` (the Better Auth `Auth<any>` alias) is owned by @opengeni/core
|
|
30
50
|
// (`managed-auth-type.ts`) — `dependencies.ts`/`access` reference it as a
|
|
31
51
|
// type-only slot. We re-export it from this construction site so existing
|
|
@@ -33,26 +53,61 @@ import {
|
|
|
33
53
|
export type { ManagedAuth };
|
|
34
54
|
|
|
35
55
|
export function managedAuthRequiresEmailVerification(
|
|
36
|
-
settings: Pick<Settings, "environment">,
|
|
56
|
+
settings: Pick<Settings, "environment" | "managedAuthRequireEmailVerification">,
|
|
37
57
|
): boolean {
|
|
38
|
-
return settings.environment !== "local";
|
|
58
|
+
return settings.managedAuthRequireEmailVerification ?? settings.environment !== "local";
|
|
39
59
|
}
|
|
40
60
|
|
|
41
61
|
export function managedAuthUserCreateOverride(
|
|
42
|
-
settings: Pick<Settings, "environment">,
|
|
62
|
+
settings: Pick<Settings, "environment" | "managedAuthRequireEmailVerification">,
|
|
43
63
|
user: { emailVerified: boolean } & Record<string, unknown>,
|
|
44
64
|
): { data: typeof user } | undefined {
|
|
45
65
|
if (managedAuthRequiresEmailVerification(settings)) return undefined;
|
|
46
66
|
return { data: { ...user, emailVerified: true } };
|
|
47
67
|
}
|
|
48
68
|
|
|
69
|
+
export const MANAGED_AUTH_NEW_SIGNUPS_PAUSED_MESSAGE =
|
|
70
|
+
"We're at capacity for new accounts right now. Please try again later.";
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Typed refusal for a new account while the deployment has paused sign-ups.
|
|
74
|
+
* Existing accounts are unaffected; the body mirrors Better Auth's
|
|
75
|
+
* `{ code, message }` error shape so browser and SDK callers parse it alike.
|
|
76
|
+
*/
|
|
77
|
+
export function managedAuthNewSignupsPausedResponse(): Response {
|
|
78
|
+
return Response.json(
|
|
79
|
+
{
|
|
80
|
+
code: MANAGED_AUTH_NEW_SIGNUPS_PAUSED_CODE,
|
|
81
|
+
message: MANAGED_AUTH_NEW_SIGNUPS_PAUSED_MESSAGE,
|
|
82
|
+
},
|
|
83
|
+
{ status: 403, headers: { "cache-control": "no-store" } },
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Thrown from the user-create hook while the runtime switch has paused new
|
|
89
|
+
* sign-ups. Better Auth returns it as `403 { code: "NEW_SIGNUPS_PAUSED" }` on
|
|
90
|
+
* email sign-up, and its OAuth callback turns the message into the
|
|
91
|
+
* `error=signup_disabled` redirect it also uses for a static provider refusal.
|
|
92
|
+
*/
|
|
93
|
+
export class ManagedAuthNewSignupsPausedError extends APIError {
|
|
94
|
+
constructor() {
|
|
95
|
+
super("FORBIDDEN", { code: MANAGED_AUTH_NEW_SIGNUPS_PAUSED_CODE, message: "signup disabled" });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
49
99
|
export function managedAuthUserCreateAdmission(
|
|
50
|
-
settings: Pick<Settings, "environment"
|
|
100
|
+
settings: Pick<Settings, "environment" | "allowedUserEmails"> &
|
|
101
|
+
Partial<Pick<Settings, "managedAuthNewSignupsEnabled" | "managedAuthRequireEmailVerification">>,
|
|
51
102
|
user: { emailVerified: boolean } & Record<string, unknown>,
|
|
52
103
|
providerId: string,
|
|
53
104
|
): { data: typeof user } | false | undefined {
|
|
105
|
+
// Backstop for every Better Auth user-create path. Invited-user account
|
|
106
|
+
// setup does not create users through Better Auth, so it is unaffected.
|
|
107
|
+
if (settings.managedAuthNewSignupsEnabled === false) return false;
|
|
108
|
+
if (!managedUserEmailAllowed(settings.allowedUserEmails, user.email)) return false;
|
|
54
109
|
if (
|
|
55
|
-
managedAuthRequiresEmailVerification(settings) &&
|
|
110
|
+
(settings.environment !== "local" || managedAuthRequiresEmailVerification(settings)) &&
|
|
56
111
|
providerId !== "credential" &&
|
|
57
112
|
!user.emailVerified
|
|
58
113
|
) {
|
|
@@ -61,29 +116,168 @@ export function managedAuthUserCreateAdmission(
|
|
|
61
116
|
return managedAuthUserCreateOverride(settings, user);
|
|
62
117
|
}
|
|
63
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Per-provider Better Auth options while sign-ups are paused. A social sign-in
|
|
121
|
+
* for an existing human still signs in (and may link a verified provider);
|
|
122
|
+
* an unknown human is redirected back with `error=signup_disabled`.
|
|
123
|
+
* `disableSignUp` is the hard switch: `disableImplicitSignUp` alone can be
|
|
124
|
+
* overridden by a client-supplied `requestSignUp`.
|
|
125
|
+
*/
|
|
126
|
+
export function managedAuthSocialSignupOptions(
|
|
127
|
+
settings: Pick<Settings, "managedAuthNewSignupsEnabled">,
|
|
128
|
+
): { disableImplicitSignUp?: true; disableSignUp?: true } {
|
|
129
|
+
return settings.managedAuthNewSignupsEnabled
|
|
130
|
+
? {}
|
|
131
|
+
: { disableImplicitSignUp: true, disableSignUp: true };
|
|
132
|
+
}
|
|
133
|
+
|
|
64
134
|
/** Keep Better Auth password policy and storage format behind this boundary. */
|
|
65
135
|
export async function hashManagedAuthPassword(password: string): Promise<string> {
|
|
66
136
|
return await hashPassword(password);
|
|
67
137
|
}
|
|
68
138
|
|
|
139
|
+
export async function verifyManagedAuthPassword(password: string, hash: string): Promise<boolean> {
|
|
140
|
+
return await verifyPassword({ password, hash });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
type ManagedAuthPoolObservability = Pick<Observability, "warn" | "incrementCounter">;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Better Auth's default console output, plus handing logged failures to the
|
|
147
|
+
* session-lookup boundary so a lost database connection behind its generic
|
|
148
|
+
* INTERNAL_SERVER_ERROR stays recognizable (see `withManagedAuthSessionLookup`).
|
|
149
|
+
*/
|
|
150
|
+
function logBetterAuthMessage(
|
|
151
|
+
level: "debug" | "info" | "warn" | "error",
|
|
152
|
+
message: string,
|
|
153
|
+
...args: unknown[]
|
|
154
|
+
): void {
|
|
155
|
+
if (level === "error") recordManagedAuthLoggedFailure(args);
|
|
156
|
+
const line = `${new Date().toISOString()} ${level.toUpperCase()} [Better Auth]: ${message}`;
|
|
157
|
+
if (level === "error") console.error(line, ...args);
|
|
158
|
+
else if (level === "warn") console.warn(line, ...args);
|
|
159
|
+
else console.log(line, ...args);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Bounded pool settings for Better Auth's dedicated `pg` pool. A connection
|
|
164
|
+
* attempt fails after 10 s instead of queueing requests indefinitely while the
|
|
165
|
+
* database is unreachable, and connections recycle like the main postgres-js
|
|
166
|
+
* pool so a pooler- or failover-replaced backend is not held forever.
|
|
167
|
+
*/
|
|
168
|
+
export const MANAGED_AUTH_DATABASE_POOL_OPTIONS = {
|
|
169
|
+
max: 10,
|
|
170
|
+
connectionTimeoutMillis: 10_000,
|
|
171
|
+
idleTimeoutMillis: 30_000,
|
|
172
|
+
maxLifetimeSeconds: 1_800,
|
|
173
|
+
keepAlive: true,
|
|
174
|
+
} as const satisfies PoolConfig;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Better Auth's `pg` pool. When the server closes a connection (a restart,
|
|
178
|
+
* failover, or maintenance window) `pg` emits `error`: on the pool for an idle
|
|
179
|
+
* client, and on the client itself for one checked out by Better Auth's query
|
|
180
|
+
* layer. Without listeners either becomes an uncaught exception and the API's
|
|
181
|
+
* fatal process boundary exits. Both listeners record one content-free signal
|
|
182
|
+
* and keep serving. The pool has already discarded a failed idle client and
|
|
183
|
+
* opens a fresh connection for the next checkout; a checked-out client's
|
|
184
|
+
* in-flight query already rejects to its caller, and the pool discards the
|
|
185
|
+
* dead client on release. An idle client's error also reaches its own
|
|
186
|
+
* listener, so that listener records only while the client is checked out,
|
|
187
|
+
* and at most once per checkout.
|
|
188
|
+
*/
|
|
189
|
+
export function createManagedAuthDatabasePool(
|
|
190
|
+
databaseUrl: string,
|
|
191
|
+
observability?: ManagedAuthPoolObservability,
|
|
192
|
+
): Pool {
|
|
193
|
+
const pool = new Pool({ connectionString: databaseUrl, ...MANAGED_AUTH_DATABASE_POOL_OPTIONS });
|
|
194
|
+
const checkedOut = new WeakSet<object>();
|
|
195
|
+
pool.on("acquire", (client) => checkedOut.add(client));
|
|
196
|
+
pool.on("release", (_error, client) => checkedOut.delete(client));
|
|
197
|
+
pool.on("connect", (client) => {
|
|
198
|
+
client.on("error", () => {
|
|
199
|
+
// One lost connection can emit twice (the server's termination
|
|
200
|
+
// message, then the socket end), so count it once.
|
|
201
|
+
if (checkedOut.delete(client)) {
|
|
202
|
+
recordManagedAuthPoolError(observability, "checked_out_connection_failed");
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
pool.on("error", () => recordManagedAuthPoolError(observability, "idle_connection_discarded"));
|
|
207
|
+
return pool;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export const MANAGED_AUTH_DATABASE_POOL_ERRORS_METRIC = {
|
|
211
|
+
name: "opengeni_managed_auth_database_pool_errors_total",
|
|
212
|
+
help: "Managed-auth database connections the server closed or lost, by pool state.",
|
|
213
|
+
} as const;
|
|
214
|
+
|
|
215
|
+
function recordManagedAuthPoolError(
|
|
216
|
+
observability: ManagedAuthPoolObservability | undefined,
|
|
217
|
+
outcome: "idle_connection_discarded" | "checked_out_connection_failed",
|
|
218
|
+
): void {
|
|
219
|
+
try {
|
|
220
|
+
observability?.incrementCounter({
|
|
221
|
+
...MANAGED_AUTH_DATABASE_POOL_ERRORS_METRIC,
|
|
222
|
+
labels: { outcome },
|
|
223
|
+
});
|
|
224
|
+
observability?.warn("Managed auth database connection failed", {
|
|
225
|
+
dependency: "managed_auth_database",
|
|
226
|
+
outcome,
|
|
227
|
+
});
|
|
228
|
+
} catch {
|
|
229
|
+
// An observer failure must not turn a recovered pool error into a crash.
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
69
233
|
export function createManagedAuth(
|
|
70
234
|
settings: Settings,
|
|
71
235
|
db: Database,
|
|
72
236
|
managedEmailTransport: ManagedEmailTransport,
|
|
237
|
+
options: {
|
|
238
|
+
observability?: ManagedAuthPoolObservability;
|
|
239
|
+
newSignupsGate?: ManagedAuthNewSignupsGate;
|
|
240
|
+
} = {},
|
|
73
241
|
): ManagedAuth | null {
|
|
74
242
|
if (settings.productAccessMode !== "managed") {
|
|
75
243
|
return null;
|
|
76
244
|
}
|
|
245
|
+
// Content-free sign-up funnel counters; recording never fails an auth flow.
|
|
246
|
+
const funnel = options.observability
|
|
247
|
+
? createSignupFunnelMetrics(options.observability)
|
|
248
|
+
: undefined;
|
|
77
249
|
const requireEmailVerification = managedAuthRequiresEmailVerification(settings);
|
|
78
|
-
const pool =
|
|
79
|
-
|
|
80
|
-
|
|
250
|
+
const pool = createManagedAuthDatabasePool(settings.databaseUrl, options.observability);
|
|
251
|
+
// The deployment ceiling is static Better Auth configuration; the runtime
|
|
252
|
+
// switch is checked per user create in the hook below.
|
|
253
|
+
const newSignupsSocialProviderOptions = managedAuthSocialSignupOptions(settings);
|
|
254
|
+
const newSignupsGate =
|
|
255
|
+
options.newSignupsGate ??
|
|
256
|
+
createManagedAuthNewSignupsGate({ db, settings, observability: options.observability });
|
|
257
|
+
const auth = betterAuth({
|
|
258
|
+
appName: "Opengeni",
|
|
81
259
|
baseURL: betterAuthBaseUrl(settings),
|
|
82
260
|
basePath: "/v1/auth",
|
|
83
261
|
secret: settings.betterAuthSecret,
|
|
84
262
|
database: pool,
|
|
85
263
|
trustedOrigins: betterAuthTrustedOrigins(settings),
|
|
264
|
+
logger: { log: logBetterAuthMessage },
|
|
265
|
+
hooks: {
|
|
266
|
+
before: createManagedAuthEmailThrottleHook(
|
|
267
|
+
db,
|
|
268
|
+
settings.betterAuthSecret ?? MANAGED_AUTH_EMAIL_THROTTLE_FALLBACK_KEY,
|
|
269
|
+
),
|
|
270
|
+
},
|
|
86
271
|
advanced: {
|
|
272
|
+
// Better Auth reads client addresses only from request headers. The API
|
|
273
|
+
// strips this header from every inbound request and re-stamps it on
|
|
274
|
+
// managed-auth routes with the trusted source address (transport peer,
|
|
275
|
+
// or the forwarded client when OPENGENI_API_TRUSTED_PROXY_HOPS declares
|
|
276
|
+
// a proxy chain), so callers cannot choose their rate-limit bucket or
|
|
277
|
+
// recorded session address.
|
|
278
|
+
ipAddress: {
|
|
279
|
+
ipAddressHeaders: [TRUSTED_CLIENT_ADDRESS_HEADER],
|
|
280
|
+
},
|
|
87
281
|
useSecureCookies: settings.publicBaseUrl?.startsWith("https://") ?? false,
|
|
88
282
|
...(settings.betterAuthCookieDomain
|
|
89
283
|
? {
|
|
@@ -104,6 +298,7 @@ export function createManagedAuth(
|
|
|
104
298
|
fields: {
|
|
105
299
|
lastRequest: "last_request",
|
|
106
300
|
},
|
|
301
|
+
customRules: MANAGED_AUTH_CLIENT_RATE_LIMIT_RULES,
|
|
107
302
|
},
|
|
108
303
|
user: {
|
|
109
304
|
modelName: "auth_users",
|
|
@@ -180,7 +375,18 @@ export function createManagedAuth(
|
|
|
180
375
|
updatedAt: "updated_at",
|
|
181
376
|
},
|
|
182
377
|
accountLinking: {
|
|
183
|
-
enabled:
|
|
378
|
+
enabled: true,
|
|
379
|
+
requireLocalEmailVerified: true,
|
|
380
|
+
trustedProviders: [],
|
|
381
|
+
allowDifferentEmails: false,
|
|
382
|
+
},
|
|
383
|
+
additionalFields: {
|
|
384
|
+
managedLinkIntentId: {
|
|
385
|
+
type: "string",
|
|
386
|
+
fieldName: "managed_link_intent_id",
|
|
387
|
+
input: false,
|
|
388
|
+
returned: false,
|
|
389
|
+
},
|
|
184
390
|
},
|
|
185
391
|
encryptOAuthTokens: true,
|
|
186
392
|
storeStateStrategy: "database",
|
|
@@ -192,6 +398,7 @@ export function createManagedAuth(
|
|
|
192
398
|
clientId: settings.managedAuthGoogleClientId,
|
|
193
399
|
clientSecret: settings.managedAuthGoogleClientSecret,
|
|
194
400
|
prompt: "select_account" as const,
|
|
401
|
+
...newSignupsSocialProviderOptions,
|
|
195
402
|
},
|
|
196
403
|
}
|
|
197
404
|
: {}),
|
|
@@ -200,6 +407,7 @@ export function createManagedAuth(
|
|
|
200
407
|
github: {
|
|
201
408
|
clientId: settings.managedAuthGithubClientId,
|
|
202
409
|
clientSecret: settings.managedAuthGithubClientSecret,
|
|
410
|
+
...newSignupsSocialProviderOptions,
|
|
203
411
|
},
|
|
204
412
|
}
|
|
205
413
|
: {}),
|
|
@@ -215,45 +423,48 @@ export function createManagedAuth(
|
|
|
215
423
|
},
|
|
216
424
|
emailAndPassword: {
|
|
217
425
|
enabled: true,
|
|
426
|
+
// Sign-in, password reset, and verification stay enabled; only new
|
|
427
|
+
// account creation is refused while sign-ups are paused.
|
|
428
|
+
disableSignUp: !settings.managedAuthNewSignupsEnabled,
|
|
218
429
|
// Local managed mode exists so the complete human/org tenancy flow can
|
|
219
430
|
// be exercised without first configuring a transactional-email vendor.
|
|
220
|
-
//
|
|
431
|
+
// Non-local deployments require verification unless explicitly overridden.
|
|
221
432
|
requireEmailVerification,
|
|
222
433
|
revokeSessionsOnPasswordReset: true,
|
|
223
434
|
onExistingUserSignUp: async ({ user }) => {
|
|
224
435
|
if (requireEmailVerification && !user.emailVerified) {
|
|
225
436
|
const url = await verificationUrl(settings, user.email);
|
|
226
|
-
await sendManagedAuthEmail(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
text: `Verify your OpenGeni email: ${url}`,
|
|
231
|
-
html: `<p>Verify your OpenGeni email:</p><p><a href="${escapeHtml(url)}">Verify email</a></p>`,
|
|
232
|
-
});
|
|
437
|
+
await sendManagedAuthEmail(
|
|
438
|
+
managedEmailTransport,
|
|
439
|
+
emailVerificationMessage(user.email, url),
|
|
440
|
+
);
|
|
233
441
|
}
|
|
234
442
|
},
|
|
235
443
|
sendResetPassword: async ({ user, url }) => {
|
|
236
444
|
await sendManagedAuthEmail(managedEmailTransport, {
|
|
237
445
|
kind: "password_reset",
|
|
238
446
|
to: user.email,
|
|
239
|
-
subject: "Reset your
|
|
240
|
-
text: `Reset your
|
|
241
|
-
html: `<p>Reset your
|
|
447
|
+
subject: "Reset your Opengeni password",
|
|
448
|
+
text: `Reset your Opengeni password: ${url}`,
|
|
449
|
+
html: `<p>Reset your Opengeni password:</p><p><a href="${escapeHtml(url)}">Reset password</a></p>`,
|
|
242
450
|
});
|
|
243
451
|
},
|
|
244
452
|
},
|
|
245
453
|
emailVerification: {
|
|
246
454
|
sendOnSignUp: requireEmailVerification,
|
|
455
|
+
// The first successful verification link click signs the user in (a
|
|
456
|
+
// reused link creates no session). Only legacy mode: session-set modes
|
|
457
|
+
// bind sign-in to an isolated browser transaction, and the provider
|
|
458
|
+
// session this would create is discarded there by design.
|
|
459
|
+
autoSignInAfterVerification: settings.managedAuthSessionSetMode === "legacy",
|
|
247
460
|
sendVerificationEmail: async ({ user, url }) => {
|
|
248
|
-
await sendManagedAuthEmail(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
text: `Verify your OpenGeni email: ${url}`,
|
|
253
|
-
html: `<p>Verify your OpenGeni email:</p><p><a href="${escapeHtml(url)}">Verify email</a></p>`,
|
|
254
|
-
});
|
|
461
|
+
await sendManagedAuthEmail(
|
|
462
|
+
managedEmailTransport,
|
|
463
|
+
emailVerificationMessage(user.email, url),
|
|
464
|
+
);
|
|
255
465
|
},
|
|
256
466
|
afterEmailVerification: async (user) => {
|
|
467
|
+
funnel?.recordEmailVerified();
|
|
257
468
|
await ensureManagedAccessForUser(db, {
|
|
258
469
|
userId: user.id,
|
|
259
470
|
email: user.email,
|
|
@@ -264,9 +475,41 @@ export function createManagedAuth(
|
|
|
264
475
|
},
|
|
265
476
|
},
|
|
266
477
|
databaseHooks: {
|
|
478
|
+
account: {
|
|
479
|
+
create: {
|
|
480
|
+
before: async (account) => ({
|
|
481
|
+
data: {
|
|
482
|
+
...account,
|
|
483
|
+
...(currentManagedSignInConnectIntent()
|
|
484
|
+
? { managedLinkIntentId: currentManagedSignInConnectIntent() }
|
|
485
|
+
: {}),
|
|
486
|
+
},
|
|
487
|
+
}),
|
|
488
|
+
after: async (account) => {
|
|
489
|
+
if (
|
|
490
|
+
!["google", "github"].includes(account.providerId) ||
|
|
491
|
+
currentManagedSignInConnectIntent()
|
|
492
|
+
)
|
|
493
|
+
return;
|
|
494
|
+
await deliverManagedSignInNotification(db, managedEmailTransport, account.id);
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
},
|
|
267
498
|
session: {
|
|
268
499
|
create: {
|
|
269
500
|
before: async (session) => {
|
|
501
|
+
if (settings.allowedUserEmails !== undefined) {
|
|
502
|
+
const result = await pool.query<{ email: string; email_verified: boolean }>(
|
|
503
|
+
"select email, email_verified from auth_users where id = $1",
|
|
504
|
+
[session.userId],
|
|
505
|
+
);
|
|
506
|
+
const user = result.rows[0];
|
|
507
|
+
if (
|
|
508
|
+
!user?.email_verified ||
|
|
509
|
+
!managedUserEmailAllowed(settings.allowedUserEmails, user.email)
|
|
510
|
+
)
|
|
511
|
+
return false;
|
|
512
|
+
}
|
|
270
513
|
const providerId = currentManagedAuthProviderId();
|
|
271
514
|
await ensureCanonicalHumanIdentityForAuthUser(db, session.userId);
|
|
272
515
|
const preflightProjection = await getCanonicalHumanIdentityProjection(
|
|
@@ -357,6 +600,7 @@ export function createManagedAuth(
|
|
|
357
600
|
};
|
|
358
601
|
},
|
|
359
602
|
after: async (session) => {
|
|
603
|
+
funnel?.recordSignIn();
|
|
360
604
|
recordCurrentManagedAuthSession(session.id);
|
|
361
605
|
if (!shouldDiscardCurrentManagedAuthProviderSession()) return;
|
|
362
606
|
await db.execute(sql`delete from auth_sessions where id = ${session.id}`);
|
|
@@ -365,9 +609,18 @@ export function createManagedAuth(
|
|
|
365
609
|
},
|
|
366
610
|
user: {
|
|
367
611
|
create: {
|
|
368
|
-
before: async (user) =>
|
|
369
|
-
|
|
370
|
-
|
|
612
|
+
before: async (user) => {
|
|
613
|
+
const admission = managedAuthUserCreateAdmission(
|
|
614
|
+
settings,
|
|
615
|
+
user,
|
|
616
|
+
currentManagedAuthProviderId(),
|
|
617
|
+
);
|
|
618
|
+
if (admission === false) return false;
|
|
619
|
+
if (!(await newSignupsGate.signupsOpen())) throw new ManagedAuthNewSignupsPausedError();
|
|
620
|
+
return admission;
|
|
621
|
+
},
|
|
622
|
+
after: async (user, context) => {
|
|
623
|
+
await funnel?.recordSignUp(context);
|
|
371
624
|
if (!user.emailVerified) return;
|
|
372
625
|
await ensureManagedAccessForUser(db, {
|
|
373
626
|
userId: user.id,
|
|
@@ -381,6 +634,8 @@ export function createManagedAuth(
|
|
|
381
634
|
},
|
|
382
635
|
},
|
|
383
636
|
}) as ManagedAuth;
|
|
637
|
+
configureManagedUserAdmission(auth, settings.allowedUserEmails);
|
|
638
|
+
return auth;
|
|
384
639
|
}
|
|
385
640
|
|
|
386
641
|
export type ManagedAuthOAuthAttempt = {
|
|
@@ -393,7 +648,7 @@ export type ManagedAuthOAuthAttempt = {
|
|
|
393
648
|
};
|
|
394
649
|
|
|
395
650
|
/**
|
|
396
|
-
* Resolve
|
|
651
|
+
* Resolve Opengeni's server-only login transaction proof from Better Auth's
|
|
397
652
|
* database-backed OAuth state before the provider callback consumes it.
|
|
398
653
|
*/
|
|
399
654
|
export async function resolveManagedAuthOAuthAttempt(
|
|
@@ -533,6 +788,19 @@ export async function sendManagedAuthEmail(
|
|
|
533
788
|
if (result.status !== "sent") throw new Error(`managed email ${result.status}`);
|
|
534
789
|
}
|
|
535
790
|
|
|
791
|
+
// Verification can sign the clicker in (autoSignInAfterVerification), so an
|
|
792
|
+
// unsolicited verification email must say plainly that it can be ignored.
|
|
793
|
+
function emailVerificationMessage(to: string, url: string): Omit<ManagedEmailMessage, "from"> {
|
|
794
|
+
const ignore = "If you did not create an Opengeni account, ignore this email.";
|
|
795
|
+
return {
|
|
796
|
+
kind: "email_verification",
|
|
797
|
+
to,
|
|
798
|
+
subject: "Verify your Opengeni email",
|
|
799
|
+
text: `Verify your Opengeni email: ${url}\n\n${ignore}`,
|
|
800
|
+
html: `<p>Verify your Opengeni email:</p><p><a href="${escapeHtml(url)}">Verify email</a></p><p>${ignore}</p>`,
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
|
|
536
804
|
async function verificationUrl(settings: Settings, email: string): Promise<string> {
|
|
537
805
|
if (!settings.betterAuthSecret) {
|
|
538
806
|
throw new Error(
|
|
@@ -33,7 +33,7 @@ export class InMemoryManagedEmailTransport implements ManagedEmailTransport {
|
|
|
33
33
|
idempotency?: ManagedEmailTransport["idempotency"];
|
|
34
34
|
} = {},
|
|
35
35
|
) {
|
|
36
|
-
this.sender = options.sender ?? "
|
|
36
|
+
this.sender = options.sender ?? "Opengeni <auth@mail.opengeni.ai>";
|
|
37
37
|
this.idempotency = options.idempotency ?? {
|
|
38
38
|
scope: "opengeni-in-memory-v1",
|
|
39
39
|
retentionSeconds: 86_400,
|
|
@@ -88,6 +88,20 @@ class UnconfiguredManagedEmailTransport implements ManagedEmailTransport {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/** Operator-selected OPENGENI_MANAGED_EMAIL_DELIVERY=disabled: never contacts a provider. */
|
|
92
|
+
class DisabledManagedEmailTransport implements ManagedEmailTransport {
|
|
93
|
+
readonly idempotency = {
|
|
94
|
+
scope: "opengeni-disabled-v1",
|
|
95
|
+
retentionSeconds: 0,
|
|
96
|
+
} as const;
|
|
97
|
+
|
|
98
|
+
constructor(readonly sender: string) {}
|
|
99
|
+
|
|
100
|
+
async send(): Promise<ManagedEmailDeliveryResult> {
|
|
101
|
+
return { status: "failed", errorClass: "delivery_disabled" };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
class ResendManagedEmailTransport implements ManagedEmailTransport {
|
|
92
106
|
private readonly client: Resend;
|
|
93
107
|
readonly idempotency: ManagedEmailTransport["idempotency"];
|
|
@@ -144,6 +158,9 @@ class ResendManagedEmailTransport implements ManagedEmailTransport {
|
|
|
144
158
|
}
|
|
145
159
|
|
|
146
160
|
export function createManagedEmailTransport(settings: Settings): ManagedEmailTransport {
|
|
161
|
+
if (settings.managedEmailDelivery === "disabled") {
|
|
162
|
+
return new DisabledManagedEmailTransport(settings.emailFrom);
|
|
163
|
+
}
|
|
147
164
|
if (settings.resendApiKey) {
|
|
148
165
|
if (!settings.betterAuthSecret) {
|
|
149
166
|
throw new Error("OPENGENI_BETTER_AUTH_SECRET is required for managed email delivery");
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ManagedEmailTransport } from "@opengeni/core";
|
|
2
|
+
import type { Database } from "@opengeni/db";
|
|
3
|
+
import { sql } from "drizzle-orm";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
const Claim = z.object({
|
|
7
|
+
operationId: z.string().uuid(),
|
|
8
|
+
leaseId: z.string().uuid(),
|
|
9
|
+
email: z.string().email(),
|
|
10
|
+
provider: z.enum(["password", "google", "github"]),
|
|
11
|
+
sender: z.string(),
|
|
12
|
+
});
|
|
13
|
+
const started = new WeakSet<object>();
|
|
14
|
+
|
|
15
|
+
export async function deliverManagedSignInNotification(
|
|
16
|
+
db: Database,
|
|
17
|
+
transport: ManagedEmailTransport,
|
|
18
|
+
operationId: string | null = null,
|
|
19
|
+
): Promise<"sent" | "failed" | "outcome_unknown"> {
|
|
20
|
+
try {
|
|
21
|
+
const result = await db.execute(
|
|
22
|
+
sql`select claim_managed_sign_in_notification(${operationId}::uuid,${transport.sender},${transport.idempotency.scope},${transport.idempotency.retentionSeconds}::integer) as claim`,
|
|
23
|
+
);
|
|
24
|
+
const row = (Array.isArray(result) ? result : result.rows)[0] as { claim: unknown } | undefined;
|
|
25
|
+
if (!row?.claim) return "outcome_unknown";
|
|
26
|
+
const claim = Claim.parse(row.claim);
|
|
27
|
+
let status: "sent" | "failed" | "outcome_unknown" = "outcome_unknown";
|
|
28
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
29
|
+
try {
|
|
30
|
+
const response = await Promise.race([
|
|
31
|
+
transport.send({
|
|
32
|
+
kind: "sign_in_method_changed",
|
|
33
|
+
from: claim.sender,
|
|
34
|
+
to: claim.email,
|
|
35
|
+
idempotencyKey: `sign-in-method:${claim.operationId}`,
|
|
36
|
+
subject: "Your Opengeni sign-in methods changed",
|
|
37
|
+
text: `Your Opengeni ${claim.provider} sign-in method changed. If this was not you, reset your password and contact your administrator.`,
|
|
38
|
+
html: `<p>Your Opengeni ${claim.provider} sign-in method changed. If this was not you, reset your password and contact your administrator.</p>`,
|
|
39
|
+
}),
|
|
40
|
+
new Promise<{ status: "outcome_unknown" }>((resolve) => {
|
|
41
|
+
timer = setTimeout(() => resolve({ status: "outcome_unknown" }), 5_000);
|
|
42
|
+
}),
|
|
43
|
+
]);
|
|
44
|
+
status = response.status;
|
|
45
|
+
} catch {
|
|
46
|
+
/* Retain the durable unknown claim for idempotent retry. */
|
|
47
|
+
} finally {
|
|
48
|
+
if (timer) clearTimeout(timer);
|
|
49
|
+
}
|
|
50
|
+
await db.execute(
|
|
51
|
+
sql`select settle_managed_sign_in_notification(${claim.operationId}::uuid,${claim.leaseId}::uuid,${status})`,
|
|
52
|
+
);
|
|
53
|
+
return status;
|
|
54
|
+
} catch {
|
|
55
|
+
// Security state is already committed. A failed claim/ack must never be
|
|
56
|
+
// reported as a failed method change; its durable obligation remains live.
|
|
57
|
+
return "outcome_unknown";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function startManagedSignInNotificationDelivery(
|
|
62
|
+
db: Database,
|
|
63
|
+
transport: ManagedEmailTransport,
|
|
64
|
+
): void {
|
|
65
|
+
if (started.has(db as object)) return;
|
|
66
|
+
started.add(db as object);
|
|
67
|
+
let active = false;
|
|
68
|
+
const drain = async () => {
|
|
69
|
+
if (active) return;
|
|
70
|
+
active = true;
|
|
71
|
+
try {
|
|
72
|
+
for (let count = 0; count < 10; count++)
|
|
73
|
+
if ((await deliverManagedSignInNotification(db, transport)) === "outcome_unknown") break;
|
|
74
|
+
} finally {
|
|
75
|
+
active = false;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const timer = setInterval(() => void drain(), 60_000);
|
|
79
|
+
(timer as ReturnType<typeof setInterval> & { unref?: () => void }).unref?.();
|
|
80
|
+
void drain();
|
|
81
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Settings } from "@opengeni/config";
|
|
2
|
+
import { readManagedAuthNewSignupsSwitch, type Database } from "@opengeni/db";
|
|
3
|
+
import type { Observability } from "@opengeni/observability";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Decides whether a new managed account may be created right now.
|
|
7
|
+
*
|
|
8
|
+
* `OPENGENI_MANAGED_AUTH_NEW_SIGNUPS_ENABLED` is the deployment ceiling (read at
|
|
9
|
+
* startup). While it allows sign-ups, the newest revision of the operator
|
|
10
|
+
* runtime switch (migration 0585) decides, read on every call so a flip
|
|
11
|
+
* applies to the next request on every API replica without a restart.
|
|
12
|
+
*
|
|
13
|
+
* Fail-safe: if the read fails, the last value this process observed wins;
|
|
14
|
+
* before any successful read, the deployment ceiling wins. A missing revision
|
|
15
|
+
* (pre-0585 schema) also follows the ceiling.
|
|
16
|
+
*/
|
|
17
|
+
export type ManagedAuthNewSignupsGate = {
|
|
18
|
+
signupsOpen(): Promise<boolean>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function createManagedAuthNewSignupsGate(input: {
|
|
22
|
+
db: Database;
|
|
23
|
+
settings: Pick<Settings, "managedAuthNewSignupsEnabled">;
|
|
24
|
+
observability?: Pick<Observability, "warn"> | undefined;
|
|
25
|
+
}): ManagedAuthNewSignupsGate {
|
|
26
|
+
const ceiling = input.settings.managedAuthNewSignupsEnabled !== false;
|
|
27
|
+
let lastKnown: boolean | null = null;
|
|
28
|
+
return {
|
|
29
|
+
async signupsOpen() {
|
|
30
|
+
if (!ceiling) return false;
|
|
31
|
+
try {
|
|
32
|
+
const current = await readManagedAuthNewSignupsSwitch(input.db);
|
|
33
|
+
lastKnown = current ? current.signupsEnabled : true;
|
|
34
|
+
return lastKnown;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
try {
|
|
37
|
+
input.observability?.warn("Managed auth new signups switch read failed", {
|
|
38
|
+
dependency: "managed_auth_new_signups_switch",
|
|
39
|
+
fallback: lastKnown === null ? "deployment_ceiling" : "last_known",
|
|
40
|
+
errorClass: error instanceof Error ? error.name : "UnknownError",
|
|
41
|
+
});
|
|
42
|
+
} catch {
|
|
43
|
+
// An observer failure must not decide a sign-up.
|
|
44
|
+
}
|
|
45
|
+
return lastKnown ?? ceiling;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|