@push.rocks/smartproxy 25.17.10 → 26.1.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/changelog.md +15 -0
- package/dist_rust/rustproxy_linux_amd64 +0 -0
- package/dist_rust/rustproxy_linux_arm64 +0 -0
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/core/index.d.ts +0 -1
- package/dist_ts/core/index.js +1 -2
- package/dist_ts/core/models/index.d.ts +0 -1
- package/dist_ts/core/models/index.js +1 -2
- package/dist_ts/core/utils/index.d.ts +0 -12
- package/dist_ts/core/utils/index.js +1 -13
- package/dist_ts/index.d.ts +0 -3
- package/dist_ts/index.js +2 -7
- package/dist_ts/protocols/http/index.d.ts +0 -1
- package/dist_ts/protocols/http/index.js +1 -2
- package/dist_ts/protocols/index.d.ts +0 -7
- package/dist_ts/protocols/index.js +1 -8
- package/dist_ts/proxies/smart-proxy/models/metrics-types.d.ts +20 -0
- package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.d.ts +2 -1
- package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.js +4 -1
- package/dist_ts/proxies/smart-proxy/socket-handler-server.js +6 -1
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.d.ts +0 -7
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +50 -51
- package/dist_ts/routing/index.d.ts +0 -1
- package/dist_ts/routing/index.js +1 -3
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/index.ts +0 -1
- package/ts/core/models/index.ts +0 -1
- package/ts/core/utils/index.ts +0 -12
- package/ts/index.ts +1 -7
- package/ts/protocols/http/index.ts +1 -2
- package/ts/protocols/index.ts +0 -7
- package/ts/proxies/smart-proxy/models/metrics-types.ts +21 -0
- package/ts/proxies/smart-proxy/rust-metrics-adapter.ts +4 -1
- package/ts/proxies/smart-proxy/socket-handler-server.ts +6 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.ts +60 -59
- package/ts/routing/index.ts +0 -3
- package/dist_ts/core/events/index.d.ts +0 -4
- package/dist_ts/core/events/index.js +0 -5
- package/dist_ts/core/models/socket-augmentation.d.ts +0 -15
- package/dist_ts/core/models/socket-augmentation.js +0 -18
- package/dist_ts/core/utils/async-utils.d.ts +0 -81
- package/dist_ts/core/utils/async-utils.js +0 -216
- package/dist_ts/core/utils/binary-heap.d.ts +0 -73
- package/dist_ts/core/utils/binary-heap.js +0 -193
- package/dist_ts/core/utils/enhanced-connection-pool.d.ts +0 -110
- package/dist_ts/core/utils/enhanced-connection-pool.js +0 -325
- package/dist_ts/core/utils/fs-utils.d.ts +0 -144
- package/dist_ts/core/utils/fs-utils.js +0 -252
- package/dist_ts/core/utils/ip-utils.d.ts +0 -69
- package/dist_ts/core/utils/ip-utils.js +0 -270
- package/dist_ts/core/utils/lifecycle-component.d.ts +0 -59
- package/dist_ts/core/utils/lifecycle-component.js +0 -211
- package/dist_ts/core/utils/log-deduplicator.d.ts +0 -39
- package/dist_ts/core/utils/log-deduplicator.js +0 -305
- package/dist_ts/core/utils/security-utils.d.ts +0 -111
- package/dist_ts/core/utils/security-utils.js +0 -212
- package/dist_ts/core/utils/shared-security-manager.d.ts +0 -128
- package/dist_ts/core/utils/shared-security-manager.js +0 -362
- package/dist_ts/core/utils/socket-utils.d.ts +0 -63
- package/dist_ts/core/utils/socket-utils.js +0 -249
- package/dist_ts/core/utils/template-utils.d.ts +0 -37
- package/dist_ts/core/utils/template-utils.js +0 -104
- package/dist_ts/core/utils/validation-utils.d.ts +0 -61
- package/dist_ts/core/utils/validation-utils.js +0 -149
- package/dist_ts/core/utils/websocket-utils.d.ts +0 -22
- package/dist_ts/core/utils/websocket-utils.js +0 -30
- package/dist_ts/detection/detectors/http-detector.d.ts +0 -33
- package/dist_ts/detection/detectors/http-detector.js +0 -101
- package/dist_ts/detection/detectors/quick-detector.d.ts +0 -28
- package/dist_ts/detection/detectors/quick-detector.js +0 -131
- package/dist_ts/detection/detectors/routing-extractor.d.ts +0 -28
- package/dist_ts/detection/detectors/routing-extractor.js +0 -122
- package/dist_ts/detection/detectors/tls-detector.d.ts +0 -47
- package/dist_ts/detection/detectors/tls-detector.js +0 -183
- package/dist_ts/detection/index.d.ts +0 -17
- package/dist_ts/detection/index.js +0 -22
- package/dist_ts/detection/models/detection-types.d.ts +0 -87
- package/dist_ts/detection/models/detection-types.js +0 -5
- package/dist_ts/detection/models/interfaces.d.ts +0 -97
- package/dist_ts/detection/models/interfaces.js +0 -5
- package/dist_ts/detection/protocol-detector.d.ts +0 -79
- package/dist_ts/detection/protocol-detector.js +0 -253
- package/dist_ts/detection/utils/buffer-utils.d.ts +0 -61
- package/dist_ts/detection/utils/buffer-utils.js +0 -127
- package/dist_ts/detection/utils/fragment-manager.d.ts +0 -31
- package/dist_ts/detection/utils/fragment-manager.js +0 -53
- package/dist_ts/detection/utils/parser-utils.d.ts +0 -42
- package/dist_ts/detection/utils/parser-utils.js +0 -63
- package/dist_ts/protocols/common/fragment-handler.d.ts +0 -73
- package/dist_ts/protocols/common/fragment-handler.js +0 -121
- package/dist_ts/protocols/common/index.d.ts +0 -7
- package/dist_ts/protocols/common/index.js +0 -8
- package/dist_ts/protocols/common/types.d.ts +0 -68
- package/dist_ts/protocols/common/types.js +0 -7
- package/dist_ts/protocols/http/parser.d.ts +0 -58
- package/dist_ts/protocols/http/parser.js +0 -184
- package/dist_ts/protocols/proxy/index.d.ts +0 -5
- package/dist_ts/protocols/proxy/index.js +0 -6
- package/dist_ts/protocols/proxy/types.d.ts +0 -47
- package/dist_ts/protocols/proxy/types.js +0 -6
- package/dist_ts/protocols/tls/alerts/index.d.ts +0 -4
- package/dist_ts/protocols/tls/alerts/index.js +0 -5
- package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +0 -150
- package/dist_ts/protocols/tls/alerts/tls-alert.js +0 -226
- package/dist_ts/protocols/tls/index.d.ts +0 -12
- package/dist_ts/protocols/tls/index.js +0 -27
- package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +0 -100
- package/dist_ts/protocols/tls/sni/client-hello-parser.js +0 -463
- package/dist_ts/protocols/tls/sni/index.d.ts +0 -5
- package/dist_ts/protocols/tls/sni/index.js +0 -6
- package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +0 -58
- package/dist_ts/protocols/tls/sni/sni-extraction.js +0 -275
- package/dist_ts/protocols/tls/utils/index.d.ts +0 -4
- package/dist_ts/protocols/tls/utils/index.js +0 -5
- package/dist_ts/protocols/tls/utils/tls-utils.d.ts +0 -158
- package/dist_ts/protocols/tls/utils/tls-utils.js +0 -187
- package/dist_ts/protocols/websocket/constants.d.ts +0 -55
- package/dist_ts/protocols/websocket/constants.js +0 -58
- package/dist_ts/protocols/websocket/index.d.ts +0 -7
- package/dist_ts/protocols/websocket/index.js +0 -8
- package/dist_ts/protocols/websocket/types.d.ts +0 -47
- package/dist_ts/protocols/websocket/types.js +0 -5
- package/dist_ts/protocols/websocket/utils.d.ts +0 -25
- package/dist_ts/protocols/websocket/utils.js +0 -103
- package/dist_ts/routing/router/http-router.d.ts +0 -89
- package/dist_ts/routing/router/http-router.js +0 -205
- package/dist_ts/routing/router/index.d.ts +0 -5
- package/dist_ts/routing/router/index.js +0 -6
- package/dist_ts/tls/index.d.ts +0 -16
- package/dist_ts/tls/index.js +0 -24
- package/dist_ts/tls/sni/index.d.ts +0 -4
- package/dist_ts/tls/sni/index.js +0 -5
- package/dist_ts/tls/sni/sni-handler.d.ts +0 -154
- package/dist_ts/tls/sni/sni-handler.js +0 -191
- package/ts/core/events/index.ts +0 -3
- package/ts/core/models/socket-augmentation.ts +0 -38
- package/ts/core/utils/async-utils.ts +0 -275
- package/ts/core/utils/binary-heap.ts +0 -225
- package/ts/core/utils/enhanced-connection-pool.ts +0 -425
- package/ts/core/utils/fs-utils.ts +0 -270
- package/ts/core/utils/ip-utils.ts +0 -303
- package/ts/core/utils/lifecycle-component.ts +0 -251
- package/ts/core/utils/log-deduplicator.ts +0 -370
- package/ts/core/utils/security-utils.ts +0 -305
- package/ts/core/utils/shared-security-manager.ts +0 -470
- package/ts/core/utils/socket-utils.ts +0 -322
- package/ts/core/utils/template-utils.ts +0 -124
- package/ts/core/utils/validation-utils.ts +0 -177
- package/ts/core/utils/websocket-utils.ts +0 -33
- package/ts/detection/detectors/http-detector.ts +0 -127
- package/ts/detection/detectors/quick-detector.ts +0 -148
- package/ts/detection/detectors/routing-extractor.ts +0 -147
- package/ts/detection/detectors/tls-detector.ts +0 -223
- package/ts/detection/index.ts +0 -25
- package/ts/detection/models/detection-types.ts +0 -102
- package/ts/detection/models/interfaces.ts +0 -115
- package/ts/detection/protocol-detector.ts +0 -319
- package/ts/detection/utils/buffer-utils.ts +0 -141
- package/ts/detection/utils/fragment-manager.ts +0 -64
- package/ts/detection/utils/parser-utils.ts +0 -77
- package/ts/protocols/common/fragment-handler.ts +0 -167
- package/ts/protocols/common/index.ts +0 -8
- package/ts/protocols/common/types.ts +0 -76
- package/ts/protocols/http/parser.ts +0 -219
- package/ts/protocols/proxy/index.ts +0 -6
- package/ts/protocols/proxy/types.ts +0 -53
- package/ts/protocols/tls/alerts/index.ts +0 -3
- package/ts/protocols/tls/alerts/tls-alert.ts +0 -259
- package/ts/protocols/tls/index.ts +0 -37
- package/ts/protocols/tls/sni/client-hello-parser.ts +0 -629
- package/ts/protocols/tls/sni/index.ts +0 -6
- package/ts/protocols/tls/sni/sni-extraction.ts +0 -353
- package/ts/protocols/tls/utils/index.ts +0 -3
- package/ts/protocols/tls/utils/tls-utils.ts +0 -201
- package/ts/protocols/websocket/constants.ts +0 -60
- package/ts/protocols/websocket/index.ts +0 -8
- package/ts/protocols/websocket/types.ts +0 -53
- package/ts/protocols/websocket/utils.ts +0 -98
- package/ts/routing/router/http-router.ts +0 -266
- package/ts/routing/router/index.ts +0 -7
- package/ts/tls/index.ts +0 -29
- package/ts/tls/sni/index.ts +0 -3
- package/ts/tls/sni/sni-handler.ts +0 -264
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../../plugins.js';
|
|
2
|
-
import { isIPAuthorized, checkMaxConnections, checkConnectionRate, trackConnection, removeConnection, cleanupExpiredRateLimits, parseBasicAuthHeader, normalizeIP } from './security-utils.js';
|
|
3
|
-
/**
|
|
4
|
-
* Shared SecurityManager for use across proxy components
|
|
5
|
-
* Handles IP tracking, rate limiting, and authentication
|
|
6
|
-
*/
|
|
7
|
-
export class SharedSecurityManager {
|
|
8
|
-
/**
|
|
9
|
-
* Create a new SharedSecurityManager
|
|
10
|
-
*
|
|
11
|
-
* @param options - Configuration options
|
|
12
|
-
* @param logger - Logger instance
|
|
13
|
-
*/
|
|
14
|
-
constructor(options, logger) {
|
|
15
|
-
this.logger = logger;
|
|
16
|
-
// IP connection tracking
|
|
17
|
-
this.connectionsByIP = new Map();
|
|
18
|
-
// Route-specific rate limiting
|
|
19
|
-
this.rateLimits = new Map();
|
|
20
|
-
// Cache IP filtering results to avoid constant regex matching
|
|
21
|
-
this.ipFilterCache = new Map();
|
|
22
|
-
// Cache cleanup interval
|
|
23
|
-
this.cleanupInterval = null;
|
|
24
|
-
this.maxConnectionsPerIP = options.maxConnectionsPerIP || 100;
|
|
25
|
-
this.connectionRateLimitPerMinute = options.connectionRateLimitPerMinute || 300;
|
|
26
|
-
// Set up logger with defaults if not provided
|
|
27
|
-
this.logger = logger || {
|
|
28
|
-
info: console.log,
|
|
29
|
-
warn: console.warn,
|
|
30
|
-
error: console.error
|
|
31
|
-
};
|
|
32
|
-
// Set up cache cleanup interval
|
|
33
|
-
const cleanupInterval = options.cleanupIntervalMs || 60000; // Default: 1 minute
|
|
34
|
-
this.cleanupInterval = setInterval(() => {
|
|
35
|
-
this.cleanupCaches();
|
|
36
|
-
}, cleanupInterval);
|
|
37
|
-
// Don't keep the process alive just for cleanup
|
|
38
|
-
if (this.cleanupInterval.unref) {
|
|
39
|
-
this.cleanupInterval.unref();
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Get connections count by IP
|
|
44
|
-
*
|
|
45
|
-
* @param ip - The IP address to check
|
|
46
|
-
* @returns Number of connections from this IP
|
|
47
|
-
*/
|
|
48
|
-
getConnectionCountByIP(ip) {
|
|
49
|
-
// Check all normalized variants of the IP
|
|
50
|
-
const variants = normalizeIP(ip);
|
|
51
|
-
for (const variant of variants) {
|
|
52
|
-
const info = this.connectionsByIP.get(variant);
|
|
53
|
-
if (info) {
|
|
54
|
-
return info.connections.size;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return 0;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Track connection by IP
|
|
61
|
-
*
|
|
62
|
-
* @param ip - The IP address to track
|
|
63
|
-
* @param connectionId - The connection ID to associate
|
|
64
|
-
*/
|
|
65
|
-
trackConnectionByIP(ip, connectionId) {
|
|
66
|
-
// Check if any variant already exists
|
|
67
|
-
const variants = normalizeIP(ip);
|
|
68
|
-
let existingKey = null;
|
|
69
|
-
for (const variant of variants) {
|
|
70
|
-
if (this.connectionsByIP.has(variant)) {
|
|
71
|
-
existingKey = variant;
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
// Use existing key or the original IP
|
|
76
|
-
trackConnection(existingKey || ip, connectionId, this.connectionsByIP);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Remove connection tracking for an IP
|
|
80
|
-
*
|
|
81
|
-
* @param ip - The IP address to update
|
|
82
|
-
* @param connectionId - The connection ID to remove
|
|
83
|
-
*/
|
|
84
|
-
removeConnectionByIP(ip, connectionId) {
|
|
85
|
-
// Check all variants to find where the connection is tracked
|
|
86
|
-
const variants = normalizeIP(ip);
|
|
87
|
-
for (const variant of variants) {
|
|
88
|
-
if (this.connectionsByIP.has(variant)) {
|
|
89
|
-
removeConnection(variant, connectionId, this.connectionsByIP);
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Check if IP is authorized based on route security settings
|
|
96
|
-
*
|
|
97
|
-
* @param ip - The IP address to check
|
|
98
|
-
* @param allowedIPs - List of allowed IP patterns
|
|
99
|
-
* @param blockedIPs - List of blocked IP patterns
|
|
100
|
-
* @returns Whether the IP is authorized
|
|
101
|
-
*/
|
|
102
|
-
isIPAuthorized(ip, allowedIPs = ['*'], blockedIPs = []) {
|
|
103
|
-
return isIPAuthorized(ip, allowedIPs, blockedIPs);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Validate IP against rate limits and connection limits
|
|
107
|
-
*
|
|
108
|
-
* @param ip - The IP address to validate
|
|
109
|
-
* @returns Result with allowed status and reason if blocked
|
|
110
|
-
*/
|
|
111
|
-
validateIP(ip) {
|
|
112
|
-
// Check connection count limit
|
|
113
|
-
const connectionResult = checkMaxConnections(ip, this.connectionsByIP, this.maxConnectionsPerIP);
|
|
114
|
-
if (!connectionResult.allowed) {
|
|
115
|
-
return connectionResult;
|
|
116
|
-
}
|
|
117
|
-
// Check connection rate limit
|
|
118
|
-
const rateResult = checkConnectionRate(ip, this.connectionsByIP, this.connectionRateLimitPerMinute);
|
|
119
|
-
if (!rateResult.allowed) {
|
|
120
|
-
return rateResult;
|
|
121
|
-
}
|
|
122
|
-
return { allowed: true };
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Atomically validate an IP and track the connection if allowed.
|
|
126
|
-
* This prevents race conditions where concurrent connections could bypass per-IP limits.
|
|
127
|
-
*
|
|
128
|
-
* @param ip - The IP address to validate
|
|
129
|
-
* @param connectionId - The connection ID to track if validation passes
|
|
130
|
-
* @returns Object with validation result and reason
|
|
131
|
-
*/
|
|
132
|
-
validateAndTrackIP(ip, connectionId) {
|
|
133
|
-
// Check connection count limit BEFORE tracking
|
|
134
|
-
const connectionResult = checkMaxConnections(ip, this.connectionsByIP, this.maxConnectionsPerIP);
|
|
135
|
-
if (!connectionResult.allowed) {
|
|
136
|
-
return connectionResult;
|
|
137
|
-
}
|
|
138
|
-
// Check connection rate limit
|
|
139
|
-
const rateResult = checkConnectionRate(ip, this.connectionsByIP, this.connectionRateLimitPerMinute);
|
|
140
|
-
if (!rateResult.allowed) {
|
|
141
|
-
return rateResult;
|
|
142
|
-
}
|
|
143
|
-
// Validation passed - immediately track to prevent race conditions
|
|
144
|
-
this.trackConnectionByIP(ip, connectionId);
|
|
145
|
-
return { allowed: true };
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Check if a client is allowed to access a specific route
|
|
149
|
-
*
|
|
150
|
-
* @param route - The route to check
|
|
151
|
-
* @param context - The request context
|
|
152
|
-
* @param routeConnectionCount - Current connection count for this route (optional)
|
|
153
|
-
* @returns Whether access is allowed
|
|
154
|
-
*/
|
|
155
|
-
isAllowed(route, context, routeConnectionCount) {
|
|
156
|
-
if (!route.security) {
|
|
157
|
-
return true; // No security restrictions
|
|
158
|
-
}
|
|
159
|
-
// --- IP filtering ---
|
|
160
|
-
if (!this.isClientIpAllowed(route, context.clientIp)) {
|
|
161
|
-
this.logger?.debug?.(`IP ${context.clientIp} is blocked for route ${route.name || 'unnamed'}`);
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
// --- Route-level connection limit ---
|
|
165
|
-
if (route.security.maxConnections !== undefined && routeConnectionCount !== undefined) {
|
|
166
|
-
if (routeConnectionCount >= route.security.maxConnections) {
|
|
167
|
-
this.logger?.debug?.(`Route connection limit (${route.security.maxConnections}) exceeded for route ${route.name || 'unnamed'}`);
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// --- Rate limiting ---
|
|
172
|
-
if (route.security.rateLimit?.enabled && !this.isWithinRateLimit(route, context)) {
|
|
173
|
-
this.logger?.debug?.(`Rate limit exceeded for route ${route.name || 'unnamed'}`);
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Check if a client IP is allowed for a route
|
|
180
|
-
*
|
|
181
|
-
* @param route - The route to check
|
|
182
|
-
* @param clientIp - The client IP
|
|
183
|
-
* @returns Whether the IP is allowed
|
|
184
|
-
*/
|
|
185
|
-
isClientIpAllowed(route, clientIp) {
|
|
186
|
-
if (!route.security) {
|
|
187
|
-
return true; // No security restrictions
|
|
188
|
-
}
|
|
189
|
-
const routeId = route.id || route.name || 'unnamed';
|
|
190
|
-
// Check cache first
|
|
191
|
-
if (!this.ipFilterCache.has(routeId)) {
|
|
192
|
-
this.ipFilterCache.set(routeId, new Map());
|
|
193
|
-
}
|
|
194
|
-
const routeCache = this.ipFilterCache.get(routeId);
|
|
195
|
-
if (routeCache.has(clientIp)) {
|
|
196
|
-
return routeCache.get(clientIp);
|
|
197
|
-
}
|
|
198
|
-
// Check IP against route security settings
|
|
199
|
-
const ipAllowList = route.security.ipAllowList;
|
|
200
|
-
const ipBlockList = route.security.ipBlockList;
|
|
201
|
-
const allowed = this.isIPAuthorized(clientIp, ipAllowList, ipBlockList);
|
|
202
|
-
// Cache the result
|
|
203
|
-
routeCache.set(clientIp, allowed);
|
|
204
|
-
return allowed;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Check if request is within rate limit
|
|
208
|
-
*
|
|
209
|
-
* @param route - The route to check
|
|
210
|
-
* @param context - The request context
|
|
211
|
-
* @returns Whether the request is within rate limit
|
|
212
|
-
*/
|
|
213
|
-
isWithinRateLimit(route, context) {
|
|
214
|
-
if (!route.security?.rateLimit?.enabled) {
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
const rateLimit = route.security.rateLimit;
|
|
218
|
-
const routeId = route.id || route.name || 'unnamed';
|
|
219
|
-
// Determine rate limit key (by IP, path, or header)
|
|
220
|
-
let key = context.clientIp; // Default to IP
|
|
221
|
-
if (rateLimit.keyBy === 'path' && context.path) {
|
|
222
|
-
key = `${context.clientIp}:${context.path}`;
|
|
223
|
-
}
|
|
224
|
-
else if (rateLimit.keyBy === 'header' && rateLimit.headerName && context.headers) {
|
|
225
|
-
const headerValue = context.headers[rateLimit.headerName.toLowerCase()];
|
|
226
|
-
if (headerValue) {
|
|
227
|
-
key = `${context.clientIp}:${headerValue}`;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
// Get or create rate limit tracking for this route
|
|
231
|
-
if (!this.rateLimits.has(routeId)) {
|
|
232
|
-
this.rateLimits.set(routeId, new Map());
|
|
233
|
-
}
|
|
234
|
-
const routeLimits = this.rateLimits.get(routeId);
|
|
235
|
-
const now = Date.now();
|
|
236
|
-
// Get or create rate limit tracking for this key
|
|
237
|
-
let limit = routeLimits.get(key);
|
|
238
|
-
if (!limit || limit.expiry < now) {
|
|
239
|
-
// Create new rate limit or reset expired one
|
|
240
|
-
limit = {
|
|
241
|
-
count: 1,
|
|
242
|
-
expiry: now + (rateLimit.window * 1000)
|
|
243
|
-
};
|
|
244
|
-
routeLimits.set(key, limit);
|
|
245
|
-
return true;
|
|
246
|
-
}
|
|
247
|
-
// Increment the counter
|
|
248
|
-
limit.count++;
|
|
249
|
-
// Check if rate limit is exceeded
|
|
250
|
-
return limit.count <= rateLimit.maxRequests;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Validate HTTP Basic Authentication
|
|
254
|
-
*
|
|
255
|
-
* @param route - The route to check
|
|
256
|
-
* @param authHeader - The Authorization header
|
|
257
|
-
* @returns Whether authentication is valid
|
|
258
|
-
*/
|
|
259
|
-
validateBasicAuth(route, authHeader) {
|
|
260
|
-
// Skip if basic auth not enabled for route
|
|
261
|
-
if (!route.security?.basicAuth?.enabled) {
|
|
262
|
-
return true;
|
|
263
|
-
}
|
|
264
|
-
// No auth header means auth failed
|
|
265
|
-
if (!authHeader) {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
// Parse auth header
|
|
269
|
-
const credentials = parseBasicAuthHeader(authHeader);
|
|
270
|
-
if (!credentials) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
// Check credentials against configured users
|
|
274
|
-
const { username, password } = credentials;
|
|
275
|
-
const users = route.security.basicAuth.users;
|
|
276
|
-
return users.some(user => user.username === username && user.password === password);
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Verify a JWT token against route configuration
|
|
280
|
-
*
|
|
281
|
-
* @param route - The route to verify the token for
|
|
282
|
-
* @param token - The JWT token to verify
|
|
283
|
-
* @returns True if the token is valid, false otherwise
|
|
284
|
-
*/
|
|
285
|
-
verifyJwtToken(route, token) {
|
|
286
|
-
if (!route.security?.jwtAuth?.enabled) {
|
|
287
|
-
return true;
|
|
288
|
-
}
|
|
289
|
-
try {
|
|
290
|
-
const jwtAuth = route.security.jwtAuth;
|
|
291
|
-
// Verify structure (header.payload.signature)
|
|
292
|
-
const parts = token.split('.');
|
|
293
|
-
if (parts.length !== 3) {
|
|
294
|
-
return false;
|
|
295
|
-
}
|
|
296
|
-
// Decode payload
|
|
297
|
-
const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString());
|
|
298
|
-
// Check expiration
|
|
299
|
-
if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {
|
|
300
|
-
return false;
|
|
301
|
-
}
|
|
302
|
-
// Check issuer
|
|
303
|
-
if (jwtAuth.issuer && payload.iss !== jwtAuth.issuer) {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
// Check audience
|
|
307
|
-
if (jwtAuth.audience && payload.aud !== jwtAuth.audience) {
|
|
308
|
-
return false;
|
|
309
|
-
}
|
|
310
|
-
// Note: In a real implementation, you'd also verify the signature
|
|
311
|
-
// using the secret and algorithm specified in jwtAuth.
|
|
312
|
-
// This requires a proper JWT library for cryptographic verification.
|
|
313
|
-
return true;
|
|
314
|
-
}
|
|
315
|
-
catch (err) {
|
|
316
|
-
this.logger?.error?.(`Error verifying JWT: ${err}`);
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Clean up caches to prevent memory leaks
|
|
322
|
-
*/
|
|
323
|
-
cleanupCaches() {
|
|
324
|
-
// Clean up rate limits
|
|
325
|
-
cleanupExpiredRateLimits(this.rateLimits, this.logger);
|
|
326
|
-
// Clean up IP connection tracking
|
|
327
|
-
let cleanedIPs = 0;
|
|
328
|
-
for (const [ip, info] of this.connectionsByIP.entries()) {
|
|
329
|
-
// Remove IPs with no active connections and no recent timestamps
|
|
330
|
-
if (info.connections.size === 0 && info.timestamps.length === 0) {
|
|
331
|
-
this.connectionsByIP.delete(ip);
|
|
332
|
-
cleanedIPs++;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
if (cleanedIPs > 0 && this.logger?.debug) {
|
|
336
|
-
this.logger.debug(`Cleaned up ${cleanedIPs} IPs with no active connections`);
|
|
337
|
-
}
|
|
338
|
-
// IP filter cache doesn't need cleanup (tied to routes)
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Clear all IP tracking data (for shutdown)
|
|
342
|
-
*/
|
|
343
|
-
clearIPTracking() {
|
|
344
|
-
this.connectionsByIP.clear();
|
|
345
|
-
this.rateLimits.clear();
|
|
346
|
-
this.ipFilterCache.clear();
|
|
347
|
-
if (this.cleanupInterval) {
|
|
348
|
-
clearInterval(this.cleanupInterval);
|
|
349
|
-
this.cleanupInterval = null;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Update routes for security checking
|
|
354
|
-
*
|
|
355
|
-
* @param routes - New routes to use
|
|
356
|
-
*/
|
|
357
|
-
setRoutes(routes) {
|
|
358
|
-
// Only clear the IP filter cache - route-specific
|
|
359
|
-
this.ipFilterCache.clear();
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLXNlY3VyaXR5LW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb3JlL3V0aWxzL3NoYXJlZC1zZWN1cml0eS1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFRNUMsT0FBTyxFQUNMLGNBQWMsRUFDZCxtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLG9CQUFvQixFQUNwQixXQUFXLEVBQ1osTUFBTSxxQkFBcUIsQ0FBQztBQUU3Qjs7O0dBR0c7QUFDSCxNQUFNLE9BQU8scUJBQXFCO0lBaUJoQzs7Ozs7T0FLRztJQUNILFlBQVksT0FLWCxFQUFVLE1BQXdCO1FBQXhCLFdBQU0sR0FBTixNQUFNLENBQWtCO1FBM0JuQyx5QkFBeUI7UUFDakIsb0JBQWUsR0FBbUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUVwRSwrQkFBK0I7UUFDdkIsZUFBVSxHQUE2QyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRXpFLDhEQUE4RDtRQUN0RCxrQkFBYSxHQUFzQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBTXJFLHlCQUF5QjtRQUNqQixvQkFBZSxHQUEwQixJQUFJLENBQUM7UUFjcEQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsSUFBSSxHQUFHLENBQUM7UUFDOUQsSUFBSSxDQUFDLDRCQUE0QixHQUFHLE9BQU8sQ0FBQyw0QkFBNEIsSUFBSSxHQUFHLENBQUM7UUFFaEYsOENBQThDO1FBQzlDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxJQUFJO1lBQ3RCLElBQUksRUFBRSxPQUFPLENBQUMsR0FBRztZQUNqQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1NBQ3JCLENBQUM7UUFFRixnQ0FBZ0M7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
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../../plugins.js';
|
|
2
|
-
export interface CleanupOptions {
|
|
3
|
-
immediate?: boolean;
|
|
4
|
-
allowDrain?: boolean;
|
|
5
|
-
gracePeriod?: number;
|
|
6
|
-
}
|
|
7
|
-
export interface SafeSocketOptions {
|
|
8
|
-
port: number;
|
|
9
|
-
host: string;
|
|
10
|
-
onError?: (error: Error) => void;
|
|
11
|
-
onConnect?: () => void;
|
|
12
|
-
timeout?: number;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Safely cleanup a socket by removing all listeners and destroying it
|
|
16
|
-
* @param socket The socket to cleanup
|
|
17
|
-
* @param socketName Optional name for logging
|
|
18
|
-
* @param options Cleanup options
|
|
19
|
-
*/
|
|
20
|
-
export declare function cleanupSocket(socket: plugins.net.Socket | plugins.tls.TLSSocket | null, socketName?: string, options?: CleanupOptions): Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Create independent cleanup handlers for paired sockets that support half-open connections
|
|
23
|
-
* @param clientSocket The client socket
|
|
24
|
-
* @param serverSocket The server socket
|
|
25
|
-
* @param onBothClosed Callback when both sockets are closed
|
|
26
|
-
* @returns Independent cleanup functions for each socket
|
|
27
|
-
*/
|
|
28
|
-
export declare function createIndependentSocketHandlers(clientSocket: plugins.net.Socket | plugins.tls.TLSSocket, serverSocket: plugins.net.Socket | plugins.tls.TLSSocket, onBothClosed: (reason: string) => void, options?: {
|
|
29
|
-
enableHalfOpen?: boolean;
|
|
30
|
-
}): {
|
|
31
|
-
cleanupClient: (reason: string) => Promise<void>;
|
|
32
|
-
cleanupServer: (reason: string) => Promise<void>;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Setup socket error and close handlers with proper cleanup
|
|
36
|
-
* @param socket The socket to setup handlers for
|
|
37
|
-
* @param handleClose The cleanup function to call
|
|
38
|
-
* @param handleTimeout Optional custom timeout handler
|
|
39
|
-
* @param errorPrefix Optional prefix for error messages
|
|
40
|
-
*/
|
|
41
|
-
export declare function setupSocketHandlers(socket: plugins.net.Socket | plugins.tls.TLSSocket, handleClose: (reason: string) => void, handleTimeout?: (socket: plugins.net.Socket | plugins.tls.TLSSocket) => void, errorPrefix?: string): void;
|
|
42
|
-
/**
|
|
43
|
-
* Setup bidirectional data forwarding between two sockets with proper cleanup
|
|
44
|
-
* @param clientSocket The client/incoming socket
|
|
45
|
-
* @param serverSocket The server/outgoing socket
|
|
46
|
-
* @param handlers Object containing optional handlers for data and cleanup
|
|
47
|
-
* @returns Cleanup functions for both sockets
|
|
48
|
-
*/
|
|
49
|
-
export declare function setupBidirectionalForwarding(clientSocket: plugins.net.Socket | plugins.tls.TLSSocket, serverSocket: plugins.net.Socket | plugins.tls.TLSSocket, handlers: {
|
|
50
|
-
onClientData?: (chunk: Buffer) => void;
|
|
51
|
-
onServerData?: (chunk: Buffer) => void;
|
|
52
|
-
onCleanup: (reason: string) => void;
|
|
53
|
-
enableHalfOpen?: boolean;
|
|
54
|
-
}): {
|
|
55
|
-
cleanupClient: (reason: string) => Promise<void>;
|
|
56
|
-
cleanupServer: (reason: string) => Promise<void>;
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Create a socket with immediate error handling to prevent crashes
|
|
60
|
-
* @param options Socket creation options
|
|
61
|
-
* @returns The created socket
|
|
62
|
-
*/
|
|
63
|
-
export declare function createSocketWithErrorHandler(options: SafeSocketOptions): plugins.net.Socket;
|