Skip to content

Commit

Permalink
Use URLSearchParams when parsing callback querystring (#1061)
Browse files Browse the repository at this point in the history
* Use URLSearchParams when parsing callback querystring

* Add additional tests
  • Loading branch information
frederikprijck authored Dec 22, 2022
1 parent 19ddff4 commit ab09110
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 31 deletions.
2 changes: 1 addition & 1 deletion __tests__/Auth0Client/getTokenSilently.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1685,7 +1685,7 @@ describe('Auth0Client', () => {
redirect_uri: TEST_REDIRECT_URI,
client_id: TEST_CLIENT_ID,
grant_type: 'authorization_code',
custom_param: 'hello+world',
custom_param: 'hello world',
another_custom_param: 'bar',
code_verifier: TEST_CODE_VERIFIER
},
Expand Down
7 changes: 6 additions & 1 deletion __tests__/Auth0Client/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ export const assertPostFn = (mockFetch: jest.Mock) => {
expect(url).toEqual(actualUrl);

expect(body).toEqual(
json ? JSON.parse(call.body) : utils.parseQueryResult(call.body)
json
? JSON.parse(call.body)
: Array.from(new URLSearchParams(call.body).entries()).reduce(
(acc, curr) => ({ ...acc, [curr[0]]: curr[1] }),
{}
)
);

if (headers) {
Expand Down
2 changes: 1 addition & 1 deletion __tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const setup = async (
utils.sha256.mockReturnValue(Promise.resolve(TEST_ARRAY_BUFFER));
utils.bufferToBase64UrlEncoded.mockReturnValue(TEST_BASE64_ENCODED_STRING);

utils.parseQueryResult.mockReturnValue({
utils.parseAuthenticationResult.mockReturnValue({
state: TEST_ENCODED_STATE,
code: TEST_CODE
});
Expand Down
37 changes: 25 additions & 12 deletions __tests__/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
parseQueryResult,
parseAuthenticationResult,
createQueryParams,
bufferToBase64UrlEncoded,
createRandomString,
Expand All @@ -23,29 +23,42 @@ afterEach(() => {
});

describe('utils', () => {
describe('parseQueryResult', () => {
describe('parseAuthenticationResult', () => {
it('parses the query string', () => {
expect(
parseQueryResult('value=test&otherValue=another-test')
parseAuthenticationResult('code=test&state=another-test')
).toMatchObject({
value: 'test',
otherValue: 'another-test'
code: 'test',
state: 'another-test'
});
});

it('parses the query string when containing raw =', () => {
expect(
parseAuthenticationResult('code=test&state=another-test==')
).toMatchObject({
code: 'test',
state: 'another-test=='
});
});

it('parses the query string when containing url encoded =', () => {
expect(
parseAuthenticationResult('code=test&state=another-test%3D%3D')
).toMatchObject({
code: 'test',
state: 'another-test=='
});
});

it('strips off hash values', () => {
expect(
parseQueryResult('code=some-code&state=some-state#__')
parseAuthenticationResult('code=some-code&state=some-state#__')
).toMatchObject({
code: 'some-code',
state: 'some-state'
});
});
it('converts `expires_in` to int', () => {
expect(parseQueryResult('value=test&expires_in=10')).toMatchObject({
value: 'test',
expires_in: 10
});
});
});
describe('createQueryParams', () => {
it('creates query string from object', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/Auth0Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Lock from 'browser-tabs-lock';
import {
createQueryParams,
runPopup,
parseQueryResult,
parseAuthenticationResult,
encode,
createRandomString,
runIframe,
Expand Down Expand Up @@ -486,7 +486,7 @@ export class Auth0Client {
throw new Error('There are no query params available for parsing.');
}

const { state, code, error, error_description } = parseQueryResult(
const { state, code, error, error_description } = parseAuthenticationResult(
queryStringFragments.join('')
);

Expand Down
25 changes: 11 additions & 14 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,21 @@ import {
PopupCancelledError
} from './errors';

export const parseQueryResult = (queryString: string): AuthenticationResult => {
export const parseAuthenticationResult = (
queryString: string
): AuthenticationResult => {
if (queryString.indexOf('#') > -1) {
queryString = queryString.substr(0, queryString.indexOf('#'));
queryString = queryString.substring(0, queryString.indexOf('#'));
}

const queryParams = queryString.split('&');
const parsedQuery: Record<string, any> = {};
const searchParams = new URLSearchParams(queryString);

queryParams.forEach(qp => {
const [key, val] = qp.split('=');
parsedQuery[key] = decodeURIComponent(val);
});

if (parsedQuery.expires_in) {
parsedQuery.expires_in = parseInt(parsedQuery.expires_in);
}

return parsedQuery as AuthenticationResult;
return {
state: searchParams.get('state')!,
code: searchParams.get('code') || undefined,
error: searchParams.get('error') || undefined,
error_description: searchParams.get('error_description') || undefined
};
};

export const runIframe = (
Expand Down

0 comments on commit ab09110

Please sign in to comment.