@@ -983,5 +983,66 @@ describe("OAuth Authorization", () => {
983
983
expect ( body . get ( "grant_type" ) ) . toBe ( "refresh_token" ) ;
984
984
expect ( body . get ( "refresh_token" ) ) . toBe ( "refresh123" ) ;
985
985
} ) ;
986
+
987
+ it ( "skips default PRM resource validation when custom validateProtectedResourceMetadata is provided" , async ( ) => {
988
+ const mockValidateProtectedResourceMetadata = jest . fn ( ) . mockResolvedValue ( undefined ) ;
989
+ const providerWithCustomValidation = {
990
+ ...mockProvider ,
991
+ validateProtectedResourceMetadata : mockValidateProtectedResourceMetadata ,
992
+ } ;
993
+
994
+ // Mock protected resource metadata with mismatched resource URL
995
+ // This would normally throw an error in default validation, but should be skipped
996
+ mockFetch . mockImplementation ( ( url ) => {
997
+ const urlString = url . toString ( ) ;
998
+
999
+ if ( urlString . includes ( "/.well-known/oauth-protected-resource" ) ) {
1000
+ return Promise . resolve ( {
1001
+ ok : true ,
1002
+ status : 200 ,
1003
+ json : async ( ) => ( {
1004
+ resource : "https://different-resource.example.com/mcp-server" , // Mismatched resource
1005
+ authorization_servers : [ "https://auth.example.com" ] ,
1006
+ } ) ,
1007
+ } ) ;
1008
+ } else if ( urlString . includes ( "/.well-known/oauth-authorization-server" ) ) {
1009
+ return Promise . resolve ( {
1010
+ ok : true ,
1011
+ status : 200 ,
1012
+ json : async ( ) => ( {
1013
+ issuer : "https://auth.example.com" ,
1014
+ authorization_endpoint : "https://auth.example.com/authorize" ,
1015
+ token_endpoint : "https://auth.example.com/token" ,
1016
+ response_types_supported : [ "code" ] ,
1017
+ code_challenge_methods_supported : [ "S256" ] ,
1018
+ } ) ,
1019
+ } ) ;
1020
+ }
1021
+
1022
+ return Promise . resolve ( { ok : false , status : 404 } ) ;
1023
+ } ) ;
1024
+
1025
+ // Mock provider methods
1026
+ ( providerWithCustomValidation . clientInformation as jest . Mock ) . mockResolvedValue ( {
1027
+ client_id : "test-client" ,
1028
+ client_secret : "test-secret" ,
1029
+ } ) ;
1030
+ ( providerWithCustomValidation . tokens as jest . Mock ) . mockResolvedValue ( undefined ) ;
1031
+ ( providerWithCustomValidation . saveCodeVerifier as jest . Mock ) . mockResolvedValue ( undefined ) ;
1032
+ ( providerWithCustomValidation . redirectToAuthorization as jest . Mock ) . mockResolvedValue ( undefined ) ;
1033
+
1034
+ // Call auth - should succeed despite resource mismatch because custom validation overrides default
1035
+ const result = await auth ( providerWithCustomValidation , {
1036
+ serverUrl : "https://api.example.com/mcp-server" ,
1037
+ } ) ;
1038
+
1039
+ expect ( result ) . toBe ( "REDIRECT" ) ;
1040
+
1041
+ // Verify custom validation method was called
1042
+ expect ( mockValidateProtectedResourceMetadata ) . toHaveBeenCalledWith ( {
1043
+ resource : "https://different-resource.example.com/mcp-server" ,
1044
+ authorization_servers : [ "https://auth.example.com" ] ,
1045
+ } ) ;
1046
+ } ) ;
986
1047
} ) ;
987
1048
} ) ;
0 commit comments