@@ -377,25 +377,39 @@ export class ProfileManager {
377377 }
378378 }
379379
380- private async resolveTokenForUrl ( url : string ) : Promise < string > {
381- // Check if URL matches a cached realm token
380+ private async getRealmTokenForUrl ( url : string ) : Promise < string | undefined > {
382381 let realmToken = this . findRealmTokenForUrl ( url ) ;
383382 if ( realmToken ) {
384383 return realmToken ;
385384 }
386385
387- // Fetch all realm tokens and try again
388- await this . fetchAndStoreAllRealmTokens ( ) ;
389- realmToken = this . findRealmTokenForUrl ( url ) ;
390- if ( realmToken ) {
391- return realmToken ;
386+ try {
387+ await this . fetchAndStoreAllRealmTokens ( ) ;
388+ } catch {
389+ // Token prefetch failed (e.g. expired server token) — caller will handle 401 retry
390+ return undefined ;
392391 }
392+ return this . findRealmTokenForUrl ( url ) ;
393+ }
393394
394- // Fall back to server token for server-level endpoints
395- return this . getOrRefreshServerToken ( ) ;
395+ private buildHeaders (
396+ input : string | URL | Request ,
397+ init : RequestInit | undefined ,
398+ token : string ,
399+ ) : Headers {
400+ let baseHeaders =
401+ input instanceof Request ? new Headers ( input . headers ) : new Headers ( ) ;
402+ let initHeaders = new Headers ( init ?. headers ) ;
403+ for ( let [ key , value ] of initHeaders ) {
404+ baseHeaders . set ( key , value ) ;
405+ }
406+ if ( ! baseHeaders . has ( 'Authorization' ) ) {
407+ baseHeaders . set ( 'Authorization' , token ) ;
408+ }
409+ return baseHeaders ;
396410 }
397411
398- async authedFetch (
412+ async authedRealmFetch (
399413 input : string | URL | Request ,
400414 init ?: RequestInit ,
401415 ) : Promise < Response > {
@@ -405,30 +419,50 @@ export class ProfileManager {
405419 : input instanceof URL
406420 ? input . href
407421 : input ;
408- let token = await this . resolveTokenForUrl ( url ) ;
409- let baseHeaders =
410- input instanceof Request ? new Headers ( input . headers ) : new Headers ( ) ;
411- let initHeaders = new Headers ( init ?. headers ) ;
412- for ( let [ key , value ] of initHeaders ) {
413- baseHeaders . set ( key , value ) ;
422+
423+ let token = await this . getRealmTokenForUrl ( url ) ;
424+ if ( token ) {
425+ let headers = this . buildHeaders ( input , init , token ) ;
426+ let response = await fetch ( input , { ...init , headers } ) ;
427+
428+ if ( response . status !== 401 ) {
429+ return response ;
430+ }
414431 }
415- if ( ! baseHeaders . has ( 'Authorization' ) ) {
416- baseHeaders . set ( 'Authorization' , token ) ;
432+
433+ // Either no cached realm token (e.g. server token was expired during
434+ // prefetch) or the request got a 401. Refresh everything and retry.
435+ let active = this . getActiveProfile ( ) ;
436+ if ( active ) {
437+ active . profile . realmTokens = { } ;
438+ active . profile . realmServerToken = undefined ;
439+ this . saveConfig ( ) ;
440+ }
441+ await this . fetchAndStoreAllRealmTokens ( ) ;
442+ token = this . findRealmTokenForUrl ( url ) ;
443+ if ( ! token ) {
444+ throw new Error (
445+ `No realm token available for ${ url } . The realm may not be accessible.` ,
446+ ) ;
417447 }
448+ let headers = this . buildHeaders ( input , init , token ) ;
449+ let response = await fetch ( input , { ...init , headers } ) ;
418450
419- let response = await fetch ( input , { ...init , headers : baseHeaders } ) ;
451+ return response ;
452+ }
453+
454+ async authedRealmServerFetch (
455+ input : string | URL | Request ,
456+ init ?: RequestInit ,
457+ ) : Promise < Response > {
458+ let token = await this . getOrRefreshServerToken ( ) ;
459+ let headers = this . buildHeaders ( input , init , token ) ;
460+ let response = await fetch ( input , { ...init , headers } ) ;
420461
421462 if ( response . status === 401 ) {
422- // Clear cached tokens and retry
423- let active = this . getActiveProfile ( ) ;
424- if ( active ) {
425- active . profile . realmTokens = { } ;
426- active . profile . realmServerToken = undefined ;
427- this . saveConfig ( ) ;
428- }
429- token = await this . resolveTokenForUrl ( url ) ;
430- baseHeaders . set ( 'Authorization' , token ) ;
431- response = await fetch ( input , { ...init , headers : baseHeaders } ) ;
463+ token = await this . refreshServerToken ( ) ;
464+ headers = this . buildHeaders ( input , init , token ) ;
465+ response = await fetch ( input , { ...init , headers } ) ;
432466 }
433467
434468 return response ;
0 commit comments