@@ -796,32 +796,6 @@ describe("OAuth Authorization", () => {
796
796
expect ( calls [ 1 ] [ 0 ] . toString ( ) ) . toBe ( "https://auth.example.com/.well-known/oauth-authorization-server" ) ;
797
797
} ) ;
798
798
799
- it ( "throws error when OIDC provider does not support S256 PKCE" , async ( ) => {
800
- // OAuth discovery fails
801
- mockFetch . mockResolvedValueOnce ( {
802
- ok : false ,
803
- status : 404 ,
804
- } ) ;
805
-
806
- // OpenID Connect discovery succeeds but without S256 support
807
- const invalidOpenIdMetadata = {
808
- ...validOpenIdMetadata ,
809
- code_challenge_methods_supported : [ "plain" ] , // Missing S256
810
- } ;
811
-
812
- mockFetch . mockResolvedValueOnce ( {
813
- ok : true ,
814
- status : 200 ,
815
- json : async ( ) => invalidOpenIdMetadata ,
816
- } ) ;
817
-
818
- await expect (
819
- discoverAuthorizationServerMetadata (
820
- "https://auth.example.com"
821
- )
822
- ) . rejects . toThrow ( "does not support S256 code challenge method required by MCP specification" ) ;
823
- } ) ;
824
-
825
799
it ( "continues on 4xx errors" , async ( ) => {
826
800
mockFetch . mockResolvedValueOnce ( {
827
801
ok : false ,
@@ -936,6 +910,17 @@ describe("OAuth Authorization", () => {
936
910
code_challenge_methods_supported : [ "S256" ] ,
937
911
} ;
938
912
913
+ const validOpenIdMetadata = {
914
+ issuer : "https://auth.example.com" ,
915
+ authorization_endpoint : "https://auth.example.com/auth" ,
916
+ token_endpoint : "https://auth.example.com/token" ,
917
+ jwks_uri : "https://auth.example.com/jwks" ,
918
+ subject_types_supported : [ "public" ] ,
919
+ id_token_signing_alg_values_supported : [ "RS256" ] ,
920
+ response_types_supported : [ "code" ] ,
921
+ code_challenge_methods_supported : [ "S256" ] ,
922
+ } ;
923
+
939
924
const validClientInfo = {
940
925
client_id : "client123" ,
941
926
client_secret : "secret123" ,
@@ -1033,11 +1018,11 @@ describe("OAuth Authorization", () => {
1033
1018
expect ( authorizationUrl . searchParams . get ( "prompt" ) ) . toBe ( "consent" ) ;
1034
1019
} ) ;
1035
1020
1036
- it ( "uses metadata authorization_endpoint when provided" , async ( ) => {
1021
+ it . each ( [ validMetadata , validOpenIdMetadata ] ) ( "uses metadata authorization_endpoint when provided" , async ( baseMetadata ) => {
1037
1022
const { authorizationUrl } = await startAuthorization (
1038
1023
"https://auth.example.com" ,
1039
1024
{
1040
- metadata : validMetadata ,
1025
+ metadata : baseMetadata ,
1041
1026
clientInformation : validClientInfo ,
1042
1027
redirectUrl : "http://localhost:3000/callback" ,
1043
1028
}
@@ -1048,9 +1033,9 @@ describe("OAuth Authorization", () => {
1048
1033
) ;
1049
1034
} ) ;
1050
1035
1051
- it ( "validates response type support" , async ( ) => {
1036
+ it . each ( [ validMetadata , validOpenIdMetadata ] ) ( "validates response type support" , async ( baseMetadata ) => {
1052
1037
const metadata = {
1053
- ...validMetadata ,
1038
+ ...baseMetadata ,
1054
1039
response_types_supported : [ "token" ] , // Does not support 'code'
1055
1040
} ;
1056
1041
@@ -1063,9 +1048,28 @@ describe("OAuth Authorization", () => {
1063
1048
) . 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 / ) ;
1064
1049
} ) ;
1065
1050
1066
- it ( "validates PKCE support" , async ( ) => {
1051
+ // https://github.com/modelcontextprotocol/typescript-sdk/issues/832
1052
+ it . each ( [ validMetadata , validOpenIdMetadata ] ) ( "assumes supported code challenge methods includes S256 if absent" , async ( baseMetadata ) => {
1053
+ const metadata = {
1054
+ ...baseMetadata ,
1055
+ response_types_supported : [ "code" ] ,
1056
+ code_challenge_methods_supported : undefined
1057
+ } ;
1058
+
1059
+ const { authorizationUrl } = await startAuthorization ( "https://auth.example.com" , {
1060
+ metadata,
1061
+ clientInformation : validClientInfo ,
1062
+ redirectUrl : "http://localhost:3000/callback" ,
1063
+ } )
1064
+
1065
+ expect ( authorizationUrl . toString ( ) ) . toMatch (
1066
+ / ^ 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 /
1067
+ ) ;
1068
+ } ) ;
1069
+
1070
+ it . each ( [ validMetadata , validOpenIdMetadata ] ) ( "validates supported code challenge methods includes S256 if present" , async ( baseMetadata ) => {
1067
1071
const metadata = {
1068
- ...validMetadata ,
1072
+ ...baseMetadata ,
1069
1073
response_types_supported : [ "code" ] ,
1070
1074
code_challenge_methods_supported : [ "plain" ] , // Does not support 'S256'
1071
1075
} ;
0 commit comments