@push.rocks/smartproxy 3.41.8 → 4.0.0

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.
Files changed (43) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/classes.pp.acmemanager.d.ts +34 -0
  3. package/dist_ts/classes.pp.acmemanager.js +123 -0
  4. package/dist_ts/classes.pp.connectionhandler.d.ts +39 -0
  5. package/dist_ts/classes.pp.connectionhandler.js +693 -0
  6. package/dist_ts/classes.pp.connectionmanager.d.ts +78 -0
  7. package/dist_ts/classes.pp.connectionmanager.js +378 -0
  8. package/dist_ts/classes.pp.domainconfigmanager.d.ts +55 -0
  9. package/dist_ts/classes.pp.domainconfigmanager.js +103 -0
  10. package/dist_ts/classes.pp.interfaces.d.ts +109 -0
  11. package/dist_ts/classes.pp.interfaces.js +2 -0
  12. package/dist_ts/classes.pp.networkproxybridge.d.ts +43 -0
  13. package/dist_ts/classes.pp.networkproxybridge.js +211 -0
  14. package/dist_ts/classes.pp.portproxy.d.ts +48 -0
  15. package/dist_ts/classes.pp.portproxy.js +268 -0
  16. package/dist_ts/classes.pp.portrangemanager.d.ts +56 -0
  17. package/dist_ts/classes.pp.portrangemanager.js +179 -0
  18. package/dist_ts/classes.pp.securitymanager.d.ts +47 -0
  19. package/dist_ts/classes.pp.securitymanager.js +126 -0
  20. package/dist_ts/classes.pp.snihandler.d.ts +160 -0
  21. package/dist_ts/classes.pp.snihandler.js +1073 -0
  22. package/dist_ts/classes.pp.timeoutmanager.d.ts +47 -0
  23. package/dist_ts/classes.pp.timeoutmanager.js +154 -0
  24. package/dist_ts/classes.pp.tlsmanager.d.ts +57 -0
  25. package/dist_ts/classes.pp.tlsmanager.js +132 -0
  26. package/dist_ts/index.d.ts +2 -2
  27. package/dist_ts/index.js +3 -3
  28. package/package.json +1 -1
  29. package/ts/00_commitinfo_data.ts +1 -1
  30. package/ts/classes.pp.acmemanager.ts +149 -0
  31. package/ts/classes.pp.connectionhandler.ts +982 -0
  32. package/ts/classes.pp.connectionmanager.ts +446 -0
  33. package/ts/classes.pp.domainconfigmanager.ts +123 -0
  34. package/ts/classes.pp.interfaces.ts +136 -0
  35. package/ts/classes.pp.networkproxybridge.ts +258 -0
  36. package/ts/classes.pp.portproxy.ts +344 -0
  37. package/ts/classes.pp.portrangemanager.ts +214 -0
  38. package/ts/classes.pp.securitymanager.ts +147 -0
  39. package/ts/{classes.snihandler.ts → classes.pp.snihandler.ts} +2 -169
  40. package/ts/classes.pp.timeoutmanager.ts +190 -0
  41. package/ts/classes.pp.tlsmanager.ts +206 -0
  42. package/ts/index.ts +2 -2
  43. package/ts/classes.portproxy.ts +0 -2503
