110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import { SmartProxy } from '../ts/index.js';
|
|
|
|
/**
|
|
* Simple test to check that ACME challenge routes are created
|
|
*/
|
|
tap.test('should create ACME challenge route', async (tools) => {
|
|
tools.timeout(5000);
|
|
|
|
const mockRouteUpdates: any[] = [];
|
|
|
|
const settings = {
|
|
routes: [
|
|
{
|
|
name: 'secure-route',
|
|
match: {
|
|
ports: [8443],
|
|
domains: 'test.example.com'
|
|
},
|
|
action: {
|
|
type: 'forward' as const,
|
|
target: { host: 'localhost', port: 8080 },
|
|
tls: {
|
|
mode: 'terminate' as const,
|
|
certificate: 'auto' as const,
|
|
acme: {
|
|
email: 'ssl@bleu.de',
|
|
challengePort: 8080 // Use non-privileged port for challenges
|
|
}
|
|
}
|
|
}
|
|
}
|
|
],
|
|
acme: {
|
|
email: 'ssl@bleu.de',
|
|
port: 8080, // Use non-privileged port globally
|
|
useProduction: false
|
|
}
|
|
};
|
|
|
|
const proxy = new SmartProxy(settings);
|
|
|
|
// Mock certificate manager
|
|
let updateRoutesCallback: any;
|
|
|
|
(proxy as any).createCertificateManager = async function(routes: any[], certDir: string, acmeOptions: any) {
|
|
const mockCertManager = {
|
|
setUpdateRoutesCallback: function(callback: any) {
|
|
updateRoutesCallback = callback;
|
|
},
|
|
setHttpProxy: function() {},
|
|
setGlobalAcmeDefaults: function() {},
|
|
setAcmeStateManager: function() {},
|
|
initialize: async function() {
|
|
// Simulate adding ACME challenge route
|
|
if (updateRoutesCallback) {
|
|
const challengeRoute = {
|
|
name: 'acme-challenge',
|
|
priority: 1000,
|
|
match: {
|
|
ports: 8080,
|
|
path: '/.well-known/acme-challenge/*'
|
|
},
|
|
action: {
|
|
type: 'static',
|
|
handler: async (context: any) => {
|
|
const token = context.path?.split('/').pop() || '';
|
|
return {
|
|
status: 200,
|
|
headers: { 'Content-Type': 'text/plain' },
|
|
body: `mock-challenge-response-${token}`
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
const updatedRoutes = [...routes, challengeRoute];
|
|
mockRouteUpdates.push(updatedRoutes);
|
|
await updateRoutesCallback(updatedRoutes);
|
|
}
|
|
},
|
|
getAcmeOptions: () => acmeOptions,
|
|
getState: () => ({ challengeRouteActive: false }),
|
|
stop: async () => {}
|
|
};
|
|
return mockCertManager;
|
|
};
|
|
|
|
// Mock NFTables
|
|
(proxy as any).nftablesManager = {
|
|
ensureNFTablesSetup: async () => {},
|
|
stop: async () => {}
|
|
};
|
|
|
|
await proxy.start();
|
|
|
|
// Verify that routes were updated with challenge route
|
|
expect(mockRouteUpdates.length).toBeGreaterThan(0);
|
|
|
|
const lastUpdate = mockRouteUpdates[mockRouteUpdates.length - 1];
|
|
const challengeRoute = lastUpdate.find((r: any) => r.name === 'acme-challenge');
|
|
|
|
expect(challengeRoute).toBeDefined();
|
|
expect(challengeRoute.match.path).toEqual('/.well-known/acme-challenge/*');
|
|
expect(challengeRoute.match.ports).toEqual(8080);
|
|
|
|
await proxy.stop();
|
|
});
|
|
|
|
tap.start(); |