@push.rocks/smartproxy 16.0.4 → 18.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/common/port80-adapter.js +29 -3
- package/dist_ts/core/utils/shared-security-manager.js +3 -3
- package/dist_ts/forwarding/config/forwarding-types.d.ts +3 -29
- package/dist_ts/forwarding/config/forwarding-types.js +3 -36
- package/dist_ts/forwarding/config/index.d.ts +3 -2
- package/dist_ts/forwarding/config/index.js +4 -3
- package/dist_ts/forwarding/factory/forwarding-factory.js +9 -3
- package/dist_ts/forwarding/handlers/base-handler.d.ts +8 -1
- package/dist_ts/forwarding/handlers/base-handler.js +29 -4
- package/dist_ts/forwarding/handlers/http-handler.js +8 -4
- package/dist_ts/forwarding/index.d.ts +3 -8
- package/dist_ts/forwarding/index.js +4 -13
- package/dist_ts/proxies/smart-proxy/models/index.d.ts +0 -1
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +2 -11
- package/dist_ts/proxies/smart-proxy/models/interfaces.js +1 -12
- package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +22 -71
- package/dist_ts/proxies/smart-proxy/models/route-types.js +2 -1
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +0 -3
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +7 -12
- package/dist_ts/proxies/smart-proxy/route-manager.js +6 -7
- package/dist_ts/proxies/smart-proxy/security-manager.d.ts +7 -8
- package/dist_ts/proxies/smart-proxy/security-manager.js +8 -9
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +2 -3
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +0 -2
- package/dist_ts/proxies/smart-proxy/utils/index.js +3 -6
- package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +48 -0
- package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +106 -2
- package/package.json +1 -1
- package/readme.plan.md +122 -79
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/common/port80-adapter.ts +26 -2
- package/ts/core/utils/shared-security-manager.ts +2 -2
- package/ts/forwarding/config/forwarding-types.ts +12 -70
- package/ts/forwarding/config/index.ts +19 -2
- package/ts/forwarding/factory/forwarding-factory.ts +7 -2
- package/ts/forwarding/handlers/base-handler.ts +29 -3
- package/ts/forwarding/handlers/http-handler.ts +8 -3
- package/ts/forwarding/index.ts +17 -17
- package/ts/proxies/smart-proxy/models/index.ts +0 -3
- package/ts/proxies/smart-proxy/models/interfaces.ts +3 -19
- package/ts/proxies/smart-proxy/models/route-types.ts +32 -85
- package/ts/proxies/smart-proxy/route-connection-handler.ts +4 -14
- package/ts/proxies/smart-proxy/route-manager.ts +7 -12
- package/ts/proxies/smart-proxy/security-manager.ts +7 -8
- package/ts/proxies/smart-proxy/smart-proxy.ts +2 -4
- package/ts/proxies/smart-proxy/utils/index.ts +2 -5
- package/ts/proxies/smart-proxy/utils/route-patterns.ts +146 -2
- package/ts/proxies/smart-proxy/utils/route-migration-utils.ts +0 -165
|
@@ -21,9 +21,21 @@ export function convertToLegacyForwardConfig(
|
|
|
21
21
|
? forwardConfig.target.host[0] // Use the first host in the array
|
|
22
22
|
: forwardConfig.target.host;
|
|
23
23
|
|
|
24
|
+
// Extract port number, handling different port formats
|
|
25
|
+
let port: number;
|
|
26
|
+
if (typeof forwardConfig.target.port === 'function') {
|
|
27
|
+
// Use a default port for function-based ports in adapter context
|
|
28
|
+
port = 80;
|
|
29
|
+
} else if (forwardConfig.target.port === 'preserve') {
|
|
30
|
+
// For 'preserve', use the default port 80 in this adapter context
|
|
31
|
+
port = 80;
|
|
32
|
+
} else {
|
|
33
|
+
port = forwardConfig.target.port;
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
return {
|
|
25
37
|
ip: host,
|
|
26
|
-
port:
|
|
38
|
+
port: port
|
|
27
39
|
};
|
|
28
40
|
}
|
|
29
41
|
|
|
@@ -75,11 +87,23 @@ export function createPort80HandlerOptions(
|
|
|
75
87
|
forwardConfig.type === 'https-terminate-to-https'));
|
|
76
88
|
|
|
77
89
|
if (supportsHttp) {
|
|
90
|
+
// Determine port value handling different formats
|
|
91
|
+
let port: number;
|
|
92
|
+
if (typeof forwardConfig.target.port === 'function') {
|
|
93
|
+
// Use a default port for function-based ports
|
|
94
|
+
port = 80;
|
|
95
|
+
} else if (forwardConfig.target.port === 'preserve') {
|
|
96
|
+
// For 'preserve', use 80 in this adapter context
|
|
97
|
+
port = 80;
|
|
98
|
+
} else {
|
|
99
|
+
port = forwardConfig.target.port;
|
|
100
|
+
}
|
|
101
|
+
|
|
78
102
|
options.forward = {
|
|
79
103
|
ip: Array.isArray(forwardConfig.target.host)
|
|
80
104
|
? forwardConfig.target.host[0]
|
|
81
105
|
: forwardConfig.target.host,
|
|
82
|
-
port:
|
|
106
|
+
port: port
|
|
83
107
|
};
|
|
84
108
|
}
|
|
85
109
|
|
|
@@ -199,8 +199,8 @@ export class SharedSecurityManager {
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
// Check IP against route security settings
|
|
202
|
-
const ipAllowList = route.security.ipAllowList
|
|
203
|
-
const ipBlockList = route.security.ipBlockList
|
|
202
|
+
const ipAllowList = route.security.ipAllowList;
|
|
203
|
+
const ipBlockList = route.security.ipBlockList;
|
|
204
204
|
|
|
205
205
|
const allowed = this.isIPAuthorized(clientIp, ipAllowList, ipBlockList);
|
|
206
206
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type * as plugins from '../../plugins.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @deprecated The legacy forwarding types are being replaced by the route-based configuration system.
|
|
5
|
-
* See /ts/proxies/smart-proxy/models/route-types.ts for the new route-based configuration.
|
|
6
|
-
*
|
|
7
4
|
* The primary forwarding types supported by SmartProxy
|
|
5
|
+
* Used for configuration compatibility
|
|
8
6
|
*/
|
|
9
7
|
export type TForwardingType =
|
|
10
8
|
| 'http-only' // HTTP forwarding only (no HTTPS)
|
|
@@ -35,7 +33,7 @@ export interface IForwardingHandler extends plugins.EventEmitter {
|
|
|
35
33
|
handleHttpRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void;
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
//
|
|
36
|
+
// Route-based helpers are now available directly from route-patterns.ts
|
|
39
37
|
import {
|
|
40
38
|
createHttpRoute,
|
|
41
39
|
createHttpsTerminateRoute,
|
|
@@ -43,7 +41,7 @@ import {
|
|
|
43
41
|
createHttpToHttpsRedirect,
|
|
44
42
|
createCompleteHttpsServer,
|
|
45
43
|
createLoadBalancerRoute
|
|
46
|
-
} from '../../proxies/smart-proxy/utils/route-
|
|
44
|
+
} from '../../proxies/smart-proxy/utils/route-patterns.js';
|
|
47
45
|
|
|
48
46
|
export {
|
|
49
47
|
createHttpRoute,
|
|
@@ -54,23 +52,20 @@ export {
|
|
|
54
52
|
createLoadBalancerRoute
|
|
55
53
|
};
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
* - createHttpToHttpsRedirect
|
|
64
|
-
*/
|
|
55
|
+
// Note: Legacy helper functions have been removed
|
|
56
|
+
// Please use the route-based helpers instead:
|
|
57
|
+
// - createHttpRoute
|
|
58
|
+
// - createHttpsTerminateRoute
|
|
59
|
+
// - createHttpsPassthroughRoute
|
|
60
|
+
// - createHttpToHttpsRedirect
|
|
65
61
|
import type { IRouteConfig } from '../../proxies/smart-proxy/models/route-types.js';
|
|
66
|
-
import { domainConfigToRouteConfig } from '../../proxies/smart-proxy/utils/route-migration-utils.js';
|
|
67
62
|
|
|
68
|
-
// For backward compatibility
|
|
63
|
+
// For backward compatibility, kept only the basic configuration interface
|
|
69
64
|
export interface IForwardConfig {
|
|
70
65
|
type: TForwardingType;
|
|
71
66
|
target: {
|
|
72
67
|
host: string | string[];
|
|
73
|
-
port: number;
|
|
68
|
+
port: number | 'preserve' | ((ctx: any) => number);
|
|
74
69
|
};
|
|
75
70
|
http?: any;
|
|
76
71
|
https?: any;
|
|
@@ -78,57 +73,4 @@ export interface IForwardConfig {
|
|
|
78
73
|
security?: any;
|
|
79
74
|
advanced?: any;
|
|
80
75
|
[key: string]: any;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface IDeprecatedForwardConfig {
|
|
84
|
-
type: TForwardingType;
|
|
85
|
-
target: {
|
|
86
|
-
host: string | string[];
|
|
87
|
-
port: number;
|
|
88
|
-
};
|
|
89
|
-
[key: string]: any;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @deprecated Use createHttpRoute instead
|
|
94
|
-
*/
|
|
95
|
-
export const httpOnly = (
|
|
96
|
-
partialConfig: Partial<IDeprecatedForwardConfig> & Pick<IDeprecatedForwardConfig, 'target'>
|
|
97
|
-
): IDeprecatedForwardConfig => ({
|
|
98
|
-
type: 'http-only',
|
|
99
|
-
target: partialConfig.target,
|
|
100
|
-
...(partialConfig)
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @deprecated Use createHttpsTerminateRoute instead
|
|
105
|
-
*/
|
|
106
|
-
export const tlsTerminateToHttp = (
|
|
107
|
-
partialConfig: Partial<IDeprecatedForwardConfig> & Pick<IDeprecatedForwardConfig, 'target'>
|
|
108
|
-
): IDeprecatedForwardConfig => ({
|
|
109
|
-
type: 'https-terminate-to-http',
|
|
110
|
-
target: partialConfig.target,
|
|
111
|
-
...(partialConfig)
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* @deprecated Use createHttpsTerminateRoute with reencrypt option instead
|
|
116
|
-
*/
|
|
117
|
-
export const tlsTerminateToHttps = (
|
|
118
|
-
partialConfig: Partial<IDeprecatedForwardConfig> & Pick<IDeprecatedForwardConfig, 'target'>
|
|
119
|
-
): IDeprecatedForwardConfig => ({
|
|
120
|
-
type: 'https-terminate-to-https',
|
|
121
|
-
target: partialConfig.target,
|
|
122
|
-
...(partialConfig)
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* @deprecated Use createHttpsPassthroughRoute instead
|
|
127
|
-
*/
|
|
128
|
-
export const httpsPassthrough = (
|
|
129
|
-
partialConfig: Partial<IDeprecatedForwardConfig> & Pick<IDeprecatedForwardConfig, 'target'>
|
|
130
|
-
): IDeprecatedForwardConfig => ({
|
|
131
|
-
type: 'https-passthrough',
|
|
132
|
-
target: partialConfig.target,
|
|
133
|
-
...(partialConfig)
|
|
134
|
-
});
|
|
76
|
+
}
|
|
@@ -5,5 +5,22 @@
|
|
|
5
5
|
* See /ts/proxies/smart-proxy/models/route-types.ts for the new route-based configuration.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export
|
|
9
|
-
|
|
8
|
+
export type {
|
|
9
|
+
TForwardingType,
|
|
10
|
+
IForwardConfig,
|
|
11
|
+
IForwardingHandler
|
|
12
|
+
} from './forwarding-types.js';
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
ForwardingHandlerEvents
|
|
16
|
+
} from './forwarding-types.js';
|
|
17
|
+
|
|
18
|
+
// Import route helpers from route-patterns instead of deleted route-helpers
|
|
19
|
+
export {
|
|
20
|
+
createHttpRoute,
|
|
21
|
+
createHttpsTerminateRoute,
|
|
22
|
+
createHttpsPassthroughRoute,
|
|
23
|
+
createHttpToHttpsRedirect,
|
|
24
|
+
createCompleteHttpsServer,
|
|
25
|
+
createLoadBalancerRoute
|
|
26
|
+
} from '../../proxies/smart-proxy/utils/route-patterns.js';
|
|
@@ -122,8 +122,13 @@ export class ForwardingHandlerFactory {
|
|
|
122
122
|
throw new Error('Target must include a host or array of hosts');
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
// Validate port if it's a number
|
|
126
|
+
if (typeof config.target.port === 'number') {
|
|
127
|
+
if (config.target.port <= 0 || config.target.port > 65535) {
|
|
128
|
+
throw new Error('Target must include a valid port (1-65535)');
|
|
129
|
+
}
|
|
130
|
+
} else if (config.target.port !== 'preserve' && typeof config.target.port !== 'function') {
|
|
131
|
+
throw new Error('Target port must be a number, "preserve", or a function');
|
|
127
132
|
}
|
|
128
133
|
|
|
129
134
|
// Type-specific validation
|
|
@@ -40,9 +40,10 @@ export abstract class ForwardingHandler extends plugins.EventEmitter implements
|
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Get a target from the configuration, supporting round-robin selection
|
|
43
|
+
* @param incomingPort Optional incoming port for 'preserve' mode
|
|
43
44
|
* @returns A resolved target object with host and port
|
|
44
45
|
*/
|
|
45
|
-
protected getTargetFromConfig(): { host: string, port: number } {
|
|
46
|
+
protected getTargetFromConfig(incomingPort: number = 80): { host: string, port: number } {
|
|
46
47
|
const { target } = this.config;
|
|
47
48
|
|
|
48
49
|
// Handle round-robin host selection
|
|
@@ -55,17 +56,42 @@ export abstract class ForwardingHandler extends plugins.EventEmitter implements
|
|
|
55
56
|
const randomIndex = Math.floor(Math.random() * target.host.length);
|
|
56
57
|
return {
|
|
57
58
|
host: target.host[randomIndex],
|
|
58
|
-
port: target.port
|
|
59
|
+
port: this.resolvePort(target.port, incomingPort)
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
// Single host
|
|
63
64
|
return {
|
|
64
65
|
host: target.host,
|
|
65
|
-
port: target.port
|
|
66
|
+
port: this.resolvePort(target.port, incomingPort)
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Resolves a port value, handling 'preserve' and function ports
|
|
72
|
+
* @param port The port value to resolve
|
|
73
|
+
* @param incomingPort Optional incoming port to use for 'preserve' mode
|
|
74
|
+
*/
|
|
75
|
+
protected resolvePort(
|
|
76
|
+
port: number | 'preserve' | ((ctx: any) => number),
|
|
77
|
+
incomingPort: number = 80
|
|
78
|
+
): number {
|
|
79
|
+
if (typeof port === 'function') {
|
|
80
|
+
try {
|
|
81
|
+
// Create a minimal context for the function that includes the incoming port
|
|
82
|
+
const ctx = { port: incomingPort };
|
|
83
|
+
return port(ctx);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
console.error('Error resolving port function:', err);
|
|
86
|
+
return incomingPort; // Fall back to incoming port
|
|
87
|
+
}
|
|
88
|
+
} else if (port === 'preserve') {
|
|
89
|
+
return incomingPort; // Use the actual incoming port for 'preserve'
|
|
90
|
+
} else {
|
|
91
|
+
return port;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
69
95
|
/**
|
|
70
96
|
* Redirect an HTTP request to HTTPS
|
|
71
97
|
* @param req The HTTP request
|
|
@@ -38,6 +38,7 @@ export class HttpForwardingHandler extends ForwardingHandler {
|
|
|
38
38
|
// For HTTP, we mainly handle parsed requests, but we can still set up
|
|
39
39
|
// some basic connection tracking
|
|
40
40
|
const remoteAddress = socket.remoteAddress || 'unknown';
|
|
41
|
+
const localPort = socket.localPort || 80;
|
|
41
42
|
|
|
42
43
|
socket.on('close', (hadError) => {
|
|
43
44
|
this.emit(ForwardingHandlerEvents.DISCONNECTED, {
|
|
@@ -54,7 +55,8 @@ export class HttpForwardingHandler extends ForwardingHandler {
|
|
|
54
55
|
});
|
|
55
56
|
|
|
56
57
|
this.emit(ForwardingHandlerEvents.CONNECTED, {
|
|
57
|
-
remoteAddress
|
|
58
|
+
remoteAddress,
|
|
59
|
+
localPort
|
|
58
60
|
});
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -64,8 +66,11 @@ export class HttpForwardingHandler extends ForwardingHandler {
|
|
|
64
66
|
* @param res The HTTP response
|
|
65
67
|
*/
|
|
66
68
|
public handleHttpRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void {
|
|
67
|
-
// Get the
|
|
68
|
-
const
|
|
69
|
+
// Get the local port from the request (for 'preserve' port handling)
|
|
70
|
+
const localPort = req.socket.localPort || 80;
|
|
71
|
+
|
|
72
|
+
// Get the target from configuration, passing the incoming port
|
|
73
|
+
const target = this.getTargetFromConfig(localPort);
|
|
69
74
|
|
|
70
75
|
// Create a custom headers object with variables for substitution
|
|
71
76
|
const variables = {
|
package/ts/forwarding/index.ts
CHANGED
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
* Provides a flexible and type-safe way to configure and manage various forwarding strategies
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
// Export types and configuration
|
|
7
|
-
export * from './config/forwarding-types.js';
|
|
8
|
-
|
|
9
6
|
// Export handlers
|
|
10
7
|
export { ForwardingHandler } from './handlers/base-handler.js';
|
|
11
8
|
export * from './handlers/http-handler.js';
|
|
@@ -16,20 +13,23 @@ export * from './handlers/https-terminate-to-https-handler.js';
|
|
|
16
13
|
// Export factory
|
|
17
14
|
export * from './factory/forwarding-factory.js';
|
|
18
15
|
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
httpsPassthrough
|
|
16
|
+
// Export types - these include TForwardingType and IForwardConfig
|
|
17
|
+
export type {
|
|
18
|
+
TForwardingType,
|
|
19
|
+
IForwardConfig,
|
|
20
|
+
IForwardingHandler
|
|
25
21
|
} from './config/forwarding-types.js';
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
export {
|
|
24
|
+
ForwardingHandlerEvents
|
|
25
|
+
} from './config/forwarding-types.js';
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
// Export route helpers directly from route-patterns
|
|
28
|
+
export {
|
|
29
|
+
createHttpRoute,
|
|
30
|
+
createHttpsTerminateRoute,
|
|
31
|
+
createHttpsPassthroughRoute,
|
|
32
|
+
createHttpToHttpsRedirect,
|
|
33
|
+
createCompleteHttpsServer,
|
|
34
|
+
createLoadBalancerRoute
|
|
35
|
+
} from '../proxies/smart-proxy/utils/route-patterns.js';
|
|
@@ -8,23 +8,7 @@ import type { TForwardingType } from '../../../forwarding/config/forwarding-type
|
|
|
8
8
|
*/
|
|
9
9
|
export type TSmartProxyCertProvisionObject = plugins.tsclass.network.ICert | 'http01';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
* Alias for backward compatibility with code that uses IRoutedSmartProxyOptions
|
|
13
|
-
*/
|
|
14
|
-
export type IRoutedSmartProxyOptions = ISmartProxyOptions;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Helper functions for type checking configuration types
|
|
18
|
-
*/
|
|
19
|
-
export function isLegacyOptions(options: any): boolean {
|
|
20
|
-
// Legacy options are no longer supported
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function isRoutedOptions(options: any): boolean {
|
|
25
|
-
// All configurations are now route-based
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
11
|
+
// Legacy options and type checking functions have been removed
|
|
28
12
|
|
|
29
13
|
/**
|
|
30
14
|
* SmartProxy configuration options
|
|
@@ -43,8 +27,8 @@ export interface ISmartProxyOptions {
|
|
|
43
27
|
port: number; // Default port to use when not specified in routes
|
|
44
28
|
};
|
|
45
29
|
security?: {
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
ipAllowList?: string[]; // Default allowed IPs
|
|
31
|
+
ipBlockList?: string[]; // Default blocked IPs
|
|
48
32
|
maxConnections?: number; // Default max connections
|
|
49
33
|
};
|
|
50
34
|
preserveSourceIP?: boolean; // Default source IP preservation
|
|
@@ -112,13 +112,39 @@ export interface IRouteAuthentication {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
|
-
* Security options for
|
|
115
|
+
* Security options for routes
|
|
116
116
|
*/
|
|
117
117
|
export interface IRouteSecurity {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
// Access control lists
|
|
119
|
+
ipAllowList?: string[]; // IP addresses that are allowed to connect
|
|
120
|
+
ipBlockList?: string[]; // IP addresses that are blocked from connecting
|
|
121
|
+
|
|
122
|
+
// Connection limits
|
|
123
|
+
maxConnections?: number; // Maximum concurrent connections
|
|
124
|
+
|
|
125
|
+
// Authentication
|
|
121
126
|
authentication?: IRouteAuthentication;
|
|
127
|
+
|
|
128
|
+
// Rate limiting
|
|
129
|
+
rateLimit?: IRouteRateLimit;
|
|
130
|
+
|
|
131
|
+
// Authentication methods
|
|
132
|
+
basicAuth?: {
|
|
133
|
+
enabled: boolean;
|
|
134
|
+
users: Array<{ username: string; password: string }>;
|
|
135
|
+
realm?: string;
|
|
136
|
+
excludePaths?: string[];
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
jwtAuth?: {
|
|
140
|
+
enabled: boolean;
|
|
141
|
+
secret: string;
|
|
142
|
+
algorithm?: string;
|
|
143
|
+
issuer?: string;
|
|
144
|
+
audience?: string;
|
|
145
|
+
expiresIn?: number;
|
|
146
|
+
excludePaths?: string[];
|
|
147
|
+
};
|
|
122
148
|
}
|
|
123
149
|
|
|
124
150
|
/**
|
|
@@ -247,29 +273,7 @@ export interface IRouteRateLimit {
|
|
|
247
273
|
errorMessage?: string;
|
|
248
274
|
}
|
|
249
275
|
|
|
250
|
-
|
|
251
|
-
* Security features for routes
|
|
252
|
-
*/
|
|
253
|
-
export interface IRouteSecurity {
|
|
254
|
-
rateLimit?: IRouteRateLimit;
|
|
255
|
-
basicAuth?: {
|
|
256
|
-
enabled: boolean;
|
|
257
|
-
users: Array<{ username: string; password: string }>;
|
|
258
|
-
realm?: string;
|
|
259
|
-
excludePaths?: string[];
|
|
260
|
-
};
|
|
261
|
-
jwtAuth?: {
|
|
262
|
-
enabled: boolean;
|
|
263
|
-
secret: string;
|
|
264
|
-
algorithm?: string;
|
|
265
|
-
issuer?: string;
|
|
266
|
-
audience?: string;
|
|
267
|
-
expiresIn?: number;
|
|
268
|
-
excludePaths?: string[];
|
|
269
|
-
};
|
|
270
|
-
ipAllowList?: string[];
|
|
271
|
-
ipBlockList?: string[];
|
|
272
|
-
}
|
|
276
|
+
// IRouteSecurity is defined above - unified definition is used for all routes
|
|
273
277
|
|
|
274
278
|
/**
|
|
275
279
|
* CORS configuration for a route
|
|
@@ -321,61 +325,4 @@ export interface IRouteConfig {
|
|
|
321
325
|
enabled?: boolean; // Whether the route is active (default: true)
|
|
322
326
|
}
|
|
323
327
|
|
|
324
|
-
|
|
325
|
-
* Unified SmartProxy options with routes-based configuration
|
|
326
|
-
*/
|
|
327
|
-
export interface IRoutedSmartProxyOptions {
|
|
328
|
-
// The unified configuration array (required)
|
|
329
|
-
routes: IRouteConfig[];
|
|
330
|
-
|
|
331
|
-
// Global/default settings
|
|
332
|
-
defaults?: {
|
|
333
|
-
target?: {
|
|
334
|
-
host: string;
|
|
335
|
-
port: number;
|
|
336
|
-
};
|
|
337
|
-
security?: IRouteSecurity;
|
|
338
|
-
tls?: IRouteTls;
|
|
339
|
-
// ...other defaults
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
// Other global settings remain (acme, etc.)
|
|
343
|
-
acme?: IAcmeOptions;
|
|
344
|
-
|
|
345
|
-
// Connection timeouts and other global settings
|
|
346
|
-
initialDataTimeout?: number;
|
|
347
|
-
socketTimeout?: number;
|
|
348
|
-
inactivityCheckInterval?: number;
|
|
349
|
-
maxConnectionLifetime?: number;
|
|
350
|
-
inactivityTimeout?: number;
|
|
351
|
-
gracefulShutdownTimeout?: number;
|
|
352
|
-
|
|
353
|
-
// Socket optimization settings
|
|
354
|
-
noDelay?: boolean;
|
|
355
|
-
keepAlive?: boolean;
|
|
356
|
-
keepAliveInitialDelay?: number;
|
|
357
|
-
maxPendingDataSize?: number;
|
|
358
|
-
|
|
359
|
-
// Enhanced features
|
|
360
|
-
disableInactivityCheck?: boolean;
|
|
361
|
-
enableKeepAliveProbes?: boolean;
|
|
362
|
-
enableDetailedLogging?: boolean;
|
|
363
|
-
enableTlsDebugLogging?: boolean;
|
|
364
|
-
enableRandomizedTimeouts?: boolean;
|
|
365
|
-
allowSessionTicket?: boolean;
|
|
366
|
-
|
|
367
|
-
// Rate limiting and security
|
|
368
|
-
maxConnectionsPerIP?: number;
|
|
369
|
-
connectionRateLimitPerMinute?: number;
|
|
370
|
-
|
|
371
|
-
// Enhanced keep-alive settings
|
|
372
|
-
keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
|
|
373
|
-
keepAliveInactivityMultiplier?: number;
|
|
374
|
-
extendedKeepAliveLifetime?: number;
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Optional certificate provider callback. Return 'http01' to use HTTP-01 challenges,
|
|
378
|
-
* or a static certificate object for immediate provisioning.
|
|
379
|
-
*/
|
|
380
|
-
certProvisionFunction?: (domain: string) => Promise<any>;
|
|
381
|
-
}
|
|
328
|
+
// Configuration moved to models/interfaces.ts as ISmartProxyOptions
|
|
@@ -3,9 +3,7 @@ import type {
|
|
|
3
3
|
IConnectionRecord,
|
|
4
4
|
ISmartProxyOptions
|
|
5
5
|
} from './models/interfaces.js';
|
|
6
|
-
|
|
7
|
-
isRoutedOptions
|
|
8
|
-
} from './models/interfaces.js';
|
|
6
|
+
// Route checking functions have been removed
|
|
9
7
|
import type {
|
|
10
8
|
IRouteConfig,
|
|
11
9
|
IRouteAction,
|
|
@@ -291,11 +289,11 @@ export class RouteConnectionHandler {
|
|
|
291
289
|
// Check default security settings
|
|
292
290
|
const defaultSecuritySettings = this.settings.defaults?.security;
|
|
293
291
|
if (defaultSecuritySettings) {
|
|
294
|
-
if (defaultSecuritySettings.
|
|
292
|
+
if (defaultSecuritySettings.ipAllowList && defaultSecuritySettings.ipAllowList.length > 0) {
|
|
295
293
|
const isAllowed = this.securityManager.isIPAuthorized(
|
|
296
294
|
remoteIP,
|
|
297
|
-
defaultSecuritySettings.
|
|
298
|
-
defaultSecuritySettings.
|
|
295
|
+
defaultSecuritySettings.ipAllowList,
|
|
296
|
+
defaultSecuritySettings.ipBlockList || []
|
|
299
297
|
);
|
|
300
298
|
|
|
301
299
|
if (!isAllowed) {
|
|
@@ -316,7 +314,6 @@ export class RouteConnectionHandler {
|
|
|
316
314
|
return this.setupDirectConnection(
|
|
317
315
|
socket,
|
|
318
316
|
record,
|
|
319
|
-
undefined,
|
|
320
317
|
serverName,
|
|
321
318
|
initialChunk,
|
|
322
319
|
undefined,
|
|
@@ -457,7 +454,6 @@ export class RouteConnectionHandler {
|
|
|
457
454
|
return this.setupDirectConnection(
|
|
458
455
|
socket,
|
|
459
456
|
record,
|
|
460
|
-
undefined,
|
|
461
457
|
record.lockedDomain,
|
|
462
458
|
initialChunk,
|
|
463
459
|
undefined,
|
|
@@ -538,7 +534,6 @@ export class RouteConnectionHandler {
|
|
|
538
534
|
return this.setupDirectConnection(
|
|
539
535
|
socket,
|
|
540
536
|
record,
|
|
541
|
-
undefined,
|
|
542
537
|
record.lockedDomain,
|
|
543
538
|
initialChunk,
|
|
544
539
|
undefined,
|
|
@@ -656,17 +651,12 @@ export class RouteConnectionHandler {
|
|
|
656
651
|
this.connectionManager.initiateCleanupOnce(record, 'route_blocked');
|
|
657
652
|
}
|
|
658
653
|
|
|
659
|
-
/**
|
|
660
|
-
* Legacy connection handling has been removed in favor of pure route-based approach
|
|
661
|
-
*/
|
|
662
|
-
|
|
663
654
|
/**
|
|
664
655
|
* Sets up a direct connection to the target
|
|
665
656
|
*/
|
|
666
657
|
private setupDirectConnection(
|
|
667
658
|
socket: plugins.net.Socket,
|
|
668
659
|
record: IConnectionRecord,
|
|
669
|
-
_unused?: any, // kept for backward compatibility
|
|
670
660
|
serverName?: string,
|
|
671
661
|
initialChunk?: Buffer,
|
|
672
662
|
overridePort?: number,
|
|
@@ -6,12 +6,7 @@ import type {
|
|
|
6
6
|
TPortRange
|
|
7
7
|
} from './models/route-types.js';
|
|
8
8
|
import type {
|
|
9
|
-
ISmartProxyOptions
|
|
10
|
-
IRoutedSmartProxyOptions
|
|
11
|
-
} from './models/interfaces.js';
|
|
12
|
-
import {
|
|
13
|
-
isRoutedOptions,
|
|
14
|
-
isLegacyOptions
|
|
9
|
+
ISmartProxyOptions
|
|
15
10
|
} from './models/interfaces.js';
|
|
16
11
|
|
|
17
12
|
/**
|
|
@@ -29,12 +24,12 @@ export interface IRouteMatchResult {
|
|
|
29
24
|
export class RouteManager extends plugins.EventEmitter {
|
|
30
25
|
private routes: IRouteConfig[] = [];
|
|
31
26
|
private portMap: Map<number, IRouteConfig[]> = new Map();
|
|
32
|
-
private options:
|
|
27
|
+
private options: ISmartProxyOptions;
|
|
33
28
|
|
|
34
29
|
constructor(options: ISmartProxyOptions) {
|
|
35
30
|
super();
|
|
36
31
|
|
|
37
|
-
//
|
|
32
|
+
// Store options
|
|
38
33
|
this.options = options;
|
|
39
34
|
|
|
40
35
|
// Initialize routes from either source
|
|
@@ -218,8 +213,8 @@ export class RouteManager extends plugins.EventEmitter {
|
|
|
218
213
|
}
|
|
219
214
|
|
|
220
215
|
// Check blocked IPs first
|
|
221
|
-
if (security.
|
|
222
|
-
for (const pattern of security.
|
|
216
|
+
if (security.ipBlockList && security.ipBlockList.length > 0) {
|
|
217
|
+
for (const pattern of security.ipBlockList) {
|
|
223
218
|
if (this.matchIpPattern(pattern, clientIp)) {
|
|
224
219
|
return false; // IP is blocked
|
|
225
220
|
}
|
|
@@ -227,8 +222,8 @@ export class RouteManager extends plugins.EventEmitter {
|
|
|
227
222
|
}
|
|
228
223
|
|
|
229
224
|
// If there are allowed IPs, check them
|
|
230
|
-
if (security.
|
|
231
|
-
for (const pattern of security.
|
|
225
|
+
if (security.ipAllowList && security.ipAllowList.length > 0) {
|
|
226
|
+
for (const pattern of security.ipAllowList) {
|
|
232
227
|
if (this.matchIpPattern(pattern, clientIp)) {
|
|
233
228
|
return true; // IP is allowed
|
|
234
229
|
}
|