feat: use scopes_supported from resource metadata by default (forward-port #757) (#1614)

Co-authored-by: Anthony Giniers <antogyn@gmail.com>
This commit is contained in:
Paul Carleton 2026-03-02 17:13:59 +00:00 • committed by GitHub
commit 1a78b0138f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -503,6 +503,13 @@ async function authInternal(
const resource: URL | undefined = await selectResourceURL(serverUrl, provider, resourceMetadata);
// Apply scope selection strategy (SEP-835):
// 1. WWW-Authenticate scope (passed via `scope` param)
// 2. PRM scopes_supported
// 3. Client metadata scope (user-configured fallback)
// The resolved scope is used consistently for both DCR and the authorization request.
const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(' ') || provider.clientMetadata.scope;
// Handle client registration if needed
let clientInformation = await Promise.resolve(provider.clientInformation());
if (!clientInformation) {
@ -537,6 +544,7 @@ async function authInternal(
const fullInformation = await registerClient(authorizationServerUrl, {
metadata,
clientMetadata: provider.clientMetadata,
scope: resolvedScope,
fetchFn
});
@ -597,7 +605,7 @@ async function authInternal(
clientInformation,
state,
redirectUrl: provider.redirectUrl,
scope: scope || resourceMetadata?.scopes_supported?.join(' ') || provider.clientMetadata.scope,
scope: resolvedScope,
resource
});
@ -1437,16 +1445,22 @@ export async function fetchToken(
/**
* Performs OAuth 2.0 Dynamic Client Registration according to
* {@link https://datatracker.ietf.org/doc/html/rfc7591 | RFC 7591}.
*
* If `scope` is provided, it overrides `clientMetadata.scope` in the registration
* request body. This allows callers to apply the Scope Selection Strategy (SEP-835)
* consistently across both DCR and the subsequent authorization request.
*/
export async function registerClient(
authorizationServerUrl: string | URL,
{
metadata,
clientMetadata,
scope,
fetchFn
}: {
metadata?: AuthorizationServerMetadata;
clientMetadata: OAuthClientMetadata;
scope?: string;
fetchFn?: FetchLike;
}
): Promise<OAuthClientInformationFull> {
@ -1467,7 +1481,10 @@ export async function registerClient(
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(clientMetadata)
body: JSON.stringify({
...clientMetadata,
...(scope === undefined ? {} : { scope })
})
});
if (!response.ok) {