refactor: compute login return_to client-side, drop middleware header injection#412
Draft
alukach wants to merge 2 commits into
Draft
refactor: compute login return_to client-side, drop middleware header injection#412alukach wants to merge 2 commits into
alukach wants to merge 2 commits into
Conversation
… injection The login button and the edit-page auth guards built their `return_to` server-side from `x-pathname`/`x-search` request headers that middleware injected on every matched request. This replaces that with client-side computation, removing the middleware header injection entirely. - Add `LoginButton` (client): reads `window.location.href` at click time to build the login URL, mirroring the logout button. - Add `LoginRequired` interstitial (reuses `StatusPage`) shown when an unauthenticated user hits a protected edit page, instead of a server-side redirect-to-login. The authorization checks (isAuthorized → 403/404) are unchanged. - `StatusPage`: add an `unauthenticated` type and a custom `action` slot. - Header login button now renders `<LoginButton />` (no server-side return_to). - Delete `getReturnToUrl()` (its only callers are gone) and stop the middleware from stamping x-pathname/x-search on every request. Cost: one extra click when a logged-out user lands directly on an edit page. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
Claude finished @alukach's task in 2m 44s —— View job Review complete
✅ No blocking issues — safe to merge. The refactor is clean: auth checks ( Two minor, non-blocking notes:
|
…href Use a real <a> (via Button asChild) so the sign-in control behaves like a link — open-in-new-tab, middle-click, keyboard. A plain anchor (not next/link) forces the full-page navigation the Ory login flow needs (external domain in prod, middleware-proxied relative path in dev). return_to is set to the current absolute URL after mount and refreshed on navigation via usePathname, since the button lives in the persistent header. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The login flow's
return_towas built server-side fromx-pathname/x-searchheaders thatmiddleware.tsinjected on every matched request. Server components can't read the current path directly, so the middleware stamped it on forgetReturnToUrl()to reconstruct. This removes that cross-cutting mechanism by computingreturn_toclient-side instead.Follow-up to #411 (logout return_to). Discussion: the middleware header injection fed not just the header login button but three server-side redirect guards on the edit pages, so making the button client-side alone couldn't remove it — the guards had to stop redirecting server-side too.
What changed
LoginButton(new, client): readswindow.location.hrefat click time to build the login URL — same pattern as the logout button. Used by the header and the interstitial.LoginRequired(new): interstitial shown when an unauthenticated user hits a protected edit page, replacingredirect(loginUrl(await getReturnToUrl())). ReusesStatusPage.StatusPage: added anunauthenticatedtype and a customactionslot (for the client login button).edit/page.tsx,edit/account/.../layout.tsx,edit/product/.../layout.tsx): unauthenticated → render<LoginRequired />instead of server-redirect. TheisAuthorizedchecks (403/404) are unchanged — only the unauthenticated presentation changed.getReturnToUrl()deleted (all callers gone);getBaseUrl()kept.middleware.ts: dropped thex-pathname/x-searchinjection — the fallthrough is now a plainNextResponse.next(). (Ory proxying, legacy redirects, and the devtools 404 are untouched.)params/SettingsPagePropsfromedit/page.tsxwhile there.Behavior change
A logged-out user who lands directly on an edit page now sees a "Sign in required" page with a Sign in button (one extra click) instead of an instant redirect to login. After login they still return to the edit page. The common case (navigating to edit while already logged in) is unchanged.
Verification
tsc --noEmit— cleannext linton touched files — cleannext build— compiles, type-checks, lints, and generates static pages; only fails prerendering/(marketing)/pagebecausegetFeaturedProductscan't reach AWS in the sandbox (no valid credentials). Unrelated to this change.Note: Ory's
selfservice.allowed_return_urlsmust permit same-origin URLs (already required by the existing login flow), so no Ory config change needed.🤖 Generated with Claude Code