@@ -144,20 +144,44 @@ export class Credentials {
144144 */
145145 private async refreshAccessToken ( ) {
146146 const clientCredentials = ( this . authConfig as { method : CredentialsMethod . ClientCredentials ; config : ClientCredentialsConfig } ) ?. config ;
147- const url = `https://${ clientCredentials . apiTokenIssuer } /oauth/token` ;
148- const credentialsPayload = await this . buildClientAuthenticationPayload ( ) ;
147+
148+ // Ensure scheme exists; default to https:// if missing
149+ const issuerWithScheme = clientCredentials . apiTokenIssuer . startsWith ( "http://" ) || clientCredentials . apiTokenIssuer . startsWith ( "https://" )
150+ ? clientCredentials . apiTokenIssuer
151+ : `https://${ clientCredentials . apiTokenIssuer } ` ;
152+
153+ // Parse to detect if a path is present
154+ let tokenUrl : string ;
155+ try {
156+ const parsed = new URL ( issuerWithScheme ) ;
157+
158+ // If path is empty or just '/', append default /oauth/token
159+ if ( ! parsed . pathname || parsed . pathname === "/" ) {
160+ tokenUrl = `${ parsed . origin } /oauth/token` ;
161+ } else {
162+ // Use the provided path as-is (preserves /oauth/v2/token etc.)
163+ tokenUrl = parsed . toString ( ) ;
164+ }
165+ } catch ( e ) {
166+ // If for some reason URL parsing fails, fall back to previous behavior
167+ tokenUrl = `https://${ clientCredentials . apiTokenIssuer } /oauth/token` ;
168+ }
169+
170+ const credentialsPayload = await this . buildClientAuthenticationPayload ( ) ;
171+
149172
150173 try {
151- const wrappedResponse = await attemptHttpRequest < ClientSecretRequest | ClientAssertionRequest , {
152- access_token : string ,
153- expires_in : number ,
154- } > ( {
155- url,
174+ const wrappedResponse = await attemptHttpRequest <
175+ ClientSecretRequest | ClientAssertionRequest ,
176+ { access_token : string ; expires_in : number }
177+ > ( {
178+ url : tokenUrl ,
156179 method : "POST" ,
157180 data : credentialsPayload ,
158181 headers : {
159- "Content-Type" : "application/x-www-form-urlencoded"
160- }
182+ "Content-Type" : "application/x-www-form-urlencoded" ,
183+ } ,
184+
161185 } , {
162186 maxRetry : 3 ,
163187 minWaitInMs : 100 ,
@@ -176,7 +200,7 @@ export class Credentials {
176200 attributes = TelemetryAttributes . fromRequest ( {
177201 userAgent : this . baseOptions ?. headers [ "User-Agent" ] ,
178202 fgaMethod : "TokenExchange" ,
179- url,
203+ url : tokenUrl ,
180204 resendCount : wrappedResponse ?. retries ,
181205 httpMethod : "POST" ,
182206 credentials : clientCredentials ,
0 commit comments