fix(auth): strip internal port from OAuth redirects on BYOD domains (#728)
* fix(auth): strip internal port from OAuth redirects on BYOD domains When BYOD custom domains proxy auth requests through the dashboard to PRIVATE_SERVER_URL (e.g. http://cio-api-vymh:10000), Node's URL host setter preserves the upstream port. Better Auth then redirects browsers to https://customer.example:10000/... which fails. - Add oauth-proxy-redirect helpers to clear backend ports explicitly - Rewrite inbound auth request URLs and outbound oauth-proxy-callback Location headers - Send hostname-only X-Forwarded-Host from dashboard proxy when port matches backend Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com> * fix(auth): address Greptile review on oauth port stripping - Only treat PRIVATE_SERVER_URL as an internal backend port - Add test for rewriteAuthRequestUrl when forwarded host still has :10000 Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
This commit is contained in:
co-authored by
Rotimi Best
Cursor Agent
parent
3eb5e1268d
commit
2fb6b1c477
@@ -34,8 +34,27 @@ function resolveApiUpstreamBase(): string | null {
|
||||
return base.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
function resolveOriginalHost(request: Request, url: URL): string {
|
||||
return request.headers.get('x-forwarded-host') ?? request.headers.get('host') ?? url.host;
|
||||
function resolveBrowserForwardedHost(request: Request, url: URL): string {
|
||||
const raw = request.headers.get('x-forwarded-host') ?? request.headers.get('host') ?? url.hostname;
|
||||
const [hostname, port = ''] = raw.includes(':') ? raw.split(':', 2) : [raw, ''];
|
||||
|
||||
if (!port) {
|
||||
return hostname;
|
||||
}
|
||||
|
||||
const privateServerUrl = process.env.PRIVATE_SERVER_URL;
|
||||
if (privateServerUrl) {
|
||||
try {
|
||||
const backendPort = new URL(privateServerUrl).port;
|
||||
if (backendPort && port === backendPort) {
|
||||
return hostname;
|
||||
}
|
||||
} catch {
|
||||
// Ignore malformed PRIVATE_SERVER_URL.
|
||||
}
|
||||
}
|
||||
|
||||
return raw;
|
||||
}
|
||||
|
||||
export async function proxyRequestToApi(request: Request): Promise<Response> {
|
||||
@@ -49,7 +68,7 @@ export async function proxyRequestToApi(request: Request): Promise<Response> {
|
||||
|
||||
const upstreamPath = resolveApiUpstreamPath(url.pathname);
|
||||
const upstreamUrl = new URL(`${upstreamPath}${url.search}`, apiBase);
|
||||
const originalHost = resolveOriginalHost(request, url);
|
||||
const originalHost = resolveBrowserForwardedHost(request, url);
|
||||
|
||||
const upstreamHeaders = new Headers(request.headers);
|
||||
upstreamHeaders.set('host', upstreamUrl.host);
|
||||
|
||||
Reference in New Issue
Block a user