diff --git a/web/app/auth/signin/page.tsx b/web/app/auth/signin/page.tsx index 47296d6ef..4f8d3dd58 100644 --- a/web/app/auth/signin/page.tsx +++ b/web/app/auth/signin/page.tsx @@ -1,7 +1,28 @@ import { Suspense } from 'react'; +import { redirect } from 'next/navigation'; import SignInForm from './form'; +import { loadConsoleProfile } from '@/lib/services/console-profile'; + +export const dynamic = 'force-dynamic'; + +export default async function SignIn({ + searchParams, +}: { + searchParams: Promise<{ next?: string }>; +}) { + // Auth guard: an already-signed-in user should never sit on the sign-in + // screen. On mobile the device Back button pops history to /auth/signin + // (the OAuth flow leaves it on the stack), which read as "Back dumps me at + // sign-in". Bounce authenticated users forward into the app instead, so Back + // effectively returns them to the console. + const profile = await loadConsoleProfile(); + if (profile) { + const { next } = await searchParams; + // Only honour app-internal paths to avoid an open-redirect via ?next=. + const dest = next && next.startsWith('/') && !next.startsWith('//') ? next : '/dashboard'; + redirect(dest); + } -export default function SignIn() { return ( Loading...}>