fix(auth): убрать SSO-цикл на /auth/callback после replaceState
Docker / build (push) Failing after 18s
Docker / build (push) Failing after 18s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -38,9 +38,13 @@ async function fetchApi<T>(path: string, options: RequestInit = {}): Promise<T>
|
||||
})
|
||||
if (!res.ok) {
|
||||
if (res.status === 401) {
|
||||
// Avoid redirect storms: only hand off once per page load
|
||||
const handoffKey = 'vps_auth_401_handoff'
|
||||
const already = sessionStorage.getItem(handoffKey)
|
||||
clearToken()
|
||||
const cfg = await ensureAuthConfig()
|
||||
if (cfg.required || isAuthEnabled()) {
|
||||
if ((cfg.required || isAuthEnabled()) && !already) {
|
||||
sessionStorage.setItem(handoffKey, '1')
|
||||
redirectToPortalLogin(`${window.location.origin}/auth/callback`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import { createFileRoute, redirect } from '@tanstack/react-router'
|
||||
import {
|
||||
ensureAuthConfig,
|
||||
firstAllowedPath,
|
||||
getClaims,
|
||||
getToken,
|
||||
parseHashToken,
|
||||
redirectToPortalLogin,
|
||||
setToken,
|
||||
@@ -11,14 +13,19 @@ export const Route = createFileRoute('/auth/callback')({
|
||||
beforeLoad: async () => {
|
||||
await ensureAuthConfig()
|
||||
const { accessToken } = parseHashToken(window.location.hash)
|
||||
if (!accessToken) {
|
||||
redirectToPortalLogin(`${window.location.origin}/auth/callback`)
|
||||
await new Promise(() => {})
|
||||
return
|
||||
if (accessToken) {
|
||||
setToken(accessToken)
|
||||
// Do not replaceState to strip the hash here — that re-triggers beforeLoad
|
||||
// with an empty hash and sends the user back to the portal (SSO loop).
|
||||
sessionStorage.removeItem('vps_auth_401_handoff')
|
||||
throw redirect({ to: firstAllowedPath() })
|
||||
}
|
||||
setToken(accessToken)
|
||||
window.history.replaceState(null, '', '/auth/callback')
|
||||
throw redirect({ to: firstAllowedPath() })
|
||||
// Already stored from a previous parse (e.g. remount) — finish handoff.
|
||||
if (getToken() && getClaims()) {
|
||||
throw redirect({ to: firstAllowedPath() })
|
||||
}
|
||||
redirectToPortalLogin(`${window.location.origin}/auth/callback`)
|
||||
await new Promise(() => {})
|
||||
},
|
||||
component: () => null,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user