197 lines
6.0 KiB
TypeScript
197 lines
6.0 KiB
TypeScript
import * as path from 'path';
|
|
import { tap, expect } from '@push.rocks/tapbundle';
|
|
|
|
import { SmartProxy } from '../ts/proxies/smart-proxy/index.js';
|
|
import {
|
|
createHttpRoute,
|
|
createHttpsRoute,
|
|
createPassthroughRoute,
|
|
createRedirectRoute,
|
|
createHttpToHttpsRedirect,
|
|
createBlockRoute,
|
|
createLoadBalancerRoute,
|
|
createHttpsServer,
|
|
createPortRange,
|
|
createSecurityConfig,
|
|
createStaticFileRoute,
|
|
createTestRoute
|
|
} from '../ts/proxies/smart-proxy/route-helpers/index.js';
|
|
import type { IRouteConfig } from '../ts/proxies/smart-proxy/models/route-types.js';
|
|
|
|
// Test to demonstrate various route configurations using the new helpers
|
|
tap.test('Route-based configuration examples', async (tools) => {
|
|
// Example 1: HTTP-only configuration
|
|
const httpOnlyRoute = createHttpRoute({
|
|
domains: 'http.example.com',
|
|
target: {
|
|
host: 'localhost',
|
|
port: 3000
|
|
},
|
|
security: {
|
|
allowedIps: ['*'] // Allow all
|
|
},
|
|
name: 'Basic HTTP Route'
|
|
});
|
|
|
|
console.log('HTTP-only route created successfully:', httpOnlyRoute.name);
|
|
expect(httpOnlyRoute.action.type).toEqual('forward');
|
|
expect(httpOnlyRoute.match.domains).toEqual('http.example.com');
|
|
|
|
// Example 2: HTTPS Passthrough (SNI) configuration
|
|
const httpsPassthroughRoute = createPassthroughRoute({
|
|
domains: 'pass.example.com',
|
|
target: {
|
|
host: ['10.0.0.1', '10.0.0.2'], // Round-robin target IPs
|
|
port: 443
|
|
},
|
|
security: {
|
|
allowedIps: ['*'] // Allow all
|
|
},
|
|
name: 'HTTPS Passthrough Route'
|
|
});
|
|
|
|
expect(httpsPassthroughRoute).toBeTruthy();
|
|
expect(httpsPassthroughRoute.action.tls?.mode).toEqual('passthrough');
|
|
expect(Array.isArray(httpsPassthroughRoute.action.target?.host)).toBeTrue();
|
|
|
|
// Example 3: HTTPS Termination to HTTP Backend
|
|
const terminateToHttpRoute = createHttpsRoute({
|
|
domains: 'secure.example.com',
|
|
target: {
|
|
host: 'localhost',
|
|
port: 8080
|
|
},
|
|
tlsMode: 'terminate',
|
|
certificate: 'auto',
|
|
headers: {
|
|
'X-Forwarded-Proto': 'https'
|
|
},
|
|
security: {
|
|
allowedIps: ['*'] // Allow all
|
|
},
|
|
name: 'HTTPS Termination to HTTP Backend'
|
|
});
|
|
|
|
// Create the HTTP to HTTPS redirect for this domain
|
|
const httpToHttpsRedirect = createHttpToHttpsRedirect({
|
|
domains: 'secure.example.com',
|
|
name: 'HTTP to HTTPS Redirect for secure.example.com'
|
|
});
|
|
|
|
expect(terminateToHttpRoute).toBeTruthy();
|
|
expect(terminateToHttpRoute.action.tls?.mode).toEqual('terminate');
|
|
expect(terminateToHttpRoute.action.advanced?.headers?.['X-Forwarded-Proto']).toEqual('https');
|
|
expect(httpToHttpsRedirect.action.type).toEqual('redirect');
|
|
|
|
// Example 4: Load Balancer with HTTPS
|
|
const loadBalancerRoute = createLoadBalancerRoute({
|
|
domains: 'proxy.example.com',
|
|
targets: ['internal-api-1.local', 'internal-api-2.local'],
|
|
targetPort: 8443,
|
|
tlsMode: 'terminate-and-reencrypt',
|
|
certificate: 'auto',
|
|
headers: {
|
|
'X-Original-Host': '{domain}'
|
|
},
|
|
security: {
|
|
allowedIps: ['10.0.0.0/24', '192.168.1.0/24'],
|
|
maxConnections: 1000
|
|
},
|
|
name: 'Load Balanced HTTPS Route'
|
|
});
|
|
|
|
expect(loadBalancerRoute).toBeTruthy();
|
|
expect(loadBalancerRoute.action.tls?.mode).toEqual('terminate-and-reencrypt');
|
|
expect(Array.isArray(loadBalancerRoute.action.target?.host)).toBeTrue();
|
|
expect(loadBalancerRoute.action.security?.allowedIps?.length).toEqual(2);
|
|
|
|
// Example 5: Block specific IPs
|
|
const blockRoute = createBlockRoute({
|
|
ports: [80, 443],
|
|
clientIp: ['192.168.5.0/24'],
|
|
name: 'Block Suspicious IPs',
|
|
priority: 1000 // High priority to ensure it's evaluated first
|
|
});
|
|
|
|
expect(blockRoute.action.type).toEqual('block');
|
|
expect(blockRoute.match.clientIp?.length).toEqual(1);
|
|
expect(blockRoute.priority).toEqual(1000);
|
|
|
|
// Example 6: Complete HTTPS Server with HTTP Redirect
|
|
const httpsServerRoutes = createHttpsServer({
|
|
domains: 'complete.example.com',
|
|
target: {
|
|
host: 'localhost',
|
|
port: 8080
|
|
},
|
|
certificate: 'auto',
|
|
name: 'Complete HTTPS Server'
|
|
});
|
|
|
|
expect(Array.isArray(httpsServerRoutes)).toBeTrue();
|
|
expect(httpsServerRoutes.length).toEqual(2); // HTTPS route and HTTP redirect
|
|
expect(httpsServerRoutes[0].action.tls?.mode).toEqual('terminate');
|
|
expect(httpsServerRoutes[1].action.type).toEqual('redirect');
|
|
|
|
// Example 7: Static File Server
|
|
const staticFileRoute = createStaticFileRoute({
|
|
domains: 'static.example.com',
|
|
targetDirectory: '/var/www/static',
|
|
tlsMode: 'terminate',
|
|
certificate: 'auto',
|
|
headers: {
|
|
'Cache-Control': 'public, max-age=86400'
|
|
},
|
|
name: 'Static File Server'
|
|
});
|
|
|
|
expect(staticFileRoute.action.advanced?.staticFiles?.directory).toEqual('/var/www/static');
|
|
expect(staticFileRoute.action.advanced?.headers?.['Cache-Control']).toEqual('public, max-age=86400');
|
|
|
|
// Example 8: Test Route for Debugging
|
|
const testRoute = createTestRoute({
|
|
ports: 8000,
|
|
domains: 'test.example.com',
|
|
response: {
|
|
status: 200,
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ status: 'ok', message: 'API is working!' })
|
|
}
|
|
});
|
|
|
|
expect(testRoute.match.ports).toEqual(8000);
|
|
expect(testRoute.action.advanced?.testResponse?.status).toEqual(200);
|
|
|
|
// Create a SmartProxy instance with all routes
|
|
const allRoutes: IRouteConfig[] = [
|
|
httpOnlyRoute,
|
|
httpsPassthroughRoute,
|
|
terminateToHttpRoute,
|
|
httpToHttpsRedirect,
|
|
loadBalancerRoute,
|
|
blockRoute,
|
|
...httpsServerRoutes,
|
|
staticFileRoute,
|
|
testRoute
|
|
];
|
|
|
|
// We're not actually starting the SmartProxy in this test,
|
|
// just verifying that the configuration is valid
|
|
const smartProxy = new SmartProxy({
|
|
routes: allRoutes,
|
|
acme: {
|
|
email: 'admin@example.com',
|
|
termsOfServiceAgreed: true,
|
|
directoryUrl: 'https://acme-staging-v02.api.letsencrypt.org/directory'
|
|
}
|
|
});
|
|
|
|
console.log(`Smart Proxy configured with ${allRoutes.length} routes`);
|
|
|
|
// Verify our example proxy was created correctly
|
|
expect(smartProxy).toBeTruthy();
|
|
});
|
|
|
|
export default tap.start(); |