Skip to content

Commit 43be86f

Browse files
committed
refactor(backend): use getAutoProxyUrlFromEnvironment instead of header-based detection
1 parent e0a275d commit 43be86f

2 files changed

Lines changed: 31 additions & 14 deletions

File tree

packages/backend/src/tokens/__tests__/authenticateContext.test.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,21 @@ describe('AuthenticateContext', () => {
259259
});
260260

261261
describe('auto-proxy for eligible hosts', () => {
262-
it('auto-derives proxyUrl for production instances on eligible hostnames', async () => {
262+
const originalEnv = process.env;
263+
264+
beforeEach(() => {
265+
process.env = {
266+
...originalEnv,
267+
VERCEL_TARGET_ENV: 'production',
268+
VERCEL_PROJECT_PRODUCTION_URL: 'myapp-abc123.vercel.app',
269+
};
270+
});
271+
272+
afterEach(() => {
273+
process.env = originalEnv;
274+
});
275+
276+
it('auto-derives proxyUrl when Vercel env vars indicate production vercel.app', async () => {
263277
const clerkRequest = createClerkRequest(new Request('https://myapp-abc123.vercel.app/dashboard'));
264278
const context = await createAuthenticateContext(clerkRequest, {
265279
publishableKey: pkLive,
@@ -268,7 +282,7 @@ describe('AuthenticateContext', () => {
268282
expect(context.proxyUrl).toBe('https://myapp-abc123.vercel.app/__clerk');
269283
});
270284

271-
it('does NOT auto-derive proxyUrl for development instances on eligible hostnames', async () => {
285+
it('does NOT auto-derive proxyUrl for development keys', async () => {
272286
const clerkRequest = createClerkRequest(new Request('https://myapp-abc123.vercel.app/dashboard'));
273287
const context = await createAuthenticateContext(clerkRequest, {
274288
publishableKey: pkTest,
@@ -277,8 +291,10 @@ describe('AuthenticateContext', () => {
277291
expect(context.proxyUrl).toBeUndefined();
278292
});
279293

280-
it('does NOT auto-derive proxyUrl for ineligible domains', async () => {
281-
const clerkRequest = createClerkRequest(new Request('https://myapp.com/dashboard'));
294+
it('does NOT auto-derive proxyUrl when Vercel env vars are absent', async () => {
295+
delete process.env.VERCEL_TARGET_ENV;
296+
delete process.env.VERCEL_PROJECT_PRODUCTION_URL;
297+
const clerkRequest = createClerkRequest(new Request('https://myapp-abc123.vercel.app/dashboard'));
282298
const context = await createAuthenticateContext(clerkRequest, {
283299
publishableKey: pkLive,
284300
});

packages/backend/src/tokens/authenticateContext.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { buildAccountsBaseUrl } from '@clerk/shared/buildAccountsBaseUrl';
2-
import { isProductionFromPublishableKey } from '@clerk/shared/keys';
3-
import { AUTO_PROXY_PATH, shouldAutoProxy } from '@clerk/shared/proxy';
2+
import { AUTO_PROXY_PATH, getAutoProxyUrlFromEnvironment } from '@clerk/shared/proxy';
43
import type { Jwt } from '@clerk/shared/types';
54
import { isCurrentDevAccountPortalOrigin, isLegacyDevAccountPortalOrigin } from '@clerk/shared/url';
65

@@ -72,14 +71,16 @@ class AuthenticateContext implements AuthenticateContext {
7271
private clerkRequest: ClerkRequest,
7372
options: AuthenticateRequestOptions,
7473
) {
75-
// Auto-detect proxy for supported platform deployments (production only).
76-
// Note: hostname is derived from X-Forwarded-Host when present, which is
77-
// authoritative on Vercel's edge but spoofable behind misconfigured proxies.
78-
if (!options.proxyUrl && !options.domain && isProductionFromPublishableKey(options.publishableKey ?? '')) {
79-
const hostname = clerkRequest.clerkUrl.hostname;
80-
if (shouldAutoProxy(hostname)) {
81-
options = { ...options, proxyUrl: `${clerkRequest.clerkUrl.origin}${AUTO_PROXY_PATH}` };
82-
}
74+
// Auto-detect proxy for supported platform deployments using environment
75+
// variables (e.g. VERCEL_TARGET_ENV, VERCEL_PROJECT_PRODUCTION_URL) instead
76+
// of request headers, which avoids X-Forwarded-Host spoofing concerns.
77+
const autoProxyPath = getAutoProxyUrlFromEnvironment({
78+
publishableKey: options.publishableKey ?? '',
79+
hasProxyUrl: !!options.proxyUrl,
80+
hasDomain: !!options.domain,
81+
});
82+
if (autoProxyPath) {
83+
options = { ...options, proxyUrl: `${clerkRequest.clerkUrl.origin}${autoProxyPath}` };
8384
}
8485

8586
if (options.acceptsToken === TokenType.M2MToken || options.acceptsToken === TokenType.ApiKey) {

0 commit comments

Comments
 (0)