@@ -4837,6 +4837,106 @@ paths:
48374837 } ) ;
48384838 } ) ;
48394839
4840+ // -------------------------------------------------------------------------
4841+ describe ( 'getEffectiveUpstreamAuth' , ( ) => {
4842+ it ( 'skips oauth and returns bearer when interceptors.auth = [oauth, bearer]' , async ( ) => {
4843+ const provider = { ...upstreamProvider } ; // no provider.auth
4844+ ( upstreamServer as any ) . profile . interceptors = {
4845+ auth : [
4846+ { type : 'oauth' } ,
4847+ { type : 'bearer' , value_from_env : 'BEARER_TOKEN' } ,
4848+ ] ,
4849+ } ;
4850+ ( upstreamServer as any ) . httpTransport = {
4851+ ...( upstreamServer as any ) . httpTransport ,
4852+ getUpstreamMcpConfig : ( ) => provider ,
4853+ getSessionToken : ( ) => 'client-token' ,
4854+ } ;
4855+ try {
4856+ await ( upstreamServer as any ) . handleOtherRequest (
4857+ { jsonrpc : '2.0' , id : '1' , method : 'tools/list' , params : { } } ,
4858+ 'session-123' ,
4859+ 'upstream-profile' ,
4860+ ) ;
4861+ // effectiveAuth should be bearer; effectiveProvider passed to client should have auth.type === 'bearer'
4862+ expect ( mockGetUpstreamClient ) . toHaveBeenCalledWith (
4863+ 'session-123' ,
4864+ expect . objectContaining ( { auth : expect . objectContaining ( { type : 'bearer' } ) } ) ,
4865+ 'client-token' ,
4866+ ) ;
4867+ } finally {
4868+ delete ( upstreamServer as any ) . profile . interceptors ;
4869+ }
4870+ } ) ;
4871+
4872+ it ( 'returns undefined when interceptors.auth = [session-cookie] only' , ( ) => {
4873+ const server = new MCPServer ( ) ;
4874+ ( server as any ) . profile = {
4875+ profile_name : 'p' ,
4876+ tools : [ ] ,
4877+ interceptors : { auth : [ { type : 'session-cookie' } ] } ,
4878+ } ;
4879+ const result = ( server as any ) . getEffectiveUpstreamAuth ( { name : 'x' , transport : { type : 'http-streamable' , url : 'https://example.com' } } ) ;
4880+ expect ( result ) . toBeUndefined ( ) ;
4881+ } ) ;
4882+
4883+ it ( 'priority sort: lower priority value wins — query(priority:1) before bearer(priority:5)' , ( ) => {
4884+ const server = new MCPServer ( ) ;
4885+ ( server as any ) . profile = {
4886+ profile_name : 'p' ,
4887+ tools : [ ] ,
4888+ interceptors : {
4889+ auth : [
4890+ { type : 'bearer' , value_from_env : 'T' , priority : 5 } ,
4891+ { type : 'query' , value_from_env : 'T' , query_param : 'token' , priority : 1 } ,
4892+ ] ,
4893+ } ,
4894+ } ;
4895+ const result = ( server as any ) . getEffectiveUpstreamAuth ( { name : 'x' , transport : { type : 'http-streamable' , url : 'https://example.com' } } ) ;
4896+ expect ( result ?. type ) . toBe ( 'query' ) ;
4897+ } ) ;
4898+
4899+ it ( 'uses provider.auth directly and ignores interceptors.auth when provider.auth set' , ( ) => {
4900+ const server = new MCPServer ( ) ;
4901+ ( server as any ) . profile = {
4902+ profile_name : 'p' ,
4903+ tools : [ ] ,
4904+ interceptors : { auth : [ { type : 'bearer' , value_from_env : 'INTERCEPTOR_TOKEN' } ] } ,
4905+ } ;
4906+ const providerAuth = { type : 'bearer' as const , value_from_env : 'PROVIDER_TOKEN' } ;
4907+ const result = ( server as any ) . getEffectiveUpstreamAuth ( {
4908+ name : 'x' ,
4909+ transport : { type : 'http-streamable' , url : 'https://example.com' } ,
4910+ auth : providerAuth ,
4911+ } ) ;
4912+ expect ( result ) . toBe ( providerAuth ) ;
4913+ } ) ;
4914+
4915+ it ( 'blocks anonymous HTTP session when interceptors.auth contains only oauth (gate bypass fix)' , async ( ) => {
4916+ const provider = { ...upstreamProvider } ; // no provider.auth
4917+ ( upstreamServer as any ) . profile . interceptors = {
4918+ auth : [ { type : 'oauth' } ] ,
4919+ } ;
4920+ ( upstreamServer as any ) . httpTransport = {
4921+ ...( upstreamServer as any ) . httpTransport ,
4922+ getUpstreamMcpConfig : ( ) => provider ,
4923+ getSessionToken : ( ) => undefined , // anonymous HTTP session
4924+ } ;
4925+ try {
4926+ const response = await ( upstreamServer as any ) . handleOtherRequest (
4927+ { jsonrpc : '2.0' , id : '1' , method : 'tools/list' , params : { } } ,
4928+ 'session-123' ,
4929+ 'upstream-profile' ,
4930+ ) as any ;
4931+ expect ( mockGetUpstreamClient ) . not . toHaveBeenCalled ( ) ;
4932+ expect ( response . error ) . toBeDefined ( ) ;
4933+ expect ( response . error . code ) . toBe ( - 32603 ) ;
4934+ } finally {
4935+ delete ( upstreamServer as any ) . profile . interceptors ;
4936+ }
4937+ } ) ;
4938+ } ) ;
4939+
48404940 // -------------------------------------------------------------------------
48414941 describe ( 'tool_prefix warning' , ( ) => {
48424942 it ( 'emits a warning when tool_prefix is configured' , async ( ) => {
0 commit comments