@@ -1045,5 +1045,66 @@ describe("OAuth Authorization", () => {
1045
1045
"https://different-resource.example.com/mcp-server"
1046
1046
) ;
1047
1047
} ) ;
1048
+
1049
+ it ( "uses prefix of server URL from PRM resource as resource parameter" , async ( ) => {
1050
+ // Mock successful metadata discovery with resource URL that is a prefix of requested URL
1051
+ mockFetch . mockImplementation ( ( url ) => {
1052
+ const urlString = url . toString ( ) ;
1053
+
1054
+ if ( urlString . includes ( "/.well-known/oauth-protected-resource" ) ) {
1055
+ return Promise . resolve ( {
1056
+ ok : true ,
1057
+ status : 200 ,
1058
+ json : async ( ) => ( {
1059
+ // Resource is a prefix of the requested server URL
1060
+ resource : "https://api.example.com/" ,
1061
+ authorization_servers : [ "https://auth.example.com" ] ,
1062
+ } ) ,
1063
+ } ) ;
1064
+ } else if ( urlString . includes ( "/.well-known/oauth-authorization-server" ) ) {
1065
+ return Promise . resolve ( {
1066
+ ok : true ,
1067
+ status : 200 ,
1068
+ json : async ( ) => ( {
1069
+ issuer : "https://auth.example.com" ,
1070
+ authorization_endpoint : "https://auth.example.com/authorize" ,
1071
+ token_endpoint : "https://auth.example.com/token" ,
1072
+ response_types_supported : [ "code" ] ,
1073
+ code_challenge_methods_supported : [ "S256" ] ,
1074
+ } ) ,
1075
+ } ) ;
1076
+ }
1077
+
1078
+ return Promise . resolve ( { ok : false , status : 404 } ) ;
1079
+ } ) ;
1080
+
1081
+ // Mock provider methods
1082
+ ( mockProvider . clientInformation as jest . Mock ) . mockResolvedValue ( {
1083
+ client_id : "test-client" ,
1084
+ client_secret : "test-secret" ,
1085
+ } ) ;
1086
+ ( mockProvider . tokens as jest . Mock ) . mockResolvedValue ( undefined ) ;
1087
+ ( mockProvider . saveCodeVerifier as jest . Mock ) . mockResolvedValue ( undefined ) ;
1088
+ ( mockProvider . redirectToAuthorization as jest . Mock ) . mockResolvedValue ( undefined ) ;
1089
+
1090
+ // Call auth with a URL that has the resource as prefix
1091
+ const result = await auth ( mockProvider , {
1092
+ serverUrl : "https://api.example.com/mcp-server/endpoint" ,
1093
+ } ) ;
1094
+
1095
+ expect ( result ) . toBe ( "REDIRECT" ) ;
1096
+
1097
+ // Verify the authorization URL includes the resource parameter from PRM
1098
+ expect ( mockProvider . redirectToAuthorization ) . toHaveBeenCalledWith (
1099
+ expect . objectContaining ( {
1100
+ searchParams : expect . any ( URLSearchParams ) ,
1101
+ } )
1102
+ ) ;
1103
+
1104
+ const redirectCall = ( mockProvider . redirectToAuthorization as jest . Mock ) . mock . calls [ 0 ] ;
1105
+ const authUrl : URL = redirectCall [ 0 ] ;
1106
+ // Should use the PRM's resource value, not the full requested URL
1107
+ expect ( authUrl . searchParams . get ( "resource" ) ) . toBe ( "https://api.example.com/" ) ;
1108
+ } ) ;
1048
1109
} ) ;
1049
1110
} ) ;
0 commit comments