From 4ff440fb3466acb4bc950b5d7f06bddde2598889 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sat, 18 Jul 2026 14:09:21 +0700 Subject: [PATCH] =?UTF-8?q?fix(auth):=20SSO=20return=5Fto=20=D0=B1=D0=B5?= =?UTF-8?q?=D0=B7=20/me=20=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D0=B1=D0=B8=D1=82=D1=8C=20rate=20limit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- apps/web/src/routes/index.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx index c4eea9b..aada620 100644 --- a/apps/web/src/routes/index.tsx +++ b/apps/web/src/routes/index.tsx @@ -18,21 +18,24 @@ export const Route = createFileRoute('/')({ beforeLoad: async ({ search }) => { const token = getToken() if (!token) return - try { - const me = await api.get('/api/v1/auth/me') + + // SSO handoff first — avoid /me round-trip (rate-limit loops under redirect storms) + if (search.return_to) { const allowlist = await ensureReturnToAllowlist() - if ( - search.return_to && - isReturnToAllowed(search.return_to, allowlist) - ) { + if (isReturnToAllowed(search.return_to, allowlist)) { const exp = new Date(Date.now() + 60 * 60 * 1000).toISOString() window.location.href = buildSsoRedirectUrl( search.return_to, token, exp, ) + await new Promise(() => {}) return } + } + + try { + const me = await api.get('/api/v1/auth/me') throw redirect({ to: me.is_admin ? '/admin' : '/apps' }) } catch (err) { if (err && typeof err === 'object' && 'to' in err) throw err