From d098048fa79893d8430be3dee3b5f796f2946942 Mon Sep 17 00:00:00 2001 From: Brace Sproul Date: Tue, 29 Jul 2025 14:24:22 -0700 Subject: [PATCH] fix: Initial auth flow (#596) --- apps/open-swe/src/utils/llms/model-manager.ts | 19 ++++++++++++----- .../web/src/components/github/auth-status.tsx | 21 +++++++++++++++---- .../web/src/components/thread/messages/ai.tsx | 7 ------- .../src/features/settings-page/api-keys.tsx | 6 ------ apps/web/src/hooks/useGitHubApp.ts | 8 +++---- apps/web/src/middleware.ts | 10 +++++++-- 6 files changed, 43 insertions(+), 28 deletions(-) diff --git a/apps/open-swe/src/utils/llms/model-manager.ts b/apps/open-swe/src/utils/llms/model-manager.ts index 42b5b928..fc184163 100644 --- a/apps/open-swe/src/utils/llms/model-manager.ts +++ b/apps/open-swe/src/utils/llms/model-manager.ts @@ -148,12 +148,21 @@ export class ModelManager { if (!apiKeys) { throw new Error("API keys not found in config"); } - apiKey = decryptSecret( - providerToApiKey(provider, apiKeys), - secretsEncryptionKey, - ); + const providerApiKey = providerToApiKey(provider, apiKeys); + if (!providerApiKey) { + throw new Error( + "No API key found for provider: " + + provider + + ". Please add one in the settings page.", + ); + } + apiKey = decryptSecret(providerApiKey, secretsEncryptionKey); if (!apiKey) { - throw new Error("No API key found for provider: " + provider); + throw new Error( + "No API key found for provider: " + + provider + + ". Please add one in the settings page.", + ); } } } diff --git a/apps/web/src/components/github/auth-status.tsx b/apps/web/src/components/github/auth-status.tsx index ba39dd75..2640f1cd 100644 --- a/apps/web/src/components/github/auth-status.tsx +++ b/apps/web/src/components/github/auth-status.tsx @@ -7,8 +7,10 @@ import { LangGraphLogoSVG } from "../icons/langgraph"; import { useGitHubToken } from "@/hooks/useGitHubToken"; import { useGitHubAppProvider } from "@/providers/GitHubApp"; import { GitHubAppProvider } from "@/providers/GitHubApp"; +import { useRouter } from "next/navigation"; function AuthStatusContent() { + const router = useRouter(); const [isAuth, setIsAuth] = useState(null); const [isLoading, setIsLoading] = useState(false); @@ -61,7 +63,18 @@ function AuthStatusContent() { window.location.href = "/api/github/installation"; }; - if (!isAuth) { + const showGetStarted = !isAuth; + const showInstallApp = + !showGetStarted && !hasGitHubAppInstalled && !isTokenLoading; + const showLoading = !showGetStarted && !showInstallApp && !githubToken; + + useEffect(() => { + if (!showGetStarted && !showInstallApp && !showLoading) { + router.push("/chat"); + } + }, [showGetStarted, showInstallApp, showLoading]); + + if (showGetStarted) { return (
@@ -91,7 +104,7 @@ function AuthStatusContent() { ); } - if (isAuth && hasGitHubAppInstalled === false && !isTokenLoading) { + if (showInstallApp) { return (
@@ -124,7 +137,7 @@ function AuthStatusContent() {
- -
-

- Your API key is stored -

-
))} diff --git a/apps/web/src/hooks/useGitHubApp.ts b/apps/web/src/hooks/useGitHubApp.ts index 9ec17f1a..9cd5c0ee 100644 --- a/apps/web/src/hooks/useGitHubApp.ts +++ b/apps/web/src/hooks/useGitHubApp.ts @@ -230,8 +230,8 @@ export function useGitHubApp(): UseGitHubAppReturn { setError("Failed to check GitHub App installation status"); setIsInstalled(false); } finally { - if (!append) setIsLoading(false); - if (append) setRepositoriesLoadingMore(false); + setIsLoading(false); + setRepositoriesLoadingMore(false); } }; @@ -352,9 +352,9 @@ export function useGitHubApp(): UseGitHubAppReturn { } previousInstallationIdRef.current = currentInstallationId; - - checkInstallation(); } + + checkInstallation(); }, [currentInstallationId]); useEffect(() => { diff --git a/apps/web/src/middleware.ts b/apps/web/src/middleware.ts index a6cb2574..c72b5904 100644 --- a/apps/web/src/middleware.ts +++ b/apps/web/src/middleware.ts @@ -1,10 +1,16 @@ import { NextRequest, NextResponse } from "next/server"; -import { GITHUB_TOKEN_COOKIE } from "@open-swe/shared/constants"; +import { + GITHUB_TOKEN_COOKIE, + GITHUB_INSTALLATION_ID_COOKIE, +} from "@open-swe/shared/constants"; import { verifyGithubUser } from "@open-swe/shared/github/verify-user"; export async function middleware(request: NextRequest) { const token = request.cookies.get(GITHUB_TOKEN_COOKIE)?.value; - const user = token ? await verifyGithubUser(token) : null; + const installationId = request.cookies.get( + GITHUB_INSTALLATION_ID_COOKIE, + )?.value; + const user = token && installationId ? await verifyGithubUser(token) : null; if (request.nextUrl.pathname === "/") { if (user) {