diff --git a/lib/oidc/endpoints/token.ts b/lib/oidc/endpoints/token.ts index 76e0f25d8..8a257a5cc 100644 --- a/lib/oidc/endpoints/token.ts +++ b/lib/oidc/endpoints/token.ts @@ -131,24 +131,23 @@ export async function postRefreshToken( options: TokenEndpointParams, refreshToken: RefreshToken ): Promise { - let requestParams = { + const data = Object.entries({ client_id: options.clientId, // eslint-disable-line camelcase grant_type: 'refresh_token', // eslint-disable-line camelcase scope: refreshToken.scopes.join(' '), refresh_token: refreshToken.refreshToken, // eslint-disable-line camelcase - }; - - if (options.extraParams) { - requestParams = { ...options.extraParams, ...requestParams }; - } - - const data = Object.entries(requestParams).map(function ([name, value]) { + }).map(function ([name, value]) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return name + '=' + encodeURIComponent(value!); }).join('&'); + let url = refreshToken.tokenUrl; + if (options.extraParams && Object.keys(options.extraParams).length >= 1) { + url += toQueryString(options.extraParams); + } + const params: TokenRequestParams = { - url: refreshToken.tokenUrl, + url, data, dpopKeyPair: options?.dpopKeyPair }; diff --git a/test/spec/oidc/endpoints/token.ts b/test/spec/oidc/endpoints/token.ts index 1651c6c11..507b30501 100644 --- a/test/spec/oidc/endpoints/token.ts +++ b/test/spec/oidc/endpoints/token.ts @@ -57,7 +57,6 @@ describe('token endpoint', function() { client_id: CLIENT_ID, grant_type: 'authorization_code', redirect_uri: REDIRECT_URI, - extraParams: extraParams }, headers: { 'Accept': 'application/json', @@ -82,8 +81,7 @@ describe('token endpoint', function() { clientId: CLIENT_ID, redirectUri: REDIRECT_URI, authorizationCode: authorizationCode, - codeVerifier: codeVerifier, - extraParams: extraParams + codeVerifier: codeVerifier }, { tokenUrl: ISSUER + endpoint }); @@ -159,6 +157,37 @@ describe('token endpoint', function() { }); + describe('postRefreshToken', () => { + var authClient; + var oauthOptions; + + beforeEach(function() { + spyOn(OktaAuth.features, 'isPKCESupported').and.returnValue(true); + authClient = new OktaAuth({ + issuer: 'https://auth-js-test.okta.com' + }); + + oauthOptions = { + clientId: CLIENT_ID, + redirectUri: REDIRECT_URI, + authorizationCode: authorizationCode, + codeVerifier: codeVerifier, + }; + }); + + it('should append extra params as query params', async () => { + var httpRequest = jest.spyOn(mocked.http, 'httpRequest').mockImplementation(); + const refreshToken = tokens.standardRefreshTokenParsed; + await postRefreshToken(authClient, { extraParams }, refreshToken); + expect(httpRequest).toHaveBeenCalled(); + expect(httpRequest).toHaveBeenLastCalledWith(expect.any(OktaAuth), expect.objectContaining({ + url: 'https://auth-js-test.okta.com/oauth2/v1/token?foo=bar', + method: 'POST', + headers: {'Content-Type': 'application/x-www-form-urlencoded' } + })); + }); + }); + describe('dpop', () => { const ctx: any = {};