@@ -983,5 +983,66 @@ describe("OAuth Authorization", () => {
983983 expect ( body . get ( "grant_type" ) ) . toBe ( "refresh_token" ) ;
984984 expect ( body . get ( "refresh_token" ) ) . toBe ( "refresh123" ) ;
985985 } ) ;
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+ } ) ;
9861047 } ) ;
9871048} ) ;
0 commit comments