fix(auth): post-callback redirect honors APP_URL (reverse-proxy) #102
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol#102
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The
redirectTo()helper inapp/api/auth/oauth/callback/[provider]/route.tsresolves redirect locations (/login,/profile,/account) againstreq.nextUrl:A behind-reverse-proxy deployment lands here with
req.nextUrl.origin === "http://0.0.0.0:3000"(the container bind address) when the proxy doesn't passX-Forwarded-Host+X-Forwarded-Protoin a way Next trusts. Every refused-callback path then 302s the user to an internal URL their browser can't reach.Same class of bug as the outbound
redirect_uribeforeAPP_URLwas threaded throughappOrigin()— the inbound IdP callback works correctly (usesAPP_URL), but the post-callback redirect usesreq.nextUrlraw.Discovered while testing the #100 diagnostic surfacing on a deployed Authentik:
?error=oidc_claimcorrectly identified, but the redirect landed onhttp://0.0.0.0:3000/login?error=oidc_claiminstead ofhttps://carol.int.wynning.tech/login?error=oidc_claim.Scope
redirectTo()to build the URL againstappOrigin(req)(which honorsAPP_URLwhen set, falls back toreq.nextUrl.origin).APP_URLis honored on a refused-callback redirect (e.g. the existingno_verified_emailpath underAPP_URL="https://carol.example.com").Out of scope
X-Forwarded-*headers. Still out per the rationale in #99./api/auth/loginand/api/auth/registeruse absolute URLs inredirect()that already referenceAPP_URLindirectly. Worth a separate sweep ticket if one's found.Acceptance
A self-hoster with
APP_URL=https://<host>set behind a reverse proxy lands onhttps://<host>/login?error=...(nothttp://0.0.0.0:3000/...) after every refused-callback path.