@@ -1045,5 +1045,66 @@ describe("OAuth Authorization", () => {
10451045 "https://different-resource.example.com/mcp-server"
10461046 ) ;
10471047 } ) ;
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+ } ) ;
10481109 } ) ;
10491110} ) ;
0 commit comments