diff --git a/.changeset/happy-tools-cry.md b/.changeset/happy-tools-cry.md new file mode 100644 index 00000000000..a4eb1493758 --- /dev/null +++ b/.changeset/happy-tools-cry.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': patch +--- + +Fix calculation of handshake URL when proxy URL is set on the ClerkProvider diff --git a/packages/backend/src/tokens/__tests__/handshake.test.ts b/packages/backend/src/tokens/__tests__/handshake.test.ts index 2e8f70a93fe..f174b7f3228 100644 --- a/packages/backend/src/tokens/__tests__/handshake.test.ts +++ b/packages/backend/src/tokens/__tests__/handshake.test.ts @@ -176,6 +176,35 @@ describe('HandshakeService', () => { 'Missing clerkUrl in authenticateContext', ); }); + + it('should use proxy URL when available', () => { + mockAuthenticateContext.proxyUrl = 'https://my-proxy.example.com'; + const headers = handshakeService.buildRedirectToHandshake('test-reason'); + const location = headers.get(constants.Headers.Location); + if (!location) { + throw new Error('Location header is missing'); + } + const url = new URL(location); + + expect(url.hostname).toBe('my-proxy.example.com'); + expect(url.pathname).toBe('/v1/client/handshake'); + expect(url.searchParams.get('redirect_url')).toBe('https://example.com/'); + expect(url.searchParams.get(constants.QueryParameters.SuffixedCookies)).toBe('true'); + expect(url.searchParams.get(constants.QueryParameters.HandshakeReason)).toBe('test-reason'); + }); + + it('should handle proxy URL with trailing slash', () => { + mockAuthenticateContext.proxyUrl = 'https://my-proxy.example.com/'; + const headers = handshakeService.buildRedirectToHandshake('test-reason'); + const location = headers.get(constants.Headers.Location); + if (!location) { + throw new Error('Location header is missing'); + } + const url = new URL(location); + + expect(url.hostname).toBe('my-proxy.example.com'); + expect(url.pathname).toBe('/v1/client/handshake'); + }); }); describe('handleTokenVerificationErrorInDevelopment', () => { diff --git a/packages/backend/src/tokens/handshake.ts b/packages/backend/src/tokens/handshake.ts index 55ad3e39fce..3120f2aacc8 100644 --- a/packages/backend/src/tokens/handshake.ts +++ b/packages/backend/src/tokens/handshake.ts @@ -136,7 +136,11 @@ export class HandshakeService { const redirectUrl = this.removeDevBrowserFromURL(this.authenticateContext.clerkUrl); const frontendApiNoProtocol = this.authenticateContext.frontendApi.replace(/http(s)?:\/\//, ''); - const url = new URL(`https://${frontendApiNoProtocol}/v1/client/handshake`); + const baseUrl = this.authenticateContext.proxyUrl + ? this.authenticateContext.proxyUrl.replace(/\/$/, '') + : `https://${frontendApiNoProtocol}`; + + const url = new URL(`${baseUrl}/v1/client/handshake`); url.searchParams.append('redirect_url', redirectUrl?.href || ''); url.searchParams.append('__clerk_api_version', SUPPORTED_BAPI_VERSION); url.searchParams.append(