@cat-factory/server 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/agents/CompositeAgentExecutor.d.ts +39 -0
- package/dist/agents/CompositeAgentExecutor.d.ts.map +1 -0
- package/dist/agents/CompositeAgentExecutor.js +169 -0
- package/dist/agents/CompositeAgentExecutor.js.map +1 -0
- package/dist/agents/ContainerAgentExecutor.d.ts +235 -0
- package/dist/agents/ContainerAgentExecutor.d.ts.map +1 -0
- package/dist/agents/ContainerAgentExecutor.js +825 -0
- package/dist/agents/ContainerAgentExecutor.js.map +1 -0
- package/dist/agents/ContainerRepoBootstrapper.d.ts +78 -0
- package/dist/agents/ContainerRepoBootstrapper.d.ts.map +1 -0
- package/dist/agents/ContainerRepoBootstrapper.js +279 -0
- package/dist/agents/ContainerRepoBootstrapper.js.map +1 -0
- package/dist/agents/ModelRouter.d.ts +69 -0
- package/dist/agents/ModelRouter.d.ts.map +1 -0
- package/dist/agents/ModelRouter.js +84 -0
- package/dist/agents/ModelRouter.js.map +1 -0
- package/dist/agents/RunnerJobClient.d.ts +41 -0
- package/dist/agents/RunnerJobClient.d.ts.map +1 -0
- package/dist/agents/RunnerJobClient.js +43 -0
- package/dist/agents/RunnerJobClient.js.map +1 -0
- package/dist/agents/modelProviderResolver.d.ts +33 -0
- package/dist/agents/modelProviderResolver.d.ts.map +1 -0
- package/dist/agents/modelProviderResolver.js +48 -0
- package/dist/agents/modelProviderResolver.js.map +1 -0
- package/dist/agents/providerCapabilities.d.ts +22 -0
- package/dist/agents/providerCapabilities.d.ts.map +1 -0
- package/dist/agents/providerCapabilities.js +43 -0
- package/dist/agents/providerCapabilities.js.map +1 -0
- package/dist/agents/resolveRepoTarget.d.ts +33 -0
- package/dist/agents/resolveRepoTarget.d.ts.map +1 -0
- package/dist/agents/resolveRepoTarget.js +81 -0
- package/dist/agents/resolveRepoTarget.js.map +1 -0
- package/dist/app.d.ts +12 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +102 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/GitHubOAuth.d.ts +39 -0
- package/dist/auth/GitHubOAuth.d.ts.map +1 -0
- package/dist/auth/GitHubOAuth.js +90 -0
- package/dist/auth/GitHubOAuth.js.map +1 -0
- package/dist/auth/GoogleOAuth.d.ts +35 -0
- package/dist/auth/GoogleOAuth.d.ts.map +1 -0
- package/dist/auth/GoogleOAuth.js +66 -0
- package/dist/auth/GoogleOAuth.js.map +1 -0
- package/dist/auth/middleware.d.ts +15 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +63 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/signing.d.ts +50 -0
- package/dist/auth/signing.d.ts.map +1 -0
- package/dist/auth/signing.js +96 -0
- package/dist/auth/signing.js.map +1 -0
- package/dist/auth/wsTicket.d.ts +34 -0
- package/dist/auth/wsTicket.d.ts.map +1 -0
- package/dist/auth/wsTicket.js +50 -0
- package/dist/auth/wsTicket.js.map +1 -0
- package/dist/config/types.d.ts +294 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/url-safety.d.ts +8 -0
- package/dist/config/url-safety.d.ts.map +1 -0
- package/dist/config/url-safety.js +11 -0
- package/dist/config/url-safety.js.map +1 -0
- package/dist/containers/ContainerSessionService.d.ts +67 -0
- package/dist/containers/ContainerSessionService.d.ts.map +1 -0
- package/dist/containers/ContainerSessionService.js +44 -0
- package/dist/containers/ContainerSessionService.js.map +1 -0
- package/dist/crypto/WebCryptoPasswordHasher.d.ts +9 -0
- package/dist/crypto/WebCryptoPasswordHasher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoPasswordHasher.js +67 -0
- package/dist/crypto/WebCryptoPasswordHasher.js.map +1 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts +6 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.js +57 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.js.map +1 -0
- package/dist/crypto/WebCryptoSecretCipher.d.ts +23 -0
- package/dist/crypto/WebCryptoSecretCipher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoSecretCipher.js +60 -0
- package/dist/crypto/WebCryptoSecretCipher.js.map +1 -0
- package/dist/crypto/encoding.d.ts +14 -0
- package/dist/crypto/encoding.d.ts.map +1 -0
- package/dist/crypto/encoding.js +58 -0
- package/dist/crypto/encoding.js.map +1 -0
- package/dist/events/FanOutEventPublisher.d.ts +32 -0
- package/dist/events/FanOutEventPublisher.d.ts.map +1 -0
- package/dist/events/FanOutEventPublisher.js +76 -0
- package/dist/events/FanOutEventPublisher.js.map +1 -0
- package/dist/events/InAppNotificationChannel.d.ts +20 -0
- package/dist/events/InAppNotificationChannel.d.ts.map +1 -0
- package/dist/events/InAppNotificationChannel.js +23 -0
- package/dist/events/InAppNotificationChannel.js.map +1 -0
- package/dist/github/FetchGitHubClient.d.ts +72 -0
- package/dist/github/FetchGitHubClient.d.ts.map +1 -0
- package/dist/github/FetchGitHubClient.js +485 -0
- package/dist/github/FetchGitHubClient.js.map +1 -0
- package/dist/github/FetchGitHubProvisioningClient.d.ts +13 -0
- package/dist/github/FetchGitHubProvisioningClient.d.ts.map +1 -0
- package/dist/github/FetchGitHubProvisioningClient.js +59 -0
- package/dist/github/FetchGitHubProvisioningClient.js.map +1 -0
- package/dist/github/GitHubAppAuth.d.ts +30 -0
- package/dist/github/GitHubAppAuth.d.ts.map +1 -0
- package/dist/github/GitHubAppAuth.js +95 -0
- package/dist/github/GitHubAppAuth.js.map +1 -0
- package/dist/github/GitHubAppRegistry.d.ts +57 -0
- package/dist/github/GitHubAppRegistry.d.ts.map +1 -0
- package/dist/github/GitHubAppRegistry.js +51 -0
- package/dist/github/GitHubAppRegistry.js.map +1 -0
- package/dist/github/GitHubCiStatusProvider.d.ts +21 -0
- package/dist/github/GitHubCiStatusProvider.d.ts.map +1 -0
- package/dist/github/GitHubCiStatusProvider.js +39 -0
- package/dist/github/GitHubCiStatusProvider.js.map +1 -0
- package/dist/github/GitHubMergeabilityProvider.d.ts +26 -0
- package/dist/github/GitHubMergeabilityProvider.d.ts.map +1 -0
- package/dist/github/GitHubMergeabilityProvider.js +38 -0
- package/dist/github/GitHubMergeabilityProvider.js.map +1 -0
- package/dist/github/GitHubPullRequestMerger.d.ts +23 -0
- package/dist/github/GitHubPullRequestMerger.d.ts.map +1 -0
- package/dist/github/GitHubPullRequestMerger.js +38 -0
- package/dist/github/GitHubPullRequestMerger.js.map +1 -0
- package/dist/github/WebCryptoWebhookVerifier.d.ts +9 -0
- package/dist/github/WebCryptoWebhookVerifier.d.ts.map +1 -0
- package/dist/github/WebCryptoWebhookVerifier.js +40 -0
- package/dist/github/WebCryptoWebhookVerifier.js.map +1 -0
- package/dist/github/ensureWorkBranch.d.ts +26 -0
- package/dist/github/ensureWorkBranch.d.ts.map +1 -0
- package/dist/github/ensureWorkBranch.js +97 -0
- package/dist/github/ensureWorkBranch.js.map +1 -0
- package/dist/github/state.d.ts +19 -0
- package/dist/github/state.d.ts.map +1 -0
- package/dist/github/state.js +55 -0
- package/dist/github/state.js.map +1 -0
- package/dist/http/authGate.d.ts +21 -0
- package/dist/http/authGate.d.ts.map +1 -0
- package/dist/http/authGate.js +77 -0
- package/dist/http/authGate.js.map +1 -0
- package/dist/http/cors.d.ts +13 -0
- package/dist/http/cors.d.ts.map +1 -0
- package/dist/http/cors.js +30 -0
- package/dist/http/cors.js.map +1 -0
- package/dist/http/env.d.ts +68 -0
- package/dist/http/env.d.ts.map +1 -0
- package/dist/http/env.js +2 -0
- package/dist/http/env.js.map +1 -0
- package/dist/http/errorHandler.d.ts +4 -0
- package/dist/http/errorHandler.d.ts.map +1 -0
- package/dist/http/errorHandler.js +33 -0
- package/dist/http/errorHandler.js.map +1 -0
- package/dist/http/params.d.ts +8 -0
- package/dist/http/params.d.ts.map +1 -0
- package/dist/http/params.js +13 -0
- package/dist/http/params.js.map +1 -0
- package/dist/http/validation.d.ts +12 -0
- package/dist/http/validation.d.ts.map +1 -0
- package/dist/http/validation.js +21 -0
- package/dist/http/validation.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/accounts/AccountController.d.ts +10 -0
- package/dist/modules/accounts/AccountController.d.ts.map +1 -0
- package/dist/modules/accounts/AccountController.js +197 -0
- package/dist/modules/accounts/AccountController.js.map +1 -0
- package/dist/modules/agentRuns/AgentRunController.d.ts +10 -0
- package/dist/modules/agentRuns/AgentRunController.d.ts.map +1 -0
- package/dist/modules/agentRuns/AgentRunController.js +65 -0
- package/dist/modules/agentRuns/AgentRunController.js.map +1 -0
- package/dist/modules/auth/AuthController.d.ts +12 -0
- package/dist/modules/auth/AuthController.d.ts.map +1 -0
- package/dist/modules/auth/AuthController.js +457 -0
- package/dist/modules/auth/AuthController.js.map +1 -0
- package/dist/modules/board/BoardController.d.ts +8 -0
- package/dist/modules/board/BoardController.d.ts.map +1 -0
- package/dist/modules/board/BoardController.js +89 -0
- package/dist/modules/board/BoardController.js.map +1 -0
- package/dist/modules/boardScan/BoardScanController.d.ts +10 -0
- package/dist/modules/boardScan/BoardScanController.d.ts.map +1 -0
- package/dist/modules/boardScan/BoardScanController.js +53 -0
- package/dist/modules/boardScan/BoardScanController.js.map +1 -0
- package/dist/modules/bootstrap/BootstrapController.d.ts +10 -0
- package/dist/modules/bootstrap/BootstrapController.d.ts.map +1 -0
- package/dist/modules/bootstrap/BootstrapController.js +75 -0
- package/dist/modules/bootstrap/BootstrapController.js.map +1 -0
- package/dist/modules/clarity/ClarityReviewController.d.ts +11 -0
- package/dist/modules/clarity/ClarityReviewController.d.ts.map +1 -0
- package/dist/modules/clarity/ClarityReviewController.js +97 -0
- package/dist/modules/clarity/ClarityReviewController.js.map +1 -0
- package/dist/modules/consensus/ConsensusController.d.ts +12 -0
- package/dist/modules/consensus/ConsensusController.d.ts.map +1 -0
- package/dist/modules/consensus/ConsensusController.js +23 -0
- package/dist/modules/consensus/ConsensusController.js.map +1 -0
- package/dist/modules/documents/DocumentSourceController.d.ts +10 -0
- package/dist/modules/documents/DocumentSourceController.d.ts.map +1 -0
- package/dist/modules/documents/DocumentSourceController.js +116 -0
- package/dist/modules/documents/DocumentSourceController.js.map +1 -0
- package/dist/modules/environments/EnvironmentController.d.ts +10 -0
- package/dist/modules/environments/EnvironmentController.d.ts.map +1 -0
- package/dist/modules/environments/EnvironmentController.js +95 -0
- package/dist/modules/environments/EnvironmentController.js.map +1 -0
- package/dist/modules/events/EventsController.d.ts +26 -0
- package/dist/modules/events/EventsController.d.ts.map +1 -0
- package/dist/modules/events/EventsController.js +56 -0
- package/dist/modules/events/EventsController.js.map +1 -0
- package/dist/modules/execution/ExecutionController.d.ts +10 -0
- package/dist/modules/execution/ExecutionController.d.ts.map +1 -0
- package/dist/modules/execution/ExecutionController.js +156 -0
- package/dist/modules/execution/ExecutionController.js.map +1 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts +14 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts.map +1 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js +128 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js.map +1 -0
- package/dist/modules/github/GitHubController.d.ts +12 -0
- package/dist/modules/github/GitHubController.d.ts.map +1 -0
- package/dist/modules/github/GitHubController.js +234 -0
- package/dist/modules/github/GitHubController.js.map +1 -0
- package/dist/modules/github/GitHubWebhookController.d.ts +13 -0
- package/dist/modules/github/GitHubWebhookController.d.ts.map +1 -0
- package/dist/modules/github/GitHubWebhookController.js +74 -0
- package/dist/modules/github/GitHubWebhookController.js.map +1 -0
- package/dist/modules/llmProxy/LlmProxyController.d.ts +18 -0
- package/dist/modules/llmProxy/LlmProxyController.d.ts.map +1 -0
- package/dist/modules/llmProxy/LlmProxyController.js +567 -0
- package/dist/modules/llmProxy/LlmProxyController.js.map +1 -0
- package/dist/modules/localModels/LocalModelEndpointController.d.ts +4 -0
- package/dist/modules/localModels/LocalModelEndpointController.d.ts.map +1 -0
- package/dist/modules/localModels/LocalModelEndpointController.js +58 -0
- package/dist/modules/localModels/LocalModelEndpointController.js.map +1 -0
- package/dist/modules/merge/MergePresetController.d.ts +9 -0
- package/dist/modules/merge/MergePresetController.d.ts.map +1 -0
- package/dist/modules/merge/MergePresetController.js +46 -0
- package/dist/modules/merge/MergePresetController.js.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.d.ts +9 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.d.ts.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.js +32 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.js.map +1 -0
- package/dist/modules/models/ModelController.d.ts +11 -0
- package/dist/modules/models/ModelController.d.ts.map +1 -0
- package/dist/modules/models/ModelController.js +38 -0
- package/dist/modules/models/ModelController.js.map +1 -0
- package/dist/modules/notifications/NotificationController.d.ts +13 -0
- package/dist/modules/notifications/NotificationController.d.ts.map +1 -0
- package/dist/modules/notifications/NotificationController.js +67 -0
- package/dist/modules/notifications/NotificationController.js.map +1 -0
- package/dist/modules/pipelines/PipelineController.d.ts +5 -0
- package/dist/modules/pipelines/PipelineController.d.ts.map +1 -0
- package/dist/modules/pipelines/PipelineController.js +46 -0
- package/dist/modules/pipelines/PipelineController.js.map +1 -0
- package/dist/modules/promptFragments/PromptFragmentController.d.ts +11 -0
- package/dist/modules/promptFragments/PromptFragmentController.d.ts.map +1 -0
- package/dist/modules/promptFragments/PromptFragmentController.js +18 -0
- package/dist/modules/promptFragments/PromptFragmentController.js.map +1 -0
- package/dist/modules/providers/ApiKeyController.d.ts +13 -0
- package/dist/modules/providers/ApiKeyController.d.ts.map +1 -0
- package/dist/modules/providers/ApiKeyController.js +98 -0
- package/dist/modules/providers/ApiKeyController.js.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionController.d.ts +4 -0
- package/dist/modules/providers/PersonalSubscriptionController.d.ts.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionController.js +48 -0
- package/dist/modules/providers/PersonalSubscriptionController.js.map +1 -0
- package/dist/modules/providers/VendorCredentialController.d.ts +4 -0
- package/dist/modules/providers/VendorCredentialController.d.ts.map +1 -0
- package/dist/modules/providers/VendorCredentialController.js +55 -0
- package/dist/modules/providers/VendorCredentialController.js.map +1 -0
- package/dist/modules/providers/personalCredentialGate.d.ts +34 -0
- package/dist/modules/providers/personalCredentialGate.d.ts.map +1 -0
- package/dist/modules/providers/personalCredentialGate.js +106 -0
- package/dist/modules/providers/personalCredentialGate.js.map +1 -0
- package/dist/modules/recurring/RecurringPipelineController.d.ts +8 -0
- package/dist/modules/recurring/RecurringPipelineController.d.ts.map +1 -0
- package/dist/modules/recurring/RecurringPipelineController.js +58 -0
- package/dist/modules/recurring/RecurringPipelineController.js.map +1 -0
- package/dist/modules/recurring/TrackerSettingsController.d.ts +8 -0
- package/dist/modules/recurring/TrackerSettingsController.d.ts.map +1 -0
- package/dist/modules/recurring/TrackerSettingsController.js +30 -0
- package/dist/modules/recurring/TrackerSettingsController.js.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.d.ts +9 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.d.ts.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.js +58 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.js.map +1 -0
- package/dist/modules/requirements/RequirementReviewController.d.ts +12 -0
- package/dist/modules/requirements/RequirementReviewController.d.ts.map +1 -0
- package/dist/modules/requirements/RequirementReviewController.js +107 -0
- package/dist/modules/requirements/RequirementReviewController.js.map +1 -0
- package/dist/modules/runners/RunnerPoolController.d.ts +10 -0
- package/dist/modules/runners/RunnerPoolController.d.ts.map +1 -0
- package/dist/modules/runners/RunnerPoolController.js +52 -0
- package/dist/modules/runners/RunnerPoolController.js.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts +9 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js +32 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js.map +1 -0
- package/dist/modules/services/ServiceMountController.d.ts +11 -0
- package/dist/modules/services/ServiceMountController.d.ts.map +1 -0
- package/dist/modules/services/ServiceMountController.js +64 -0
- package/dist/modules/services/ServiceMountController.js.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsController.d.ts +9 -0
- package/dist/modules/settings/WorkspaceSettingsController.d.ts.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsController.js +32 -0
- package/dist/modules/settings/WorkspaceSettingsController.js.map +1 -0
- package/dist/modules/slack/SlackController.d.ts +17 -0
- package/dist/modules/slack/SlackController.d.ts.map +1 -0
- package/dist/modules/slack/SlackController.js +135 -0
- package/dist/modules/slack/SlackController.js.map +1 -0
- package/dist/modules/tasks/TaskSourceController.d.ts +9 -0
- package/dist/modules/tasks/TaskSourceController.d.ts.map +1 -0
- package/dist/modules/tasks/TaskSourceController.js +103 -0
- package/dist/modules/tasks/TaskSourceController.js.map +1 -0
- package/dist/modules/webSearch/WebSearchProxyController.d.ts +4 -0
- package/dist/modules/webSearch/WebSearchProxyController.d.ts.map +1 -0
- package/dist/modules/webSearch/WebSearchProxyController.js +78 -0
- package/dist/modules/webSearch/WebSearchProxyController.js.map +1 -0
- package/dist/modules/webSearch/upstreams.d.ts +50 -0
- package/dist/modules/webSearch/upstreams.d.ts.map +1 -0
- package/dist/modules/webSearch/upstreams.js +107 -0
- package/dist/modules/webSearch/upstreams.js.map +1 -0
- package/dist/modules/workspaces/WorkspaceController.d.ts +5 -0
- package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -0
- package/dist/modules/workspaces/WorkspaceController.js +167 -0
- package/dist/modules/workspaces/WorkspaceController.js.map +1 -0
- package/dist/observability/logger.d.ts +9 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +39 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/persistence/mappers.d.ts +101 -0
- package/dist/persistence/mappers.d.ts.map +1 -0
- package/dist/persistence/mappers.js +260 -0
- package/dist/persistence/mappers.js.map +1 -0
- package/dist/runtime/escalateNotifications.d.ts +12 -0
- package/dist/runtime/escalateNotifications.d.ts.map +1 -0
- package/dist/runtime/escalateNotifications.js +25 -0
- package/dist/runtime/escalateNotifications.js.map +1 -0
- package/dist/runtime/gateways.d.ts +159 -0
- package/dist/runtime/gateways.d.ts.map +1 -0
- package/dist/runtime/gateways.js +2 -0
- package/dist/runtime/gateways.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { passwordLoginSchema, signupSchema } from '@cat-factory/contracts';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { deleteCookie, getCookie, setCookie } from 'hono/cookie';
|
|
4
|
+
import { GitHubOAuth } from '../../auth/GitHubOAuth.js';
|
|
5
|
+
import { GoogleOAuth } from '../../auth/GoogleOAuth.js';
|
|
6
|
+
import { verifySession } from '../../auth/middleware.js';
|
|
7
|
+
import { HmacSigner, TOKEN_AUDIENCE, } from '../../auth/signing.js';
|
|
8
|
+
import { jsonBody } from '../../http/validation.js';
|
|
9
|
+
import { ConflictError, NotFoundError, ValidationError } from '@cat-factory/kernel';
|
|
10
|
+
// Authentication endpoints. The SPA is handed a signed session token (via the URL
|
|
11
|
+
// fragment for OAuth redirects, or the JSON body for password login) which it carries
|
|
12
|
+
// as `Authorization: Bearer` on subsequent calls. Three login providers compose here:
|
|
13
|
+
// - GitHub OAuth (browser round-trip)
|
|
14
|
+
// - Google OAuth (browser round-trip)
|
|
15
|
+
// - email/password (direct JSON)
|
|
16
|
+
// All resolve to ONE canonical `users` row via the UserService, so the session id is
|
|
17
|
+
// always the internal `usr_*` id regardless of how the user signed in.
|
|
18
|
+
const OAUTH_STATE_TTL_MS = 10 * 60 * 1000;
|
|
19
|
+
/** Browser-binding cookie for an OAuth round-trip (see the GitHub flow notes below). */
|
|
20
|
+
const OAUTH_STATE_COOKIE = 'cf_oauth_state';
|
|
21
|
+
const unavailable = (c) => c.json({ error: { code: 'unavailable', message: 'Authentication is not configured' } }, 503);
|
|
22
|
+
function authConfig(c) {
|
|
23
|
+
return c.get('container').config.auth;
|
|
24
|
+
}
|
|
25
|
+
function githubClient(cfg) {
|
|
26
|
+
return new GitHubOAuth({
|
|
27
|
+
clientId: cfg.clientId,
|
|
28
|
+
clientSecret: cfg.clientSecret,
|
|
29
|
+
apiBase: cfg.apiBase,
|
|
30
|
+
oauthBase: cfg.oauthBase,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function googleClient(cfg) {
|
|
34
|
+
if (!cfg.google)
|
|
35
|
+
return null;
|
|
36
|
+
return new GoogleOAuth({
|
|
37
|
+
clientId: cfg.google.clientId,
|
|
38
|
+
clientSecret: cfg.google.clientSecret,
|
|
39
|
+
oauthBase: cfg.google.oauthBase,
|
|
40
|
+
apiBase: cfg.google.apiBase,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function githubCallbackUrl(c, cfg) {
|
|
44
|
+
if (cfg.callbackUrl)
|
|
45
|
+
return cfg.callbackUrl;
|
|
46
|
+
return `${new URL(c.req.url).origin}/auth/callback`;
|
|
47
|
+
}
|
|
48
|
+
function googleCallbackUrl(c, cfg) {
|
|
49
|
+
if (cfg.google?.redirectUrl)
|
|
50
|
+
return cfg.google.redirectUrl;
|
|
51
|
+
return `${new URL(c.req.url).origin}/auth/google/callback`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Choose the post-login landing URL from the (untrusted) `redirect` query. The
|
|
55
|
+
* session token is appended as a fragment, so an unrestricted redirect is a
|
|
56
|
+
* token-exfiltration primitive — only same-origin or explicitly allowlisted origins
|
|
57
|
+
* are honoured, else the request origin.
|
|
58
|
+
*/
|
|
59
|
+
export function pickPostLoginRedirect(requested, requestOrigin, cfg) {
|
|
60
|
+
if (cfg.successRedirectUrl)
|
|
61
|
+
return cfg.successRedirectUrl;
|
|
62
|
+
const fallback = `${requestOrigin}/`;
|
|
63
|
+
if (!requested)
|
|
64
|
+
return fallback;
|
|
65
|
+
try {
|
|
66
|
+
const url = new URL(requested);
|
|
67
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
68
|
+
return fallback;
|
|
69
|
+
if (url.origin === requestOrigin || cfg.allowedRedirectOrigins.includes(url.origin)) {
|
|
70
|
+
return requested;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// fall through to the safe origin-relative default
|
|
75
|
+
}
|
|
76
|
+
return fallback;
|
|
77
|
+
}
|
|
78
|
+
function resolveRedirect(c, cfg) {
|
|
79
|
+
return pickPostLoginRedirect(c.req.query('redirect'), new URL(c.req.url).origin, cfg);
|
|
80
|
+
}
|
|
81
|
+
/** Append the session token as a URL fragment on the landing URL. */
|
|
82
|
+
function withToken(redirect, token) {
|
|
83
|
+
const url = new URL(redirect);
|
|
84
|
+
url.hash = `token=${token}`;
|
|
85
|
+
return url.toString();
|
|
86
|
+
}
|
|
87
|
+
/** Build the SessionUser surface from a canonical user + chosen display login. */
|
|
88
|
+
function sessionUser(user, login) {
|
|
89
|
+
return {
|
|
90
|
+
id: user.id,
|
|
91
|
+
login,
|
|
92
|
+
name: user.name,
|
|
93
|
+
avatarUrl: user.avatarUrl,
|
|
94
|
+
email: user.email,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function mintSession(cfg, user) {
|
|
98
|
+
const session = {
|
|
99
|
+
...user,
|
|
100
|
+
aud: TOKEN_AUDIENCE.session,
|
|
101
|
+
exp: Date.now() + cfg.sessionTtlMs,
|
|
102
|
+
};
|
|
103
|
+
return new HmacSigner(cfg.sessionSecret).sign(session);
|
|
104
|
+
}
|
|
105
|
+
/** Whether an email's domain is on the self-signup allowlist. */
|
|
106
|
+
function emailDomainAllowed(email, cfg) {
|
|
107
|
+
const at = email.lastIndexOf('@');
|
|
108
|
+
if (at < 0)
|
|
109
|
+
return false;
|
|
110
|
+
const domain = email.slice(at + 1).toLowerCase();
|
|
111
|
+
return cfg.allowedEmailDomains.includes(domain);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* GitHub allowlist gate — the deployment is private. A user is admitted only if their
|
|
115
|
+
* login is in `allowedLogins` OR they belong to an org in `allowedOrgs`. Both lists
|
|
116
|
+
* empty ⇒ deny everyone (fail closed).
|
|
117
|
+
*/
|
|
118
|
+
async function isGitHubSignInAllowed(oauth, accessToken, user, cfg) {
|
|
119
|
+
if (cfg.allowedLogins.includes(user.login.toLowerCase()))
|
|
120
|
+
return true;
|
|
121
|
+
if (cfg.allowedOrgs.length === 0)
|
|
122
|
+
return false;
|
|
123
|
+
const orgs = await oauth.fetchUserOrgs(accessToken);
|
|
124
|
+
return orgs.some((org) => cfg.allowedOrgs.includes(org));
|
|
125
|
+
}
|
|
126
|
+
// Best-effort in-process throttle for the password endpoints. It bounds naive online
|
|
127
|
+
// brute-force / credential-stuffing bursts without any new infrastructure, but is
|
|
128
|
+
// deliberately modest: the window is per-isolate (each Workers isolate / Node process
|
|
129
|
+
// keeps its own), so it is a speed bump, not an authoritative limiter — a durable,
|
|
130
|
+
// cross-runtime limiter (D1/Postgres-backed, exercised by the conformance suite) is the
|
|
131
|
+
// proper follow-up. Keyed by client IP + email so one attacker can't lock out an
|
|
132
|
+
// unrelated victim, and PBKDF2's per-attempt cost remains the primary defence.
|
|
133
|
+
const ATTEMPT_WINDOW_MS = 15 * 60 * 1000;
|
|
134
|
+
const MAX_ATTEMPTS = 10;
|
|
135
|
+
const attempts = new Map();
|
|
136
|
+
function clientIp(c) {
|
|
137
|
+
return (c.req.header('cf-connecting-ip') ||
|
|
138
|
+
c.req.header('x-forwarded-for')?.split(',')[0]?.trim() ||
|
|
139
|
+
'unknown');
|
|
140
|
+
}
|
|
141
|
+
/** Record a password attempt for `c`+`email`; true once it is over the burst limit. */
|
|
142
|
+
function passwordAttemptLimited(c, email) {
|
|
143
|
+
const now = Date.now();
|
|
144
|
+
const key = `${clientIp(c)}:${email.toLowerCase().trim()}`;
|
|
145
|
+
const recent = (attempts.get(key) ?? []).filter((t) => now - t < ATTEMPT_WINDOW_MS);
|
|
146
|
+
recent.push(now);
|
|
147
|
+
attempts.set(key, recent);
|
|
148
|
+
// Opportunistically evict fully-stale keys so the map can't grow unbounded.
|
|
149
|
+
if (attempts.size > 10_000) {
|
|
150
|
+
for (const [k, ts] of attempts) {
|
|
151
|
+
if (ts.every((t) => now - t >= ATTEMPT_WINDOW_MS))
|
|
152
|
+
attempts.delete(k);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return recent.length > MAX_ATTEMPTS;
|
|
156
|
+
}
|
|
157
|
+
const tooManyAttempts = (c) => c.json({ error: { code: 'rate_limited', message: 'Too many attempts. Please try again later.' } }, 429);
|
|
158
|
+
export function authController() {
|
|
159
|
+
const app = new Hono();
|
|
160
|
+
// Lets the SPA decide which login controls to show, and (local mode only) surface a
|
|
161
|
+
// setup banner when the GitHub PAT is missing.
|
|
162
|
+
app.get('/config', (c) => {
|
|
163
|
+
const cfg = authConfig(c);
|
|
164
|
+
const { localMode } = c.get('container').config;
|
|
165
|
+
return c.json({
|
|
166
|
+
enabled: cfg.enabled,
|
|
167
|
+
providers: {
|
|
168
|
+
github: cfg.githubEnabled,
|
|
169
|
+
password: cfg.passwordEnabled,
|
|
170
|
+
google: !!cfg.google,
|
|
171
|
+
},
|
|
172
|
+
...(localMode ? { localMode } : {}),
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
// ---- GitHub OAuth -------------------------------------------------------
|
|
176
|
+
app.get('/login', async (c) => {
|
|
177
|
+
const cfg = authConfig(c);
|
|
178
|
+
if (!cfg.githubEnabled)
|
|
179
|
+
return unavailable(c);
|
|
180
|
+
const nonce = crypto.randomUUID();
|
|
181
|
+
const state = {
|
|
182
|
+
aud: TOKEN_AUDIENCE.oauthState,
|
|
183
|
+
nonce,
|
|
184
|
+
redirect: resolveRedirect(c, cfg),
|
|
185
|
+
...(c.req.query('invite') ? { invite: c.req.query('invite') } : {}),
|
|
186
|
+
exp: Date.now() + OAUTH_STATE_TTL_MS,
|
|
187
|
+
};
|
|
188
|
+
const signedState = await new HmacSigner(cfg.sessionSecret).sign(state);
|
|
189
|
+
setCookie(c, OAUTH_STATE_COOKIE, nonce, {
|
|
190
|
+
httpOnly: true,
|
|
191
|
+
secure: new URL(c.req.url).protocol === 'https:',
|
|
192
|
+
sameSite: 'Lax',
|
|
193
|
+
path: '/auth',
|
|
194
|
+
maxAge: OAUTH_STATE_TTL_MS / 1000,
|
|
195
|
+
});
|
|
196
|
+
const url = githubClient(cfg).authorizeUrl({
|
|
197
|
+
redirectUri: githubCallbackUrl(c, cfg),
|
|
198
|
+
state: signedState,
|
|
199
|
+
scope: cfg.allowedOrgs.length > 0 ? 'read:user read:org' : 'read:user',
|
|
200
|
+
});
|
|
201
|
+
return c.redirect(url);
|
|
202
|
+
});
|
|
203
|
+
app.get('/callback', async (c) => {
|
|
204
|
+
const cfg = authConfig(c);
|
|
205
|
+
if (!cfg.githubEnabled)
|
|
206
|
+
return unavailable(c);
|
|
207
|
+
const state = await consumeState(c, cfg);
|
|
208
|
+
const code = c.req.query('code');
|
|
209
|
+
if (!code || !state) {
|
|
210
|
+
return c.json({ error: { code: 'validation', message: 'Invalid OAuth callback' } }, 400);
|
|
211
|
+
}
|
|
212
|
+
const oauth = githubClient(cfg);
|
|
213
|
+
const accessToken = await oauth.exchangeCode(code, githubCallbackUrl(c, cfg));
|
|
214
|
+
const identity = await oauth.fetchUser(accessToken);
|
|
215
|
+
const container = c.get('container');
|
|
216
|
+
// An invite (matching this user's email) OR the allowlist admits the user. The
|
|
217
|
+
// invite short-circuits the org allowlist, so it is bound to the invited email —
|
|
218
|
+
// a leaked link can't admit an arbitrary GitHub account onto a private deployment.
|
|
219
|
+
const invited = state.invite ? await peekInvite(c, state.invite) : null;
|
|
220
|
+
const inviteAdmits = invited != null && emailMatchesInvite(identity.email, invited.email);
|
|
221
|
+
if (!inviteAdmits && !(await isGitHubSignInAllowed(oauth, accessToken, identity, cfg))) {
|
|
222
|
+
return c.json({ error: { code: 'forbidden', message: `@${identity.login} is not allowed to sign in` } }, 403);
|
|
223
|
+
}
|
|
224
|
+
const user = await container.userService.findOrCreateByIdentity('github', String(identity.id), {
|
|
225
|
+
name: identity.name,
|
|
226
|
+
email: identity.email,
|
|
227
|
+
// GitHub only exposes an email it has verified for the account, so it is trusted
|
|
228
|
+
// to link this login onto an existing same-email user.
|
|
229
|
+
emailVerified: !!identity.email,
|
|
230
|
+
avatarUrl: identity.avatarUrl,
|
|
231
|
+
metadata: { login: identity.login },
|
|
232
|
+
});
|
|
233
|
+
await container.accountService.ensurePersonalAccount({
|
|
234
|
+
id: user.id,
|
|
235
|
+
login: identity.login,
|
|
236
|
+
name: user.name,
|
|
237
|
+
});
|
|
238
|
+
if (state.invite)
|
|
239
|
+
await acceptInvite(c, state.invite, user.id, user.email);
|
|
240
|
+
const token = await mintSession(cfg, sessionUser(user, identity.login));
|
|
241
|
+
return c.redirect(withToken(state.redirect, token));
|
|
242
|
+
});
|
|
243
|
+
// ---- Google OAuth -------------------------------------------------------
|
|
244
|
+
app.get('/google/login', async (c) => {
|
|
245
|
+
const cfg = authConfig(c);
|
|
246
|
+
const google = googleClient(cfg);
|
|
247
|
+
if (!google)
|
|
248
|
+
return unavailable(c);
|
|
249
|
+
const nonce = crypto.randomUUID();
|
|
250
|
+
const state = {
|
|
251
|
+
aud: TOKEN_AUDIENCE.oauthState,
|
|
252
|
+
nonce,
|
|
253
|
+
redirect: resolveRedirect(c, cfg),
|
|
254
|
+
...(c.req.query('invite') ? { invite: c.req.query('invite') } : {}),
|
|
255
|
+
exp: Date.now() + OAUTH_STATE_TTL_MS,
|
|
256
|
+
};
|
|
257
|
+
const signedState = await new HmacSigner(cfg.sessionSecret).sign(state);
|
|
258
|
+
setCookie(c, OAUTH_STATE_COOKIE, nonce, {
|
|
259
|
+
httpOnly: true,
|
|
260
|
+
secure: new URL(c.req.url).protocol === 'https:',
|
|
261
|
+
sameSite: 'Lax',
|
|
262
|
+
path: '/auth',
|
|
263
|
+
maxAge: OAUTH_STATE_TTL_MS / 1000,
|
|
264
|
+
});
|
|
265
|
+
return c.redirect(google.authorizeUrl({ redirectUri: googleCallbackUrl(c, cfg), state: signedState }));
|
|
266
|
+
});
|
|
267
|
+
app.get('/google/callback', async (c) => {
|
|
268
|
+
const cfg = authConfig(c);
|
|
269
|
+
const google = googleClient(cfg);
|
|
270
|
+
if (!google)
|
|
271
|
+
return unavailable(c);
|
|
272
|
+
const state = await consumeState(c, cfg);
|
|
273
|
+
const code = c.req.query('code');
|
|
274
|
+
if (!code || !state) {
|
|
275
|
+
return c.json({ error: { code: 'validation', message: 'Invalid OAuth callback' } }, 400);
|
|
276
|
+
}
|
|
277
|
+
const accessToken = await google.exchangeCode(code, googleCallbackUrl(c, cfg));
|
|
278
|
+
const identity = await google.fetchUser(accessToken);
|
|
279
|
+
const container = c.get('container');
|
|
280
|
+
const existing = await container.userService.findByIdentity('google', identity.subject);
|
|
281
|
+
// Gate NEW-user creation: an invite (matching the verified email) OR an allowlisted
|
|
282
|
+
// VERIFIED email domain. An unverified Google email is never trusted to self-signup.
|
|
283
|
+
const invited = state.invite ? await peekInvite(c, state.invite) : null;
|
|
284
|
+
const verifiedEmail = identity.emailVerified ? identity.email : null;
|
|
285
|
+
const inviteAdmits = invited != null && emailMatchesInvite(verifiedEmail, invited.email);
|
|
286
|
+
if (!existing) {
|
|
287
|
+
const allowed = inviteAdmits || (verifiedEmail ? emailDomainAllowed(verifiedEmail, cfg) : false);
|
|
288
|
+
if (!allowed) {
|
|
289
|
+
return c.json({ error: { code: 'forbidden', message: 'Sign-up requires an invitation' } }, 403);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const user = await container.userService.findOrCreateByIdentity('google', identity.subject, {
|
|
293
|
+
name: identity.name,
|
|
294
|
+
email: identity.email,
|
|
295
|
+
emailVerified: identity.emailVerified,
|
|
296
|
+
avatarUrl: identity.avatarUrl,
|
|
297
|
+
metadata: { email: identity.email },
|
|
298
|
+
});
|
|
299
|
+
await container.accountService.ensurePersonalAccount({
|
|
300
|
+
id: user.id,
|
|
301
|
+
login: identity.email || user.id,
|
|
302
|
+
name: user.name,
|
|
303
|
+
});
|
|
304
|
+
if (state.invite)
|
|
305
|
+
await acceptInvite(c, state.invite, user.id, user.email);
|
|
306
|
+
const token = await mintSession(cfg, sessionUser(user, identity.email || user.id));
|
|
307
|
+
return c.redirect(withToken(state.redirect, token));
|
|
308
|
+
});
|
|
309
|
+
// ---- Email / password ---------------------------------------------------
|
|
310
|
+
app.post('/signup', jsonBody(signupSchema), async (c) => {
|
|
311
|
+
const cfg = authConfig(c);
|
|
312
|
+
if (!cfg.passwordEnabled)
|
|
313
|
+
return unavailable(c);
|
|
314
|
+
const body = c.req.valid('json');
|
|
315
|
+
if (passwordAttemptLimited(c, body.email))
|
|
316
|
+
return tooManyAttempts(c);
|
|
317
|
+
const container = c.get('container');
|
|
318
|
+
// New-user creation is gated: an invite addressed to this email OR an allowlisted
|
|
319
|
+
// email domain. The invite is bound to its email so a leaked link can't be used to
|
|
320
|
+
// self-register an arbitrary address on a private deployment.
|
|
321
|
+
const invited = body.invite ? await peekInvite(c, body.invite) : null;
|
|
322
|
+
const allowed = (invited != null && emailMatchesInvite(body.email, invited.email)) ||
|
|
323
|
+
emailDomainAllowed(body.email, cfg);
|
|
324
|
+
if (!allowed) {
|
|
325
|
+
return c.json({ error: { code: 'forbidden', message: 'Sign-up requires an invitation' } }, 403);
|
|
326
|
+
}
|
|
327
|
+
try {
|
|
328
|
+
const user = await container.userService.signupWithPassword({
|
|
329
|
+
email: body.email,
|
|
330
|
+
password: body.password,
|
|
331
|
+
name: body.name,
|
|
332
|
+
});
|
|
333
|
+
await container.accountService.ensurePersonalAccount({
|
|
334
|
+
id: user.id,
|
|
335
|
+
login: user.email || user.id,
|
|
336
|
+
name: user.name,
|
|
337
|
+
});
|
|
338
|
+
if (body.invite)
|
|
339
|
+
await acceptInvite(c, body.invite, user.id, user.email);
|
|
340
|
+
const token = await mintSession(cfg, sessionUser(user, user.email || user.id));
|
|
341
|
+
return c.json({ token, user: sessionUser(user, user.email || user.id) }, 201);
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
if (err instanceof ConflictError || err instanceof ValidationError) {
|
|
345
|
+
return c.json({ error: { code: 'validation', message: err.message } }, 400);
|
|
346
|
+
}
|
|
347
|
+
throw err;
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
app.post('/password-login', jsonBody(passwordLoginSchema), async (c) => {
|
|
351
|
+
const cfg = authConfig(c);
|
|
352
|
+
if (!cfg.passwordEnabled)
|
|
353
|
+
return unavailable(c);
|
|
354
|
+
const body = c.req.valid('json');
|
|
355
|
+
if (passwordAttemptLimited(c, body.email))
|
|
356
|
+
return tooManyAttempts(c);
|
|
357
|
+
const user = await c.get('container').userService.verifyPassword(body);
|
|
358
|
+
if (!user) {
|
|
359
|
+
return c.json({ error: { code: 'unauthorized', message: 'Invalid email or password' } }, 401);
|
|
360
|
+
}
|
|
361
|
+
const token = await mintSession(cfg, sessionUser(user, user.email || user.id));
|
|
362
|
+
return c.json({ token, user: sessionUser(user, user.email || user.id) });
|
|
363
|
+
});
|
|
364
|
+
// ---- Invitations (peek + accept) ----------------------------------------
|
|
365
|
+
// Public peek so the SPA can show the org name on the accept screen.
|
|
366
|
+
app.get('/invitations/:token', async (c) => {
|
|
367
|
+
const container = c.get('container');
|
|
368
|
+
if (!container.invitations)
|
|
369
|
+
return c.json({ valid: false });
|
|
370
|
+
const record = await container.invitations.peek(c.req.param('token'));
|
|
371
|
+
if (!record)
|
|
372
|
+
return c.json({ valid: false });
|
|
373
|
+
const account = await container.accountService.get(record.accountId);
|
|
374
|
+
return c.json({ valid: true, email: record.email, accountName: account?.name ?? null });
|
|
375
|
+
});
|
|
376
|
+
// Accept an invitation as the signed-in user (the SPA calls this after login).
|
|
377
|
+
app.post('/invitations/:token/accept', async (c) => {
|
|
378
|
+
const user = await verifySession(c);
|
|
379
|
+
if (!user) {
|
|
380
|
+
return c.json({ error: { code: 'unauthorized', message: 'Sign in to accept' } }, 401);
|
|
381
|
+
}
|
|
382
|
+
const container = c.get('container');
|
|
383
|
+
if (!container.invitations) {
|
|
384
|
+
return c.json({ error: { code: 'unavailable', message: 'Invitations not configured' } }, 503);
|
|
385
|
+
}
|
|
386
|
+
try {
|
|
387
|
+
const accountId = await container.invitations.accept(c.req.param('token'), user.id, user.email ?? null);
|
|
388
|
+
return c.json({ accountId });
|
|
389
|
+
}
|
|
390
|
+
catch (err) {
|
|
391
|
+
if (err instanceof ConflictError) {
|
|
392
|
+
return c.json({ error: { code: 'conflict', message: err.message } }, 409);
|
|
393
|
+
}
|
|
394
|
+
if (err instanceof NotFoundError) {
|
|
395
|
+
return c.json({ error: { code: 'not_found', message: 'Invitation not found' } }, 404);
|
|
396
|
+
}
|
|
397
|
+
throw err;
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
// Who am I? Used by the SPA to validate a stored token on boot.
|
|
401
|
+
app.get('/me', async (c) => {
|
|
402
|
+
if (!authConfig(c).enabled)
|
|
403
|
+
return c.json({ user: null, enabled: false });
|
|
404
|
+
const user = await verifySession(c);
|
|
405
|
+
if (!user) {
|
|
406
|
+
return c.json({ error: { code: 'unauthorized', message: 'Not authenticated' } }, 401);
|
|
407
|
+
}
|
|
408
|
+
return c.json({
|
|
409
|
+
user: {
|
|
410
|
+
id: user.id,
|
|
411
|
+
login: user.login,
|
|
412
|
+
name: user.name,
|
|
413
|
+
avatarUrl: user.avatarUrl,
|
|
414
|
+
email: user.email ?? null,
|
|
415
|
+
},
|
|
416
|
+
enabled: true,
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
// Stateless sessions: logout is a client-side token drop. Provided for symmetry.
|
|
420
|
+
app.post('/logout', (c) => c.body(null, 204));
|
|
421
|
+
return app;
|
|
422
|
+
}
|
|
423
|
+
/** Verify + single-use the OAuth state (signature, expiry, browser-binding cookie). */
|
|
424
|
+
async function consumeState(c, cfg) {
|
|
425
|
+
const state = await new HmacSigner(cfg.sessionSecret).verify(c.req.query('state'), {
|
|
426
|
+
aud: TOKEN_AUDIENCE.oauthState,
|
|
427
|
+
});
|
|
428
|
+
const boundNonce = getCookie(c, OAUTH_STATE_COOKIE);
|
|
429
|
+
deleteCookie(c, OAUTH_STATE_COOKIE, { path: '/auth' });
|
|
430
|
+
if (!state || !boundNonce || boundNonce !== state.nonce)
|
|
431
|
+
return null;
|
|
432
|
+
return state;
|
|
433
|
+
}
|
|
434
|
+
async function peekInvite(c, token) {
|
|
435
|
+
const inv = c.get('container').invitations;
|
|
436
|
+
return inv ? inv.peek(token) : null;
|
|
437
|
+
}
|
|
438
|
+
/** Whether a sign-in email matches the address an invitation was sent to. */
|
|
439
|
+
function emailMatchesInvite(signInEmail, inviteEmail) {
|
|
440
|
+
return !!signInEmail && signInEmail.toLowerCase().trim() === inviteEmail;
|
|
441
|
+
}
|
|
442
|
+
async function acceptInvite(c, token, userId, userEmail) {
|
|
443
|
+
const inv = c.get('container').invitations;
|
|
444
|
+
if (!inv)
|
|
445
|
+
return;
|
|
446
|
+
try {
|
|
447
|
+
await inv.accept(token, userId, userEmail);
|
|
448
|
+
}
|
|
449
|
+
catch (err) {
|
|
450
|
+
// Expected invite states (expired / already-used / wrong email) must not block an
|
|
451
|
+
// otherwise-valid login; an unexpected infra error should still surface.
|
|
452
|
+
if (err instanceof ConflictError || err instanceof NotFoundError)
|
|
453
|
+
return;
|
|
454
|
+
throw err;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=AuthController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthController.js","sourceRoot":"","sources":["../../../src/modules/auth/AuthController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../../http/env.js';
|
|
3
|
+
/**
|
|
4
|
+
* Board mutations. Mounted under `/workspaces/:workspaceId`, so every handler
|
|
5
|
+
* reads the workspace id from the inherited path param.
|
|
6
|
+
*/
|
|
7
|
+
export declare function boardController(): Hono<AppEnv>;
|
|
8
|
+
//# sourceMappingURL=BoardController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BoardController.d.ts","sourceRoot":"","sources":["../../../src/modules/board/BoardController.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAI/C;;;GAGG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,CA0G9C"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { addFrameSchema, addModuleSchema, addServiceFromRepoSchema, addTaskSchema, moveBlockSchema, reparentSchema, toggleDependencySchema, updateBlockSchema, } from '@cat-factory/contracts';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { param } from '../../http/params.js';
|
|
4
|
+
import { jsonBody } from '../../http/validation.js';
|
|
5
|
+
/**
|
|
6
|
+
* Board mutations. Mounted under `/workspaces/:workspaceId`, so every handler
|
|
7
|
+
* reads the workspace id from the inherited path param.
|
|
8
|
+
*/
|
|
9
|
+
export function boardController() {
|
|
10
|
+
const app = new Hono();
|
|
11
|
+
app.post('/blocks', jsonBody(addFrameSchema), async (c) => {
|
|
12
|
+
const block = await c
|
|
13
|
+
.get('container')
|
|
14
|
+
.boardService.addFrame(param(c, 'workspaceId'), c.req.valid('json'));
|
|
15
|
+
return c.json(block, 201);
|
|
16
|
+
});
|
|
17
|
+
// Import an existing GitHub repo as a service frame — no bootstrap / agent run.
|
|
18
|
+
// First link + sync the repo into the workspace (it may be App-accessible but
|
|
19
|
+
// not yet tracked here), then create the `ready` frame and link the repo to it.
|
|
20
|
+
// A 409 tells the client the App can't see the repo yet (grant it access); the
|
|
21
|
+
// board service 404s an unknown repo and 422s one already on the board.
|
|
22
|
+
app.post('/blocks/from-repo', jsonBody(addServiceFromRepoSchema), async (c) => {
|
|
23
|
+
const container = c.get('container');
|
|
24
|
+
const workspaceId = param(c, 'workspaceId');
|
|
25
|
+
const { repoGithubId } = c.req.valid('json');
|
|
26
|
+
if (container.github) {
|
|
27
|
+
const linked = await container.github.syncService.linkRepo(workspaceId, repoGithubId);
|
|
28
|
+
if (!linked) {
|
|
29
|
+
return c.json({
|
|
30
|
+
error: {
|
|
31
|
+
code: 'repo_not_accessible',
|
|
32
|
+
message: 'The GitHub App cannot access this repository yet. Grant it access, then try again.',
|
|
33
|
+
},
|
|
34
|
+
}, 409);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const block = await container.boardService.addServiceFromRepo(workspaceId, c.req.valid('json'));
|
|
38
|
+
return c.json(block, 201);
|
|
39
|
+
});
|
|
40
|
+
app.post('/blocks/:blockId/tasks', jsonBody(addTaskSchema), async (c) => {
|
|
41
|
+
const block = await c
|
|
42
|
+
.get('container')
|
|
43
|
+
.boardService.addTask(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json'), c.get('user')?.id ?? null);
|
|
44
|
+
return c.json(block, 201);
|
|
45
|
+
});
|
|
46
|
+
app.post('/blocks/:blockId/modules', jsonBody(addModuleSchema), async (c) => {
|
|
47
|
+
const block = await c
|
|
48
|
+
.get('container')
|
|
49
|
+
.boardService.addModule(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json'));
|
|
50
|
+
return c.json(block, 201);
|
|
51
|
+
});
|
|
52
|
+
app.patch('/blocks/:blockId', jsonBody(updateBlockSchema), async (c) => {
|
|
53
|
+
const block = await c
|
|
54
|
+
.get('container')
|
|
55
|
+
.boardService.updateBlock(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json'));
|
|
56
|
+
return c.json(block);
|
|
57
|
+
});
|
|
58
|
+
app.post('/blocks/:blockId/move', jsonBody(moveBlockSchema), async (c) => {
|
|
59
|
+
const block = await c
|
|
60
|
+
.get('container')
|
|
61
|
+
.boardService.moveBlock(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json').position);
|
|
62
|
+
return c.json(block);
|
|
63
|
+
});
|
|
64
|
+
app.post('/blocks/:blockId/reparent', jsonBody(reparentSchema), async (c) => {
|
|
65
|
+
const block = await c
|
|
66
|
+
.get('container')
|
|
67
|
+
.boardService.reparent(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json'));
|
|
68
|
+
return c.json(block);
|
|
69
|
+
});
|
|
70
|
+
app.delete('/blocks/:blockId', async (c) => {
|
|
71
|
+
const container = c.get('container');
|
|
72
|
+
const workspaceId = param(c, 'workspaceId');
|
|
73
|
+
const blockId = param(c, 'blockId');
|
|
74
|
+
// Tear down any running runs under this subtree FIRST — killing their containers
|
|
75
|
+
// and durable drivers — so deleting a service/module never orphans a container
|
|
76
|
+
// that would idle until its watchdog. Then remove the blocks + run records.
|
|
77
|
+
await container.executionService.teardownForBlockTree(workspaceId, blockId);
|
|
78
|
+
await container.boardService.removeBlock(workspaceId, blockId);
|
|
79
|
+
return c.body(null, 204);
|
|
80
|
+
});
|
|
81
|
+
app.post('/blocks/:blockId/dependencies', jsonBody(toggleDependencySchema), async (c) => {
|
|
82
|
+
const block = await c
|
|
83
|
+
.get('container')
|
|
84
|
+
.boardService.toggleDependency(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json').sourceId);
|
|
85
|
+
return c.json(block);
|
|
86
|
+
});
|
|
87
|
+
return app;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=BoardController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BoardController.js","sourceRoot":"","sources":["../../../src/modules/board/BoardController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../../http/env.js';
|
|
3
|
+
/**
|
|
4
|
+
* Workspace-scoped board-scan endpoints: read the persisted repository blueprints,
|
|
5
|
+
* and the "scan repository" command (decompose a repo into a service → modules
|
|
6
|
+
* blueprint, optionally spawning it onto the board). Mounted under
|
|
7
|
+
* `/workspaces/:workspaceId`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function boardScanController(): Hono<AppEnv>;
|
|
10
|
+
//# sourceMappingURL=BoardScanController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BoardScanController.d.ts","sourceRoot":"","sources":["../../../src/modules/boardScan/BoardScanController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAY/C;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,CA0ClD"}
|