@@ -1276,6 +1276,27 @@ describe('OAuth Authorization', () => {
12761276 const authMethod = selectClientAuthMethod ( clientInfo , supportedMethods ) ;
12771277 expect ( authMethod ) . toBe ( 'none' ) ;
12781278 } ) ;
1279+ it ( 'defaults to client_secret_basic when server omits token_endpoint_auth_methods_supported (RFC 8414 §2)' , ( ) => {
1280+ // RFC 8414 §2: if omitted, the default is client_secret_basic.
1281+ // RFC 6749 §2.3.1: servers MUST support HTTP Basic for clients with a secret.
1282+ const clientInfo = { client_id : 'test-client-id' , client_secret : 'test-client-secret' } ;
1283+ const authMethod = selectClientAuthMethod ( clientInfo , [ ] ) ;
1284+ expect ( authMethod ) . toBe ( 'client_secret_basic' ) ;
1285+ } ) ;
1286+ it ( 'defaults to none for public clients when server omits token_endpoint_auth_methods_supported' , ( ) => {
1287+ const clientInfo = { client_id : 'test-client-id' } ;
1288+ const authMethod = selectClientAuthMethod ( clientInfo , [ ] ) ;
1289+ expect ( authMethod ) . toBe ( 'none' ) ;
1290+ } ) ;
1291+ it ( 'honors DCR-returned token_endpoint_auth_method even when server metadata omits supported methods' , ( ) => {
1292+ const clientInfo = {
1293+ client_id : 'test-client-id' ,
1294+ client_secret : 'test-client-secret' ,
1295+ token_endpoint_auth_method : 'client_secret_post'
1296+ } ;
1297+ const authMethod = selectClientAuthMethod ( clientInfo , [ ] ) ;
1298+ expect ( authMethod ) . toBe ( 'client_secret_post' ) ;
1299+ } ) ;
12791300 } ) ;
12801301
12811302 describe ( 'startAuthorization' , ( ) => {
@@ -1492,8 +1513,10 @@ describe('OAuth Authorization', () => {
14921513 expect ( body . get ( 'grant_type' ) ) . toBe ( 'authorization_code' ) ;
14931514 expect ( body . get ( 'code' ) ) . toBe ( 'code123' ) ;
14941515 expect ( body . get ( 'code_verifier' ) ) . toBe ( 'verifier123' ) ;
1495- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1496- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1516+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1517+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1518+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1519+ expect ( options . headers . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
14971520 expect ( body . get ( 'redirect_uri' ) ) . toBe ( 'http://localhost:3000/callback' ) ;
14981521 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
14991522 } ) ;
@@ -1531,8 +1554,10 @@ describe('OAuth Authorization', () => {
15311554 expect ( body . get ( 'grant_type' ) ) . toBe ( 'authorization_code' ) ;
15321555 expect ( body . get ( 'code' ) ) . toBe ( 'code123' ) ;
15331556 expect ( body . get ( 'code_verifier' ) ) . toBe ( 'verifier123' ) ;
1534- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1535- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1557+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1558+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1559+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1560+ expect ( options . headers . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
15361561 expect ( body . get ( 'redirect_uri' ) ) . toBe ( 'http://localhost:3000/callback' ) ;
15371562 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
15381563 } ) ;
@@ -1656,8 +1681,10 @@ describe('OAuth Authorization', () => {
16561681 expect ( body . get ( 'grant_type' ) ) . toBe ( 'authorization_code' ) ;
16571682 expect ( body . get ( 'code' ) ) . toBe ( 'code123' ) ;
16581683 expect ( body . get ( 'code_verifier' ) ) . toBe ( 'verifier123' ) ;
1659- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1660- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1684+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1685+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1686+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1687+ expect ( ( options . headers as Headers ) . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
16611688 expect ( body . get ( 'redirect_uri' ) ) . toBe ( 'http://localhost:3000/callback' ) ;
16621689 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
16631690 } ) ;
@@ -1716,8 +1743,10 @@ describe('OAuth Authorization', () => {
17161743 const body = mockFetch . mock . calls [ 0 ] ! [ 1 ] . body as URLSearchParams ;
17171744 expect ( body . get ( 'grant_type' ) ) . toBe ( 'refresh_token' ) ;
17181745 expect ( body . get ( 'refresh_token' ) ) . toBe ( 'refresh123' ) ;
1719- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1720- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1746+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1747+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1748+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1749+ expect ( headers . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
17211750 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
17221751 } ) ;
17231752
@@ -3076,7 +3105,7 @@ describe('OAuth Authorization', () => {
30763105 expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
30773106 } ) ;
30783107
3079- it ( 'defaults to client_secret_post when no auth methods specified' , async ( ) => {
3108+ it ( 'defaults to client_secret_basic when no auth methods specified (RFC 8414 §2) ' , async ( ) => {
30803109 mockFetch . mockResolvedValueOnce ( {
30813110 ok : true ,
30823111 status : 200 ,
@@ -3093,13 +3122,15 @@ describe('OAuth Authorization', () => {
30933122 expect ( tokens ) . toEqual ( validTokens ) ;
30943123 const request = mockFetch . mock . calls [ 0 ] ! [ 1 ] ;
30953124
3096- // Check headers
3097- expect ( request . headers . get ( 'Content-Type' ) ) . toBe ( 'application/x-www-form-urlencoded' ) ;
3098- expect ( request . headers . get ( 'Authorization' ) ) . toBeNull ( ) ;
3125+ // RFC 8414 §2: when token_endpoint_auth_methods_supported is omitted,
3126+ // the default is client_secret_basic (HTTP Basic auth, not body params)
3127+ const authHeader = request . headers . get ( 'Authorization' ) ;
3128+ const expected = 'Basic ' + btoa ( 'client123:secret123' ) ;
3129+ expect ( authHeader ) . toBe ( expected ) ;
30993130
31003131 const body = request . body as URLSearchParams ;
3101- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
3102- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
3132+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
3133+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
31033134 } ) ;
31043135 } ) ;
31053136
0 commit comments