@@ -2663,19 +2663,19 @@ describe('Internal Route Trust', () => {
26632663 expect ( global . fetch ) . not . toHaveBeenCalled ( )
26642664 } )
26652665
2666- it ( 'allows the generic HTTP tool to target this Sim instance' , async ( ) => {
2666+ it ( 'allows the generic HTTP tool to target this Sim instance through a loopback alias ' , async ( ) => {
26672667 const result = await executeTool ( 'http_request' , {
2668- url : 'http://localhost :3000/api/v1/workflows/test' ,
2668+ url : 'http://127.0.0.2 :3000/api/v1/workflows/test' ,
26692669 method : 'GET' ,
26702670 } )
26712671
26722672 expect ( result . success ) . toBe ( true )
26732673 expect ( mockValidateUrlWithDNS ) . toHaveBeenCalledWith (
2674- 'http://localhost :3000/api/v1/workflows/test' ,
2674+ 'http://127.0.0.2 :3000/api/v1/workflows/test' ,
26752675 'toolUrl'
26762676 )
26772677 expect ( mockSecureFetchWithPinnedIP ) . toHaveBeenCalledWith (
2678- 'http://localhost :3000/api/v1/workflows/test' ,
2678+ 'http://127.0.0.2 :3000/api/v1/workflows/test' ,
26792679 '93.184.216.34' ,
26802680 expect . objectContaining ( { assertRedirectTarget : undefined } )
26812681 )
@@ -2710,6 +2710,67 @@ describe('Internal Route Trust', () => {
27102710 }
27112711 } )
27122712
2713+ it . each ( [ '127.0.0.1' , '127.0.0.2' , '[::1]' ] ) (
2714+ 'rejects the loopback alias %s for a self-hosted Sim listener' ,
2715+ async ( hostname ) => {
2716+ const mockTool = {
2717+ id : 'test_loopback_alias_integration' ,
2718+ name : 'Loopback Alias Integration' ,
2719+ description : 'Regression fixture' ,
2720+ version : '1.0.0' ,
2721+ params : { } ,
2722+ request : {
2723+ url : ( ) => `http://${ hostname } :3000/api/tools/test` ,
2724+ method : 'GET' as const ,
2725+ headers : ( ) => ( { } ) ,
2726+ } ,
2727+ }
2728+ ; ( tools as Record < string , unknown > ) . test_loopback_alias_integration = mockTool
2729+
2730+ try {
2731+ const result = await executeTool ( 'test_loopback_alias_integration' , { } )
2732+
2733+ expect ( result . success ) . toBe ( false )
2734+ expect ( result . error ) . toContain (
2735+ 'External integration tools cannot target this Sim instance; use an internal operation'
2736+ )
2737+ expect ( mockValidateUrlWithDNS ) . not . toHaveBeenCalled ( )
2738+ expect ( mockSecureFetchWithPinnedIP ) . not . toHaveBeenCalled ( )
2739+ } finally {
2740+ Reflect . deleteProperty ( tools , 'test_loopback_alias_integration' )
2741+ }
2742+ }
2743+ )
2744+
2745+ it ( 'allows a self-hosted provider on a different loopback port' , async ( ) => {
2746+ const mockTool = {
2747+ id : 'test_local_provider' ,
2748+ name : 'Local Provider' ,
2749+ description : 'Regression fixture' ,
2750+ version : '1.0.0' ,
2751+ params : { } ,
2752+ request : {
2753+ url : ( ) => 'http://127.0.0.1:4000/api/provider' ,
2754+ method : 'GET' as const ,
2755+ headers : ( ) => ( { } ) ,
2756+ } ,
2757+ }
2758+ ; ( tools as Record < string , unknown > ) . test_local_provider = mockTool
2759+
2760+ try {
2761+ const result = await executeTool ( 'test_local_provider' , { } )
2762+
2763+ expect ( result . success ) . toBe ( true )
2764+ expect ( mockValidateUrlWithDNS ) . toHaveBeenCalledWith (
2765+ 'http://127.0.0.1:4000/api/provider' ,
2766+ 'toolUrl'
2767+ )
2768+ expect ( mockSecureFetchWithPinnedIP ) . toHaveBeenCalled ( )
2769+ } finally {
2770+ Reflect . deleteProperty ( tools , 'test_local_provider' )
2771+ }
2772+ } )
2773+
27132774 it ( 'rejects an integration redirect that resolves back to this Sim instance' , async ( ) => {
27142775 const mockTool = {
27152776 id : 'test_same_origin_redirect' ,
@@ -2732,7 +2793,7 @@ describe('Internal Route Trust', () => {
27322793 const secureFetchOptions = mockSecureFetchWithPinnedIP . mock . calls . at ( - 1 ) ?. [ 2 ]
27332794 expect ( secureFetchOptions ?. assertRedirectTarget ) . toBeTypeOf ( 'function' )
27342795 expect ( ( ) =>
2735- secureFetchOptions ?. assertRedirectTarget ?.( 'http://localhost :3000/api/tools/test' )
2796+ secureFetchOptions ?. assertRedirectTarget ?.( 'http://127.0.0.2 :3000/api/tools/test' )
27362797 ) . toThrow (
27372798 'External integration tools cannot target this Sim instance; use an internal operation'
27382799 )
0 commit comments