@@ -0,0 +1,268 @@
1
+ import * as plugins from './plugins.js';
2
+ import { ConnectionManager } from './classes.pp.connectionmanager.js';
3
+ import { SecurityManager } from './classes.pp.securitymanager.js';
4
+ import { DomainConfigManager } from './classes.pp.domainconfigmanager.js';
5
+ import { TlsManager } from './classes.pp.tlsmanager.js';
6
+ import { NetworkProxyBridge } from './classes.pp.networkproxybridge.js';
7
+ import { TimeoutManager } from './classes.pp.timeoutmanager.js';
8
+ import { AcmeManager } from './classes.pp.acmemanager.js';
9
+ import { PortRangeManager } from './classes.pp.portrangemanager.js';
10
+ import { ConnectionHandler } from './classes.pp.connectionhandler.js';
11
+ /**
12
+ * PortProxy - Main class that coordinates all components
13
+ */
14
+ export class PortProxy {
15
+ constructor(settingsArg) {
16
+ this.netServers = [];
17
+ this.connectionLogger = null;
18
+ this.isShuttingDown = false;
19
+ // Set reasonable defaults for all settings
20
+ this.settings = {
21
+ ...settingsArg,
22
+ targetIP: settingsArg.targetIP || 'localhost',
23
+ initialDataTimeout: settingsArg.initialDataTimeout || 120000,
24
+ socketTimeout: settingsArg.socketTimeout || 3600000,
25
+ inactivityCheckInterval: settingsArg.inactivityCheckInterval || 60000,
26
+ maxConnectionLifetime: settingsArg.maxConnectionLifetime || 86400000,
27
+ inactivityTimeout: settingsArg.inactivityTimeout || 14400000,
28
+ gracefulShutdownTimeout: settingsArg.gracefulShutdownTimeout || 30000,
29
+ noDelay: settingsArg.noDelay !== undefined ? settingsArg.noDelay : true,
30
+ keepAlive: settingsArg.keepAlive !== undefined ? settingsArg.keepAlive : true,
31
+ keepAliveInitialDelay: settingsArg.keepAliveInitialDelay || 10000,
32
+ maxPendingDataSize: settingsArg.maxPendingDataSize || 10 * 1024 * 1024,
33
+ disableInactivityCheck: settingsArg.disableInactivityCheck || false,
34
+ enableKeepAliveProbes: settingsArg.enableKeepAliveProbes !== undefined ? settingsArg.enableKeepAliveProbes : true,
35
+ enableDetailedLogging: settingsArg.enableDetailedLogging || false,
36
+ enableTlsDebugLogging: settingsArg.enableTlsDebugLogging || false,
37
+ enableRandomizedTimeouts: settingsArg.enableRandomizedTimeouts || false,
38
+ allowSessionTicket: settingsArg.allowSessionTicket !== undefined ? settingsArg.allowSessionTicket : true,
39
+ maxConnectionsPerIP: settingsArg.maxConnectionsPerIP || 100,
40
+ connectionRateLimitPerMinute: settingsArg.connectionRateLimitPerMinute || 300,
41
+ keepAliveTreatment: settingsArg.keepAliveTreatment || 'extended',
42
+ keepAliveInactivityMultiplier: settingsArg.keepAliveInactivityMultiplier || 6,
43
+ extendedKeepAliveLifetime: settingsArg.extendedKeepAliveLifetime || 7 * 24 * 60 * 60 * 1000,
44
+ networkProxyPort: settingsArg.networkProxyPort || 8443,
45
+ acme: settingsArg.acme || {
46
+ enabled: false,
47
+ port: 80,
48
+ contactEmail: 'admin@example.com',
49
+ useProduction: false,
50
+ renewThresholdDays: 30,
51
+ autoRenew: true,
52
+ certificateStore: './certs',
53
+ skipConfiguredCerts: false,
54
+ },
55
+ };
56
+ // Initialize component managers
57
+ this.timeoutManager = new TimeoutManager(this.settings);
58
+ this.securityManager = new SecurityManager(this.settings);
59
+ this.connectionManager = new ConnectionManager(this.settings, this.securityManager, this.timeoutManager);
60
+ this.domainConfigManager = new DomainConfigManager(this.settings);
61
+ this.tlsManager = new TlsManager(this.settings);
62
+ this.networkProxyBridge = new NetworkProxyBridge(this.settings);
63
+ this.portRangeManager = new PortRangeManager(this.settings);
64
+ this.acmeManager = new AcmeManager(this.settings, this.networkProxyBridge);
65
+ // Initialize connection handler
66
+ this.connectionHandler = new ConnectionHandler(this.settings, this.connectionManager, this.securityManager, this.domainConfigManager, this.tlsManager, this.networkProxyBridge, this.timeoutManager, this.portRangeManager);
67
+ }
68
+ /**
69
+ * Start the proxy server
70
+ */
71
+ async start() {
72
+ // Don't start if already shutting down
73
+ if (this.isShuttingDown) {
74
+ console.log("Cannot start PortProxy while it's shutting down");
75
+ return;
76
+ }
77
+ // Initialize and start NetworkProxy if needed
78
+ if (this.settings.useNetworkProxy &&
79
+ this.settings.useNetworkProxy.length > 0) {
80
+ await this.networkProxyBridge.initialize();
81
+ await this.networkProxyBridge.start();
82
+ }
83
+ // Validate port configuration
84
+ const configWarnings = this.portRangeManager.validateConfiguration();
85
+ if (configWarnings.length > 0) {
86
+ console.log("Port configuration warnings:");
87
+ for (const warning of configWarnings) {
88
+ console.log(` - ${warning}`);
89
+ }
90
+ }
91
+ // Get listening ports from PortRangeManager
92
+ const listeningPorts = this.portRangeManager.getListeningPorts();
93
+ // Create servers for each port
94
+ for (const port of listeningPorts) {
95
+ const server = plugins.net.createServer((socket) => {
96
+ // Check if shutting down
97
+ if (this.isShuttingDown) {
98
+ socket.end();
99
+ socket.destroy();
100
+ return;
101
+ }
102
+ // Delegate to connection handler
103
+ this.connectionHandler.handleConnection(socket);
104
+ }).on('error', (err) => {
105
+ console.log(`Server Error on port ${port}: ${err.message}`);
106
+ });
107
+ server.listen(port, () => {
108
+ const isNetworkProxyPort = this.settings.useNetworkProxy?.includes(port);
109
+ console.log(`PortProxy -> OK: Now listening on port ${port}${this.settings.sniEnabled && !isNetworkProxyPort ? ' (SNI passthrough enabled)' : ''}${isNetworkProxyPort ? ' (NetworkProxy forwarding enabled)' : ''}`);
110
+ });
111
+ this.netServers.push(server);
112
+ }
113
+ // Set up periodic connection logging and inactivity checks
114
+ this.connectionLogger = setInterval(() => {
115
+ // Immediately return if shutting down
116
+ if (this.isShuttingDown)
117
+ return;
118
+ // Perform inactivity check
119
+ this.connectionManager.performInactivityCheck();
120
+ // Log connection statistics
121
+ const now = Date.now();
122
+ let maxIncoming = 0;
123
+ let maxOutgoing = 0;
124
+ let tlsConnections = 0;
125
+ let nonTlsConnections = 0;
126
+ let completedTlsHandshakes = 0;
127
+ let pendingTlsHandshakes = 0;
128
+ let keepAliveConnections = 0;
129
+ let networkProxyConnections = 0;
130
+ // Get connection records for analysis
131
+ const connectionRecords = this.connectionManager.getConnections();
132
+ // Analyze active connections
133
+ for (const record of connectionRecords.values()) {
134
+ // Track connection stats
135
+ if (record.isTLS) {
136
+ tlsConnections++;
137
+ if (record.tlsHandshakeComplete) {
138
+ completedTlsHandshakes++;
139
+ }
140
+ else {
141
+ pendingTlsHandshakes++;
142
+ }
143
+ }
144
+ else {
145
+ nonTlsConnections++;
146
+ }
147
+ if (record.hasKeepAlive) {
148
+ keepAliveConnections++;
149
+ }
150
+ if (record.usingNetworkProxy) {
151
+ networkProxyConnections++;
152
+ }
153
+ maxIncoming = Math.max(maxIncoming, now - record.incomingStartTime);
154
+ if (record.outgoingStartTime) {
155
+ maxOutgoing = Math.max(maxOutgoing, now - record.outgoingStartTime);
156
+ }
157
+ }
158
+ // Get termination stats
159
+ const terminationStats = this.connectionManager.getTerminationStats();
160
+ // Log detailed stats
161
+ console.log(`Active connections: ${connectionRecords.size}. ` +
162
+ `Types: TLS=${tlsConnections} (Completed=${completedTlsHandshakes}, Pending=${pendingTlsHandshakes}), ` +
163
+ `Non-TLS=${nonTlsConnections}, KeepAlive=${keepAliveConnections}, NetworkProxy=${networkProxyConnections}. ` +
164
+ `Longest running: IN=${plugins.prettyMs(maxIncoming)}, OUT=${plugins.prettyMs(maxOutgoing)}. ` +
165
+ `Termination stats: ${JSON.stringify({
166
+ IN: terminationStats.incoming,
167
+ OUT: terminationStats.outgoing,
168
+ })}`);
169
+ }, this.settings.inactivityCheckInterval || 60000);
170
+ // Make sure the interval doesn't keep the process alive
171
+ if (this.connectionLogger.unref) {
172
+ this.connectionLogger.unref();
173
+ }
174
+ }
175
+ /**
176
+ * Stop the proxy server
177
+ */
178
+ async stop() {
179
+ console.log('PortProxy shutting down...');
180
+ this.isShuttingDown = true;
181
+ // Stop accepting new connections
182
+ const closeServerPromises = this.netServers.map((server) => new Promise((resolve) => {
183
+ if (!server.listening) {
184
+ resolve();
185
+ return;
186
+ }
187
+ server.close((err) => {
188
+ if (err) {
189
+ console.log(`Error closing server: ${err.message}`);
190
+ }
191
+ resolve();
192
+ });
193
+ }));
194
+ // Stop the connection logger
195
+ if (this.connectionLogger) {
196
+ clearInterval(this.connectionLogger);
197
+ this.connectionLogger = null;
198
+ }
199
+ // Wait for servers to close
200
+ await Promise.all(closeServerPromises);
201
+ console.log('All servers closed. Cleaning up active connections...');
202
+ // Clean up all active connections
203
+ this.connectionManager.clearConnections();
204
+ // Stop NetworkProxy
205
+ await this.networkProxyBridge.stop();
206
+ // Clear all servers
207
+ this.netServers = [];
208
+ console.log('PortProxy shutdown complete.');
209
+ }
210
+ /**
211
+ * Updates the domain configurations for the proxy
212
+ */
213
+ async updateDomainConfigs(newDomainConfigs) {
214
+ console.log(`Updating domain configurations (${newDomainConfigs.length} configs)`);
215
+ // Update domain configs in DomainConfigManager
216
+ this.domainConfigManager.updateDomainConfigs(newDomainConfigs);
217
+ // If NetworkProxy is initialized, resync the configurations
218
+ if (this.networkProxyBridge.getNetworkProxy()) {
219
+ await this.networkProxyBridge.syncDomainConfigsToNetworkProxy();
220
+ }
221
+ }
222
+ /**
223
+ * Updates the ACME certificate settings
224
+ */
225
+ async updateAcmeSettings(acmeSettings) {
226
+ console.log('Updating ACME certificate settings');
227
+ // Delegate to AcmeManager
228
+ await this.acmeManager.updateAcmeSettings(acmeSettings);
229
+ }
230
+ /**
231
+ * Requests a certificate for a specific domain
232
+ */
233
+ async requestCertificate(domain) {
234
+ // Delegate to AcmeManager
235
+ return this.acmeManager.requestCertificate(domain);
236
+ }
237
+ /**
238
+ * Get statistics about current connections
239
+ */
240
+ getStatistics() {
241
+ const connectionRecords = this.connectionManager.getConnections();
242
+ const terminationStats = this.connectionManager.getTerminationStats();
243
+ let tlsConnections = 0;
244
+ let nonTlsConnections = 0;
245
+ let keepAliveConnections = 0;
246
+ let networkProxyConnections = 0;
247
+ // Analyze active connections
248
+ for (const record of connectionRecords.values()) {
249
+ if (record.isTLS)
250
+ tlsConnections++;
251
+ else
252
+ nonTlsConnections++;
253
+ if (record.hasKeepAlive)
254
+ keepAliveConnections++;
255
+ if (record.usingNetworkProxy)
256
+ networkProxyConnections++;
257
+ }
258
+ return {
259
+ activeConnections: connectionRecords.size,
260
+ tlsConnections,
261
+ nonTlsConnections,
262
+ keepAliveConnections,
263
+ networkProxyConnections,
264
+ terminationStats
265
+ };
266
+ }
267
+ }
268
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wcC5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnBwLnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUN0RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDcEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFdEU7O0dBRUc7QUFDSCxNQUFNLE9BQU8sU0FBUztJQWdCcEIsWUFBWSxXQUErQjtRQWZuQyxlQUFVLEdBQXlCLEVBQUUsQ0FBQztRQUN0QyxxQkFBZ0IsR0FBMEIsSUFBSSxDQUFDO1FBQy9DLG1CQUFjLEdBQVksS0FBSyxDQUFDO1FBY3RDLDJDQUEyQztRQUMzQyxJQUFJLENBQUMsUUFBUSxHQUFHO1lBQ2QsR0FBRyxXQUFXO1lBQ2QsUUFBUSxFQUFFLFdBQVcsQ0FBQyxRQUFRLElBQUksV0FBVztZQUM3QyxrQkFBa0IsRUFBRSxXQUFXLENBQUMsa0JBQWtCLElBQUksTUFBTTtZQUM1RCxhQUFhLEVBQUUsV0FBVyxDQUFDLGFBQWEsSUFBSSxPQUFPO1lBQ25ELHVCQUF1QixFQUFFLFdBQVcsQ0FB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
@@ -0,0 +1,56 @@
1
+ import type { IPortProxySettings } from './classes.pp.interfaces.js';
2
+ /**
3
+ * Manages port ranges and port-based configuration
4
+ */
5
+ export declare class PortRangeManager {
6
+ private settings;
7
+ constructor(settings: IPortProxySettings);
8
+ /**
9
+ * Get all ports that should be listened on
10
+ */
11
+ getListeningPorts(): Set<number>;
12
+ /**
13
+ * Check if a port should use NetworkProxy for forwarding
14
+ */
15
+ shouldUseNetworkProxy(port: number): boolean;
16
+ /**
17
+ * Check if port should use global forwarding
18
+ */
19
+ shouldUseGlobalForwarding(port: number): boolean;
20
+ /**
21
+ * Check if a port is in global ranges
22
+ */
23
+ isPortInGlobalRanges(port: number): boolean;
24
+ /**
25
+ * Check if a port falls within the specified ranges
26
+ */
27
+ isPortInRanges(port: number, ranges: Array<{
28
+ from: number;
29
+ to: number;
30
+ }>): boolean;
31
+ /**
32
+ * Get forwarding port for a specific listening port
33
+ * This determines what port to connect to on the target
34
+ */
35
+ getForwardingPort(listeningPort: number): number;
36
+ /**
37
+ * Find domain-specific port ranges that include a given port
38
+ */
39
+ findDomainPortRange(port: number): {
40
+ domainIndex: number;
41
+ range: {
42
+ from: number;
43
+ to: number;
44
+ };
45
+ } | undefined;
46
+ /**
47
+ * Get a list of all configured ports
48
+ * This includes the fromPort, NetworkProxy ports, and ports from all ranges
49
+ */
50
+ getAllConfiguredPorts(): number[];
51
+ /**
52
+ * Validate port configuration
53
+ * Returns array of warning messages
54
+ */
55
+ validateConfiguration(): string[];
56
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Manages port ranges and port-based configuration
3
+ */
4
+ export class PortRangeManager {
5
+ constructor(settings) {
6
+ this.settings = settings;
7
+ }
8
+ /**
9
+ * Get all ports that should be listened on
10
+ */
11
+ getListeningPorts() {
12
+ const listeningPorts = new Set();
13
+ // Always include the main fromPort
14
+ listeningPorts.add(this.settings.fromPort);
15
+ // Add ports from global port ranges if defined
16
+ if (this.settings.globalPortRanges && this.settings.globalPortRanges.length > 0) {
17
+ for (const range of this.settings.globalPortRanges) {
18
+ for (let port = range.from; port <= range.to; port++) {
19
+ listeningPorts.add(port);
20
+ }
21
+ }
22
+ }
23
+ return listeningPorts;
24
+ }
25
+ /**
26
+ * Check if a port should use NetworkProxy for forwarding
27
+ */
28
+ shouldUseNetworkProxy(port) {
29
+ return !!this.settings.useNetworkProxy && this.settings.useNetworkProxy.includes(port);
30
+ }
31
+ /**
32
+ * Check if port should use global forwarding
33
+ */
34
+ shouldUseGlobalForwarding(port) {
35
+ return (!!this.settings.forwardAllGlobalRanges &&
36
+ this.isPortInGlobalRanges(port));
37
+ }
38
+ /**
39
+ * Check if a port is in global ranges
40
+ */
41
+ isPortInGlobalRanges(port) {
42
+ return (this.settings.globalPortRanges &&
43
+ this.isPortInRanges(port, this.settings.globalPortRanges));
44
+ }
45
+ /**
46
+ * Check if a port falls within the specified ranges
47
+ */
48
+ isPortInRanges(port, ranges) {
49
+ return ranges.some((range) => port >= range.from && port <= range.to);
50
+ }
51
+ /**
52
+ * Get forwarding port for a specific listening port
53
+ * This determines what port to connect to on the target
54
+ */
55
+ getForwardingPort(listeningPort) {
56
+ // If using global forwarding, forward to the original port
57
+ if (this.settings.forwardAllGlobalRanges && this.isPortInGlobalRanges(listeningPort)) {
58
+ return listeningPort;
59
+ }
60
+ // Otherwise use the configured toPort
61
+ return this.settings.toPort;
62
+ }
63
+ /**
64
+ * Find domain-specific port ranges that include a given port
65
+ */
66
+ findDomainPortRange(port) {
67
+ for (let i = 0; i < this.settings.domainConfigs.length; i++) {
68
+ const domain = this.settings.domainConfigs[i];
69
+ if (domain.portRanges) {
70
+ for (const range of domain.portRanges) {
71
+ if (port >= range.from && port <= range.to) {
72
+ return { domainIndex: i, range };
73
+ }
74
+ }
75
+ }
76
+ }
77
+ return undefined;
78
+ }
79
+ /**
80
+ * Get a list of all configured ports
81
+ * This includes the fromPort, NetworkProxy ports, and ports from all ranges
82
+ */
83
+ getAllConfiguredPorts() {
84
+ const ports = new Set();
85
+ // Add main listening port
86
+ ports.add(this.settings.fromPort);
87
+ // Add NetworkProxy port if configured
88
+ if (this.settings.networkProxyPort) {
89
+ ports.add(this.settings.networkProxyPort);
90
+ }
91
+ // Add NetworkProxy ports
92
+ if (this.settings.useNetworkProxy) {
93
+ for (const port of this.settings.useNetworkProxy) {
94
+ ports.add(port);
95
+ }
96
+ }
97
+ // Add ACME HTTP challenge port if enabled
98
+ if (this.settings.acme?.enabled && this.settings.acme.port) {
99
+ ports.add(this.settings.acme.port);
100
+ }
101
+ // Add global port ranges
102
+ if (this.settings.globalPortRanges) {
103
+ for (const range of this.settings.globalPortRanges) {
104
+ for (let port = range.from; port <= range.to; port++) {
105
+ ports.add(port);
106
+ }
107
+ }
108
+ }
109
+ // Add domain-specific port ranges
110
+ for (const domain of this.settings.domainConfigs) {
111
+ if (domain.portRanges) {
112
+ for (const range of domain.portRanges) {
113
+ for (let port = range.from; port <= range.to; port++) {
114
+ ports.add(port);
115
+ }
116
+ }
117
+ }
118
+ // Add domain-specific NetworkProxy port if configured
119
+ if (domain.useNetworkProxy && domain.networkProxyPort) {
120
+ ports.add(domain.networkProxyPort);
121
+ }
122
+ }
123
+ return Array.from(ports);
124
+ }
125
+ /**
126
+ * Validate port configuration
127
+ * Returns array of warning messages
128
+ */
129
+ validateConfiguration() {
130
+ const warnings = [];
131
+ // Check for overlapping port ranges
132
+ const portMappings = new Map();
133
+ // Track global port ranges
134
+ if (this.settings.globalPortRanges) {
135
+ for (const range of this.settings.globalPortRanges) {
136
+ for (let port = range.from; port <= range.to; port++) {
137
+ if (!portMappings.has(port)) {
138
+ portMappings.set(port, []);
139
+ }
140
+ portMappings.get(port).push('Global Port Range');
141
+ }
142
+ }
143
+ }
144
+ // Track domain-specific port ranges
145
+ for (const domain of this.settings.domainConfigs) {
146
+ if (domain.portRanges) {
147
+ for (const range of domain.portRanges) {
148
+ for (let port = range.from; port <= range.to; port++) {
149
+ if (!portMappings.has(port)) {
150
+ portMappings.set(port, []);
151
+ }
152
+ portMappings.get(port).push(`Domain: ${domain.domains.join(', ')}`);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ // Check for ports with multiple mappings
158
+ for (const [port, mappings] of portMappings.entries()) {
159
+ if (mappings.length > 1) {
160
+ warnings.push(`Port ${port} has multiple mappings: ${mappings.join(', ')}`);
161
+ }
162
+ }
163
+ // Check if main ports are used elsewhere
164
+ if (portMappings.has(this.settings.fromPort) && portMappings.get(this.settings.fromPort).length > 0) {
165
+ warnings.push(`Main listening port ${this.settings.fromPort} is also used in port ranges`);
166
+ }
167
+ if (this.settings.networkProxyPort && portMappings.has(this.settings.networkProxyPort)) {
168
+ warnings.push(`NetworkProxy port ${this.settings.networkProxyPort} is also used in port ranges`);
169
+ }
170
+ // Check ACME port
171
+ if (this.settings.acme?.enabled && this.settings.acme.port) {
172
+ if (portMappings.has(this.settings.acme.port)) {
173
+ warnings.push(`ACME HTTP challenge port ${this.settings.acme.port} is also used in port ranges`);
174
+ }
175
+ }
176
+ return warnings;
177
+ }
178
+ }
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wcC5wb3J0cmFuZ2VtYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5wcC5wb3J0cmFuZ2VtYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQUMzQixZQUFvQixRQUE0QjtRQUE1QixhQUFRLEdBQVIsUUFBUSxDQUFvQjtJQUFHLENBQUM7SUFFcEQ7O09BRUc7SUFDSSxpQkFBaUI7UUFDdEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUV6QyxtQ0FBbUM7UUFDbkMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTNDLCtDQUErQztRQUMvQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDaEYsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQ25ELEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLElBQUksS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUNyRCxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMzQixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLGNBQWMsQ0FBQztJQUN4QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxxQkFBcUIsQ0FBQyxJQUFZO1FBQ3ZDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6RixDQUFDO0lB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
@@ -0,0 +1,47 @@
1
+ import type { IPortProxySettings } from './classes.pp.interfaces.js';
2
+ /**
3
+ * Handles security aspects like IP tracking, rate limiting, and authorization
4
+ */
5
+ export declare class SecurityManager {
6
+ private settings;
7
+ private connectionsByIP;
8
+ private connectionRateByIP;
9
+ constructor(settings: IPortProxySettings);
10
+ /**
11
+ * Get connections count by IP
12
+ */
13
+ getConnectionCountByIP(ip: string): number;
14
+ /**
15
+ * Check and update connection rate for an IP
16
+ * @returns true if within rate limit, false if exceeding limit
17
+ */
18
+ checkConnectionRate(ip: string): boolean;
19
+ /**
20
+ * Track connection by IP
21
+ */
22
+ trackConnectionByIP(ip: string, connectionId: string): void;
23
+ /**
24
+ * Remove connection tracking for an IP
25
+ */
26
+ removeConnectionByIP(ip: string, connectionId: string): void;
27
+ /**
28
+ * Check if an IP is allowed using glob patterns
29
+ */
30
+ isIPAuthorized(ip: string, allowedIPs: string[], blockedIPs?: string[]): boolean;
31
+ /**
32
+ * Check if the IP matches any of the glob patterns
33
+ */
34
+ private isGlobIPMatch;
35
+ /**
36
+ * Check if IP should be allowed considering connection rate and max connections
37
+ * @returns Object with result and reason
38
+ */
39
+ validateIP(ip: string): {
40
+ allowed: boolean;
41
+ reason?: string;
42
+ };
43
+ /**
44
+ * Clears all IP tracking data (for shutdown)
45
+ */
46
+ clearIPTracking(): void;
47
+ }