2025-05-09 21:21:28 +00:00
|
|
|
import * as plugins from '../../plugins.js';
|
2025-05-09 22:46:53 +00:00
|
|
|
import type { IDomainConfig, ISmartProxyOptions } from './models/interfaces.js';
|
|
|
|
import type { TForwardingType, IForwardConfig } from '../../forwarding/config/forwarding-types.js';
|
2025-05-09 21:21:28 +00:00
|
|
|
import type { ForwardingHandler } from '../../forwarding/handlers/base-handler.js';
|
|
|
|
import { ForwardingHandlerFactory } from '../../forwarding/factory/forwarding-factory.js';
|
2025-05-10 00:26:03 +00:00
|
|
|
import type { IRouteConfig } from './models/route-types.js';
|
|
|
|
import { RouteManager } from './route-manager.js';
|
2025-03-14 09:53:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Manages domain configurations and target selection
|
|
|
|
*/
|
|
|
|
export class DomainConfigManager {
|
|
|
|
// Track round-robin indices for domain configs
|
2025-05-09 22:46:53 +00:00
|
|
|
private domainTargetIndices: Map<IDomainConfig, number> = new Map();
|
2025-05-09 14:15:45 +00:00
|
|
|
|
|
|
|
// Cache forwarding handlers for each domain config
|
2025-05-09 22:46:53 +00:00
|
|
|
private forwardingHandlers: Map<IDomainConfig, ForwardingHandler> = new Map();
|
2025-05-09 14:15:45 +00:00
|
|
|
|
2025-05-10 00:26:03 +00:00
|
|
|
// Store derived domain configs from routes
|
|
|
|
private derivedDomainConfigs: IDomainConfig[] = [];
|
|
|
|
|
|
|
|
// Reference to RouteManager for route-based configuration
|
|
|
|
private routeManager?: RouteManager;
|
|
|
|
|
|
|
|
constructor(private settings: ISmartProxyOptions) {
|
|
|
|
// Initialize with derived domain configs if using route-based configuration
|
|
|
|
if (settings.routes && !settings.domainConfigs) {
|
|
|
|
this.generateDomainConfigsFromRoutes();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the route manager reference for route-based queries
|
|
|
|
*/
|
|
|
|
public setRouteManager(routeManager: RouteManager): void {
|
|
|
|
this.routeManager = routeManager;
|
|
|
|
|
|
|
|
// Regenerate domain configs from routes if needed
|
|
|
|
if (this.settings.routes && (!this.settings.domainConfigs || this.settings.domainConfigs.length === 0)) {
|
|
|
|
this.generateDomainConfigsFromRoutes();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate domain configs from routes
|
|
|
|
*/
|
|
|
|
public generateDomainConfigsFromRoutes(): void {
|
|
|
|
this.derivedDomainConfigs = [];
|
|
|
|
|
|
|
|
if (!this.settings.routes) return;
|
|
|
|
|
|
|
|
for (const route of this.settings.routes) {
|
|
|
|
if (route.action.type !== 'forward' || !route.match.domains) continue;
|
|
|
|
|
|
|
|
// Convert route to domain config
|
|
|
|
const domainConfig = this.routeToDomainConfig(route);
|
|
|
|
if (domainConfig) {
|
|
|
|
this.derivedDomainConfigs.push(domainConfig);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a route to a domain config
|
|
|
|
*/
|
|
|
|
private routeToDomainConfig(route: IRouteConfig): IDomainConfig | null {
|
|
|
|
if (route.action.type !== 'forward' || !route.action.target) return null;
|
|
|
|
|
|
|
|
// Get domains from route
|
|
|
|
const domains = Array.isArray(route.match.domains) ?
|
|
|
|
route.match.domains :
|
|
|
|
(route.match.domains ? [route.match.domains] : []);
|
|
|
|
|
|
|
|
if (domains.length === 0) return null;
|
|
|
|
|
|
|
|
// Determine forwarding type based on TLS mode
|
|
|
|
let forwardingType: TForwardingType = 'http-only';
|
|
|
|
if (route.action.tls) {
|
|
|
|
switch (route.action.tls.mode) {
|
|
|
|
case 'passthrough':
|
|
|
|
forwardingType = 'https-passthrough';
|
|
|
|
break;
|
|
|
|
case 'terminate':
|
|
|
|
forwardingType = 'https-terminate-to-http';
|
|
|
|
break;
|
|
|
|
case 'terminate-and-reencrypt':
|
|
|
|
forwardingType = 'https-terminate-to-https';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create domain config
|
|
|
|
return {
|
|
|
|
domains,
|
|
|
|
forwarding: {
|
|
|
|
type: forwardingType,
|
|
|
|
target: {
|
|
|
|
host: route.action.target.host,
|
|
|
|
port: route.action.target.port
|
|
|
|
},
|
|
|
|
security: route.action.security ? {
|
|
|
|
allowedIps: route.action.security.allowedIps,
|
|
|
|
blockedIps: route.action.security.blockedIps,
|
|
|
|
maxConnections: route.action.security.maxConnections
|
|
|
|
} : undefined,
|
|
|
|
https: route.action.tls && route.action.tls.certificate !== 'auto' ? {
|
|
|
|
customCert: route.action.tls.certificate
|
|
|
|
} : undefined,
|
|
|
|
advanced: route.action.advanced
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Updates the domain configurations
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public updateDomainConfigs(newDomainConfigs: IDomainConfig[]): void {
|
2025-05-10 00:26:03 +00:00
|
|
|
// If we're using domainConfigs property, update it
|
|
|
|
if (this.settings.domainConfigs) {
|
|
|
|
this.settings.domainConfigs = newDomainConfigs;
|
|
|
|
} else {
|
|
|
|
// Otherwise update our derived configs
|
|
|
|
this.derivedDomainConfigs = newDomainConfigs;
|
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
// Reset target indices for removed configs
|
|
|
|
const currentConfigSet = new Set(newDomainConfigs);
|
|
|
|
for (const [config] of this.domainTargetIndices) {
|
|
|
|
if (!currentConfigSet.has(config)) {
|
|
|
|
this.domainTargetIndices.delete(config);
|
|
|
|
}
|
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
|
|
|
|
// Clear handlers for removed configs and create handlers for new configs
|
2025-05-09 22:46:53 +00:00
|
|
|
const handlersToRemove: IDomainConfig[] = [];
|
2025-05-09 14:15:45 +00:00
|
|
|
for (const [config] of this.forwardingHandlers) {
|
|
|
|
if (!currentConfigSet.has(config)) {
|
|
|
|
handlersToRemove.push(config);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove handlers that are no longer needed
|
|
|
|
for (const config of handlersToRemove) {
|
|
|
|
this.forwardingHandlers.delete(config);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create handlers for new configs
|
|
|
|
for (const config of newDomainConfigs) {
|
|
|
|
if (!this.forwardingHandlers.has(config)) {
|
|
|
|
try {
|
|
|
|
const handler = this.createForwardingHandler(config);
|
|
|
|
this.forwardingHandlers.set(config, handler);
|
|
|
|
} catch (err) {
|
|
|
|
console.log(`Error creating forwarding handler for domain ${config.domains.join(', ')}: ${err}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
2025-05-09 22:46:53 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Get all domain configurations
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getDomainConfigs(): IDomainConfig[] {
|
2025-05-10 00:26:03 +00:00
|
|
|
// Use domainConfigs from settings if available, otherwise use derived configs
|
|
|
|
return this.settings.domainConfigs || this.derivedDomainConfigs;
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
2025-05-09 22:46:53 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Find domain config matching a server name
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public findDomainConfig(serverName: string): IDomainConfig | undefined {
|
2025-03-14 09:53:25 +00:00
|
|
|
if (!serverName) return undefined;
|
2025-05-09 22:46:53 +00:00
|
|
|
|
2025-05-10 00:26:03 +00:00
|
|
|
// Get domain configs from the appropriate source
|
|
|
|
const domainConfigs = this.getDomainConfigs();
|
|
|
|
|
|
|
|
// Check for direct match
|
|
|
|
for (const config of domainConfigs) {
|
|
|
|
if (config.domains.some(d => plugins.minimatch(serverName, d))) {
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No match found
|
|
|
|
return undefined;
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
2025-05-09 22:46:53 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Find domain config for a specific port
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public findDomainConfigForPort(port: number): IDomainConfig | undefined {
|
2025-05-10 00:26:03 +00:00
|
|
|
// Get domain configs from the appropriate source
|
|
|
|
const domainConfigs = this.getDomainConfigs();
|
|
|
|
|
|
|
|
// Check if any domain config has a matching port range
|
|
|
|
for (const domain of domainConfigs) {
|
|
|
|
const portRanges = domain.forwarding?.advanced?.portRanges;
|
|
|
|
if (portRanges && portRanges.length > 0 && this.isPortInRanges(port, portRanges)) {
|
|
|
|
return domain;
|
2025-05-09 15:39:15 +00:00
|
|
|
}
|
2025-05-10 00:26:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we're in route-based mode, also check routes for this port
|
|
|
|
if (this.settings.routes && (!this.settings.domainConfigs || this.settings.domainConfigs.length === 0)) {
|
|
|
|
const routesForPort = this.settings.routes.filter(route => {
|
|
|
|
// Check if this port is in the route's ports
|
|
|
|
if (typeof route.match.ports === 'number') {
|
|
|
|
return route.match.ports === port;
|
|
|
|
} else if (Array.isArray(route.match.ports)) {
|
|
|
|
return route.match.ports.some(p => {
|
|
|
|
if (typeof p === 'number') {
|
|
|
|
return p === port;
|
|
|
|
} else if (p.from && p.to) {
|
|
|
|
return port >= p.from && port <= p.to;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
// If we found any routes for this port, convert the first one to a domain config
|
|
|
|
if (routesForPort.length > 0 && routesForPort[0].action.type === 'forward') {
|
|
|
|
const domainConfig = this.routeToDomainConfig(routesForPort[0]);
|
|
|
|
if (domainConfig) {
|
|
|
|
return domainConfig;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return undefined;
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a port is within any of the given ranges
|
|
|
|
*/
|
|
|
|
public isPortInRanges(port: number, ranges: Array<{ from: number; to: number }>): boolean {
|
|
|
|
return ranges.some((range) => port >= range.from && port <= range.to);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get target IP with round-robin support
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getTargetIP(domainConfig: IDomainConfig): string {
|
2025-05-09 14:15:45 +00:00
|
|
|
const targetHosts = Array.isArray(domainConfig.forwarding.target.host)
|
|
|
|
? domainConfig.forwarding.target.host
|
|
|
|
: [domainConfig.forwarding.target.host];
|
|
|
|
|
|
|
|
if (targetHosts.length > 0) {
|
2025-03-14 09:53:25 +00:00
|
|
|
const currentIndex = this.domainTargetIndices.get(domainConfig) || 0;
|
2025-05-09 14:15:45 +00:00
|
|
|
const ip = targetHosts[currentIndex % targetHosts.length];
|
2025-03-14 09:53:25 +00:00
|
|
|
this.domainTargetIndices.set(domainConfig, currentIndex + 1);
|
|
|
|
return ip;
|
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
return this.settings.targetIP || 'localhost';
|
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
|
2025-05-09 15:39:15 +00:00
|
|
|
/**
|
|
|
|
* Get target host with round-robin support (for tests)
|
|
|
|
* This is just an alias for getTargetIP for easier test compatibility
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getTargetHost(domainConfig: IDomainConfig): string {
|
2025-05-09 15:39:15 +00:00
|
|
|
return this.getTargetIP(domainConfig);
|
|
|
|
}
|
|
|
|
|
2025-05-09 14:15:45 +00:00
|
|
|
/**
|
|
|
|
* Get target port from domain config
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getTargetPort(domainConfig: IDomainConfig, defaultPort: number): number {
|
2025-05-09 14:15:45 +00:00
|
|
|
return domainConfig.forwarding.target.port || defaultPort;
|
|
|
|
}
|
2025-05-09 22:46:53 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Checks if a domain should use NetworkProxy
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public shouldUseNetworkProxy(domainConfig: IDomainConfig): boolean {
|
2025-05-09 14:15:45 +00:00
|
|
|
const forwardingType = this.getForwardingType(domainConfig);
|
2025-05-09 15:39:15 +00:00
|
|
|
return forwardingType === 'https-terminate-to-http' ||
|
|
|
|
forwardingType === 'https-terminate-to-https';
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Gets the NetworkProxy port for a domain
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getNetworkProxyPort(domainConfig: IDomainConfig): number | undefined {
|
2025-05-09 14:15:45 +00:00
|
|
|
// First check if we should use NetworkProxy at all
|
|
|
|
if (!this.shouldUseNetworkProxy(domainConfig)) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
2025-05-09 15:39:15 +00:00
|
|
|
return domainConfig.forwarding.advanced?.networkProxyPort || this.settings.networkProxyPort;
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
2025-05-09 22:46:53 +00:00
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Get effective allowed and blocked IPs for a domain
|
2025-05-09 15:39:15 +00:00
|
|
|
*
|
|
|
|
* This method combines domain-specific security rules from the forwarding configuration
|
|
|
|
* with global security defaults when necessary.
|
2025-03-14 09:53:25 +00:00
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getEffectiveIPRules(domainConfig: IDomainConfig): {
|
2025-03-14 09:53:25 +00:00
|
|
|
allowedIPs: string[],
|
|
|
|
blockedIPs: string[]
|
|
|
|
} {
|
2025-05-09 14:15:45 +00:00
|
|
|
// Start with empty arrays
|
|
|
|
const allowedIPs: string[] = [];
|
|
|
|
const blockedIPs: string[] = [];
|
|
|
|
|
2025-05-09 15:39:15 +00:00
|
|
|
// Add IPs from forwarding security settings if available
|
2025-05-09 14:15:45 +00:00
|
|
|
if (domainConfig.forwarding?.security?.allowedIps) {
|
|
|
|
allowedIPs.push(...domainConfig.forwarding.security.allowedIps);
|
2025-05-09 15:39:15 +00:00
|
|
|
} else {
|
|
|
|
// If no allowed IPs are specified in forwarding config and global defaults exist, use them
|
|
|
|
if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
|
|
|
|
allowedIPs.push(...this.settings.defaultAllowedIPs);
|
|
|
|
} else {
|
|
|
|
// Default to allow all if no specific rules
|
|
|
|
allowedIPs.push('*');
|
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
}
|
|
|
|
|
2025-05-09 15:39:15 +00:00
|
|
|
// Add blocked IPs from forwarding security settings if available
|
2025-05-09 14:15:45 +00:00
|
|
|
if (domainConfig.forwarding?.security?.blockedIps) {
|
|
|
|
blockedIPs.push(...domainConfig.forwarding.security.blockedIps);
|
|
|
|
}
|
|
|
|
|
2025-05-09 15:39:15 +00:00
|
|
|
// Always add global blocked IPs, even if domain has its own rules
|
|
|
|
// This ensures that global blocks take precedence
|
2025-05-09 14:15:45 +00:00
|
|
|
if (this.settings.defaultBlockedIPs && this.settings.defaultBlockedIPs.length > 0) {
|
2025-05-09 15:39:15 +00:00
|
|
|
// Add only unique IPs that aren't already in the list
|
|
|
|
for (const ip of this.settings.defaultBlockedIPs) {
|
|
|
|
if (!blockedIPs.includes(ip)) {
|
|
|
|
blockedIPs.push(ip);
|
|
|
|
}
|
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
}
|
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
return {
|
2025-05-09 14:15:45 +00:00
|
|
|
allowedIPs,
|
|
|
|
blockedIPs
|
2025-03-14 09:53:25 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get connection timeout for a domain
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getConnectionTimeout(domainConfig?: IDomainConfig): number {
|
2025-05-09 15:39:15 +00:00
|
|
|
if (domainConfig?.forwarding.advanced?.timeout) {
|
2025-05-09 14:15:45 +00:00
|
|
|
return domainConfig.forwarding.advanced.timeout;
|
|
|
|
}
|
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
return this.settings.maxConnectionLifetime || 86400000; // 24 hours default
|
|
|
|
}
|
2025-05-09 14:15:45 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a forwarding handler for a domain configuration
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
private createForwardingHandler(domainConfig: IDomainConfig): ForwardingHandler {
|
2025-05-09 14:15:45 +00:00
|
|
|
// Create a new handler using the factory
|
|
|
|
const handler = ForwardingHandlerFactory.createHandler(domainConfig.forwarding);
|
|
|
|
|
|
|
|
// Initialize the handler
|
|
|
|
handler.initialize().catch(err => {
|
|
|
|
console.log(`Error initializing forwarding handler for ${domainConfig.domains.join(', ')}: ${err}`);
|
|
|
|
});
|
|
|
|
|
|
|
|
return handler;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a forwarding handler for a domain config
|
|
|
|
* If no handler exists, creates one
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getForwardingHandler(domainConfig: IDomainConfig): ForwardingHandler {
|
2025-05-09 14:15:45 +00:00
|
|
|
// If we already have a handler, return it
|
|
|
|
if (this.forwardingHandlers.has(domainConfig)) {
|
|
|
|
return this.forwardingHandlers.get(domainConfig)!;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise create a new handler
|
|
|
|
const handler = this.createForwardingHandler(domainConfig);
|
|
|
|
this.forwardingHandlers.set(domainConfig, handler);
|
|
|
|
|
|
|
|
return handler;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the forwarding type for a domain config
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public getForwardingType(domainConfig?: IDomainConfig): TForwardingType | undefined {
|
2025-05-09 14:15:45 +00:00
|
|
|
if (!domainConfig?.forwarding) return undefined;
|
|
|
|
return domainConfig.forwarding.type;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the forwarding type requires TLS termination
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public requiresTlsTermination(domainConfig?: IDomainConfig): boolean {
|
2025-05-09 14:15:45 +00:00
|
|
|
if (!domainConfig) return false;
|
|
|
|
|
|
|
|
const forwardingType = this.getForwardingType(domainConfig);
|
|
|
|
return forwardingType === 'https-terminate-to-http' ||
|
|
|
|
forwardingType === 'https-terminate-to-https';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the forwarding type supports HTTP
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public supportsHttp(domainConfig?: IDomainConfig): boolean {
|
2025-05-09 14:15:45 +00:00
|
|
|
if (!domainConfig) return false;
|
|
|
|
|
|
|
|
const forwardingType = this.getForwardingType(domainConfig);
|
|
|
|
|
|
|
|
// HTTP-only always supports HTTP
|
|
|
|
if (forwardingType === 'http-only') return true;
|
|
|
|
|
|
|
|
// For termination types, check the HTTP settings
|
|
|
|
if (forwardingType === 'https-terminate-to-http' ||
|
|
|
|
forwardingType === 'https-terminate-to-https') {
|
|
|
|
// HTTP is supported by default for termination types
|
|
|
|
return domainConfig.forwarding?.http?.enabled !== false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTPS-passthrough doesn't support HTTP
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if HTTP requests should be redirected to HTTPS
|
|
|
|
*/
|
2025-05-09 22:46:53 +00:00
|
|
|
public shouldRedirectToHttps(domainConfig?: IDomainConfig): boolean {
|
2025-05-09 14:15:45 +00:00
|
|
|
if (!domainConfig?.forwarding) return false;
|
|
|
|
|
|
|
|
// Only check for redirect if HTTP is enabled
|
|
|
|
if (this.supportsHttp(domainConfig)) {
|
|
|
|
return !!domainConfig.forwarding.http?.redirectToHttps;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|