(
provider: OAuthClientProvider,
{
serverUrl,
authorizationCode,
scope,
resourceMetadataUrl,
fetchFn
}: {
serverUrl: string | URL;
authorizationCode?: string;
scope?: string;
resourceMetadataUrl?: URL;
fetchFn?: FetchLike;
}
)
| 426 | } |
| 427 | |
| 428 | async function authInternal( |
| 429 | provider: OAuthClientProvider, |
| 430 | { |
| 431 | serverUrl, |
| 432 | authorizationCode, |
| 433 | scope, |
| 434 | resourceMetadataUrl, |
| 435 | fetchFn |
| 436 | }: { |
| 437 | serverUrl: string | URL; |
| 438 | authorizationCode?: string; |
| 439 | scope?: string; |
| 440 | resourceMetadataUrl?: URL; |
| 441 | fetchFn?: FetchLike; |
| 442 | } |
| 443 | ): Promise<AuthResult> { |
| 444 | // Check if the provider has cached discovery state to skip discovery |
| 445 | const cachedState = await provider.discoveryState?.(); |
| 446 | |
| 447 | let resourceMetadata: OAuthProtectedResourceMetadata | undefined; |
| 448 | let authorizationServerUrl: string | URL; |
| 449 | let metadata: AuthorizationServerMetadata | undefined; |
| 450 | |
| 451 | // If resourceMetadataUrl is not provided, try to load it from cached state |
| 452 | // This handles browser redirects where the URL was saved before navigation |
| 453 | let effectiveResourceMetadataUrl = resourceMetadataUrl; |
| 454 | if (!effectiveResourceMetadataUrl && cachedState?.resourceMetadataUrl) { |
| 455 | effectiveResourceMetadataUrl = new URL(cachedState.resourceMetadataUrl); |
| 456 | } |
| 457 | |
| 458 | if (cachedState?.authorizationServerUrl) { |
| 459 | // Restore discovery state from cache |
| 460 | authorizationServerUrl = cachedState.authorizationServerUrl; |
| 461 | resourceMetadata = cachedState.resourceMetadata; |
| 462 | metadata = |
| 463 | cachedState.authorizationServerMetadata ?? (await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn })); |
| 464 | |
| 465 | // If resource metadata wasn't cached, try to fetch it for selectResourceURL |
| 466 | if (!resourceMetadata) { |
| 467 | try { |
| 468 | resourceMetadata = await discoverOAuthProtectedResourceMetadata( |
| 469 | serverUrl, |
| 470 | { resourceMetadataUrl: effectiveResourceMetadataUrl }, |
| 471 | fetchFn |
| 472 | ); |
| 473 | } catch { |
| 474 | // RFC 9728 not available — selectResourceURL will handle undefined |
| 475 | } |
| 476 | } |
| 477 | |
| 478 | // Re-save if we enriched the cached state with missing metadata |
| 479 | if (metadata !== cachedState.authorizationServerMetadata || resourceMetadata !== cachedState.resourceMetadata) { |
| 480 | await provider.saveDiscoveryState?.({ |
| 481 | authorizationServerUrl: String(authorizationServerUrl), |
| 482 | resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(), |
| 483 | resourceMetadata, |
| 484 | authorizationServerMetadata: metadata |
| 485 | }); |
no test coverage detected
searching dependent graphs…