Skip to content

Commit dbc580e

Browse files
committed
refactor: generalize auto proxy naming
1 parent 70420c0 commit dbc580e

8 files changed

Lines changed: 27 additions & 31 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ describe('AuthenticateContext', () => {
258258
});
259259
});
260260

261-
describe('auto-proxy for .vercel.app', () => {
262-
it('auto-derives proxyUrl for .vercel.app hostnames', async () => {
261+
describe('auto-proxy for eligible hosts', () => {
262+
it('auto-derives proxyUrl for eligible hostnames', async () => {
263263
const clerkRequest = createClerkRequest(new Request('https://myapp-abc123.vercel.app/dashboard'));
264264
const context = await createAuthenticateContext(clerkRequest, {
265265
publishableKey: pkTest,
@@ -268,7 +268,7 @@ describe('AuthenticateContext', () => {
268268
expect(context.proxyUrl).toBe('https://myapp-abc123.vercel.app/__clerk');
269269
});
270270

271-
it('does NOT auto-derive proxyUrl for non-.vercel.app domains', async () => {
271+
it('does NOT auto-derive proxyUrl for ineligible domains', async () => {
272272
const clerkRequest = createClerkRequest(new Request('https://myapp.com/dashboard'));
273273
const context = await createAuthenticateContext(clerkRequest, {
274274
publishableKey: pkTest,

packages/backend/src/tokens/authenticateContext.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { buildAccountsBaseUrl } from '@clerk/shared/buildAccountsBaseUrl';
2-
import { isVercelPreviewDeploy } from '@clerk/shared/proxy';
2+
import { shouldAutoProxy } from '@clerk/shared/proxy';
33
import type { Jwt } from '@clerk/shared/types';
44
import { isCurrentDevAccountPortalOrigin, isLegacyDevAccountPortalOrigin } from '@clerk/shared/url';
55

@@ -70,10 +70,10 @@ class AuthenticateContext implements AuthenticateContext {
7070
private clerkRequest: ClerkRequest,
7171
options: AuthenticateRequestOptions,
7272
) {
73-
// Auto-detect proxy for Vercel preview deployments
73+
// Auto-detect proxy for supported platform deployments
7474
if (!options.proxyUrl && !options.domain) {
7575
const hostname = clerkRequest.clerkUrl.hostname;
76-
if (isVercelPreviewDeploy(hostname)) {
76+
if (shouldAutoProxy(hostname)) {
7777
options = { ...options, proxyUrl: `${clerkRequest.clerkUrl.origin}/__clerk` };
7878
}
7979
}

packages/clerk-js/src/core/__tests__/clerk.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,7 +2492,7 @@ describe('Clerk singleton', () => {
24922492
});
24932493
});
24942494

2495-
describe('auto-detection for .vercel.app', () => {
2495+
describe('auto-detection for eligible hosts', () => {
24962496
const originalLocation = window.location;
24972497

24982498
afterEach(() => {
@@ -2502,7 +2502,7 @@ describe('Clerk singleton', () => {
25022502
});
25032503
});
25042504

2505-
test('auto-derives proxyUrl when hostname is .vercel.app', () => {
2505+
test('auto-derives proxyUrl when hostname is eligible', () => {
25062506
Object.defineProperty(window, 'location', {
25072507
value: {
25082508
...originalLocation,
@@ -2517,7 +2517,7 @@ describe('Clerk singleton', () => {
25172517
expect(sut.proxyUrl).toBe('https://myapp-abc123.vercel.app/__clerk');
25182518
});
25192519

2520-
test('does NOT auto-derive proxyUrl for non-.vercel.app domains', () => {
2520+
test('does NOT auto-derive proxyUrl for ineligible domains', () => {
25212521
const sut = new Clerk(developmentPublishableKey);
25222522
expect(sut.proxyUrl).toBe('');
25232523
});

packages/clerk-js/src/core/clerk.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { windowNavigate } from '@clerk/shared/internal/clerk-js/windowNavigate';
3838
import { parsePublishableKey } from '@clerk/shared/keys';
3939
import { logger } from '@clerk/shared/logger';
4040
import { CLERK_NETLIFY_CACHE_BUST_PARAM } from '@clerk/shared/netlifyCacheHandler';
41-
import { isHttpOrHttps, isValidProxyUrl, isVercelPreviewDeploy, proxyUrlToAbsoluteURL } from '@clerk/shared/proxy';
41+
import { isHttpOrHttps, isValidProxyUrl, proxyUrlToAbsoluteURL, shouldAutoProxy } from '@clerk/shared/proxy';
4242
import {
4343
eventPrebuiltComponentMounted,
4444
eventPrebuiltComponentOpened,
@@ -355,8 +355,8 @@ export class Clerk implements ClerkInterface {
355355
if (resolved) {
356356
return resolved;
357357
}
358-
// Auto-detect for Vercel preview deployments when no explicit proxy or domain is configured
359-
if (!this.#domain && isVercelPreviewDeploy(window.location.hostname)) {
358+
// Auto-detect when no explicit proxy or domain is configured
359+
if (!this.#domain && shouldAutoProxy(window.location.hostname)) {
360360
return `${window.location.origin}/__clerk`;
361361
}
362362
}

packages/nextjs/src/server/__tests__/clerkMiddleware.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,8 +1191,8 @@ describe('frontendApiProxy multi-domain support', () => {
11911191
});
11921192
});
11931193

1194-
describe('auto-proxy for .vercel.app', () => {
1195-
it('auto-intercepts /__clerk/* requests on .vercel.app hostnames', async () => {
1194+
describe('auto-proxy for eligible hosts', () => {
1195+
it('auto-intercepts /__clerk/* requests on eligible hostnames', async () => {
11961196
const req = new NextRequest(new URL('/__clerk/v1/client', 'https://myapp-abc123.vercel.app').toString(), {
11971197
method: 'GET',
11981198
headers: new Headers(),

packages/nextjs/src/server/clerkMiddleware.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
import { clerkFrontendApiProxy, DEFAULT_PROXY_PATH, matchProxyPath } from '@clerk/backend/proxy';
2424
import { parsePublishableKey } from '@clerk/shared/keys';
2525
import { handleNetlifyCacheInDevInstance } from '@clerk/shared/netlifyCacheHandler';
26-
import { isVercelPreviewDeploy } from '@clerk/shared/proxy';
26+
import { shouldAutoProxy } from '@clerk/shared/proxy';
2727
import { notFound as nextjsNotFound } from 'next/navigation';
2828
import type { NextMiddleware, NextRequest } from 'next/server';
2929
import { NextResponse } from 'next/server';
@@ -583,7 +583,7 @@ const handleControlFlowErrors = (
583583
};
584584

585585
function getAutoDetectedProxyConfig(requestUrl: URL): FrontendApiProxyOptions | undefined {
586-
if (isVercelPreviewDeploy(requestUrl.hostname)) {
586+
if (shouldAutoProxy(requestUrl.hostname)) {
587587
return { enabled: true };
588588
}
589589
return undefined;

packages/shared/src/__tests__/proxy.spec.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
22

3-
import {
4-
isHttpOrHttps,
5-
isProxyUrlRelative,
6-
isValidProxyUrl,
7-
isVercelPreviewDeploy,
8-
proxyUrlToAbsoluteURL,
9-
} from '../proxy';
3+
import { isHttpOrHttps, isProxyUrlRelative, isValidProxyUrl, proxyUrlToAbsoluteURL, shouldAutoProxy } from '../proxy';
104

115
describe('isValidProxyUrl(key)', () => {
126
it('returns true if the proxyUrl is valid', () => {
@@ -44,25 +38,25 @@ describe('isHttpOrHttps(key)', () => {
4438
});
4539
});
4640

47-
describe('isVercelPreviewDeploy(hostname)', () => {
41+
describe('shouldAutoProxy(hostname)', () => {
4842
it('returns true for a .vercel.app subdomain', () => {
49-
expect(isVercelPreviewDeploy('myapp.vercel.app')).toBe(true);
43+
expect(shouldAutoProxy('myapp.vercel.app')).toBe(true);
5044
});
5145

5246
it('returns true for a git branch preview subdomain', () => {
53-
expect(isVercelPreviewDeploy('myapp-git-branch.vercel.app')).toBe(true);
47+
expect(shouldAutoProxy('myapp-git-branch.vercel.app')).toBe(true);
5448
});
5549

5650
it('returns false for the bare vercel.app domain', () => {
57-
expect(isVercelPreviewDeploy('vercel.app')).toBe(false);
51+
expect(shouldAutoProxy('vercel.app')).toBe(false);
5852
});
5953

6054
it('returns false for a custom domain', () => {
61-
expect(isVercelPreviewDeploy('myapp.com')).toBe(false);
55+
expect(shouldAutoProxy('myapp.com')).toBe(false);
6256
});
6357

6458
it('returns false for a domain that contains vercel.app but is not a subdomain', () => {
65-
expect(isVercelPreviewDeploy('vercel.app.evil.com')).toBe(false);
59+
expect(shouldAutoProxy('vercel.app.evil.com')).toBe(false);
6660
});
6761
});
6862

packages/shared/src/proxy.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ export function proxyUrlToAbsoluteURL(url: string | undefined): string {
3333
return isProxyUrlRelative(url) ? new URL(url, window.location.origin).toString() : url;
3434
}
3535

36-
export function isVercelPreviewDeploy(hostname: string): boolean {
37-
return hostname.endsWith('.vercel.app');
36+
const AUTO_PROXY_HOST_SUFFIXES = ['.vercel.app'];
37+
38+
export function shouldAutoProxy(hostname: string): boolean {
39+
return AUTO_PROXY_HOST_SUFFIXES.some(hostSuffix => hostname.endsWith(hostSuffix));
3840
}
3941

4042
/**

0 commit comments

Comments
 (0)