From a61461d611156de121cbb0233fd18a0e6a767e44 Mon Sep 17 00:00:00 2001 From: Juan Cobo Betancourt Date: Sat, 30 May 2026 09:55:42 -0700 Subject: [PATCH 1/2] Forward return_to from the login page into the GitHub OAuth start link The login page dropped return_to: the "Continue with GitHub" button read the error param but never forwarded return_to, so the OAuth start route stored an empty github_return_to cookie and the callback redirected to /auth instead of the deep-link destination. Read return_to from the URL and append it (encoded) to the start link, preserving the error handling. Add tests for the login-button forwarding (with a no-return_to parity case) and for a forwarded return_to landing in the github_return_to cookie. --- app/routes/auth.login.tsx | 18 +++++++++++++--- tests/routes/auth.github.test.ts | 31 ++++++++++++++++++++++++++ tests/routes/auth.login.test.ts | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/app/routes/auth.login.tsx b/app/routes/auth.login.tsx index 5a6582f..77a1d89 100644 --- a/app/routes/auth.login.tsx +++ b/app/routes/auth.login.tsx @@ -12,13 +12,16 @@ * Applies the AMPL design language: kit Button + AuthError. * * Component behaviour: - * - Renders a kit Button ("Continue with GitHub") → withBase("/github"). + * - Renders a kit Button ("Continue with GitHub") → withBase("/github"), + * forwarding any ?return_to= (percent-encoded) onto the start link so the + * deep-link destination survives the OAuth round-trip. Without this the + * param is dropped at the button and the user lands at /auth after login. * - Reads ?error= from useSearchParams() and renders AuthError with the * matching errors.* i18n key via the existing t(`errors.${errorCode}`, * { defaultValue }) safe pattern. * - Bilingual via the common namespace (login.* + errors.*). * - * @version v0.1.0 + * @version v0.2.2 */ import { useSearchParams } from "react-router"; @@ -36,6 +39,15 @@ export default function LoginPage() { const [searchParams] = useSearchParams(); const errorCode = searchParams.get("error"); + // Forward the deep-link destination into the OAuth start link. Without this + // the param is dropped at the button, so auth.github sets an empty + // github_return_to cookie and the callback lands the user at /auth instead + // of where they were heading. Encoded so the path survives the round-trip. + const returnTo = searchParams.get("return_to"); + const githubHref = withBase( + "/github" + (returnTo ? `?return_to=${encodeURIComponent(returnTo)}` : ""), + ); + return (
@@ -47,7 +59,7 @@ export default function LoginPage() { /> )} -