From 42cd7989bb498a9592078d734592981384a8866f Mon Sep 17 00:00:00 2001 From: Konstantinos Pittas Date: Wed, 5 Feb 2025 12:52:25 +0200 Subject: [PATCH] feat(clerk-js): Add Frontend API URL to allowed redirect origins --- .changeset/silver-dodos-invite.md | 5 ++ packages/clerk-js/src/core/clerk.ts | 6 ++- .../clerk-js/src/utils/__tests__/url.test.ts | 47 ++++++++++++------- packages/clerk-js/src/utils/url.ts | 5 ++ 4 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 .changeset/silver-dodos-invite.md diff --git a/.changeset/silver-dodos-invite.md b/.changeset/silver-dodos-invite.md new file mode 100644 index 00000000000..9a6e644bb31 --- /dev/null +++ b/.changeset/silver-dodos-invite.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +`createAllowedRedirectOrigins` now takes the instance type into account to include Frontend API URL for development instances. This is necessary to properly support Clerk as an IdP with OAuth for development instances. diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 4eaddfe4fb4..c2b838c9669 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -2161,7 +2161,11 @@ export class Clerk implements ClerkInterface { return { ...defaultOptions, ...options, - allowedRedirectOrigins: createAllowedRedirectOrigins(options?.allowedRedirectOrigins, this.frontendApi), + allowedRedirectOrigins: createAllowedRedirectOrigins( + options?.allowedRedirectOrigins, + this.frontendApi, + this.instanceType, + ), }; }; diff --git a/packages/clerk-js/src/utils/__tests__/url.test.ts b/packages/clerk-js/src/utils/__tests__/url.test.ts index ef37ded892e..53176d95584 100644 --- a/packages/clerk-js/src/utils/__tests__/url.test.ts +++ b/packages/clerk-js/src/utils/__tests__/url.test.ts @@ -511,26 +511,39 @@ describe('isAllowedRedirect', () => { }); describe('createAllowedRedirectOrigins', () => { - it('contains the default allowed origin values if no value is provided', async () => { - const frontendApi = 'https://somename.clerk.accounts.dev'; - const allowedRedirectOriginsValuesUndefined = createAllowedRedirectOrigins(undefined, frontendApi); - const allowedRedirectOriginsValuesEmptyArray = createAllowedRedirectOrigins([], frontendApi); - - expect(allowedRedirectOriginsValuesUndefined).toEqual([ - 'http://localhost', - `https://${getETLDPlusOneFromFrontendApi(frontendApi)}`, - `https://*.${getETLDPlusOneFromFrontendApi(frontendApi)}`, - ]); - - expect(allowedRedirectOriginsValuesEmptyArray).toEqual([ - 'http://localhost', - `https://${getETLDPlusOneFromFrontendApi(frontendApi)}`, - `https://*.${getETLDPlusOneFromFrontendApi(frontendApi)}`, - ]); + it('contains the default allowed origin values if no value is provided when production instance', () => { + const frontendApi = 'clerk.example.com'; + const allowedRedirectOriginsValuesUndefined = createAllowedRedirectOrigins(undefined, frontendApi, 'production'); + const allowedRedirectOriginsValuesEmptyArray = createAllowedRedirectOrigins([], frontendApi, 'production'); + + const expectedAllowedRedirectOrigins = [ + 'http://localhost', // Current location + `https://example.com`, // Primary domain + `https://*.example.com`, // Wildcard subdomains + ]; + + expect(allowedRedirectOriginsValuesUndefined).toEqual(expectedAllowedRedirectOrigins); + expect(allowedRedirectOriginsValuesEmptyArray).toEqual(expectedAllowedRedirectOrigins); + }); + + it('contains the default allowed origin values and FAPI if no value is provided when development instance', () => { + const frontendApi = 'foo-bar-42.clerk.accounts.dev'; + const allowedRedirectOriginsValuesUndefined = createAllowedRedirectOrigins(undefined, frontendApi, 'development'); + const allowedRedirectOriginsValuesEmptyArray = createAllowedRedirectOrigins([], frontendApi, 'development'); + + const expectedAllowedRedirectOrigins = [ + 'http://localhost', // Current location + `https://foo-bar-42.accounts.dev`, // Account Portal + `https://*.foo-bar-42.accounts.dev`, // Account Portal subdomains + `https://foo-bar-42.clerk.accounts.dev`, // Frontend API + ]; + + expect(allowedRedirectOriginsValuesUndefined).toEqual(expectedAllowedRedirectOrigins); + expect(allowedRedirectOriginsValuesEmptyArray).toEqual(expectedAllowedRedirectOrigins); }); it('contains only the allowedRedirectOrigins options given', async () => { - const frontendApi = 'https://somename.clerk.accounts.dev'; + const frontendApi = 'somename.clerk.accounts.dev'; const allowedRedirectOriginsValues = createAllowedRedirectOrigins( ['https://test.host', 'https://*.test.host'], frontendApi, diff --git a/packages/clerk-js/src/utils/url.ts b/packages/clerk-js/src/utils/url.ts index a2e5e49ce2c..d5b69503538 100644 --- a/packages/clerk-js/src/utils/url.ts +++ b/packages/clerk-js/src/utils/url.ts @@ -384,6 +384,7 @@ export const isAllowedRedirect = export function createAllowedRedirectOrigins( allowedRedirectOrigins: Array | undefined, frontendApi: string, + instanceType?: string, ): (string | RegExp)[] | undefined { if (Array.isArray(allowedRedirectOrigins) && !!allowedRedirectOrigins.length) { return allowedRedirectOrigins; @@ -397,5 +398,9 @@ export function createAllowedRedirectOrigins( origins.push(`https://${getETLDPlusOneFromFrontendApi(frontendApi)}`); origins.push(`https://*.${getETLDPlusOneFromFrontendApi(frontendApi)}`); + if (instanceType === 'development') { + origins.push(`https://${frontendApi}`); + } + return origins; }