fix(auth): break infinite redirect loop on /cp/auth/login

AuthGate redirected anonymous users to /cp/auth/login?return_to=<url>,
but the login page itself triggered AuthGate, which redirected again
with double-encoded return_to. Each redirect added another encoding
layer until the URL exceeded 431 (Request Header Fields Too Large).

Two guards:
1. redirectToLogin() returns early if already on /cp/auth/* path
2. AuthGate skips redirect check entirely for /cp/auth/* paths

[Molecule-Platform-Evolvement-Manager]

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
rabbitblood 2026-04-21 19:54:17 -07:00 committed by Hongming Wang
parent 925a71887d
commit edc42b2893
2 changed files with 9 additions and 0 deletions

View File

@ -29,6 +29,11 @@ export function AuthGate({ children }: { children: ReactNode }) {
setState({ kind: "anonymous", skipRedirect: true });
return;
}
// Never gate /cp/auth/* paths — these ARE the login pages.
if (typeof window !== "undefined" && window.location.pathname.startsWith("/cp/auth/")) {
setState({ kind: "anonymous", skipRedirect: true });
return;
}
let cancelled = false;
fetchSession()
.then((s) => {

View File

@ -44,6 +44,10 @@ export async function fetchSession(): Promise<Session | null> {
*/
export function redirectToLogin(screenHint: "sign-up" | "sign-in" = "sign-in"): void {
if (typeof window === "undefined") return;
// Guard against infinite redirect loop: if we're already on the login
// page, don't redirect again (each redirect double-encodes return_to
// until the URL exceeds header limits → 431).
if (window.location.pathname.startsWith("/cp/auth/")) return;
const returnTo = window.location.href;
const path = screenHint === "sign-up" ? "signup" : "login";
const dest = `${PLATFORM_URL}${AUTH_BASE}/${path}?return_to=${encodeURIComponent(returnTo)}`;