This repository was archived by the owner on Nov 20, 2025. It is now read-only.
File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -23,6 +23,7 @@ import * as querystring from 'querystring';
2323import * as stream from 'stream' ;
2424import * as formatEcdsa from 'ecdsa-sig-formatter' ;
2525
26+ import { removeUndefinedValuesInObject } from '../util' ;
2627import { createCrypto , JwkCertificate , hasBrowserCrypto } from '../crypto/crypto' ;
2728
2829import {
@@ -754,7 +755,7 @@ export class OAuth2Client extends AuthClient {
754755 ...OAuth2Client . RETRY_CONFIG ,
755756 method : 'POST' ,
756757 url,
757- data : new URLSearchParams ( values as { } ) ,
758+ data : new URLSearchParams ( removeUndefinedValuesInObject ( values ) as { } ) ,
758759 headers,
759760 } ;
760761 AuthClient . setMethodName ( opts , 'getTokenAsync' ) ;
@@ -820,7 +821,7 @@ export class OAuth2Client extends AuthClient {
820821 ...OAuth2Client . RETRY_CONFIG ,
821822 method : 'POST' ,
822823 url,
823- data : new URLSearchParams ( data ) ,
824+ data : new URLSearchParams ( removeUndefinedValuesInObject ( data ) ) ,
824825 } ;
825826 AuthClient . setMethodName ( opts , 'refreshTokenNoCache' ) ;
826827
Original file line number Diff line number Diff line change @@ -22,6 +22,8 @@ import {
2222 getErrorFromOAuthErrorResponse ,
2323} from './oauth2common' ;
2424
25+ import { removeUndefinedValuesInObject } from '../util' ;
26+
2527/**
2628 * Defines the interface needed to initialize an StsCredentials instance.
2729 * The interface does not directly map to the spec and instead is converted
@@ -203,20 +205,12 @@ export class StsCredentials extends OAuthClientAuthHandler {
203205 options : options && JSON . stringify ( options ) ,
204206 } ;
205207
206- // Keep defined fields.
207- const payload : Record < string , string > = { } ;
208- Object . entries ( values ) . forEach ( ( [ key , value ] ) => {
209- if ( value !== undefined ) {
210- payload [ key ] = value ;
211- }
212- } ) ;
213-
214208 const opts : GaxiosOptions = {
215209 ...StsCredentials . RETRY_CONFIG ,
216210 url : this . #tokenExchangeEndpoint. toString ( ) ,
217211 method : 'POST' ,
218212 headers,
219- data : new URLSearchParams ( payload ) ,
213+ data : new URLSearchParams ( removeUndefinedValuesInObject ( values ) ) ,
220214 } ;
221215 AuthClient . setMethodName ( opts , 'exchangeToken' ) ;
222216
Original file line number Diff line number Diff line change @@ -239,3 +239,15 @@ export class LRUCache<T> {
239239 }
240240 }
241241}
242+
243+ // Given and object remove fields where value is undefined.
244+ export function removeUndefinedValuesInObject ( object : { [ key : string ] : any } ) : {
245+ [ key : string ] : any ;
246+ } {
247+ Object . entries ( object ) . forEach ( ( [ key , value ] ) => {
248+ if ( value === undefined || value === 'undefined' ) {
249+ delete object [ key ] ;
250+ }
251+ } ) ;
252+ return object ;
253+ }
Original file line number Diff line number Diff line change @@ -1370,6 +1370,52 @@ describe('oauth2', () => {
13701370 assert . strictEqual ( params . get ( 'code_verifier' ) , 'its_verified' ) ;
13711371 } ) ;
13721372
1373+ it ( 'getToken should ignore undefined code verifier' , async ( ) => {
1374+ const scope = nock ( baseUrl , {
1375+ reqheaders : {
1376+ 'content-type' : 'application/x-www-form-urlencoded;charset=UTF-8' ,
1377+ } ,
1378+ } )
1379+ . post ( '/token' )
1380+ . reply ( 200 , {
1381+ access_token : 'abc' ,
1382+ refresh_token : '123' ,
1383+ expires_in : 10 ,
1384+ } ) ;
1385+ const res = await client . getToken ( {
1386+ code : 'code here' ,
1387+ codeVerifier : undefined ,
1388+ } ) ;
1389+ scope . done ( ) ;
1390+ assert ( res . res ) ;
1391+
1392+ const params = new URLSearchParams ( res . res . config . data || '' ) ;
1393+ assert . strictEqual ( params . get ( 'code_verifier' ) , null ) ;
1394+ } ) ;
1395+
1396+ it ( 'getToken should ignore undefined string code verifier' , async ( ) => {
1397+ const scope = nock ( baseUrl , {
1398+ reqheaders : {
1399+ 'content-type' : 'application/x-www-form-urlencoded;charset=UTF-8' ,
1400+ } ,
1401+ } )
1402+ . post ( '/token' )
1403+ . reply ( 200 , {
1404+ access_token : 'abc' ,
1405+ refresh_token : '123' ,
1406+ expires_in : 10 ,
1407+ } ) ;
1408+ const res = await client . getToken ( {
1409+ code : 'code here' ,
1410+ codeVerifier : 'undefined' ,
1411+ } ) ;
1412+ scope . done ( ) ;
1413+ assert ( res . res ) ;
1414+
1415+ const params = new URLSearchParams ( res . res . config . data || '' ) ;
1416+ assert . strictEqual ( params . get ( 'code_verifier' ) , null ) ;
1417+ } ) ;
1418+
13731419 it ( 'getToken should set redirect_uri if not provided in options' , async ( ) => {
13741420 const scope = nock ( baseUrl , {
13751421 reqheaders : {
Original file line number Diff line number Diff line change 1515import { strict as assert } from 'assert' ;
1616import * as sinon from 'sinon' ;
1717
18- import { LRUCache } from '../src/util' ;
18+ import { LRUCache , removeUndefinedValuesInObject } from '../src/util' ;
1919
2020describe ( 'util' , ( ) => {
2121 let sandbox : sinon . SinonSandbox ;
@@ -81,3 +81,24 @@ describe('util', () => {
8181 } ) ;
8282 } ) ;
8383} ) ;
84+
85+ describe ( 'util removeUndefinedValuesInObject' , ( ) => {
86+ it ( 'remove undefined type values in object' , ( ) => {
87+ const object : { [ key : string ] : any } = {
88+ undefined : undefined ,
89+ number : 1 ,
90+ } ;
91+ assert . deepEqual ( removeUndefinedValuesInObject ( object ) , {
92+ number : 1 ,
93+ } ) ;
94+ } ) ;
95+ it ( 'remove undefined string values in object' , ( ) => {
96+ const object : { [ key : string ] : any } = {
97+ undefined : 'undefined' ,
98+ number : 1 ,
99+ } ;
100+ assert . deepEqual ( removeUndefinedValuesInObject ( object ) , {
101+ number : 1 ,
102+ } ) ;
103+ } ) ;
104+ } ) ;
You can’t perform that action at this time.
0 commit comments