@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,303 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../../plugins.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Utility class for IP address operations
|
|
5
|
-
*/
|
|
6
|
-
export class IpUtils {
|
|
7
|
-
/**
|
|
8
|
-
* Check if the IP matches any of the glob patterns
|
|
9
|
-
*
|
|
10
|
-
* This method checks IP addresses against glob patterns and handles IPv4/IPv6 normalization.
|
|
11
|
-
* It's used to implement IP filtering based on security configurations.
|
|
12
|
-
*
|
|
13
|
-
* @param ip - The IP address to check
|
|
14
|
-
* @param patterns - Array of glob patterns
|
|
15
|
-
* @returns true if IP matches any pattern, false otherwise
|
|
16
|
-
*/
|
|
17
|
-
public static isGlobIPMatch(ip: string, patterns: string[]): boolean {
|
|
18
|
-
if (!ip || !patterns || patterns.length === 0) return false;
|
|
19
|
-
|
|
20
|
-
// Normalize the IP being checked
|
|
21
|
-
const normalizedIPVariants = this.normalizeIP(ip);
|
|
22
|
-
if (normalizedIPVariants.length === 0) return false;
|
|
23
|
-
|
|
24
|
-
// Check each pattern
|
|
25
|
-
for (const pattern of patterns) {
|
|
26
|
-
// Handle CIDR notation
|
|
27
|
-
if (pattern.includes('/')) {
|
|
28
|
-
if (this.matchCIDR(ip, pattern)) {
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Handle range notation
|
|
35
|
-
if (pattern.includes('-') && !pattern.includes('*')) {
|
|
36
|
-
if (this.matchIPRange(ip, pattern)) {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Expand shorthand patterns for glob matching
|
|
43
|
-
let expandedPattern = pattern;
|
|
44
|
-
if (pattern.includes('*') && !pattern.includes(':')) {
|
|
45
|
-
const parts = pattern.split('.');
|
|
46
|
-
while (parts.length < 4) {
|
|
47
|
-
parts.push('*');
|
|
48
|
-
}
|
|
49
|
-
expandedPattern = parts.join('.');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Normalize and check with minimatch
|
|
53
|
-
const normalizedPatterns = this.normalizeIP(expandedPattern);
|
|
54
|
-
|
|
55
|
-
for (const ipVariant of normalizedIPVariants) {
|
|
56
|
-
for (const normalizedPattern of normalizedPatterns) {
|
|
57
|
-
if (plugins.minimatch(ipVariant, normalizedPattern)) {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Normalize IP addresses for consistent comparison
|
|
69
|
-
*
|
|
70
|
-
* @param ip The IP address to normalize
|
|
71
|
-
* @returns Array of normalized IP forms
|
|
72
|
-
*/
|
|
73
|
-
public static normalizeIP(ip: string): string[] {
|
|
74
|
-
if (!ip) return [];
|
|
75
|
-
|
|
76
|
-
// Handle IPv4-mapped IPv6 addresses (::ffff:127.0.0.1)
|
|
77
|
-
if (ip.startsWith('::ffff:')) {
|
|
78
|
-
const ipv4 = ip.slice(7);
|
|
79
|
-
return [ip, ipv4];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Handle IPv4 addresses by also checking IPv4-mapped form
|
|
83
|
-
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(ip)) {
|
|
84
|
-
return [ip, `::ffff:${ip}`];
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return [ip];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Check if an IP is authorized using security rules
|
|
92
|
-
*
|
|
93
|
-
* @param ip - The IP address to check
|
|
94
|
-
* @param allowedIPs - Array of allowed IP patterns
|
|
95
|
-
* @param blockedIPs - Array of blocked IP patterns
|
|
96
|
-
* @returns true if IP is authorized, false if blocked
|
|
97
|
-
*/
|
|
98
|
-
public static isIPAuthorized(ip: string, allowedIPs: string[] = [], blockedIPs: string[] = []): boolean {
|
|
99
|
-
// Skip IP validation if no rules are defined
|
|
100
|
-
if (!ip || (allowedIPs.length === 0 && blockedIPs.length === 0)) {
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// First check if IP is blocked - blocked IPs take precedence
|
|
105
|
-
if (blockedIPs.length > 0 && this.isGlobIPMatch(ip, blockedIPs)) {
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Then check if IP is allowed (if no allowed IPs are specified, all non-blocked IPs are allowed)
|
|
110
|
-
return allowedIPs.length === 0 || this.isGlobIPMatch(ip, allowedIPs);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Check if an IP address is a private network address
|
|
115
|
-
*
|
|
116
|
-
* @param ip The IP address to check
|
|
117
|
-
* @returns true if the IP is a private network address, false otherwise
|
|
118
|
-
*/
|
|
119
|
-
public static isPrivateIP(ip: string): boolean {
|
|
120
|
-
if (!ip) return false;
|
|
121
|
-
|
|
122
|
-
// Handle IPv4-mapped IPv6 addresses
|
|
123
|
-
if (ip.startsWith('::ffff:')) {
|
|
124
|
-
ip = ip.slice(7);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Check IPv4 private ranges
|
|
128
|
-
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(ip)) {
|
|
129
|
-
const parts = ip.split('.').map(Number);
|
|
130
|
-
|
|
131
|
-
// Check common private ranges
|
|
132
|
-
// 10.0.0.0/8
|
|
133
|
-
if (parts[0] === 10) return true;
|
|
134
|
-
|
|
135
|
-
// 172.16.0.0/12
|
|
136
|
-
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true;
|
|
137
|
-
|
|
138
|
-
// 192.168.0.0/16
|
|
139
|
-
if (parts[0] === 192 && parts[1] === 168) return true;
|
|
140
|
-
|
|
141
|
-
// 127.0.0.0/8 (localhost)
|
|
142
|
-
if (parts[0] === 127) return true;
|
|
143
|
-
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// IPv6 local addresses
|
|
148
|
-
return ip === '::1' || ip.startsWith('fc00:') || ip.startsWith('fd00:') || ip.startsWith('fe80:');
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Check if an IP address is a public network address
|
|
153
|
-
*
|
|
154
|
-
* @param ip The IP address to check
|
|
155
|
-
* @returns true if the IP is a public network address, false otherwise
|
|
156
|
-
*/
|
|
157
|
-
public static isPublicIP(ip: string): boolean {
|
|
158
|
-
return !this.isPrivateIP(ip);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Check if an IP matches a CIDR notation
|
|
163
|
-
*
|
|
164
|
-
* @param ip The IP address to check
|
|
165
|
-
* @param cidr The CIDR notation (e.g., "192.168.1.0/24")
|
|
166
|
-
* @returns true if IP is within the CIDR range
|
|
167
|
-
*/
|
|
168
|
-
private static matchCIDR(ip: string, cidr: string): boolean {
|
|
169
|
-
if (!cidr.includes('/')) return false;
|
|
170
|
-
|
|
171
|
-
const [networkAddr, prefixStr] = cidr.split('/');
|
|
172
|
-
const prefix = parseInt(prefixStr, 10);
|
|
173
|
-
|
|
174
|
-
// Handle IPv4-mapped IPv6 in the IP being checked
|
|
175
|
-
let checkIP = ip;
|
|
176
|
-
if (checkIP.startsWith('::ffff:')) {
|
|
177
|
-
checkIP = checkIP.slice(7);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Handle IPv6 CIDR
|
|
181
|
-
if (networkAddr.includes(':')) {
|
|
182
|
-
// TODO: Implement IPv6 CIDR matching
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// IPv4 CIDR matching
|
|
187
|
-
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(checkIP)) return false;
|
|
188
|
-
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(networkAddr)) return false;
|
|
189
|
-
if (isNaN(prefix) || prefix < 0 || prefix > 32) return false;
|
|
190
|
-
|
|
191
|
-
const ipParts = checkIP.split('.').map(Number);
|
|
192
|
-
const netParts = networkAddr.split('.').map(Number);
|
|
193
|
-
|
|
194
|
-
// Validate IP parts
|
|
195
|
-
for (const part of [...ipParts, ...netParts]) {
|
|
196
|
-
if (part < 0 || part > 255) return false;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Convert to 32-bit integers
|
|
200
|
-
const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
|
|
201
|
-
const netNum = (netParts[0] << 24) | (netParts[1] << 16) | (netParts[2] << 8) | netParts[3];
|
|
202
|
-
|
|
203
|
-
// Create mask
|
|
204
|
-
const mask = (-1 << (32 - prefix)) >>> 0;
|
|
205
|
-
|
|
206
|
-
// Check if IP is in network range
|
|
207
|
-
return (ipNum & mask) === (netNum & mask);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Check if an IP matches a range notation
|
|
212
|
-
*
|
|
213
|
-
* @param ip The IP address to check
|
|
214
|
-
* @param range The range notation (e.g., "192.168.1.1-192.168.1.100")
|
|
215
|
-
* @returns true if IP is within the range
|
|
216
|
-
*/
|
|
217
|
-
private static matchIPRange(ip: string, range: string): boolean {
|
|
218
|
-
if (!range.includes('-')) return false;
|
|
219
|
-
|
|
220
|
-
const [startIP, endIP] = range.split('-').map(s => s.trim());
|
|
221
|
-
|
|
222
|
-
// Handle IPv4-mapped IPv6 in the IP being checked
|
|
223
|
-
let checkIP = ip;
|
|
224
|
-
if (checkIP.startsWith('::ffff:')) {
|
|
225
|
-
checkIP = checkIP.slice(7);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Only handle IPv4 for now
|
|
229
|
-
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(checkIP)) return false;
|
|
230
|
-
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(startIP)) return false;
|
|
231
|
-
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(endIP)) return false;
|
|
232
|
-
|
|
233
|
-
const ipParts = checkIP.split('.').map(Number);
|
|
234
|
-
const startParts = startIP.split('.').map(Number);
|
|
235
|
-
const endParts = endIP.split('.').map(Number);
|
|
236
|
-
|
|
237
|
-
// Validate parts
|
|
238
|
-
for (const part of [...ipParts, ...startParts, ...endParts]) {
|
|
239
|
-
if (part < 0 || part > 255) return false;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Convert to 32-bit integers for comparison
|
|
243
|
-
const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
|
|
244
|
-
const startNum = (startParts[0] << 24) | (startParts[1] << 16) | (startParts[2] << 8) | startParts[3];
|
|
245
|
-
const endNum = (endParts[0] << 24) | (endParts[1] << 16) | (endParts[2] << 8) | endParts[3];
|
|
246
|
-
|
|
247
|
-
// Convert to unsigned for proper comparison
|
|
248
|
-
const ipUnsigned = ipNum >>> 0;
|
|
249
|
-
const startUnsigned = startNum >>> 0;
|
|
250
|
-
const endUnsigned = endNum >>> 0;
|
|
251
|
-
|
|
252
|
-
return ipUnsigned >= startUnsigned && ipUnsigned <= endUnsigned;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Convert a subnet CIDR to an IP range for filtering
|
|
257
|
-
*
|
|
258
|
-
* @param cidr The CIDR notation (e.g., "192.168.1.0/24")
|
|
259
|
-
* @returns Array of glob patterns that match the CIDR range
|
|
260
|
-
*/
|
|
261
|
-
public static cidrToGlobPatterns(cidr: string): string[] {
|
|
262
|
-
if (!cidr || !cidr.includes('/')) return [];
|
|
263
|
-
|
|
264
|
-
const [ipPart, prefixPart] = cidr.split('/');
|
|
265
|
-
const prefix = parseInt(prefixPart, 10);
|
|
266
|
-
|
|
267
|
-
if (isNaN(prefix) || prefix < 0 || prefix > 32) return [];
|
|
268
|
-
|
|
269
|
-
// For IPv4 only for now
|
|
270
|
-
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(ipPart)) return [];
|
|
271
|
-
|
|
272
|
-
const ipParts = ipPart.split('.').map(Number);
|
|
273
|
-
const fullMask = Math.pow(2, 32 - prefix) - 1;
|
|
274
|
-
|
|
275
|
-
// Convert IP to a numeric value
|
|
276
|
-
const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
|
|
277
|
-
|
|
278
|
-
// Calculate network address (IP & ~fullMask)
|
|
279
|
-
const networkNum = ipNum & ~fullMask;
|
|
280
|
-
|
|
281
|
-
// For large ranges, return wildcard patterns
|
|
282
|
-
if (prefix <= 8) {
|
|
283
|
-
return [`${(networkNum >>> 24) & 255}.*.*.*`];
|
|
284
|
-
} else if (prefix <= 16) {
|
|
285
|
-
return [`${(networkNum >>> 24) & 255}.${(networkNum >>> 16) & 255}.*.*`];
|
|
286
|
-
} else if (prefix <= 24) {
|
|
287
|
-
return [`${(networkNum >>> 24) & 255}.${(networkNum >>> 16) & 255}.${(networkNum >>> 8) & 255}.*`];
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// For small ranges, create individual IP patterns
|
|
291
|
-
const patterns = [];
|
|
292
|
-
const maxAddresses = Math.min(256, Math.pow(2, 32 - prefix));
|
|
293
|
-
|
|
294
|
-
for (let i = 0; i < maxAddresses; i++) {
|
|
295
|
-
const currentIpNum = networkNum + i;
|
|
296
|
-
patterns.push(
|
|
297
|
-
`${(currentIpNum >>> 24) & 255}.${(currentIpNum >>> 16) & 255}.${(currentIpNum >>> 8) & 255}.${currentIpNum & 255}`
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
return patterns;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base class for components that need proper resource lifecycle management
|
|
3
|
-
* Provides automatic cleanup of timers and event listeners to prevent memory leaks
|
|
4
|
-
*/
|
|
5
|
-
export abstract class LifecycleComponent {
|
|
6
|
-
private timers: Set<NodeJS.Timeout> = new Set();
|
|
7
|
-
private intervals: Set<NodeJS.Timeout> = new Set();
|
|
8
|
-
private listeners: Array<{
|
|
9
|
-
target: any;
|
|
10
|
-
event: string;
|
|
11
|
-
handler: Function;
|
|
12
|
-
actualHandler?: Function; // The actual handler registered (may be wrapped)
|
|
13
|
-
once?: boolean;
|
|
14
|
-
}> = [];
|
|
15
|
-
private childComponents: Set<LifecycleComponent> = new Set();
|
|
16
|
-
protected isShuttingDown = false;
|
|
17
|
-
private cleanupPromise?: Promise<void>;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Create a managed setTimeout that will be automatically cleaned up
|
|
21
|
-
*/
|
|
22
|
-
protected setTimeout(handler: Function, timeout: number): NodeJS.Timeout {
|
|
23
|
-
if (this.isShuttingDown) {
|
|
24
|
-
// Return a dummy timer if shutting down
|
|
25
|
-
const dummyTimer = setTimeout(() => {}, 0);
|
|
26
|
-
if (typeof dummyTimer.unref === 'function') {
|
|
27
|
-
dummyTimer.unref();
|
|
28
|
-
}
|
|
29
|
-
return dummyTimer;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const wrappedHandler = () => {
|
|
33
|
-
this.timers.delete(timer);
|
|
34
|
-
if (!this.isShuttingDown) {
|
|
35
|
-
handler();
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const timer = setTimeout(wrappedHandler, timeout);
|
|
40
|
-
this.timers.add(timer);
|
|
41
|
-
|
|
42
|
-
// Allow process to exit even with timer
|
|
43
|
-
if (typeof timer.unref === 'function') {
|
|
44
|
-
timer.unref();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return timer;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Create a managed setInterval that will be automatically cleaned up
|
|
52
|
-
*/
|
|
53
|
-
protected setInterval(handler: Function, interval: number): NodeJS.Timeout {
|
|
54
|
-
if (this.isShuttingDown) {
|
|
55
|
-
// Return a dummy timer if shutting down
|
|
56
|
-
const dummyTimer = setInterval(() => {}, interval);
|
|
57
|
-
if (typeof dummyTimer.unref === 'function') {
|
|
58
|
-
dummyTimer.unref();
|
|
59
|
-
}
|
|
60
|
-
clearInterval(dummyTimer); // Clear immediately since we don't need it
|
|
61
|
-
return dummyTimer;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const wrappedHandler = () => {
|
|
65
|
-
if (!this.isShuttingDown) {
|
|
66
|
-
handler();
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const timer = setInterval(wrappedHandler, interval);
|
|
71
|
-
this.intervals.add(timer);
|
|
72
|
-
|
|
73
|
-
// Allow process to exit even with timer
|
|
74
|
-
if (typeof timer.unref === 'function') {
|
|
75
|
-
timer.unref();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return timer;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Clear a managed timeout
|
|
83
|
-
*/
|
|
84
|
-
protected clearTimeout(timer: NodeJS.Timeout): void {
|
|
85
|
-
clearTimeout(timer);
|
|
86
|
-
this.timers.delete(timer);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Clear a managed interval
|
|
91
|
-
*/
|
|
92
|
-
protected clearInterval(timer: NodeJS.Timeout): void {
|
|
93
|
-
clearInterval(timer);
|
|
94
|
-
this.intervals.delete(timer);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Add a managed event listener that will be automatically removed on cleanup
|
|
99
|
-
*/
|
|
100
|
-
protected addEventListener(
|
|
101
|
-
target: any,
|
|
102
|
-
event: string,
|
|
103
|
-
handler: Function,
|
|
104
|
-
options?: { once?: boolean }
|
|
105
|
-
): void {
|
|
106
|
-
if (this.isShuttingDown) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// For 'once' listeners, we need to wrap the handler to remove it from our tracking
|
|
111
|
-
let actualHandler = handler;
|
|
112
|
-
if (options?.once) {
|
|
113
|
-
actualHandler = (...args: any[]) => {
|
|
114
|
-
// Call the original handler
|
|
115
|
-
handler(...args);
|
|
116
|
-
|
|
117
|
-
// Remove from our internal tracking
|
|
118
|
-
const index = this.listeners.findIndex(
|
|
119
|
-
l => l.target === target && l.event === event && l.handler === handler
|
|
120
|
-
);
|
|
121
|
-
if (index !== -1) {
|
|
122
|
-
this.listeners.splice(index, 1);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Support both EventEmitter and DOM-style event targets
|
|
128
|
-
if (typeof target.on === 'function') {
|
|
129
|
-
if (options?.once) {
|
|
130
|
-
target.once(event, actualHandler);
|
|
131
|
-
} else {
|
|
132
|
-
target.on(event, actualHandler);
|
|
133
|
-
}
|
|
134
|
-
} else if (typeof target.addEventListener === 'function') {
|
|
135
|
-
target.addEventListener(event, actualHandler, options);
|
|
136
|
-
} else {
|
|
137
|
-
throw new Error('Target must support on() or addEventListener()');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Store both the original handler and the actual handler registered
|
|
141
|
-
this.listeners.push({
|
|
142
|
-
target,
|
|
143
|
-
event,
|
|
144
|
-
handler,
|
|
145
|
-
actualHandler, // The handler that was actually registered (may be wrapped)
|
|
146
|
-
once: options?.once
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Remove a specific event listener
|
|
152
|
-
*/
|
|
153
|
-
protected removeEventListener(target: any, event: string, handler: Function): void {
|
|
154
|
-
// Remove from target
|
|
155
|
-
if (typeof target.removeListener === 'function') {
|
|
156
|
-
target.removeListener(event, handler);
|
|
157
|
-
} else if (typeof target.removeEventListener === 'function') {
|
|
158
|
-
target.removeEventListener(event, handler);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Remove from our tracking
|
|
162
|
-
const index = this.listeners.findIndex(
|
|
163
|
-
l => l.target === target && l.event === event && l.handler === handler
|
|
164
|
-
);
|
|
165
|
-
if (index !== -1) {
|
|
166
|
-
this.listeners.splice(index, 1);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Register a child component that should be cleaned up when this component is cleaned up
|
|
172
|
-
*/
|
|
173
|
-
protected registerChildComponent(component: LifecycleComponent): void {
|
|
174
|
-
this.childComponents.add(component);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Unregister a child component
|
|
179
|
-
*/
|
|
180
|
-
protected unregisterChildComponent(component: LifecycleComponent): void {
|
|
181
|
-
this.childComponents.delete(component);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Override this method to implement component-specific cleanup logic
|
|
186
|
-
*/
|
|
187
|
-
protected async onCleanup(): Promise<void> {
|
|
188
|
-
// Override in subclasses
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Clean up all managed resources
|
|
193
|
-
*/
|
|
194
|
-
public async cleanup(): Promise<void> {
|
|
195
|
-
// Return existing cleanup promise if already cleaning up
|
|
196
|
-
if (this.cleanupPromise) {
|
|
197
|
-
return this.cleanupPromise;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
this.cleanupPromise = this.performCleanup();
|
|
201
|
-
return this.cleanupPromise;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
private async performCleanup(): Promise<void> {
|
|
205
|
-
this.isShuttingDown = true;
|
|
206
|
-
|
|
207
|
-
// First, clean up child components
|
|
208
|
-
const childCleanupPromises: Promise<void>[] = [];
|
|
209
|
-
for (const child of this.childComponents) {
|
|
210
|
-
childCleanupPromises.push(child.cleanup());
|
|
211
|
-
}
|
|
212
|
-
await Promise.all(childCleanupPromises);
|
|
213
|
-
this.childComponents.clear();
|
|
214
|
-
|
|
215
|
-
// Clear all timers
|
|
216
|
-
for (const timer of this.timers) {
|
|
217
|
-
clearTimeout(timer);
|
|
218
|
-
}
|
|
219
|
-
this.timers.clear();
|
|
220
|
-
|
|
221
|
-
// Clear all intervals
|
|
222
|
-
for (const timer of this.intervals) {
|
|
223
|
-
clearInterval(timer);
|
|
224
|
-
}
|
|
225
|
-
this.intervals.clear();
|
|
226
|
-
|
|
227
|
-
// Remove all event listeners
|
|
228
|
-
for (const { target, event, handler, actualHandler } of this.listeners) {
|
|
229
|
-
// Use actualHandler if available (for wrapped handlers), otherwise use the original handler
|
|
230
|
-
const handlerToRemove = actualHandler || handler;
|
|
231
|
-
|
|
232
|
-
// All listeners need to be removed, including 'once' listeners that might not have fired
|
|
233
|
-
if (typeof target.removeListener === 'function') {
|
|
234
|
-
target.removeListener(event, handlerToRemove);
|
|
235
|
-
} else if (typeof target.removeEventListener === 'function') {
|
|
236
|
-
target.removeEventListener(event, handlerToRemove);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
this.listeners = [];
|
|
240
|
-
|
|
241
|
-
// Call subclass cleanup
|
|
242
|
-
await this.onCleanup();
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Check if the component is shutting down
|
|
247
|
-
*/
|
|
248
|
-
protected isShuttingDownState(): boolean {
|
|
249
|
-
return this.isShuttingDown;
|
|
250
|
-
}
|
|
251
|
-
}
|