From 6cc981d36695b9546efe5fcbfe232acd656db2ec Mon Sep 17 00:00:00 2001 From: chenchen Date: Sat, 9 May 2026 17:29:01 +0800 Subject: [PATCH] fix(server/web): SPA navigate() to backend bridge URLs renders 404 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the desktop one-click login flow opens /heicode/oauth/authorize?state=...&redirect_uri=... in the browser and the user isn't signed in, Manager renders the "please log in" bridge page that links to /sign-in?redirect=. After login, useAuthRedirect's `handleLoginSuccess` calls TanStack Router's `navigate({ to: targetPath })` to send the user back to that authorize URL. But TanStack Router only knows about React routes; backend bridges (`/heicode/oauth/...`, `/api/...`) have no matching route, so the SPA renders 404. The user has to manually re-enter the URL, at which point the backend handles it and 302s to the loopback callback. This produced the 500 → 404 → success symptom users hit on first-time desktop login. Fix: detect backend prefixes (`/heicode/oauth/`, `/api/`) and use `window.location.assign()` to force a full-page navigation so the server gets the request directly. React-route paths still go through `navigate()` as before. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../features/auth/hooks/use-auth-redirect.ts | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/heicode/web/default/src/features/auth/hooks/use-auth-redirect.ts b/heicode/web/default/src/features/auth/hooks/use-auth-redirect.ts index 6398afc..258fe16 100644 --- a/heicode/web/default/src/features/auth/hooks/use-auth-redirect.ts +++ b/heicode/web/default/src/features/auth/hooks/use-auth-redirect.ts @@ -129,11 +129,34 @@ export function useAuthRedirect() { // 告知路由守卫:本会话已完成登录,避免 beforeLoad 再次请求 /me 失败导致踢回登录页 markHeicodeAuthenticatedSessionVerified() - // Navigate to target page + // Navigate to target page. + // + // Tricky bit: the SPA's `navigate()` only knows about TanStack-Router + // routes; if `redirectTo` points at a backend bridge URL like + // `/heicode/oauth/authorize?...` (set by the desktop one-click login + // flow — see `heicode/controller/heicode_oauth.go:renderHeicodeLoginRequired`), + // the router renders 404 because no React route matches. The user + // then has to manually re-enter the URL, at which point the backend + // handles it and 302s to the loopback callback. + // + // Detect known backend prefixes and force a full-page navigation + // (window.location.assign) so the server gets the request directly. const targetPath = normalizeRedirectTarget(redirectTo) + if (isBackendBridgePath(targetPath)) { + window.location.assign(targetPath) + return + } navigate({ to: targetPath, replace: true }) } + // Paths under these prefixes are served by the Go backend (oauth bridge, + // file downloads, etc.) and have NO matching React route. Navigating to + // them via TanStack `navigate()` would render the SPA's 404. + const BACKEND_BRIDGE_PREFIXES = ['/heicode/oauth/', '/api/'] + function isBackendBridgePath(path: string): boolean { + return BACKEND_BRIDGE_PREFIXES.some((prefix) => path.startsWith(prefix)) + } + /** * Redirect to 2FA page */