@push.rocks/smartproxy 15.0.2 → 16.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/certificate/index.d.ts +10 -4
- package/dist_ts/certificate/index.js +5 -7
- package/dist_ts/certificate/models/certificate-types.d.ts +35 -15
- package/dist_ts/certificate/providers/cert-provisioner.d.ts +41 -15
- package/dist_ts/certificate/providers/cert-provisioner.js +201 -41
- package/dist_ts/core/models/index.d.ts +2 -0
- package/dist_ts/core/models/index.js +3 -1
- package/dist_ts/core/models/route-context.d.ts +62 -0
- package/dist_ts/core/models/route-context.js +43 -0
- package/dist_ts/core/models/socket-augmentation.d.ts +12 -0
- package/dist_ts/core/models/socket-augmentation.js +18 -0
- package/dist_ts/core/utils/event-system.d.ts +200 -0
- package/dist_ts/core/utils/event-system.js +224 -0
- package/dist_ts/core/utils/index.d.ts +7 -0
- package/dist_ts/core/utils/index.js +8 -1
- package/dist_ts/core/utils/route-manager.d.ts +118 -0
- package/dist_ts/core/utils/route-manager.js +383 -0
- package/dist_ts/core/utils/route-utils.d.ts +94 -0
- package/dist_ts/core/utils/route-utils.js +264 -0
- package/dist_ts/core/utils/security-utils.d.ts +111 -0
- package/dist_ts/core/utils/security-utils.js +212 -0
- package/dist_ts/core/utils/shared-security-manager.d.ts +110 -0
- package/dist_ts/core/utils/shared-security-manager.js +252 -0
- package/dist_ts/core/utils/template-utils.d.ts +37 -0
- package/dist_ts/core/utils/template-utils.js +104 -0
- package/dist_ts/core/utils/websocket-utils.d.ts +23 -0
- package/dist_ts/core/utils/websocket-utils.js +86 -0
- package/dist_ts/forwarding/config/forwarding-types.d.ts +40 -76
- package/dist_ts/forwarding/config/forwarding-types.js +19 -18
- package/dist_ts/forwarding/config/index.d.ts +4 -2
- package/dist_ts/forwarding/config/index.js +5 -3
- package/dist_ts/forwarding/handlers/base-handler.js +3 -1
- package/dist_ts/forwarding/index.d.ts +5 -6
- package/dist_ts/forwarding/index.js +3 -3
- package/dist_ts/http/models/http-types.js +1 -1
- package/dist_ts/http/port80/acme-interfaces.d.ts +30 -0
- package/dist_ts/http/port80/acme-interfaces.js +46 -1
- package/dist_ts/http/port80/port80-handler.d.ts +17 -2
- package/dist_ts/http/port80/port80-handler.js +49 -11
- package/dist_ts/http/router/index.d.ts +5 -1
- package/dist_ts/http/router/index.js +4 -2
- package/dist_ts/http/router/route-router.d.ts +108 -0
- package/dist_ts/http/router/route-router.js +393 -0
- package/dist_ts/index.d.ts +8 -2
- package/dist_ts/index.js +10 -3
- package/dist_ts/proxies/index.d.ts +7 -2
- package/dist_ts/proxies/index.js +10 -4
- package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +21 -0
- package/dist_ts/proxies/network-proxy/certificate-manager.js +92 -1
- package/dist_ts/proxies/network-proxy/context-creator.d.ts +34 -0
- package/dist_ts/proxies/network-proxy/context-creator.js +108 -0
- package/dist_ts/proxies/network-proxy/function-cache.d.ts +90 -0
- package/dist_ts/proxies/network-proxy/function-cache.js +198 -0
- package/dist_ts/proxies/network-proxy/http-request-handler.d.ts +40 -0
- package/dist_ts/proxies/network-proxy/http-request-handler.js +256 -0
- package/dist_ts/proxies/network-proxy/http2-request-handler.d.ts +24 -0
- package/dist_ts/proxies/network-proxy/http2-request-handler.js +201 -0
- package/dist_ts/proxies/network-proxy/models/types.d.ts +73 -1
- package/dist_ts/proxies/network-proxy/models/types.js +242 -1
- package/dist_ts/proxies/network-proxy/network-proxy.d.ts +23 -20
- package/dist_ts/proxies/network-proxy/network-proxy.js +147 -60
- package/dist_ts/proxies/network-proxy/request-handler.d.ts +38 -5
- package/dist_ts/proxies/network-proxy/request-handler.js +584 -198
- package/dist_ts/proxies/network-proxy/security-manager.d.ts +65 -0
- package/dist_ts/proxies/network-proxy/security-manager.js +255 -0
- package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +13 -2
- package/dist_ts/proxies/network-proxy/websocket-handler.js +238 -20
- package/dist_ts/proxies/smart-proxy/index.d.ts +1 -1
- package/dist_ts/proxies/smart-proxy/index.js +3 -3
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -66
- package/dist_ts/proxies/smart-proxy/models/interfaces.js +5 -4
- package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +173 -6
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +20 -7
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +49 -108
- package/dist_ts/proxies/smart-proxy/port-manager.d.ts +81 -0
- package/dist_ts/proxies/smart-proxy/port-manager.js +166 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +7 -5
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +155 -160
- package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +9 -0
- package/dist_ts/proxies/smart-proxy/route-helpers/index.js +11 -0
- package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +5 -125
- package/dist_ts/proxies/smart-proxy/route-helpers.js +8 -195
- package/dist_ts/proxies/smart-proxy/route-manager.d.ts +14 -11
- package/dist_ts/proxies/smart-proxy/route-manager.js +81 -124
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +101 -12
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +178 -306
- package/dist_ts/proxies/smart-proxy/timeout-manager.js +3 -3
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +12 -0
- package/dist_ts/proxies/smart-proxy/utils/index.js +19 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +240 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +451 -0
- package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.d.ts +51 -0
- package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.js +124 -0
- package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +131 -0
- package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +217 -0
- package/dist_ts/proxies/smart-proxy/utils/route-utils.d.ts +79 -0
- package/dist_ts/proxies/smart-proxy/utils/route-utils.js +266 -0
- package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +73 -0
- package/dist_ts/proxies/smart-proxy/utils/route-validators.js +264 -0
- package/package.json +1 -1
- package/readme.md +241 -125
- package/readme.plan.md +73 -286
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/certificate/index.ts +17 -9
- package/ts/certificate/models/certificate-types.ts +37 -16
- package/ts/certificate/providers/cert-provisioner.ts +247 -54
- package/ts/core/models/index.ts +2 -0
- package/ts/core/models/route-context.ts +113 -0
- package/ts/core/models/socket-augmentation.ts +33 -0
- package/ts/core/utils/event-system.ts +376 -0
- package/ts/core/utils/index.ts +7 -0
- package/ts/core/utils/route-manager.ts +489 -0
- package/ts/core/utils/route-utils.ts +312 -0
- package/ts/core/utils/security-utils.ts +309 -0
- package/ts/core/utils/shared-security-manager.ts +333 -0
- package/ts/core/utils/template-utils.ts +124 -0
- package/ts/core/utils/websocket-utils.ts +81 -0
- package/ts/forwarding/config/forwarding-types.ts +79 -107
- package/ts/forwarding/config/index.ts +4 -2
- package/ts/forwarding/handlers/base-handler.ts +4 -2
- package/ts/forwarding/index.ts +3 -2
- package/ts/http/models/http-types.ts +0 -1
- package/ts/http/port80/acme-interfaces.ts +84 -0
- package/ts/http/port80/port80-handler.ts +61 -15
- package/ts/http/router/index.ts +8 -1
- package/ts/http/router/route-router.ts +482 -0
- package/ts/index.ts +14 -2
- package/ts/proxies/index.ts +12 -3
- package/ts/proxies/network-proxy/certificate-manager.ts +114 -10
- package/ts/proxies/network-proxy/context-creator.ts +145 -0
- package/ts/proxies/network-proxy/function-cache.ts +259 -0
- package/ts/proxies/network-proxy/http-request-handler.ts +330 -0
- package/ts/proxies/network-proxy/http2-request-handler.ts +255 -0
- package/ts/proxies/network-proxy/models/types.ts +312 -1
- package/ts/proxies/network-proxy/network-proxy.ts +195 -86
- package/ts/proxies/network-proxy/request-handler.ts +698 -246
- package/ts/proxies/network-proxy/security-manager.ts +298 -0
- package/ts/proxies/network-proxy/websocket-handler.ts +276 -33
- package/ts/proxies/smart-proxy/index.ts +2 -12
- package/ts/proxies/smart-proxy/models/interfaces.ts +13 -67
- package/ts/proxies/smart-proxy/models/route-types.ts +223 -25
- package/ts/proxies/smart-proxy/network-proxy-bridge.ts +57 -123
- package/ts/proxies/smart-proxy/port-manager.ts +195 -0
- package/ts/proxies/smart-proxy/route-connection-handler.ts +191 -225
- package/ts/proxies/smart-proxy/route-manager.ts +101 -144
- package/ts/proxies/smart-proxy/smart-proxy.ts +206 -377
- package/ts/proxies/smart-proxy/timeout-manager.ts +2 -2
- package/ts/proxies/smart-proxy/utils/index.ts +40 -0
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +621 -0
- package/ts/proxies/smart-proxy/utils/route-migration-utils.ts +165 -0
- package/ts/proxies/smart-proxy/utils/route-patterns.ts +309 -0
- package/ts/proxies/smart-proxy/utils/route-utils.ts +330 -0
- package/ts/proxies/smart-proxy/utils/route-validators.ts +288 -0
- package/ts/forwarding/config/domain-config.ts +0 -28
- package/ts/forwarding/config/domain-manager.ts +0 -283
- package/ts/proxies/smart-proxy/connection-handler.ts +0 -1240
- package/ts/proxies/smart-proxy/domain-config-manager.ts +0 -441
- package/ts/proxies/smart-proxy/port-range-manager.ts +0 -211
- package/ts/proxies/smart-proxy/route-helpers.ts +0 -344
|
@@ -3,11 +3,10 @@ import * as plugins from '../../plugins.js';
|
|
|
3
3
|
// Importing required components
|
|
4
4
|
import { ConnectionManager } from './connection-manager.js';
|
|
5
5
|
import { SecurityManager } from './security-manager.js';
|
|
6
|
-
import { DomainConfigManager } from './domain-config-manager.js';
|
|
7
6
|
import { TlsManager } from './tls-manager.js';
|
|
8
7
|
import { NetworkProxyBridge } from './network-proxy-bridge.js';
|
|
9
8
|
import { TimeoutManager } from './timeout-manager.js';
|
|
10
|
-
import {
|
|
9
|
+
import { PortManager } from './port-manager.js';
|
|
11
10
|
import { RouteManager } from './route-manager.js';
|
|
12
11
|
import { RouteConnectionHandler } from './route-connection-handler.js';
|
|
13
12
|
|
|
@@ -19,31 +18,39 @@ import { buildPort80Handler } from '../../certificate/acme/acme-factory.js';
|
|
|
19
18
|
import { createPort80HandlerOptions } from '../../common/port80-adapter.js';
|
|
20
19
|
|
|
21
20
|
// Import types and utilities
|
|
22
|
-
import type {
|
|
23
|
-
ISmartProxyOptions,
|
|
24
|
-
IRoutedSmartProxyOptions
|
|
25
|
-
IDomainConfig
|
|
21
|
+
import type {
|
|
22
|
+
ISmartProxyOptions,
|
|
23
|
+
IRoutedSmartProxyOptions
|
|
26
24
|
} from './models/interfaces.js';
|
|
27
25
|
import { isRoutedOptions, isLegacyOptions } from './models/interfaces.js';
|
|
28
26
|
import type { IRouteConfig } from './models/route-types.js';
|
|
29
27
|
|
|
30
28
|
/**
|
|
31
|
-
* SmartProxy -
|
|
29
|
+
* SmartProxy - Pure route-based API
|
|
30
|
+
*
|
|
31
|
+
* SmartProxy is a unified proxy system that works with routes to define connection handling behavior.
|
|
32
|
+
* Each route contains matching criteria (ports, domains, etc.) and an action to take (forward, redirect, block).
|
|
33
|
+
*
|
|
34
|
+
* Configuration is provided through a set of routes, with each route defining:
|
|
35
|
+
* - What to match (ports, domains, paths, client IPs)
|
|
36
|
+
* - What to do with matching traffic (forward, redirect, block)
|
|
37
|
+
* - How to handle TLS (passthrough, terminate, terminate-and-reencrypt)
|
|
38
|
+
* - Security settings (IP restrictions, connection limits)
|
|
39
|
+
* - Advanced options (timeout, headers, etc.)
|
|
32
40
|
*/
|
|
33
41
|
export class SmartProxy extends plugins.EventEmitter {
|
|
34
|
-
|
|
42
|
+
// Port manager handles dynamic listener management
|
|
43
|
+
private portManager: PortManager;
|
|
35
44
|
private connectionLogger: NodeJS.Timeout | null = null;
|
|
36
45
|
private isShuttingDown: boolean = false;
|
|
37
46
|
|
|
38
47
|
// Component managers
|
|
39
48
|
private connectionManager: ConnectionManager;
|
|
40
49
|
private securityManager: SecurityManager;
|
|
41
|
-
private domainConfigManager: DomainConfigManager;
|
|
42
50
|
private tlsManager: TlsManager;
|
|
43
51
|
private networkProxyBridge: NetworkProxyBridge;
|
|
44
52
|
private timeoutManager: TimeoutManager;
|
|
45
|
-
|
|
46
|
-
private routeManager: RouteManager;
|
|
53
|
+
public routeManager: RouteManager; // Made public for route management
|
|
47
54
|
private routeConnectionHandler: RouteConnectionHandler;
|
|
48
55
|
|
|
49
56
|
// Port80Handler for ACME certificate management
|
|
@@ -52,7 +59,35 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
52
59
|
private certProvisioner?: CertProvisioner;
|
|
53
60
|
|
|
54
61
|
/**
|
|
55
|
-
* Constructor
|
|
62
|
+
* Constructor for SmartProxy
|
|
63
|
+
*
|
|
64
|
+
* @param settingsArg Configuration options containing routes and other settings
|
|
65
|
+
* Routes define how traffic is matched and handled, with each route having:
|
|
66
|
+
* - match: criteria for matching traffic (ports, domains, paths, IPs)
|
|
67
|
+
* - action: what to do with matched traffic (forward, redirect, block)
|
|
68
|
+
*
|
|
69
|
+
* Example:
|
|
70
|
+
* ```ts
|
|
71
|
+
* const proxy = new SmartProxy({
|
|
72
|
+
* routes: [
|
|
73
|
+
* {
|
|
74
|
+
* match: {
|
|
75
|
+
* ports: 443,
|
|
76
|
+
* domains: ['example.com', '*.example.com']
|
|
77
|
+
* },
|
|
78
|
+
* action: {
|
|
79
|
+
* type: 'forward',
|
|
80
|
+
* target: { host: '10.0.0.1', port: 8443 },
|
|
81
|
+
* tls: { mode: 'passthrough' }
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* ],
|
|
85
|
+
* defaults: {
|
|
86
|
+
* target: { host: 'localhost', port: 8080 },
|
|
87
|
+
* security: { allowedIps: ['*'] }
|
|
88
|
+
* }
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
56
91
|
*/
|
|
57
92
|
constructor(settingsArg: ISmartProxyOptions) {
|
|
58
93
|
super();
|
|
@@ -98,9 +133,9 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
98
133
|
autoRenew: true,
|
|
99
134
|
certificateStore: './certs',
|
|
100
135
|
skipConfiguredCerts: false,
|
|
101
|
-
httpsRedirectPort:
|
|
136
|
+
httpsRedirectPort: 443,
|
|
102
137
|
renewCheckIntervalHours: 24,
|
|
103
|
-
|
|
138
|
+
routeForwards: []
|
|
104
139
|
};
|
|
105
140
|
}
|
|
106
141
|
|
|
@@ -113,18 +148,9 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
113
148
|
this.timeoutManager
|
|
114
149
|
);
|
|
115
150
|
|
|
116
|
-
// Create the
|
|
151
|
+
// Create the route manager
|
|
117
152
|
this.routeManager = new RouteManager(this.settings);
|
|
118
153
|
|
|
119
|
-
// Create domain config manager and port range manager
|
|
120
|
-
this.domainConfigManager = new DomainConfigManager(this.settings);
|
|
121
|
-
|
|
122
|
-
// Share the route manager with the domain config manager
|
|
123
|
-
if (typeof this.domainConfigManager.setRouteManager === 'function') {
|
|
124
|
-
this.domainConfigManager.setRouteManager(this.routeManager);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
this.portRangeManager = new PortRangeManager(this.settings);
|
|
128
154
|
|
|
129
155
|
// Create other required components
|
|
130
156
|
this.tlsManager = new TlsManager(this.settings);
|
|
@@ -135,12 +161,14 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
135
161
|
this.settings,
|
|
136
162
|
this.connectionManager,
|
|
137
163
|
this.securityManager,
|
|
138
|
-
this.domainConfigManager,
|
|
139
164
|
this.tlsManager,
|
|
140
165
|
this.networkProxyBridge,
|
|
141
166
|
this.timeoutManager,
|
|
142
167
|
this.routeManager
|
|
143
168
|
);
|
|
169
|
+
|
|
170
|
+
// Initialize port manager
|
|
171
|
+
this.portManager = new PortManager(this.settings, this.routeConnectionHandler);
|
|
144
172
|
}
|
|
145
173
|
|
|
146
174
|
/**
|
|
@@ -162,7 +190,7 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
162
190
|
// Build and start the Port80Handler
|
|
163
191
|
this.port80Handler = buildPort80Handler({
|
|
164
192
|
...config,
|
|
165
|
-
httpsRedirectPort: config.httpsRedirectPort ||
|
|
193
|
+
httpsRedirectPort: config.httpsRedirectPort || 443
|
|
166
194
|
});
|
|
167
195
|
|
|
168
196
|
// Share Port80Handler with NetworkProxyBridge before start
|
|
@@ -184,17 +212,7 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
184
212
|
return;
|
|
185
213
|
}
|
|
186
214
|
|
|
187
|
-
//
|
|
188
|
-
if (isLegacyOptions(this.settings)) {
|
|
189
|
-
// Initialize domain config manager with the legacy domain configs
|
|
190
|
-
this.domainConfigManager.updateDomainConfigs(this.settings.domainConfigs || []);
|
|
191
|
-
} else if (isRoutedOptions(this.settings)) {
|
|
192
|
-
// For pure route-based configuration, the domain config is already initialized
|
|
193
|
-
// in the constructor, but we might need to regenerate it
|
|
194
|
-
if (typeof this.domainConfigManager.generateDomainConfigsFromRoutes === 'function') {
|
|
195
|
-
this.domainConfigManager.generateDomainConfigsFromRoutes();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
215
|
+
// Pure route-based configuration - no domain configs needed
|
|
198
216
|
|
|
199
217
|
// Initialize Port80Handler if enabled
|
|
200
218
|
await this.initializePort80Handler();
|
|
@@ -203,80 +221,22 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
203
221
|
if (this.port80Handler) {
|
|
204
222
|
const acme = this.settings.acme!;
|
|
205
223
|
|
|
206
|
-
// Setup
|
|
207
|
-
const
|
|
208
|
-
if (isLegacyOptions(this.settings)) {
|
|
209
|
-
// If using legacy mode, check if domain config exists
|
|
210
|
-
const domainConfig = this.settings.domainConfigs.find(
|
|
211
|
-
dc => dc.domains.some(d => d === f.domain)
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
if (domainConfig?.forwarding) {
|
|
215
|
-
return {
|
|
216
|
-
domain: f.domain,
|
|
217
|
-
forwardConfig: f.forwardConfig,
|
|
218
|
-
acmeForwardConfig: f.acmeForwardConfig,
|
|
219
|
-
sslRedirect: f.sslRedirect || domainConfig.forwarding.http?.redirectToHttps || false
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
} else {
|
|
223
|
-
// In route mode, look for matching route
|
|
224
|
-
const route = this.routeManager.findMatchingRoute({
|
|
225
|
-
port: 443,
|
|
226
|
-
domain: f.domain,
|
|
227
|
-
clientIp: '127.0.0.1' // Dummy IP for finding routes
|
|
228
|
-
})?.route;
|
|
229
|
-
|
|
230
|
-
if (route && route.action.type === 'forward' && route.action.tls) {
|
|
231
|
-
// If we found a matching route with TLS settings
|
|
232
|
-
return {
|
|
233
|
-
domain: f.domain,
|
|
234
|
-
forwardConfig: f.forwardConfig,
|
|
235
|
-
acmeForwardConfig: f.acmeForwardConfig,
|
|
236
|
-
sslRedirect: f.sslRedirect || false
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Otherwise use the existing configuration
|
|
242
|
-
return {
|
|
243
|
-
domain: f.domain,
|
|
244
|
-
forwardConfig: f.forwardConfig,
|
|
245
|
-
acmeForwardConfig: f.acmeForwardConfig,
|
|
246
|
-
sslRedirect: f.sslRedirect || false
|
|
247
|
-
};
|
|
248
|
-
}) || [];
|
|
224
|
+
// Setup route forwards
|
|
225
|
+
const routeForwards = acme.routeForwards?.map(f => f) || [];
|
|
249
226
|
|
|
250
227
|
// Create CertProvisioner with appropriate parameters
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
// For route-based configuration, we need to adapt the interface
|
|
264
|
-
// Convert routes to domain configs for CertProvisioner
|
|
265
|
-
const domainConfigs: IDomainConfig[] = this.extractDomainConfigsFromRoutes(
|
|
266
|
-
(this.settings as IRoutedSmartProxyOptions).routes
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
this.certProvisioner = new CertProvisioner(
|
|
270
|
-
domainConfigs,
|
|
271
|
-
this.port80Handler,
|
|
272
|
-
this.networkProxyBridge,
|
|
273
|
-
this.settings.certProvisionFunction,
|
|
274
|
-
acme.renewThresholdDays!,
|
|
275
|
-
acme.renewCheckIntervalHours!,
|
|
276
|
-
acme.autoRenew!,
|
|
277
|
-
domainForwards
|
|
278
|
-
);
|
|
279
|
-
}
|
|
228
|
+
// No longer need to support multiple configuration types
|
|
229
|
+
// Just pass the routes directly
|
|
230
|
+
this.certProvisioner = new CertProvisioner(
|
|
231
|
+
this.settings.routes,
|
|
232
|
+
this.port80Handler,
|
|
233
|
+
this.networkProxyBridge,
|
|
234
|
+
this.settings.certProvisionFunction,
|
|
235
|
+
acme.renewThresholdDays!,
|
|
236
|
+
acme.renewCheckIntervalHours!,
|
|
237
|
+
acme.autoRenew!,
|
|
238
|
+
routeForwards
|
|
239
|
+
);
|
|
280
240
|
|
|
281
241
|
// Register certificate event handler
|
|
282
242
|
this.certProvisioner.on('certificate', (certData) => {
|
|
@@ -312,35 +272,8 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
312
272
|
// Get listening ports from RouteManager
|
|
313
273
|
const listeningPorts = this.routeManager.getListeningPorts();
|
|
314
274
|
|
|
315
|
-
//
|
|
316
|
-
|
|
317
|
-
const server = plugins.net.createServer((socket) => {
|
|
318
|
-
// Check if shutting down
|
|
319
|
-
if (this.isShuttingDown) {
|
|
320
|
-
socket.end();
|
|
321
|
-
socket.destroy();
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Delegate to route connection handler
|
|
326
|
-
this.routeConnectionHandler.handleConnection(socket);
|
|
327
|
-
}).on('error', (err: Error) => {
|
|
328
|
-
console.log(`Server Error on port ${port}: ${err.message}`);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
server.listen(port, () => {
|
|
332
|
-
const isNetworkProxyPort = this.settings.useNetworkProxy?.includes(port);
|
|
333
|
-
console.log(
|
|
334
|
-
`SmartProxy -> OK: Now listening on port ${port}${
|
|
335
|
-
isLegacyOptions(this.settings) && this.settings.sniEnabled && !isNetworkProxyPort ?
|
|
336
|
-
' (SNI passthrough enabled)' :
|
|
337
|
-
''
|
|
338
|
-
}${isNetworkProxyPort ? ' (NetworkProxy forwarding enabled)' : ''}`
|
|
339
|
-
);
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
this.netServers.push(server);
|
|
343
|
-
}
|
|
275
|
+
// Start port listeners using the PortManager
|
|
276
|
+
await this.portManager.addPorts(listeningPorts);
|
|
344
277
|
|
|
345
278
|
// Set up periodic connection logging and inactivity checks
|
|
346
279
|
this.connectionLogger = setInterval(() => {
|
|
@@ -416,60 +349,9 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
416
349
|
|
|
417
350
|
/**
|
|
418
351
|
* Extract domain configurations from routes for certificate provisioning
|
|
352
|
+
*
|
|
353
|
+
* Note: This method has been removed as we now work directly with routes
|
|
419
354
|
*/
|
|
420
|
-
private extractDomainConfigsFromRoutes(routes: IRouteConfig[]): IDomainConfig[] {
|
|
421
|
-
const domainConfigs: IDomainConfig[] = [];
|
|
422
|
-
|
|
423
|
-
for (const route of routes) {
|
|
424
|
-
// Skip routes without domain specs
|
|
425
|
-
if (!route.match.domains) continue;
|
|
426
|
-
|
|
427
|
-
// Skip non-forward routes
|
|
428
|
-
if (route.action.type !== 'forward') continue;
|
|
429
|
-
|
|
430
|
-
// Only process routes that need TLS termination (those with certificates)
|
|
431
|
-
if (!route.action.tls ||
|
|
432
|
-
route.action.tls.mode === 'passthrough' ||
|
|
433
|
-
!route.action.target) continue;
|
|
434
|
-
|
|
435
|
-
const domains = Array.isArray(route.match.domains)
|
|
436
|
-
? route.match.domains
|
|
437
|
-
: [route.match.domains];
|
|
438
|
-
|
|
439
|
-
// Determine forwarding type based on TLS mode
|
|
440
|
-
const forwardingType = route.action.tls.mode === 'terminate'
|
|
441
|
-
? 'https-terminate-to-http'
|
|
442
|
-
: 'https-terminate-to-https';
|
|
443
|
-
|
|
444
|
-
// Create a forwarding config
|
|
445
|
-
const forwarding = {
|
|
446
|
-
type: forwardingType as any,
|
|
447
|
-
target: {
|
|
448
|
-
host: Array.isArray(route.action.target.host)
|
|
449
|
-
? route.action.target.host[0]
|
|
450
|
-
: route.action.target.host,
|
|
451
|
-
port: route.action.target.port
|
|
452
|
-
},
|
|
453
|
-
// Add TLS settings
|
|
454
|
-
https: {
|
|
455
|
-
customCert: route.action.tls.certificate !== 'auto'
|
|
456
|
-
? route.action.tls.certificate
|
|
457
|
-
: undefined
|
|
458
|
-
},
|
|
459
|
-
// Add security settings if present
|
|
460
|
-
security: route.action.security,
|
|
461
|
-
// Add advanced settings if present
|
|
462
|
-
advanced: route.action.advanced
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
domainConfigs.push({
|
|
466
|
-
domains,
|
|
467
|
-
forwarding
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
return domainConfigs;
|
|
472
|
-
}
|
|
473
355
|
|
|
474
356
|
/**
|
|
475
357
|
* Stop the proxy server
|
|
@@ -477,6 +359,7 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
477
359
|
public async stop() {
|
|
478
360
|
console.log('SmartProxy shutting down...');
|
|
479
361
|
this.isShuttingDown = true;
|
|
362
|
+
this.portManager.setShuttingDown(true);
|
|
480
363
|
|
|
481
364
|
// Stop CertProvisioner if active
|
|
482
365
|
if (this.certProvisioner) {
|
|
@@ -495,31 +378,14 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
495
378
|
}
|
|
496
379
|
}
|
|
497
380
|
|
|
498
|
-
// Stop accepting new connections
|
|
499
|
-
const closeServerPromises: Promise<void>[] = this.netServers.map(
|
|
500
|
-
(server) =>
|
|
501
|
-
new Promise<void>((resolve) => {
|
|
502
|
-
if (!server.listening) {
|
|
503
|
-
resolve();
|
|
504
|
-
return;
|
|
505
|
-
}
|
|
506
|
-
server.close((err) => {
|
|
507
|
-
if (err) {
|
|
508
|
-
console.log(`Error closing server: ${err.message}`);
|
|
509
|
-
}
|
|
510
|
-
resolve();
|
|
511
|
-
});
|
|
512
|
-
})
|
|
513
|
-
);
|
|
514
|
-
|
|
515
381
|
// Stop the connection logger
|
|
516
382
|
if (this.connectionLogger) {
|
|
517
383
|
clearInterval(this.connectionLogger);
|
|
518
384
|
this.connectionLogger = null;
|
|
519
385
|
}
|
|
520
386
|
|
|
521
|
-
//
|
|
522
|
-
await
|
|
387
|
+
// Stop all port listeners
|
|
388
|
+
await this.portManager.closeAll();
|
|
523
389
|
console.log('All servers closed. Cleaning up active connections...');
|
|
524
390
|
|
|
525
391
|
// Clean up all active connections
|
|
@@ -528,195 +394,130 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
528
394
|
// Stop NetworkProxy
|
|
529
395
|
await this.networkProxyBridge.stop();
|
|
530
396
|
|
|
531
|
-
// Clear all servers
|
|
532
|
-
this.netServers = [];
|
|
533
397
|
|
|
534
398
|
console.log('SmartProxy shutdown complete.');
|
|
535
399
|
}
|
|
536
400
|
|
|
537
401
|
/**
|
|
538
|
-
* Updates the domain configurations for the proxy
|
|
402
|
+
* Updates the domain configurations for the proxy
|
|
403
|
+
*
|
|
404
|
+
* Note: This legacy method has been removed. Use updateRoutes instead.
|
|
539
405
|
*/
|
|
540
|
-
public async updateDomainConfigs(
|
|
541
|
-
console.
|
|
406
|
+
public async updateDomainConfigs(): Promise<void> {
|
|
407
|
+
console.warn('Method updateDomainConfigs() is deprecated. Use updateRoutes() instead.');
|
|
408
|
+
throw new Error('updateDomainConfigs() is deprecated - use updateRoutes() instead');
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Update routes with new configuration
|
|
413
|
+
*
|
|
414
|
+
* This method replaces the current route configuration with the provided routes.
|
|
415
|
+
* It also provisions certificates for routes that require TLS termination and have
|
|
416
|
+
* `certificate: 'auto'` set in their TLS configuration.
|
|
417
|
+
*
|
|
418
|
+
* @param newRoutes Array of route configurations to use
|
|
419
|
+
*
|
|
420
|
+
* Example:
|
|
421
|
+
* ```ts
|
|
422
|
+
* proxy.updateRoutes([
|
|
423
|
+
* {
|
|
424
|
+
* match: { ports: 443, domains: 'secure.example.com' },
|
|
425
|
+
* action: {
|
|
426
|
+
* type: 'forward',
|
|
427
|
+
* target: { host: '10.0.0.1', port: 8443 },
|
|
428
|
+
* tls: { mode: 'terminate', certificate: 'auto' }
|
|
429
|
+
* }
|
|
430
|
+
* }
|
|
431
|
+
* ]);
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
public async updateRoutes(newRoutes: IRouteConfig[]): Promise<void> {
|
|
435
|
+
console.log(`Updating routes (${newRoutes.length} routes)`);
|
|
436
|
+
|
|
437
|
+
// Update routes in RouteManager
|
|
438
|
+
this.routeManager.updateRoutes(newRoutes);
|
|
542
439
|
|
|
543
|
-
//
|
|
544
|
-
this.
|
|
440
|
+
// Get the new set of required ports
|
|
441
|
+
const requiredPorts = this.routeManager.getListeningPorts();
|
|
545
442
|
|
|
546
|
-
//
|
|
547
|
-
this.
|
|
443
|
+
// Update port listeners to match the new configuration
|
|
444
|
+
await this.portManager.updatePorts(requiredPorts);
|
|
548
445
|
|
|
549
446
|
// If NetworkProxy is initialized, resync the configurations
|
|
550
447
|
if (this.networkProxyBridge.getNetworkProxy()) {
|
|
551
|
-
await this.networkProxyBridge.
|
|
448
|
+
await this.networkProxyBridge.syncRoutesToNetworkProxy(newRoutes);
|
|
552
449
|
}
|
|
553
450
|
|
|
554
|
-
// If Port80Handler is running, provision certificates based on
|
|
451
|
+
// If Port80Handler is running, provision certificates based on routes
|
|
555
452
|
if (this.port80Handler && this.settings.acme?.enabled) {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const forwardingType = this.domainConfigManager.getForwardingType(domainConfig);
|
|
559
|
-
const needsCertificate =
|
|
560
|
-
forwardingType === 'https-terminate-to-http' ||
|
|
561
|
-
forwardingType === 'https-terminate-to-https';
|
|
562
|
-
|
|
563
|
-
// Skip certificate provisioning if ACME is explicitly disabled for this domain
|
|
564
|
-
const acmeDisabled = domainConfig.forwarding.acme?.enabled === false;
|
|
565
|
-
|
|
566
|
-
if (!needsCertificate || acmeDisabled) {
|
|
567
|
-
if (this.settings.enableDetailedLogging) {
|
|
568
|
-
console.log(`Skipping certificate provisioning for ${domainConfig.domains.join(', ')} (${forwardingType})`);
|
|
569
|
-
}
|
|
570
|
-
continue;
|
|
571
|
-
}
|
|
453
|
+
// Register all eligible domains from routes
|
|
454
|
+
this.port80Handler.addDomainsFromRoutes(newRoutes);
|
|
572
455
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
456
|
+
// Handle static certificates from certProvisionFunction if available
|
|
457
|
+
if (this.settings.certProvisionFunction) {
|
|
458
|
+
for (const route of newRoutes) {
|
|
459
|
+
// Skip routes without domains
|
|
460
|
+
if (!route.match.domains) continue;
|
|
576
461
|
|
|
577
|
-
//
|
|
578
|
-
|
|
462
|
+
// Skip non-forward routes
|
|
463
|
+
if (route.action.type !== 'forward') continue;
|
|
579
464
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
console.log(`certProvider error for ${domain}: ${err}`);
|
|
585
|
-
}
|
|
586
|
-
} else if (isWildcard) {
|
|
587
|
-
console.warn(`Skipping wildcard domain without certProvisionFunction: ${domain}`);
|
|
588
|
-
continue;
|
|
589
|
-
}
|
|
465
|
+
// Skip routes without TLS termination
|
|
466
|
+
if (!route.action.tls ||
|
|
467
|
+
route.action.tls.mode === 'passthrough' ||
|
|
468
|
+
!route.action.target) continue;
|
|
590
469
|
|
|
591
|
-
if
|
|
592
|
-
|
|
593
|
-
console.warn(`Skipping HTTP-01 for wildcard domain: ${domain}`);
|
|
594
|
-
continue;
|
|
595
|
-
}
|
|
470
|
+
// Skip certificate provisioning if certificate is not auto
|
|
471
|
+
if (route.action.tls.certificate !== 'auto') continue;
|
|
596
472
|
|
|
597
|
-
|
|
598
|
-
|
|
473
|
+
const domains = Array.isArray(route.match.domains)
|
|
474
|
+
? route.match.domains
|
|
475
|
+
: [route.match.domains];
|
|
599
476
|
|
|
600
|
-
|
|
601
|
-
console.log(`Registered domain ${domain} with Port80Handler for HTTP-01`);
|
|
602
|
-
} else {
|
|
603
|
-
// Static certificate (e.g., DNS-01 provisioned) supports wildcards
|
|
604
|
-
const certObj = provision as plugins.tsclass.network.ICert;
|
|
605
|
-
const certData: ICertificateData = {
|
|
606
|
-
domain: certObj.domainName,
|
|
607
|
-
certificate: certObj.publicKey,
|
|
608
|
-
privateKey: certObj.privateKey,
|
|
609
|
-
expiryDate: new Date(certObj.validUntil)
|
|
610
|
-
};
|
|
611
|
-
this.networkProxyBridge.applyExternalCertificate(certData);
|
|
612
|
-
console.log(`Applied static certificate for ${domain} from certProvider`);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
console.log('Provisioned certificates for new domains');
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
/**
|
|
621
|
-
* Update routes with new configuration (new API)
|
|
622
|
-
*/
|
|
623
|
-
public async updateRoutes(newRoutes: IRouteConfig[]): Promise<void> {
|
|
624
|
-
console.log(`Updating routes (${newRoutes.length} routes)`);
|
|
625
|
-
|
|
626
|
-
// Update routes in RouteManager
|
|
627
|
-
this.routeManager.updateRoutes(newRoutes);
|
|
628
|
-
|
|
629
|
-
// If NetworkProxy is initialized, resync the configurations
|
|
630
|
-
if (this.networkProxyBridge.getNetworkProxy()) {
|
|
631
|
-
// Create equivalent domain configs for NetworkProxy
|
|
632
|
-
const domainConfigs = this.extractDomainConfigsFromRoutes(newRoutes);
|
|
633
|
-
|
|
634
|
-
// Update domain configs in DomainConfigManager for sync
|
|
635
|
-
this.domainConfigManager.updateDomainConfigs(domainConfigs);
|
|
636
|
-
|
|
637
|
-
// Sync with NetworkProxy
|
|
638
|
-
await this.networkProxyBridge.syncDomainConfigsToNetworkProxy();
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// If Port80Handler is running, provision certificates based on routes
|
|
642
|
-
if (this.port80Handler && this.settings.acme?.enabled) {
|
|
643
|
-
for (const route of newRoutes) {
|
|
644
|
-
// Skip routes without domains
|
|
645
|
-
if (!route.match.domains) continue;
|
|
646
|
-
|
|
647
|
-
// Skip non-forward routes
|
|
648
|
-
if (route.action.type !== 'forward') continue;
|
|
649
|
-
|
|
650
|
-
// Skip routes without TLS termination
|
|
651
|
-
if (!route.action.tls ||
|
|
652
|
-
route.action.tls.mode === 'passthrough' ||
|
|
653
|
-
!route.action.target) continue;
|
|
654
|
-
|
|
655
|
-
// Skip certificate provisioning if certificate is not auto
|
|
656
|
-
if (route.action.tls.certificate !== 'auto') continue;
|
|
657
|
-
|
|
658
|
-
const domains = Array.isArray(route.match.domains)
|
|
659
|
-
? route.match.domains
|
|
660
|
-
: [route.match.domains];
|
|
661
|
-
|
|
662
|
-
for (const domain of domains) {
|
|
663
|
-
const isWildcard = domain.includes('*');
|
|
664
|
-
let provision: string | plugins.tsclass.network.ICert = 'http01';
|
|
665
|
-
|
|
666
|
-
if (this.settings.certProvisionFunction) {
|
|
477
|
+
for (const domain of domains) {
|
|
667
478
|
try {
|
|
668
|
-
provision = await this.settings.certProvisionFunction(domain);
|
|
479
|
+
const provision = await this.settings.certProvisionFunction(domain);
|
|
480
|
+
|
|
481
|
+
// Skip http01 as those are handled by Port80Handler
|
|
482
|
+
if (provision !== 'http01') {
|
|
483
|
+
// Handle static certificate (e.g., DNS-01 provisioned)
|
|
484
|
+
const certObj = provision as plugins.tsclass.network.ICert;
|
|
485
|
+
const certData: ICertificateData = {
|
|
486
|
+
domain: certObj.domainName,
|
|
487
|
+
certificate: certObj.publicKey,
|
|
488
|
+
privateKey: certObj.privateKey,
|
|
489
|
+
expiryDate: new Date(certObj.validUntil),
|
|
490
|
+
routeReference: {
|
|
491
|
+
routeName: route.name
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
this.networkProxyBridge.applyExternalCertificate(certData);
|
|
495
|
+
console.log(`Applied static certificate for ${domain} from certProvider`);
|
|
496
|
+
}
|
|
669
497
|
} catch (err) {
|
|
670
498
|
console.log(`certProvider error for ${domain}: ${err}`);
|
|
671
499
|
}
|
|
672
|
-
} else if (isWildcard) {
|
|
673
|
-
console.warn(`Skipping wildcard domain without certProvisionFunction: ${domain}`);
|
|
674
|
-
continue;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
if (provision === 'http01') {
|
|
678
|
-
if (isWildcard) {
|
|
679
|
-
console.warn(`Skipping HTTP-01 for wildcard domain: ${domain}`);
|
|
680
|
-
continue;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// Register domain with Port80Handler
|
|
684
|
-
this.port80Handler.addDomain({
|
|
685
|
-
domainName: domain,
|
|
686
|
-
sslRedirect: true,
|
|
687
|
-
acmeMaintenance: true
|
|
688
|
-
});
|
|
689
|
-
|
|
690
|
-
console.log(`Registered domain ${domain} with Port80Handler for HTTP-01`);
|
|
691
|
-
} else {
|
|
692
|
-
// Handle static certificate (e.g., DNS-01 provisioned)
|
|
693
|
-
const certObj = provision as plugins.tsclass.network.ICert;
|
|
694
|
-
const certData: ICertificateData = {
|
|
695
|
-
domain: certObj.domainName,
|
|
696
|
-
certificate: certObj.publicKey,
|
|
697
|
-
privateKey: certObj.privateKey,
|
|
698
|
-
expiryDate: new Date(certObj.validUntil)
|
|
699
|
-
};
|
|
700
|
-
this.networkProxyBridge.applyExternalCertificate(certData);
|
|
701
|
-
console.log(`Applied static certificate for ${domain} from certProvider`);
|
|
702
500
|
}
|
|
703
501
|
}
|
|
704
502
|
}
|
|
705
|
-
|
|
503
|
+
|
|
706
504
|
console.log('Provisioned certificates for new routes');
|
|
707
505
|
}
|
|
708
506
|
}
|
|
709
507
|
|
|
710
508
|
/**
|
|
711
509
|
* Request a certificate for a specific domain
|
|
510
|
+
*
|
|
511
|
+
* @param domain The domain to request a certificate for
|
|
512
|
+
* @param routeName Optional route name to associate with the certificate
|
|
712
513
|
*/
|
|
713
|
-
public async requestCertificate(domain: string): Promise<boolean> {
|
|
514
|
+
public async requestCertificate(domain: string, routeName?: string): Promise<boolean> {
|
|
714
515
|
// Validate domain format
|
|
715
516
|
if (!this.isValidDomain(domain)) {
|
|
716
517
|
console.log(`Invalid domain format: ${domain}`);
|
|
717
518
|
return false;
|
|
718
519
|
}
|
|
719
|
-
|
|
520
|
+
|
|
720
521
|
// Use Port80Handler if available
|
|
721
522
|
if (this.port80Handler) {
|
|
722
523
|
try {
|
|
@@ -726,15 +527,16 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
726
527
|
console.log(`Certificate already exists for ${domain}, valid until ${cert.expiryDate.toISOString()}`);
|
|
727
528
|
return true;
|
|
728
529
|
}
|
|
729
|
-
|
|
530
|
+
|
|
730
531
|
// Register domain for certificate issuance
|
|
731
532
|
this.port80Handler.addDomain({
|
|
732
|
-
|
|
533
|
+
domain,
|
|
733
534
|
sslRedirect: true,
|
|
734
|
-
acmeMaintenance: true
|
|
535
|
+
acmeMaintenance: true,
|
|
536
|
+
routeReference: routeName ? { routeName } : undefined
|
|
735
537
|
});
|
|
736
|
-
|
|
737
|
-
console.log(`Domain ${domain} registered for certificate issuance`);
|
|
538
|
+
|
|
539
|
+
console.log(`Domain ${domain} registered for certificate issuance` + (routeName ? ` for route '${routeName}'` : ''));
|
|
738
540
|
return true;
|
|
739
541
|
} catch (err) {
|
|
740
542
|
console.log(`Error registering domain with Port80Handler: ${err}`);
|
|
@@ -771,6 +573,41 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
771
573
|
return true;
|
|
772
574
|
}
|
|
773
575
|
|
|
576
|
+
/**
|
|
577
|
+
* Add a new listening port without changing the route configuration
|
|
578
|
+
*
|
|
579
|
+
* This allows you to add a port listener without updating routes.
|
|
580
|
+
* Useful for preparing to listen on a port before adding routes for it.
|
|
581
|
+
*
|
|
582
|
+
* @param port The port to start listening on
|
|
583
|
+
* @returns Promise that resolves when the port is listening
|
|
584
|
+
*/
|
|
585
|
+
public async addListeningPort(port: number): Promise<void> {
|
|
586
|
+
return this.portManager.addPort(port);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Stop listening on a specific port without changing the route configuration
|
|
591
|
+
*
|
|
592
|
+
* This allows you to stop a port listener without updating routes.
|
|
593
|
+
* Useful for temporary maintenance or port changes.
|
|
594
|
+
*
|
|
595
|
+
* @param port The port to stop listening on
|
|
596
|
+
* @returns Promise that resolves when the port is closed
|
|
597
|
+
*/
|
|
598
|
+
public async removeListeningPort(port: number): Promise<void> {
|
|
599
|
+
return this.portManager.removePort(port);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Get a list of all ports currently being listened on
|
|
604
|
+
*
|
|
605
|
+
* @returns Array of port numbers
|
|
606
|
+
*/
|
|
607
|
+
public getListeningPorts(): number[] {
|
|
608
|
+
return this.portManager.getListeningPorts();
|
|
609
|
+
}
|
|
610
|
+
|
|
774
611
|
/**
|
|
775
612
|
* Get statistics about current connections
|
|
776
613
|
*/
|
|
@@ -800,7 +637,9 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
800
637
|
terminationStats,
|
|
801
638
|
acmeEnabled: !!this.port80Handler,
|
|
802
639
|
port80HandlerPort: this.port80Handler ? this.settings.acme?.port : null,
|
|
803
|
-
routes: this.routeManager.getListeningPorts().length
|
|
640
|
+
routes: this.routeManager.getListeningPorts().length,
|
|
641
|
+
listeningPorts: this.portManager.getListeningPorts(),
|
|
642
|
+
activePorts: this.portManager.getListeningPorts().length
|
|
804
643
|
};
|
|
805
644
|
}
|
|
806
645
|
|
|
@@ -834,17 +673,7 @@ export class SmartProxy extends plugins.EventEmitter {
|
|
|
834
673
|
domains.push(...eligibleDomains);
|
|
835
674
|
}
|
|
836
675
|
|
|
837
|
-
//
|
|
838
|
-
if (isLegacyOptions(this.settings)) {
|
|
839
|
-
for (const config of this.settings.domainConfigs) {
|
|
840
|
-
// Skip domains that can't be used with ACME
|
|
841
|
-
const eligibleDomains = config.domains.filter(domain =>
|
|
842
|
-
!domain.includes('*') && this.isValidDomain(domain)
|
|
843
|
-
);
|
|
844
|
-
|
|
845
|
-
domains.push(...eligibleDomains);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
676
|
+
// Legacy mode is no longer supported
|
|
848
677
|
|
|
849
678
|
return domains;
|
|
850
679
|
}
|