@@ -70,7 +70,6 @@ describe('OidcTokenProvider', () => {
7070 // Override login host to use mock server
7171 provider . _loginHost = `127.0.0.1:${ serverPort } ` ;
7272 // Override _httpPost to use http (not https)
73- const originalPost = provider . _httpPost . bind ( provider ) ;
7473 provider . _httpPost = function ( url , body , headers ) {
7574 // Rewrite https to http for mock
7675 const httpUrl = url . replace ( 'https://' , 'http://' ) ;
@@ -173,12 +172,54 @@ describe('OidcTokenProvider', () => {
173172 provider . shutdown ( ) ;
174173 await new Promise ( resolve => failServer . close ( resolve ) ) ;
175174 } ) ;
175+
176+ it ( 'should schedule refresh at 75% or 5 minutes-before-expiry, whichever is earlier' , async ( ) => {
177+ const provider = new OidcTokenProvider ( {
178+ requestUrl : 'http://localhost/token' ,
179+ requestToken : 'test' ,
180+ tenantId : 'test' ,
181+ clientId : 'test' ,
182+ } ) ;
183+
184+ provider . _mintGitHubOidcToken = jest . fn ( ) . mockResolvedValue ( 'oidc-jwt' ) ;
185+ provider . _exchangeForAzureToken = jest . fn ( ) . mockResolvedValue ( {
186+ access_token : 'azure-token' ,
187+ expires_in : 600 ,
188+ } ) ;
189+ provider . _scheduleRefresh = jest . fn ( ) ;
190+
191+ await provider . _refreshToken ( ) ;
192+
193+ expect ( provider . _scheduleRefresh ) . toHaveBeenCalledWith ( 300000 ) ;
194+ provider . shutdown ( ) ;
195+ } ) ;
196+
197+ it ( 'should schedule immediate refresh when token lifetime is below minimum margin' , async ( ) => {
198+ const provider = new OidcTokenProvider ( {
199+ requestUrl : 'http://localhost/token' ,
200+ requestToken : 'test' ,
201+ tenantId : 'test' ,
202+ clientId : 'test' ,
203+ } ) ;
204+
205+ provider . _mintGitHubOidcToken = jest . fn ( ) . mockResolvedValue ( 'oidc-jwt' ) ;
206+ provider . _exchangeForAzureToken = jest . fn ( ) . mockResolvedValue ( {
207+ access_token : 'azure-token' ,
208+ expires_in : 240 ,
209+ } ) ;
210+ provider . _scheduleRefresh = jest . fn ( ) ;
211+
212+ await provider . _refreshToken ( ) ;
213+
214+ expect ( provider . _scheduleRefresh ) . toHaveBeenCalledWith ( 0 ) ;
215+ provider . shutdown ( ) ;
216+ } ) ;
176217} ) ;
177218
178219describe ( 'OpenAI adapter with OIDC' , ( ) => {
179220 const { createOpenAIAdapter } = require ( './providers/openai' ) ;
180221
181- it ( 'should report enabled when OIDC is configured ' , ( ) => {
222+ it ( 'should report disabled until OIDC token is initialized ' , ( ) => {
182223 const adapter = createOpenAIAdapter ( {
183224 AWF_AUTH_TYPE : 'github-oidc' ,
184225 ACTIONS_ID_TOKEN_REQUEST_URL : 'http://localhost/token' ,
@@ -188,7 +229,7 @@ describe('OpenAI adapter with OIDC', () => {
188229 OPENAI_API_TARGET : 'my-resource.openai.azure.com' ,
189230 } ) ;
190231
191- expect ( adapter . isEnabled ( ) ) . toBe ( true ) ;
232+ expect ( adapter . isEnabled ( ) ) . toBe ( false ) ;
192233 expect ( adapter . getOidcProvider ( ) ) . not . toBeNull ( ) ;
193234 expect ( adapter . getValidationProbe ( ) ) . toEqual ( { skip : true , reason : 'OIDC auth; validation via token acquisition' } ) ;
194235 expect ( adapter . getModelsFetchConfig ( ) ) . toBeNull ( ) ;
@@ -217,7 +258,7 @@ describe('OpenAI adapter with OIDC', () => {
217258 expect ( adapter . getOidcProvider ( ) ) . toBeNull ( ) ;
218259 } ) ;
219260
220- it ( 'should return oidc-token-unavailable when OIDC token not yet acquired' , ( ) => {
261+ it ( 'should return empty auth headers when OIDC token is not yet acquired' , ( ) => {
221262 const adapter = createOpenAIAdapter ( {
222263 AWF_AUTH_TYPE : 'github-oidc' ,
223264 ACTIONS_ID_TOKEN_REQUEST_URL : 'http://localhost/token' ,
@@ -228,7 +269,27 @@ describe('OpenAI adapter with OIDC', () => {
228269
229270 // Before initialization, token should be unavailable
230271 const headers = adapter . getAuthHeaders ( { } ) ;
231- expect ( headers [ 'Authorization' ] ) . toBe ( 'Bearer oidc-token-unavailable' ) ;
272+ expect ( headers ) . toEqual ( { } ) ;
273+
274+ adapter . getOidcProvider ( ) . shutdown ( ) ;
275+ } ) ;
276+
277+ it ( 'should inject only Authorization header in OIDC mode' , ( ) => {
278+ const adapter = createOpenAIAdapter ( {
279+ AWF_AUTH_TYPE : 'github-oidc' ,
280+ ACTIONS_ID_TOKEN_REQUEST_URL : 'http://localhost/token' ,
281+ ACTIONS_ID_TOKEN_REQUEST_TOKEN : 'test-token' ,
282+ AWF_AUTH_AZURE_TENANT_ID : 'test-tenant' ,
283+ AWF_AUTH_AZURE_CLIENT_ID : 'test-client' ,
284+ } ) ;
285+
286+ const provider = adapter . getOidcProvider ( ) ;
287+ provider . _cachedToken = 'azure-ad-token' ;
288+ provider . _expiresAt = Math . floor ( Date . now ( ) / 1000 ) + 600 ;
289+
290+ const headers = adapter . getAuthHeaders ( { } ) ;
291+ expect ( headers ) . toEqual ( { Authorization : 'Bearer azure-ad-token' } ) ;
292+ expect ( headers [ 'api-key' ] ) . toBeUndefined ( ) ;
232293
233294 adapter . getOidcProvider ( ) . shutdown ( ) ;
234295 } ) ;
0 commit comments