diff --git a/packages/core/src/auth/utils.test.ts b/packages/core/src/auth/utils.test.ts index e4fc39176..a5332cd4a 100644 --- a/packages/core/src/auth/utils.test.ts +++ b/packages/core/src/auth/utils.test.ts @@ -4,6 +4,7 @@ import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest' import {AUTH_CODE_PARAM, DEFAULT_BASE} from './authConstants' import { getAuthCode, + getCleanedUrl, getDefaultLocation, getDefaultStorage, getStorageEvents, @@ -230,3 +231,36 @@ describe('getTokenFromLocation', () => { expect(result).toBe(testToken) }) }) + +describe('getCleanedUrl', () => { + it('removes only token from hash when it is the only param', () => { + const url = 'http://example.com/page#token=abc' + const cleaned = getCleanedUrl(url) + expect(cleaned).toBe('http://example.com/page') + }) + + it('removes only token from hash and preserves other hash params', () => { + const url = 'http://example.com/page#token=abc&foo=bar' + const cleaned = getCleanedUrl(url) + expect(cleaned).toBe('http://example.com/page#foo=bar') + }) + + it('removes token when it appears among multiple hash params', () => { + const url = 'http://example.com/page#foo=bar&token=abc&baz=qux' + const cleaned = getCleanedUrl(url) + expect(cleaned).toBe('http://example.com/page#foo=bar&baz=qux') + }) + + it('removes sid and url from query string while preserving others', () => { + const url = + 'http://example.com/callback?sid=s1&url=https%3A%2F%2Freturn.example%2Fdone&x=1#token=abc' + const cleaned = getCleanedUrl(url) + expect(cleaned).toBe('http://example.com/callback?x=1') + }) + + it('preserves non key-value hash fragments', () => { + const url = 'http://example.com/page#section' + const cleaned = getCleanedUrl(url) + expect(cleaned).toBe('http://example.com/page#section') + }) +}) diff --git a/packages/core/src/auth/utils.ts b/packages/core/src/auth/utils.ts index 809c4aaf6..c04e62103 100644 --- a/packages/core/src/auth/utils.ts +++ b/packages/core/src/auth/utils.ts @@ -116,12 +116,20 @@ export function getDefaultLocation(): string { } /** - * Cleans up the URL by removing the hash and the sid and url parameters. + * Cleans up the URL by removing the `token` from the hash and the `sid` and `url` search params. * @internal */ export function getCleanedUrl(locationUrl: string): string { const loc = new URL(locationUrl) - loc.hash = '' + // Remove only the `token` param from the hash while preserving other fragments + const rawHash = loc.hash.startsWith('#') ? loc.hash.slice(1) : loc.hash + if (rawHash && rawHash.includes('=')) { + const hashParams = new URLSearchParams(rawHash) + hashParams.delete('token') + hashParams.delete('withSid') + const nextHash = hashParams.toString() + loc.hash = nextHash ? `#${nextHash}` : '' + } loc.searchParams.delete('sid') loc.searchParams.delete('url') return loc.toString()