From c3aeba69a041ed9f335ed90d584449e2b3c83a40 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 6 Jul 2026 11:10:27 +0000 Subject: [PATCH] fix(auth): bounce signed-in users off the sign-in page (mobile Back) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On mobile the device Back button pops history to /auth/signin — the OAuth sign-in flow leaves that route on the stack — so an authenticated user pressing Back dead-ended on the sign-in screen. Guard the sign-in page: if a session already exists, redirect into the app (honouring a safe app-internal ?next, else /dashboard), so Back effectively returns to the console instead. Open-redirect-safe: only '/'-prefixed, non-'//' targets are honoured. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ByQJWuMebsKpQcHNqXCBWD --- web/app/auth/signin/page.tsx | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) 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...}>