Skip to content

Commit 5d60d17

Browse files
committed
Preserve allowlisted alternate redirect URI when retrying OAuth flow
The retry redirect previously restarted the flow with only ?next=, so logins started with an ALTERNATIVE_REDIRECT_URLS callback lost that redirect URI. Carry the state payload's redirectUrl back as ?callback= when it matches the allowlist (triggerOauthFlow re-validates it). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QWamsbC2xoGRoQazysMEVp
1 parent 5a8b420 commit 5d60d17

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

src/routes/login/callback/+server.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,28 @@ export async function GET({ url, locals, cookies, request, getClientAddress }) {
6464
if (!hasLoginRetryCookie(cookies)) {
6565
setLoginRetryCookie(cookies);
6666

67-
// Best-effort recovery of the return path from the (unverified) state payload;
68-
// it is re-sanitized to an in-app absolute path before use.
69-
let next: string | undefined;
67+
// Best-effort recovery of the return path and redirect URI from the (unverified)
68+
// state payload; the path is re-sanitized and the redirect URI is checked against
69+
// ALTERNATIVE_REDIRECT_URLS both here and again in triggerOauthFlow before use.
70+
const retryParams = new URLSearchParams();
7071
try {
71-
next = sanitizeReturnPath(JSON.parse(csrfToken)?.data?.next);
72+
const data = JSON.parse(csrfToken)?.data;
73+
const next = sanitizeReturnPath(data?.next);
74+
if (next) {
75+
retryParams.set("next", next);
76+
}
77+
if (
78+
typeof data?.redirectUrl === "string" &&
79+
config.ALTERNATIVE_REDIRECT_URLS.includes(data.redirectUrl)
80+
) {
81+
retryParams.set("callback", data.redirectUrl);
82+
}
7283
} catch {
73-
next = undefined;
84+
// Malformed state: retry without a return path or alternate redirect URI.
7485
}
7586

76-
return redirect(302, `${base}/login${next ? `?next=${encodeURIComponent(next)}` : ""}`);
87+
const retryQuery = retryParams.toString();
88+
return redirect(302, `${base}/login${retryQuery ? `?${retryQuery}` : ""}`);
7789
}
7890

7991
throw error(

0 commit comments

Comments
 (0)