@@ -786,30 +786,6 @@ describe('OAuth Authorization', () => {
786786 expect ( calls [ 1 ] [ 0 ] . toString ( ) ) . toBe ( 'https://auth.example.com/.well-known/oauth-authorization-server' ) ;
787787 } ) ;
788788
789- it ( 'throws error when OIDC provider does not support S256 PKCE' , async ( ) => {
790- // OAuth discovery fails
791- mockFetch . mockResolvedValueOnce ( {
792- ok : false ,
793- status : 404
794- } ) ;
795-
796- // OpenID Connect discovery succeeds but without S256 support
797- const invalidOpenIdMetadata = {
798- ...validOpenIdMetadata ,
799- code_challenge_methods_supported : [ 'plain' ] // Missing S256
800- } ;
801-
802- mockFetch . mockResolvedValueOnce ( {
803- ok : true ,
804- status : 200 ,
805- json : async ( ) => invalidOpenIdMetadata
806- } ) ;
807-
808- await expect ( discoverAuthorizationServerMetadata ( 'https://auth.example.com' ) ) . rejects . toThrow (
809- 'does not support S256 code challenge method required by MCP specification'
810- ) ;
811- } ) ;
812-
813789 it ( 'continues on 4xx errors' , async ( ) => {
814790 mockFetch . mockResolvedValueOnce ( {
815791 ok : false ,
@@ -913,6 +889,17 @@ describe('OAuth Authorization', () => {
913889 code_challenge_methods_supported : [ 'S256' ]
914890 } ;
915891
892+ const validOpenIdMetadata = {
893+ issuer : 'https://auth.example.com' ,
894+ authorization_endpoint : 'https://auth.example.com/auth' ,
895+ token_endpoint : 'https://auth.example.com/token' ,
896+ jwks_uri : 'https://auth.example.com/jwks' ,
897+ subject_types_supported : [ 'public' ] ,
898+ id_token_signing_alg_values_supported : [ 'RS256' ] ,
899+ response_types_supported : [ 'code' ] ,
900+ code_challenge_methods_supported : [ 'S256' ]
901+ } ;
902+
916903 const validClientInfo = {
917904 client_id : 'client123' ,
918905 client_secret : 'secret123' ,
@@ -986,19 +973,19 @@ describe('OAuth Authorization', () => {
986973 expect ( authorizationUrl . searchParams . get ( 'prompt' ) ) . toBe ( 'consent' ) ;
987974 } ) ;
988975
989- it ( 'uses metadata authorization_endpoint when provided' , async ( ) => {
976+ it . each ( [ validMetadata , validOpenIdMetadata ] ) ( 'uses metadata authorization_endpoint when provided' , async baseMetadata => {
990977 const { authorizationUrl } = await startAuthorization ( 'https://auth.example.com' , {
991- metadata : validMetadata ,
978+ metadata : baseMetadata ,
992979 clientInformation : validClientInfo ,
993980 redirectUrl : 'http://localhost:3000/callback'
994981 } ) ;
995982
996983 expect ( authorizationUrl . toString ( ) ) . toMatch ( / ^ h t t p s : \/ \/ a u t h \. e x a m p l e \. c o m \/ a u t h \? / ) ;
997984 } ) ;
998985
999- it ( 'validates response type support' , async ( ) => {
986+ it . each ( [ validMetadata , validOpenIdMetadata ] ) ( 'validates response type support' , async baseMetadata => {
1000987 const metadata = {
1001- ...validMetadata ,
988+ ...baseMetadata ,
1002989 response_types_supported : [ 'token' ] // Does not support 'code'
1003990 } ;
1004991
@@ -1011,21 +998,44 @@ describe('OAuth Authorization', () => {
1011998 ) . rejects . toThrow ( / d o e s n o t s u p p o r t r e s p o n s e t y p e / ) ;
1012999 } ) ;
10131000
1014- it ( 'validates PKCE support' , async ( ) => {
1015- const metadata = {
1016- ...validMetadata ,
1017- response_types_supported : [ 'code' ] ,
1018- code_challenge_methods_supported : [ 'plain' ] // Does not support 'S256'
1019- } ;
1001+ // https://github.com/modelcontextprotocol/typescript-sdk/issues/832
1002+ it . each ( [ validMetadata , validOpenIdMetadata ] ) (
1003+ 'assumes supported code challenge methods includes S256 if absent' ,
1004+ async baseMetadata => {
1005+ const metadata = {
1006+ ...baseMetadata ,
1007+ response_types_supported : [ 'code' ] ,
1008+ code_challenge_methods_supported : undefined
1009+ } ;
10201010
1021- await expect (
1022- startAuthorization ( 'https://auth.example.com' , {
1011+ const { authorizationUrl } = await startAuthorization ( 'https://auth.example.com' , {
10231012 metadata,
10241013 clientInformation : validClientInfo ,
10251014 redirectUrl : 'http://localhost:3000/callback'
1026- } )
1027- ) . rejects . toThrow ( / d o e s n o t s u p p o r t c o d e c h a l l e n g e m e t h o d / ) ;
1028- } ) ;
1015+ } ) ;
1016+
1017+ expect ( authorizationUrl . toString ( ) ) . toMatch ( / ^ h t t p s : \/ \/ a u t h \. e x a m p l e \. c o m \/ a u t h \? .+ & c o d e _ c h a l l e n g e _ m e t h o d = S 2 5 6 / ) ;
1018+ }
1019+ ) ;
1020+
1021+ it . each ( [ validMetadata , validOpenIdMetadata ] ) (
1022+ 'validates supported code challenge methods includes S256 if present' ,
1023+ async baseMetadata => {
1024+ const metadata = {
1025+ ...baseMetadata ,
1026+ response_types_supported : [ 'code' ] ,
1027+ code_challenge_methods_supported : [ 'plain' ] // Does not support 'S256'
1028+ } ;
1029+
1030+ await expect (
1031+ startAuthorization ( 'https://auth.example.com' , {
1032+ metadata,
1033+ clientInformation : validClientInfo ,
1034+ redirectUrl : 'http://localhost:3000/callback'
1035+ } )
1036+ ) . rejects . toThrow ( / d o e s n o t s u p p o r t c o d e c h a l l e n g e m e t h o d / ) ;
1037+ }
1038+ ) ;
10291039 } ) ;
10301040
10311041 describe ( 'exchangeAuthorization' , ( ) => {
0 commit comments