fix
This commit is contained in:
		| @@ -3,6 +3,8 @@ import type { IDomainConfig, ISmartProxyOptions } from './models/interfaces.js'; | ||||
| import type { TForwardingType, IForwardConfig } from '../../forwarding/config/forwarding-types.js'; | ||||
| import type { ForwardingHandler } from '../../forwarding/handlers/base-handler.js'; | ||||
| import { ForwardingHandlerFactory } from '../../forwarding/factory/forwarding-factory.js'; | ||||
| import type { IRouteConfig } from './models/route-types.js'; | ||||
| import { RouteManager } from './route-manager.js'; | ||||
|  | ||||
| /** | ||||
|  * Manages domain configurations and target selection | ||||
| @@ -14,13 +16,112 @@ export class DomainConfigManager { | ||||
|   // Cache forwarding handlers for each domain config | ||||
|   private forwardingHandlers: Map<IDomainConfig, ForwardingHandler> = new Map(); | ||||
|  | ||||
|   constructor(private settings: ISmartProxyOptions) {} | ||||
|    | ||||
|   // 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 | ||||
|       } | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Updates the domain configurations | ||||
|    */ | ||||
|   public updateDomainConfigs(newDomainConfigs: IDomainConfig[]): void { | ||||
|     this.settings.domainConfigs = newDomainConfigs; | ||||
|     // 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; | ||||
|     } | ||||
|  | ||||
|     // Reset target indices for removed configs | ||||
|     const currentConfigSet = new Set(newDomainConfigs); | ||||
| @@ -60,7 +161,8 @@ export class DomainConfigManager { | ||||
|    * Get all domain configurations | ||||
|    */ | ||||
|   public getDomainConfigs(): IDomainConfig[] { | ||||
|     return this.settings.domainConfigs; | ||||
|     // Use domainConfigs from settings if available, otherwise use derived configs | ||||
|     return this.settings.domainConfigs || this.derivedDomainConfigs; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
| @@ -69,23 +171,64 @@ export class DomainConfigManager { | ||||
|   public findDomainConfig(serverName: string): IDomainConfig | undefined { | ||||
|     if (!serverName) return undefined; | ||||
|  | ||||
|     return this.settings.domainConfigs.find((config) => | ||||
|       config.domains.some((d) => plugins.minimatch(serverName, d)) | ||||
|     ); | ||||
|     // 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; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Find domain config for a specific port | ||||
|    */ | ||||
|   public findDomainConfigForPort(port: number): IDomainConfig | undefined { | ||||
|     return this.settings.domainConfigs.find( | ||||
|       (domain) => { | ||||
|         const portRanges = domain.forwarding?.advanced?.portRanges; | ||||
|         return portRanges && | ||||
|                portRanges.length > 0 && | ||||
|                this.isPortInRanges(port, portRanges); | ||||
|     // 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; | ||||
|       } | ||||
|     ); | ||||
|     } | ||||
|  | ||||
|     // 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; | ||||
|   } | ||||
|    | ||||
|   /** | ||||
|   | ||||
| @@ -62,14 +62,15 @@ export interface IDomainConfig { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Helper functions for type checking - now always assume route-based config | ||||
|  * Helper functions for type checking configuration types | ||||
|  */ | ||||
| export function isLegacyOptions(options: any): boolean { | ||||
|   return false; // No longer supporting legacy options | ||||
|   return !!(options.domainConfigs && options.domainConfigs.length > 0 && | ||||
|            (!options.routes || options.routes.length === 0)); | ||||
| } | ||||
|  | ||||
| export function isRoutedOptions(options: any): boolean { | ||||
|   return true; // Always assume routed options | ||||
|   return !!(options.routes && options.routes.length > 0); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -113,12 +113,18 @@ export class SmartProxy extends plugins.EventEmitter { | ||||
|       this.timeoutManager | ||||
|     ); | ||||
|      | ||||
|     // Create domain config manager and port range manager (for backward compatibility) | ||||
|     this.domainConfigManager = new DomainConfigManager(this.settings); | ||||
|     this.portRangeManager = new PortRangeManager(this.settings); | ||||
|      | ||||
|     // Create the new route manager | ||||
|     // Create the new route manager first | ||||
|     this.routeManager = new RouteManager(this.settings); | ||||
|  | ||||
|     // Create domain config manager and port range manager | ||||
|     this.domainConfigManager = new DomainConfigManager(this.settings); | ||||
|  | ||||
|     // Share the route manager with the domain config manager | ||||
|     if (typeof this.domainConfigManager.setRouteManager === 'function') { | ||||
|       this.domainConfigManager.setRouteManager(this.routeManager); | ||||
|     } | ||||
|  | ||||
|     this.portRangeManager = new PortRangeManager(this.settings); | ||||
|      | ||||
|     // Create other required components | ||||
|     this.tlsManager = new TlsManager(this.settings); | ||||
| @@ -178,10 +184,16 @@ export class SmartProxy extends plugins.EventEmitter { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     // If using legacy format, make sure domainConfigs are initialized | ||||
|     // Initialize domain config based on configuration type | ||||
|     if (isLegacyOptions(this.settings)) { | ||||
|       // Initialize domain config manager with the processed configs | ||||
|       this.domainConfigManager.updateDomainConfigs(this.settings.domainConfigs); | ||||
|       // Initialize domain config manager with the legacy domain configs | ||||
|       this.domainConfigManager.updateDomainConfigs(this.settings.domainConfigs || []); | ||||
|     } else if (isRoutedOptions(this.settings)) { | ||||
|       // For pure route-based configuration, the domain config is already initialized | ||||
|       // in the constructor, but we might need to regenerate it | ||||
|       if (typeof this.domainConfigManager.generateDomainConfigsFromRoutes === 'function') { | ||||
|         this.domainConfigManager.generateDomainConfigsFromRoutes(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Initialize Port80Handler if enabled | ||||
|   | ||||
		Reference in New Issue
	
	Block a user