164 lines
4.4 KiB
TypeScript
164 lines
4.4 KiB
TypeScript
/**
|
|
* HTTPS Route Helper Functions
|
|
*
|
|
* This module provides utility functions for creating HTTPS route configurations
|
|
* including TLS termination and passthrough routes.
|
|
*/
|
|
|
|
import type { IRouteConfig, IRouteMatch, IRouteAction } from '../../models/route-types.js';
|
|
import { SocketHandlers } from './socket-handlers.js';
|
|
|
|
/**
|
|
* Create an HTTPS route with TLS termination
|
|
* @param domains Domain(s) to match
|
|
* @param target Target host and port
|
|
* @param options Additional route options
|
|
* @returns Route configuration object
|
|
*/
|
|
export function createHttpsTerminateRoute(
|
|
domains: string | string[],
|
|
target: { host: string | string[]; port: number },
|
|
options: {
|
|
certificate?: 'auto' | { key: string; cert: string };
|
|
httpPort?: number | number[];
|
|
httpsPort?: number | number[];
|
|
reencrypt?: boolean;
|
|
name?: string;
|
|
[key: string]: any;
|
|
} = {}
|
|
): IRouteConfig {
|
|
// Create route match
|
|
const match: IRouteMatch = {
|
|
ports: options.httpsPort || 443,
|
|
domains
|
|
};
|
|
|
|
// Create route action
|
|
const action: IRouteAction = {
|
|
type: 'forward',
|
|
targets: [target],
|
|
tls: {
|
|
mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
|
|
certificate: options.certificate || 'auto'
|
|
}
|
|
};
|
|
|
|
// Create the route config
|
|
return {
|
|
match,
|
|
action,
|
|
name: options.name || `HTTPS Route for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
|
|
...options
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create an HTTP to HTTPS redirect route
|
|
* @param domains Domain(s) to match
|
|
* @param httpsPort HTTPS port to redirect to (default: 443)
|
|
* @param options Additional route options
|
|
* @returns Route configuration object
|
|
*/
|
|
export function createHttpToHttpsRedirect(
|
|
domains: string | string[],
|
|
httpsPort: number = 443,
|
|
options: Partial<IRouteConfig> = {}
|
|
): IRouteConfig {
|
|
// Create route match
|
|
const match: IRouteMatch = {
|
|
ports: options.match?.ports || 80,
|
|
domains
|
|
};
|
|
|
|
// Create route action
|
|
const action: IRouteAction = {
|
|
type: 'socket-handler',
|
|
socketHandler: SocketHandlers.httpRedirect(`https://{domain}:${httpsPort}{path}`, 301)
|
|
};
|
|
|
|
// Create the route config
|
|
return {
|
|
match,
|
|
action,
|
|
name: options.name || `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
|
|
...options
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create an HTTPS passthrough route (SNI-based forwarding without TLS termination)
|
|
* @param domains Domain(s) to match
|
|
* @param target Target host and port
|
|
* @param options Additional route options
|
|
* @returns Route configuration object
|
|
*/
|
|
export function createHttpsPassthroughRoute(
|
|
domains: string | string[],
|
|
target: { host: string | string[]; port: number },
|
|
options: Partial<IRouteConfig> = {}
|
|
): IRouteConfig {
|
|
// Create route match
|
|
const match: IRouteMatch = {
|
|
ports: options.match?.ports || 443,
|
|
domains
|
|
};
|
|
|
|
// Create route action
|
|
const action: IRouteAction = {
|
|
type: 'forward',
|
|
targets: [target],
|
|
tls: {
|
|
mode: 'passthrough'
|
|
}
|
|
};
|
|
|
|
// Create the route config
|
|
return {
|
|
match,
|
|
action,
|
|
name: options.name || `HTTPS Passthrough for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
|
|
...options
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create a complete HTTPS server with HTTP to HTTPS redirects
|
|
* @param domains Domain(s) to match
|
|
* @param target Target host and port
|
|
* @param options Additional configuration options
|
|
* @returns Array of two route configurations (HTTPS and HTTP redirect)
|
|
*/
|
|
export function createCompleteHttpsServer(
|
|
domains: string | string[],
|
|
target: { host: string | string[]; port: number },
|
|
options: {
|
|
certificate?: 'auto' | { key: string; cert: string };
|
|
httpPort?: number | number[];
|
|
httpsPort?: number | number[];
|
|
reencrypt?: boolean;
|
|
name?: string;
|
|
[key: string]: any;
|
|
} = {}
|
|
): IRouteConfig[] {
|
|
// Create the HTTPS route
|
|
const httpsRoute = createHttpsTerminateRoute(domains, target, options);
|
|
|
|
// Create the HTTP redirect route
|
|
const httpRedirectRoute = createHttpToHttpsRedirect(
|
|
domains,
|
|
// Extract the HTTPS port from the HTTPS route - ensure it's a number
|
|
typeof options.httpsPort === 'number' ? options.httpsPort :
|
|
Array.isArray(options.httpsPort) ? options.httpsPort[0] : 443,
|
|
{
|
|
// Set the HTTP port
|
|
match: {
|
|
ports: options.httpPort || 80,
|
|
domains
|
|
},
|
|
name: `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`
|
|
}
|
|
);
|
|
|
|
return [httpsRoute, httpRedirectRoute];
|
|
}
|