@@ -1297,6 +1297,27 @@ describe('OAuth Authorization', () => {
12971297 const authMethod = selectClientAuthMethod ( clientInfo , supportedMethods ) ;
12981298 expect ( authMethod ) . toBe ( 'none' ) ;
12991299 } ) ;
1300+ it ( 'defaults to client_secret_basic when server omits token_endpoint_auth_methods_supported (RFC 8414 §2)' , ( ) => {
1301+ // RFC 8414 §2: if omitted, the default is client_secret_basic.
1302+ // RFC 6749 §2.3.1: servers MUST support HTTP Basic for clients with a secret.
1303+ const clientInfo = { client_id : 'test-client-id' , client_secret : 'test-client-secret' } ;
1304+ const authMethod = selectClientAuthMethod ( clientInfo , [ ] ) ;
1305+ expect ( authMethod ) . toBe ( 'client_secret_basic' ) ;
1306+ } ) ;
1307+ it ( 'defaults to none for public clients when server omits token_endpoint_auth_methods_supported' , ( ) => {
1308+ const clientInfo = { client_id : 'test-client-id' } ;
1309+ const authMethod = selectClientAuthMethod ( clientInfo , [ ] ) ;
1310+ expect ( authMethod ) . toBe ( 'none' ) ;
1311+ } ) ;
1312+ it ( 'honors DCR-returned token_endpoint_auth_method even when server metadata omits supported methods' , ( ) => {
1313+ const clientInfo = {
1314+ client_id : 'test-client-id' ,
1315+ client_secret : 'test-client-secret' ,
1316+ token_endpoint_auth_method : 'client_secret_post'
1317+ } ;
1318+ const authMethod = selectClientAuthMethod ( clientInfo , [ ] ) ;
1319+ expect ( authMethod ) . toBe ( 'client_secret_post' ) ;
1320+ } ) ;
13001321 } ) ;
13011322
13021323 describe ( 'startAuthorization' , ( ) => {
@@ -1513,8 +1534,10 @@ describe('OAuth Authorization', () => {
15131534 expect ( body . get ( 'grant_type' ) ) . toBe ( 'authorization_code' ) ;
15141535 expect ( body . get ( 'code' ) ) . toBe ( 'code123' ) ;
15151536 expect ( body . get ( 'code_verifier' ) ) . toBe ( 'verifier123' ) ;
1516- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1517- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1537+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1538+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1539+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1540+ expect ( options . headers . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
15181541 expect ( body . get ( 'redirect_uri' ) ) . toBe ( 'http://localhost:3000/callback' ) ;
15191542 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
15201543 } ) ;
@@ -1552,8 +1575,10 @@ describe('OAuth Authorization', () => {
15521575 expect ( body . get ( 'grant_type' ) ) . toBe ( 'authorization_code' ) ;
15531576 expect ( body . get ( 'code' ) ) . toBe ( 'code123' ) ;
15541577 expect ( body . get ( 'code_verifier' ) ) . toBe ( 'verifier123' ) ;
1555- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1556- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1578+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1579+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1580+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1581+ expect ( options . headers . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
15571582 expect ( body . get ( 'redirect_uri' ) ) . toBe ( 'http://localhost:3000/callback' ) ;
15581583 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
15591584 } ) ;
@@ -1675,8 +1700,10 @@ describe('OAuth Authorization', () => {
16751700 expect ( body . get ( 'grant_type' ) ) . toBe ( 'authorization_code' ) ;
16761701 expect ( body . get ( 'code' ) ) . toBe ( 'code123' ) ;
16771702 expect ( body . get ( 'code_verifier' ) ) . toBe ( 'verifier123' ) ;
1678- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1679- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1703+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1704+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1705+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1706+ expect ( ( options . headers as Headers ) . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
16801707 expect ( body . get ( 'redirect_uri' ) ) . toBe ( 'http://localhost:3000/callback' ) ;
16811708 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
16821709 } ) ;
@@ -1735,8 +1762,10 @@ describe('OAuth Authorization', () => {
17351762 const body = mockFetch . mock . calls [ 0 ] [ 1 ] . body as URLSearchParams ;
17361763 expect ( body . get ( 'grant_type' ) ) . toBe ( 'refresh_token' ) ;
17371764 expect ( body . get ( 'refresh_token' ) ) . toBe ( 'refresh123' ) ;
1738- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
1739- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
1765+ // Default auth method is client_secret_basic when no metadata provided (RFC 8414 §2)
1766+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
1767+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
1768+ expect ( headers . get ( 'Authorization' ) ) . toBe ( 'Basic ' + btoa ( 'client123:secret123' ) ) ;
17401769 expect ( body . get ( 'resource' ) ) . toBe ( 'https://api.example.com/mcp-server' ) ;
17411770 } ) ;
17421771
@@ -3133,7 +3162,7 @@ describe('OAuth Authorization', () => {
31333162 expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
31343163 } ) ;
31353164
3136- it ( 'defaults to client_secret_post when no auth methods specified' , async ( ) => {
3165+ it ( 'defaults to client_secret_basic when no auth methods specified (RFC 8414 §2) ' , async ( ) => {
31373166 mockFetch . mockResolvedValueOnce ( {
31383167 ok : true ,
31393168 status : 200 ,
@@ -3150,13 +3179,15 @@ describe('OAuth Authorization', () => {
31503179 expect ( tokens ) . toEqual ( validTokens ) ;
31513180 const request = mockFetch . mock . calls [ 0 ] [ 1 ] ;
31523181
3153- // Check headers
3154- expect ( request . headers . get ( 'Content-Type' ) ) . toBe ( 'application/x-www-form-urlencoded' ) ;
3155- expect ( request . headers . get ( 'Authorization' ) ) . toBeNull ( ) ;
3182+ // RFC 8414 §2: when token_endpoint_auth_methods_supported is omitted,
3183+ // the default is client_secret_basic (HTTP Basic auth, not body params)
3184+ const authHeader = request . headers . get ( 'Authorization' ) ;
3185+ const expected = 'Basic ' + btoa ( 'client123:secret123' ) ;
3186+ expect ( authHeader ) . toBe ( expected ) ;
31563187
31573188 const body = request . body as URLSearchParams ;
3158- expect ( body . get ( 'client_id' ) ) . toBe ( 'client123' ) ;
3159- expect ( body . get ( 'client_secret' ) ) . toBe ( 'secret123' ) ;
3189+ expect ( body . get ( 'client_id' ) ) . toBeNull ( ) ;
3190+ expect ( body . get ( 'client_secret' ) ) . toBeNull ( ) ;
31603191 } ) ;
31613192 } ) ;
31623193
0 commit comments