@@ -3,6 +3,7 @@ import { LATEST_PROTOCOL_VERSION } from '../types.js';
33import {
44 OAuthClientMetadata ,
55 OAuthClientInformation ,
6+ OAuthClientInformationMixed ,
67 OAuthTokens ,
78 OAuthMetadata ,
89 OAuthClientInformationFull ,
@@ -56,7 +57,7 @@ export interface OAuthClientProvider {
5657 * server, or returns `undefined` if the client is not registered with the
5758 * server.
5859 */
59- clientInformation ( ) : OAuthClientInformation | undefined | Promise < OAuthClientInformation | undefined > ;
60+ clientInformation ( ) : OAuthClientInformationMixed | undefined | Promise < OAuthClientInformationMixed | undefined > ;
6061
6162 /**
6263 * If implemented, this permits the OAuth client to dynamically register with
@@ -66,7 +67,7 @@ export interface OAuthClientProvider {
6667 * This method is not required to be implemented if client information is
6768 * statically known (e.g., pre-registered).
6869 */
69- saveClientInformation ?( clientInformation : OAuthClientInformationFull ) : void | Promise < void > ;
70+ saveClientInformation ?( clientInformation : OAuthClientInformationMixed ) : void | Promise < void > ;
7071
7172 /**
7273 * Loads any existing OAuth tokens for the current session, or returns
@@ -149,6 +150,10 @@ export class UnauthorizedError extends Error {
149150
150151type ClientAuthMethod = 'client_secret_basic' | 'client_secret_post' | 'none' ;
151152
153+ function isClientAuthMethod ( method : string ) : method is ClientAuthMethod {
154+ return [ 'client_secret_basic' , 'client_secret_post' , 'none' ] . includes ( method ) ;
155+ }
156+
152157const AUTHORIZATION_CODE_RESPONSE_TYPE = 'code' ;
153158const AUTHORIZATION_CODE_CHALLENGE_METHOD = 'S256' ;
154159
@@ -164,14 +169,24 @@ const AUTHORIZATION_CODE_CHALLENGE_METHOD = 'S256';
164169 * @param supportedMethods - Authentication methods supported by the authorization server
165170 * @returns The selected authentication method
166171 */
167- function selectClientAuthMethod ( clientInformation : OAuthClientInformation , supportedMethods : string [ ] ) : ClientAuthMethod {
172+ export function selectClientAuthMethod ( clientInformation : OAuthClientInformationMixed , supportedMethods : string [ ] ) : ClientAuthMethod {
168173 const hasClientSecret = clientInformation . client_secret !== undefined ;
169174
170175 // If server doesn't specify supported methods, use RFC 6749 defaults
171176 if ( supportedMethods . length === 0 ) {
172177 return hasClientSecret ? 'client_secret_post' : 'none' ;
173178 }
174179
180+ // Prefer the method returned by the server during client registration if valid and supported
181+ if (
182+ 'token_endpoint_auth_method' in clientInformation &&
183+ clientInformation . token_endpoint_auth_method &&
184+ isClientAuthMethod ( clientInformation . token_endpoint_auth_method ) &&
185+ supportedMethods . includes ( clientInformation . token_endpoint_auth_method )
186+ ) {
187+ return clientInformation . token_endpoint_auth_method ;
188+ }
189+
175190 // Try methods in priority order (most secure first)
176191 if ( hasClientSecret && supportedMethods . includes ( 'client_secret_basic' ) ) {
177192 return 'client_secret_basic' ;
@@ -793,7 +808,7 @@ export async function startAuthorization(
793808 resource
794809 } : {
795810 metadata ?: AuthorizationServerMetadata ;
796- clientInformation : OAuthClientInformation ;
811+ clientInformation : OAuthClientInformationMixed ;
797812 redirectUrl : string | URL ;
798813 scope ?: string ;
799814 state ?: string ;
@@ -876,7 +891,7 @@ export async function exchangeAuthorization(
876891 fetchFn
877892 } : {
878893 metadata ?: AuthorizationServerMetadata ;
879- clientInformation : OAuthClientInformation ;
894+ clientInformation : OAuthClientInformationMixed ;
880895 authorizationCode : string ;
881896 codeVerifier : string ;
882897 redirectUri : string | URL ;
@@ -955,7 +970,7 @@ export async function refreshAuthorization(
955970 fetchFn
956971 } : {
957972 metadata ?: AuthorizationServerMetadata ;
958- clientInformation : OAuthClientInformation ;
973+ clientInformation : OAuthClientInformationMixed ;
959974 refreshToken : string ;
960975 resource ?: URL ;
961976 addClientAuthentication ?: OAuthClientProvider [ 'addClientAuthentication' ] ;
0 commit comments