@@ -184,50 +184,6 @@ export interface OAuthClientProvider {
184184 */
185185 prepareTokenRequest ?( scope ?: string ) : URLSearchParams | Promise < URLSearchParams | undefined > | undefined ;
186186
187- /**
188- * Saves the authorization server URL after RFC 9728 discovery.
189- * This method is called by {@linkcode auth} after successful discovery of the
190- * authorization server via protected resource metadata.
191- *
192- * Providers implementing Cross-App Access or other flows that need access to
193- * the discovered authorization server URL should implement this method.
194- *
195- * @param authorizationServerUrl - The authorization server URL discovered via RFC 9728
196- */
197- saveAuthorizationServerUrl ?( authorizationServerUrl : string ) : void | Promise < void > ;
198-
199- /**
200- * Returns the previously saved authorization server URL, if available.
201- *
202- * Providers implementing Cross-App Access can use this to access the
203- * authorization server URL discovered during the OAuth flow.
204- *
205- * @returns The authorization server URL, or `undefined` if not available
206- */
207- authorizationServerUrl ?( ) : string | undefined | Promise < string | undefined > ;
208-
209- /**
210- * Saves the resource URL after RFC 9728 discovery.
211- * This method is called by {@linkcode auth} after successful discovery of the
212- * resource metadata.
213- *
214- * Providers implementing Cross-App Access or other flows that need access to
215- * the discovered resource URL should implement this method.
216- *
217- * @param resourceUrl - The resource URL discovered via RFC 9728
218- */
219- saveResourceUrl ?( resourceUrl : string ) : void | Promise < void > ;
220-
221- /**
222- * Returns the previously saved resource URL, if available.
223- *
224- * Providers implementing Cross-App Access can use this to access the
225- * resource URL discovered during the OAuth flow.
226- *
227- * @returns The resource URL, or `undefined` if not available
228- */
229- resourceUrl ?( ) : string | undefined | Promise < string | undefined > ;
230-
231187 /**
232188 * Saves the OAuth discovery state after RFC 9728 and authorization server metadata
233189 * discovery. Providers can persist this state to avoid redundant discovery requests
@@ -267,6 +223,9 @@ export interface OAuthClientProvider {
267223export interface OAuthDiscoveryState extends OAuthServerInfo {
268224 /** The URL at which the protected resource metadata was found, if available. */
269225 resourceMetadataUrl ?: string ;
226+
227+ /** The resolved resource URL from {@linkcode selectResourceURL}, if available. */
228+ resourceUrl ?: string ;
270229}
271230
272231export type AuthResult = 'AUTHORIZED' | 'REDIRECT' ;
@@ -489,6 +448,7 @@ async function authInternal(
489448 let resourceMetadata : OAuthProtectedResourceMetadata | undefined ;
490449 let authorizationServerUrl : string | URL ;
491450 let metadata : AuthorizationServerMetadata | undefined ;
451+ let needsDiscoveryStateSave = false ;
492452
493453 // If resourceMetadataUrl is not provided, try to load it from cached state
494454 // This handles browser redirects where the URL was saved before navigation
@@ -518,43 +478,31 @@ async function authInternal(
518478 }
519479
520480 // Re-save if we enriched the cached state with missing metadata
521- if ( metadata !== cachedState . authorizationServerMetadata || resourceMetadata !== cachedState . resourceMetadata ) {
522- await provider . saveDiscoveryState ?.( {
523- authorizationServerUrl : String ( authorizationServerUrl ) ,
524- resourceMetadataUrl : effectiveResourceMetadataUrl ?. toString ( ) ,
525- resourceMetadata,
526- authorizationServerMetadata : metadata
527- } ) ;
528- }
481+ needsDiscoveryStateSave = metadata !== cachedState . authorizationServerMetadata || resourceMetadata !== cachedState . resourceMetadata ;
529482 } else {
530483 // Full discovery via RFC 9728
531484 const serverInfo = await discoverOAuthServerInfo ( serverUrl , { resourceMetadataUrl : effectiveResourceMetadataUrl , fetchFn } ) ;
532485 authorizationServerUrl = serverInfo . authorizationServerUrl ;
533486 metadata = serverInfo . authorizationServerMetadata ;
534487 resourceMetadata = serverInfo . resourceMetadata ;
488+ needsDiscoveryStateSave = true ;
489+ }
535490
536- // Persist discovery state for future use
491+ const resource : URL | undefined = await selectResourceURL ( serverUrl , provider , resourceMetadata ) ;
492+
493+ if ( needsDiscoveryStateSave ) {
537494 // TODO: resourceMetadataUrl is only populated when explicitly provided via options
538495 // or loaded from cached state. The URL derived internally by
539496 // discoverOAuthProtectedResourceMetadata() is not captured back here.
540497 await provider . saveDiscoveryState ?.( {
541498 authorizationServerUrl : String ( authorizationServerUrl ) ,
542499 resourceMetadataUrl : effectiveResourceMetadataUrl ?. toString ( ) ,
543500 resourceMetadata,
544- authorizationServerMetadata : metadata
501+ authorizationServerMetadata : metadata ,
502+ resourceUrl : resource ?. toString ( )
545503 } ) ;
546504 }
547505
548- // Save authorization server URL for providers that need it (e.g., CrossAppAccessProvider)
549- await provider . saveAuthorizationServerUrl ?.( String ( authorizationServerUrl ) ) ;
550-
551- const resource : URL | undefined = await selectResourceURL ( serverUrl , provider , resourceMetadata ) ;
552-
553- // Save resource URL for providers that need it (e.g., CrossAppAccessProvider)
554- if ( resource ) {
555- await provider . saveResourceUrl ?.( String ( resource ) ) ;
556- }
557-
558506 // Apply scope selection strategy (SEP-835):
559507 // 1. WWW-Authenticate scope (passed via `scope` param)
560508 // 2. PRM scopes_supported
0 commit comments