diff --git a/packages/core/auth-js/src/GoTrueClient.ts b/packages/core/auth-js/src/GoTrueClient.ts index 10c738438..a7f20cd5c 100644 --- a/packages/core/auth-js/src/GoTrueClient.ts +++ b/packages/core/auth-js/src/GoTrueClient.ts @@ -168,6 +168,7 @@ const DEFAULT_OPTIONS: Omit< autoRefreshToken: true, persistSession: true, detectSessionInUrl: true, + suppressedPaths: [], headers: DEFAULT_HEADERS, flowType: 'implicit', debug: false, @@ -255,6 +256,7 @@ export default class GoTrueClient { */ protected initializePromise: Promise | null = null protected detectSessionInUrl = true + protected suppressedPaths: string[] = [] protected url: string protected headers: { [key: string]: string @@ -322,6 +324,7 @@ export default class GoTrueClient { this.fetch = resolveFetch(settings.fetch) this.lock = settings.lock || lockNoOp this.detectSessionInUrl = settings.detectSessionInUrl + this.suppressedPaths = settings.suppressedPaths this.flowType = settings.flowType this.hasCustomAuthorizationHeader = settings.hasCustomAuthorizationHeader this.throwOnError = settings.throwOnError @@ -2097,6 +2100,12 @@ export default class GoTrueClient { * Checks if the current URL contains parameters given by an implicit oauth grant flow (https://www.rfc-editor.org/rfc/rfc6749.html#section-4.2) */ private _isImplicitGrantCallback(params: { [parameter: string]: string }): boolean { + if (isBrowser() && this.suppressedPaths.length > 0) { + const currentPath = window.location.pathname + if (this.suppressedPaths.includes(currentPath)) { + return false + } + } return Boolean(params.access_token || params.error_description) } diff --git a/packages/core/auth-js/src/lib/types.ts b/packages/core/auth-js/src/lib/types.ts index 2840d9e7f..7b96076a5 100644 --- a/packages/core/auth-js/src/lib/types.ts +++ b/packages/core/auth-js/src/lib/types.ts @@ -76,6 +76,8 @@ export type GoTrueClientOptions = { storageKey?: string /* Set to "true" if you want to automatically detects OAuth grants in the URL and signs in the user. */ detectSessionInUrl?: boolean + /* Array of URL paths where session detection should be suppressed. Useful when using non-Supabase OAuth flows that return tokens in the URL. */ + suppressedPaths?: string[] /* Set to "true" if you want to automatically refresh the token before expiring. */ autoRefreshToken?: boolean /* Set to "true" if you want to automatically save the user session into local storage. If set to false, session will just be saved in memory. */ diff --git a/packages/core/auth-js/test/GoTrueClient.test.ts b/packages/core/auth-js/test/GoTrueClient.test.ts index 0312b906a..d65b6ceed 100644 --- a/packages/core/auth-js/test/GoTrueClient.test.ts +++ b/packages/core/auth-js/test/GoTrueClient.test.ts @@ -3033,6 +3033,24 @@ describe('Storage adapter edge cases', () => { expect(client._isImplicitGrantCallback({})).toBe(false) }) + test('should accept suppressedPaths configuration option', () => { + const client = new GoTrueClient({ + url: GOTRUE_URL_SIGNUP_ENABLED_AUTO_CONFIRM_ON, + suppressedPaths: ['/facebook/redirect', '/custom/oauth'], + }) + // Verify the client accepts the suppressedPaths option without error + // @ts-expect-error accessing private property + expect(client.suppressedPaths).toEqual(['/facebook/redirect', '/custom/oauth']) + }) + + test('should default suppressedPaths to empty array', () => { + const client = new GoTrueClient({ + url: GOTRUE_URL_SIGNUP_ENABLED_AUTO_CONFIRM_ON, + }) + // @ts-expect-error accessing private property + expect(client.suppressedPaths).toEqual([]) + }) + test('should return false for _isPKCECallback with missing params', async () => { const client = getClientWithSpecificStorage(memoryLocalStorageAdapter()) // @ts-expect-error private method diff --git a/packages/core/supabase-js/src/SupabaseClient.ts b/packages/core/supabase-js/src/SupabaseClient.ts index 6defb4eb2..8f263bbe1 100644 --- a/packages/core/supabase-js/src/SupabaseClient.ts +++ b/packages/core/supabase-js/src/SupabaseClient.ts @@ -348,6 +348,7 @@ export default class SupabaseClient< autoRefreshToken, persistSession, detectSessionInUrl, + suppressedPaths, storage, userStorage, storageKey, @@ -370,6 +371,7 @@ export default class SupabaseClient< autoRefreshToken, persistSession, detectSessionInUrl, + suppressedPaths, storage, userStorage, flowType, diff --git a/packages/core/supabase-js/src/lib/types.ts b/packages/core/supabase-js/src/lib/types.ts index fde2a486b..468c8a0d3 100644 --- a/packages/core/supabase-js/src/lib/types.ts +++ b/packages/core/supabase-js/src/lib/types.ts @@ -50,6 +50,11 @@ export type SupabaseClientOptions = { * Detect a session from the URL. Used for OAuth login callbacks. Defaults to true. */ detectSessionInUrl?: boolean + /** + * Array of URL paths where session detection should be suppressed. + * Useful when using non-Supabase OAuth flows that return tokens in the URL. + */ + suppressedPaths?: SupabaseAuthClientOptions['suppressedPaths'] /** * A storage provider. Used to store the logged-in session. */