From 88b282fd9fa2d29d7e552d1d33cfd6f88fdc4193 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Wed, 22 Jan 2025 11:31:25 -0600 Subject: [PATCH 1/2] Fix logic for when to pass domain to createFapiClient() --- .../clerk-js/src/core/__tests__/clerk.test.ts | 29 +++++++++++++++++++ .../src/core/__tests__/fapiClient.test.ts | 8 +++++ packages/clerk-js/src/core/clerk.ts | 3 +- packages/clerk-js/src/core/fapiClient.ts | 8 +++-- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/packages/clerk-js/src/core/__tests__/clerk.test.ts b/packages/clerk-js/src/core/__tests__/clerk.test.ts index 24a48a57b42..7b1434a91ba 100644 --- a/packages/clerk-js/src/core/__tests__/clerk.test.ts +++ b/packages/clerk-js/src/core/__tests__/clerk.test.ts @@ -2051,6 +2051,35 @@ describe('Clerk singleton', () => { }); }); + describe('Clerk multi-domain', () => { + describe('when development satellite', () => { + it('fapiClient should not use Clerk.domain as its baseUrl', async () => { + const sut = new Clerk(developmentPublishableKey, { + domain: 'satellite.dev', + }); + await sut.load({ + isSatellite: true, + signInUrl: 'https://primary.dev/sign-in', + }); + + expect(sut.getFapiClient().buildUrl({ path: '/me' }).href).toContain(`https://${sut.frontendApi}/v1/me`); + }); + }); + + describe('when production satellite', () => { + test('fapiClient should use Clerk.domain as its baseUrl', async () => { + const sut = new Clerk(productionPublishableKey, { + domain: 'satellite.com', + }); + await sut.load({ + isSatellite: true, + }); + + expect(sut.getFapiClient().buildUrl({ path: '/me' }).href).toContain('https://clerk.satellite.com/v1/me'); + }); + }); + }); + describe('buildUrlWithAuth', () => { it('builds an absolute url from a relative url in development', async () => { const sut = new Clerk(developmentPublishableKey); diff --git a/packages/clerk-js/src/core/__tests__/fapiClient.test.ts b/packages/clerk-js/src/core/__tests__/fapiClient.test.ts index d86ccafb138..cc93181cb5d 100644 --- a/packages/clerk-js/src/core/__tests__/fapiClient.test.ts +++ b/packages/clerk-js/src/core/__tests__/fapiClient.test.ts @@ -75,6 +75,14 @@ describe('buildUrl(options)', () => { ); }); + it('uses domain from options if production', () => { + expect( + createFapiClient({ ...baseFapiClientOptions, domain: 'clerk.other.com', instanceType: 'production' }).buildUrl({ + path: '/foo', + }).href, + ).toBe(`https://clerk.other.com/v1/foo?__clerk_api_version=${SUPPORTED_FAPI_VERSION}&_clerk_js_version=test`); + }); + it('adds _clerk_session_id as a query parameter if provided and path does not start with client or waitlist', () => { expect(fapiClient.buildUrl({ path: '/foo', sessionId: 'sess_42' }).href).toBe( `https://clerk.example.com/v1/foo?__clerk_api_version=${SUPPORTED_FAPI_VERSION}&_clerk_js_version=test&_clerk_session_id=sess_42`, diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index dc1701b95cd..58440a21a1c 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -306,10 +306,11 @@ export class Clerk implements ClerkInterface { this.#instanceType = publishableKey.instanceType; this.#fapiClient = createFapiClient({ - domain: (this.instanceType === 'development' && this.isSatellite && this.domain) || undefined, + domain: this.domain, frontendApi: this.frontendApi, // this.instanceType is assigned above instanceType: this.instanceType as InstanceType, + isSatellite: this.isSatellite, getSessionId: () => { return this.session?.id; }, diff --git a/packages/clerk-js/src/core/fapiClient.ts b/packages/clerk-js/src/core/fapiClient.ts index a78dbed2af9..82f669023d6 100644 --- a/packages/clerk-js/src/core/fapiClient.ts +++ b/packages/clerk-js/src/core/fapiClient.ts @@ -67,6 +67,7 @@ type FapiClientOptions = { proxyUrl?: string; instanceType: InstanceType; getSessionId: () => string | undefined; + isSatellite?: boolean; }; export function createFapiClient(options: FapiClientOptions): FapiClient { @@ -114,7 +115,7 @@ export function createFapiClient(options: FapiClientOptions): FapiClient { searchParams.append('rotating_token_nonce', rotatingTokenNonce); } - if (options.domain) { + if (options.domain && options.instanceType === 'development' && options.isSatellite) { searchParams.append('__domain', options.domain); } @@ -144,8 +145,6 @@ export function createFapiClient(options: FapiClientOptions): FapiClient { function buildUrl(requestInit: FapiRequestInit): URL { const { path, pathPrefix = 'v1' } = requestInit; - const domainOnlyInProd = options.instanceType === 'production' ? options.domain : ''; - if (options.proxyUrl) { const proxyBase = new URL(options.proxyUrl); const proxyPath = proxyBase.pathname.slice(1, proxyBase.pathname.length); @@ -159,6 +158,9 @@ export function createFapiClient(options: FapiClientOptions): FapiClient { ); } + // We only use the domain option in production, in development it should always match the frontendApi + const domainOnlyInProd = options.instanceType === 'production' ? options.domain : ''; + const baseUrl = `https://${domainOnlyInProd || options.frontendApi}`; return buildUrlUtil( From 8af2542966ab5b28bdbecc64d20e3b899d2abd71 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Wed, 22 Jan 2025 11:34:03 -0600 Subject: [PATCH 2/2] adds changeset --- .changeset/chatty-lemons-hug.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chatty-lemons-hug.md diff --git a/.changeset/chatty-lemons-hug.md b/.changeset/chatty-lemons-hug.md new file mode 100644 index 00000000000..5b1d9f03999 --- /dev/null +++ b/.changeset/chatty-lemons-hug.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Fixes an issue where Clerk's internal API client was using the incorrect domain for satellite apps.