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 */