@push.rocks/smartproxy 25.17.9 → 26.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 (179) hide show
  1. package/changelog.md +16 -0
  2. package/dist_rust/rustproxy_linux_amd64 +0 -0
  3. package/dist_rust/rustproxy_linux_arm64 +0 -0
  4. package/dist_ts/00_commitinfo_data.js +2 -2
  5. package/dist_ts/core/index.d.ts +0 -1
  6. package/dist_ts/core/index.js +1 -2
  7. package/dist_ts/core/models/index.d.ts +0 -1
  8. package/dist_ts/core/models/index.js +1 -2
  9. package/dist_ts/core/utils/index.d.ts +0 -12
  10. package/dist_ts/core/utils/index.js +1 -13
  11. package/dist_ts/index.d.ts +0 -3
  12. package/dist_ts/index.js +2 -7
  13. package/dist_ts/protocols/http/index.d.ts +0 -1
  14. package/dist_ts/protocols/http/index.js +1 -2
  15. package/dist_ts/protocols/index.d.ts +0 -7
  16. package/dist_ts/protocols/index.js +1 -8
  17. package/dist_ts/proxies/smart-proxy/socket-handler-server.js +6 -1
  18. package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.d.ts +0 -7
  19. package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +50 -51
  20. package/dist_ts/routing/index.d.ts +0 -1
  21. package/dist_ts/routing/index.js +1 -3
  22. package/package.json +1 -1
  23. package/ts/00_commitinfo_data.ts +1 -1
  24. package/ts/core/index.ts +0 -1
  25. package/ts/core/models/index.ts +0 -1
  26. package/ts/core/utils/index.ts +0 -12
  27. package/ts/index.ts +1 -7
  28. package/ts/protocols/http/index.ts +1 -2
  29. package/ts/protocols/index.ts +0 -7
  30. package/ts/proxies/smart-proxy/socket-handler-server.ts +6 -0
  31. package/ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.ts +60 -59
  32. package/ts/routing/index.ts +0 -3
  33. package/dist_ts/core/events/index.d.ts +0 -4
  34. package/dist_ts/core/events/index.js +0 -5
  35. package/dist_ts/core/models/socket-augmentation.d.ts +0 -15
  36. package/dist_ts/core/models/socket-augmentation.js +0 -18
  37. package/dist_ts/core/utils/async-utils.d.ts +0 -81
  38. package/dist_ts/core/utils/async-utils.js +0 -216
  39. package/dist_ts/core/utils/binary-heap.d.ts +0 -73
  40. package/dist_ts/core/utils/binary-heap.js +0 -193
  41. package/dist_ts/core/utils/enhanced-connection-pool.d.ts +0 -110
  42. package/dist_ts/core/utils/enhanced-connection-pool.js +0 -325
  43. package/dist_ts/core/utils/fs-utils.d.ts +0 -144
  44. package/dist_ts/core/utils/fs-utils.js +0 -252
  45. package/dist_ts/core/utils/ip-utils.d.ts +0 -69
  46. package/dist_ts/core/utils/ip-utils.js +0 -270
  47. package/dist_ts/core/utils/lifecycle-component.d.ts +0 -59
  48. package/dist_ts/core/utils/lifecycle-component.js +0 -211
  49. package/dist_ts/core/utils/log-deduplicator.d.ts +0 -39
  50. package/dist_ts/core/utils/log-deduplicator.js +0 -305
  51. package/dist_ts/core/utils/security-utils.d.ts +0 -111
  52. package/dist_ts/core/utils/security-utils.js +0 -212
  53. package/dist_ts/core/utils/shared-security-manager.d.ts +0 -128
  54. package/dist_ts/core/utils/shared-security-manager.js +0 -362
  55. package/dist_ts/core/utils/socket-utils.d.ts +0 -63
  56. package/dist_ts/core/utils/socket-utils.js +0 -249
  57. package/dist_ts/core/utils/template-utils.d.ts +0 -37
  58. package/dist_ts/core/utils/template-utils.js +0 -104
  59. package/dist_ts/core/utils/validation-utils.d.ts +0 -61
  60. package/dist_ts/core/utils/validation-utils.js +0 -149
  61. package/dist_ts/core/utils/websocket-utils.d.ts +0 -22
  62. package/dist_ts/core/utils/websocket-utils.js +0 -30
  63. package/dist_ts/detection/detectors/http-detector.d.ts +0 -33
  64. package/dist_ts/detection/detectors/http-detector.js +0 -101
  65. package/dist_ts/detection/detectors/quick-detector.d.ts +0 -28
  66. package/dist_ts/detection/detectors/quick-detector.js +0 -131
  67. package/dist_ts/detection/detectors/routing-extractor.d.ts +0 -28
  68. package/dist_ts/detection/detectors/routing-extractor.js +0 -122
  69. package/dist_ts/detection/detectors/tls-detector.d.ts +0 -47
  70. package/dist_ts/detection/detectors/tls-detector.js +0 -183
  71. package/dist_ts/detection/index.d.ts +0 -17
  72. package/dist_ts/detection/index.js +0 -22
  73. package/dist_ts/detection/models/detection-types.d.ts +0 -87
  74. package/dist_ts/detection/models/detection-types.js +0 -5
  75. package/dist_ts/detection/models/interfaces.d.ts +0 -97
  76. package/dist_ts/detection/models/interfaces.js +0 -5
  77. package/dist_ts/detection/protocol-detector.d.ts +0 -79
  78. package/dist_ts/detection/protocol-detector.js +0 -253
  79. package/dist_ts/detection/utils/buffer-utils.d.ts +0 -61
  80. package/dist_ts/detection/utils/buffer-utils.js +0 -127
  81. package/dist_ts/detection/utils/fragment-manager.d.ts +0 -31
  82. package/dist_ts/detection/utils/fragment-manager.js +0 -53
  83. package/dist_ts/detection/utils/parser-utils.d.ts +0 -42
  84. package/dist_ts/detection/utils/parser-utils.js +0 -63
  85. package/dist_ts/protocols/common/fragment-handler.d.ts +0 -73
  86. package/dist_ts/protocols/common/fragment-handler.js +0 -121
  87. package/dist_ts/protocols/common/index.d.ts +0 -7
  88. package/dist_ts/protocols/common/index.js +0 -8
  89. package/dist_ts/protocols/common/types.d.ts +0 -68
  90. package/dist_ts/protocols/common/types.js +0 -7
  91. package/dist_ts/protocols/http/parser.d.ts +0 -58
  92. package/dist_ts/protocols/http/parser.js +0 -184
  93. package/dist_ts/protocols/proxy/index.d.ts +0 -5
  94. package/dist_ts/protocols/proxy/index.js +0 -6
  95. package/dist_ts/protocols/proxy/types.d.ts +0 -47
  96. package/dist_ts/protocols/proxy/types.js +0 -6
  97. package/dist_ts/protocols/tls/alerts/index.d.ts +0 -4
  98. package/dist_ts/protocols/tls/alerts/index.js +0 -5
  99. package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +0 -150
  100. package/dist_ts/protocols/tls/alerts/tls-alert.js +0 -226
  101. package/dist_ts/protocols/tls/index.d.ts +0 -12
  102. package/dist_ts/protocols/tls/index.js +0 -27
  103. package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +0 -100
  104. package/dist_ts/protocols/tls/sni/client-hello-parser.js +0 -463
  105. package/dist_ts/protocols/tls/sni/index.d.ts +0 -5
  106. package/dist_ts/protocols/tls/sni/index.js +0 -6
  107. package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +0 -58
  108. package/dist_ts/protocols/tls/sni/sni-extraction.js +0 -275
  109. package/dist_ts/protocols/tls/utils/index.d.ts +0 -4
  110. package/dist_ts/protocols/tls/utils/index.js +0 -5
  111. package/dist_ts/protocols/tls/utils/tls-utils.d.ts +0 -158
  112. package/dist_ts/protocols/tls/utils/tls-utils.js +0 -187
  113. package/dist_ts/protocols/websocket/constants.d.ts +0 -55
  114. package/dist_ts/protocols/websocket/constants.js +0 -58
  115. package/dist_ts/protocols/websocket/index.d.ts +0 -7
  116. package/dist_ts/protocols/websocket/index.js +0 -8
  117. package/dist_ts/protocols/websocket/types.d.ts +0 -47
  118. package/dist_ts/protocols/websocket/types.js +0 -5
  119. package/dist_ts/protocols/websocket/utils.d.ts +0 -25
  120. package/dist_ts/protocols/websocket/utils.js +0 -103
  121. package/dist_ts/routing/router/http-router.d.ts +0 -89
  122. package/dist_ts/routing/router/http-router.js +0 -205
  123. package/dist_ts/routing/router/index.d.ts +0 -5
  124. package/dist_ts/routing/router/index.js +0 -6
  125. package/dist_ts/tls/index.d.ts +0 -16
  126. package/dist_ts/tls/index.js +0 -24
  127. package/dist_ts/tls/sni/index.d.ts +0 -4
  128. package/dist_ts/tls/sni/index.js +0 -5
  129. package/dist_ts/tls/sni/sni-handler.d.ts +0 -154
  130. package/dist_ts/tls/sni/sni-handler.js +0 -191
  131. package/ts/core/events/index.ts +0 -3
  132. package/ts/core/models/socket-augmentation.ts +0 -38
  133. package/ts/core/utils/async-utils.ts +0 -275
  134. package/ts/core/utils/binary-heap.ts +0 -225
  135. package/ts/core/utils/enhanced-connection-pool.ts +0 -425
  136. package/ts/core/utils/fs-utils.ts +0 -270
  137. package/ts/core/utils/ip-utils.ts +0 -303
  138. package/ts/core/utils/lifecycle-component.ts +0 -251
  139. package/ts/core/utils/log-deduplicator.ts +0 -370
  140. package/ts/core/utils/security-utils.ts +0 -305
  141. package/ts/core/utils/shared-security-manager.ts +0 -470
  142. package/ts/core/utils/socket-utils.ts +0 -322
  143. package/ts/core/utils/template-utils.ts +0 -124
  144. package/ts/core/utils/validation-utils.ts +0 -177
  145. package/ts/core/utils/websocket-utils.ts +0 -33
  146. package/ts/detection/detectors/http-detector.ts +0 -127
  147. package/ts/detection/detectors/quick-detector.ts +0 -148
  148. package/ts/detection/detectors/routing-extractor.ts +0 -147
  149. package/ts/detection/detectors/tls-detector.ts +0 -223
  150. package/ts/detection/index.ts +0 -25
  151. package/ts/detection/models/detection-types.ts +0 -102
  152. package/ts/detection/models/interfaces.ts +0 -115
  153. package/ts/detection/protocol-detector.ts +0 -319
  154. package/ts/detection/utils/buffer-utils.ts +0 -141
  155. package/ts/detection/utils/fragment-manager.ts +0 -64
  156. package/ts/detection/utils/parser-utils.ts +0 -77
  157. package/ts/protocols/common/fragment-handler.ts +0 -167
  158. package/ts/protocols/common/index.ts +0 -8
  159. package/ts/protocols/common/types.ts +0 -76
  160. package/ts/protocols/http/parser.ts +0 -219
  161. package/ts/protocols/proxy/index.ts +0 -6
  162. package/ts/protocols/proxy/types.ts +0 -53
  163. package/ts/protocols/tls/alerts/index.ts +0 -3
  164. package/ts/protocols/tls/alerts/tls-alert.ts +0 -259
  165. package/ts/protocols/tls/index.ts +0 -37
  166. package/ts/protocols/tls/sni/client-hello-parser.ts +0 -629
  167. package/ts/protocols/tls/sni/index.ts +0 -6
  168. package/ts/protocols/tls/sni/sni-extraction.ts +0 -353
  169. package/ts/protocols/tls/utils/index.ts +0 -3
  170. package/ts/protocols/tls/utils/tls-utils.ts +0 -201
  171. package/ts/protocols/websocket/constants.ts +0 -60
  172. package/ts/protocols/websocket/index.ts +0 -8
  173. package/ts/protocols/websocket/types.ts +0 -53
  174. package/ts/protocols/websocket/utils.ts +0 -98
  175. package/ts/routing/router/http-router.ts +0 -266
  176. package/ts/routing/router/index.ts +0 -7
  177. package/ts/tls/index.ts +0 -29
  178. package/ts/tls/sni/index.ts +0 -3
  179. package/ts/tls/sni/sni-handler.ts +0 -264
@@ -1,470 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import type { IRouteConfig, IRouteContext } from '../../proxies/smart-proxy/models/route-types.js';
3
- import type {
4
- IIpValidationResult,
5
- IIpConnectionInfo,
6
- ISecurityLogger,
7
- IRateLimitInfo
8
- } from './security-utils.js';
9
- import {
10
- isIPAuthorized,
11
- checkMaxConnections,
12
- checkConnectionRate,
13
- trackConnection,
14
- removeConnection,
15
- cleanupExpiredRateLimits,
16
- parseBasicAuthHeader,
17
- normalizeIP
18
- } from './security-utils.js';
19
-
20
- /**
21
- * Shared SecurityManager for use across proxy components
22
- * Handles IP tracking, rate limiting, and authentication
23
- */
24
- export class SharedSecurityManager {
25
- // IP connection tracking
26
- private connectionsByIP: Map<string, IIpConnectionInfo> = new Map();
27
-
28
- // Route-specific rate limiting
29
- private rateLimits: Map<string, Map<string, IRateLimitInfo>> = new Map();
30
-
31
- // Cache IP filtering results to avoid constant regex matching
32
- private ipFilterCache: Map<string, Map<string, boolean>> = new Map();
33
-
34
- // Default limits
35
- private maxConnectionsPerIP: number;
36
- private connectionRateLimitPerMinute: number;
37
-
38
- // Cache cleanup interval
39
- private cleanupInterval: NodeJS.Timeout | null = null;
40
-
41
- /**
42
- * Create a new SharedSecurityManager
43
- *
44
- * @param options - Configuration options
45
- * @param logger - Logger instance
46
- */
47
- constructor(options: {
48
- maxConnectionsPerIP?: number;
49
- connectionRateLimitPerMinute?: number;
50
- cleanupIntervalMs?: number;
51
- routes?: IRouteConfig[];
52
- }, private logger?: ISecurityLogger) {
53
- this.maxConnectionsPerIP = options.maxConnectionsPerIP || 100;
54
- this.connectionRateLimitPerMinute = options.connectionRateLimitPerMinute || 300;
55
-
56
- // Set up logger with defaults if not provided
57
- this.logger = logger || {
58
- info: console.log,
59
- warn: console.warn,
60
- error: console.error
61
- };
62
-
63
- // Set up cache cleanup interval
64
- const cleanupInterval = options.cleanupIntervalMs || 60000; // Default: 1 minute
65
- this.cleanupInterval = setInterval(() => {
66
- this.cleanupCaches();
67
- }, cleanupInterval);
68
-
69
- // Don't keep the process alive just for cleanup
70
- if (this.cleanupInterval.unref) {
71
- this.cleanupInterval.unref();
72
- }
73
- }
74
-
75
- /**
76
- * Get connections count by IP
77
- *
78
- * @param ip - The IP address to check
79
- * @returns Number of connections from this IP
80
- */
81
- public getConnectionCountByIP(ip: string): number {
82
- // Check all normalized variants of the IP
83
- const variants = normalizeIP(ip);
84
- for (const variant of variants) {
85
- const info = this.connectionsByIP.get(variant);
86
- if (info) {
87
- return info.connections.size;
88
- }
89
- }
90
- return 0;
91
- }
92
-
93
- /**
94
- * Track connection by IP
95
- *
96
- * @param ip - The IP address to track
97
- * @param connectionId - The connection ID to associate
98
- */
99
- public trackConnectionByIP(ip: string, connectionId: string): void {
100
- // Check if any variant already exists
101
- const variants = normalizeIP(ip);
102
- let existingKey: string | null = null;
103
-
104
- for (const variant of variants) {
105
- if (this.connectionsByIP.has(variant)) {
106
- existingKey = variant;
107
- break;
108
- }
109
- }
110
-
111
- // Use existing key or the original IP
112
- trackConnection(existingKey || ip, connectionId, this.connectionsByIP);
113
- }
114
-
115
- /**
116
- * Remove connection tracking for an IP
117
- *
118
- * @param ip - The IP address to update
119
- * @param connectionId - The connection ID to remove
120
- */
121
- public removeConnectionByIP(ip: string, connectionId: string): void {
122
- // Check all variants to find where the connection is tracked
123
- const variants = normalizeIP(ip);
124
-
125
- for (const variant of variants) {
126
- if (this.connectionsByIP.has(variant)) {
127
- removeConnection(variant, connectionId, this.connectionsByIP);
128
- break;
129
- }
130
- }
131
- }
132
-
133
- /**
134
- * Check if IP is authorized based on route security settings
135
- *
136
- * @param ip - The IP address to check
137
- * @param allowedIPs - List of allowed IP patterns
138
- * @param blockedIPs - List of blocked IP patterns
139
- * @returns Whether the IP is authorized
140
- */
141
- public isIPAuthorized(
142
- ip: string,
143
- allowedIPs: string[] = ['*'],
144
- blockedIPs: string[] = []
145
- ): boolean {
146
- return isIPAuthorized(ip, allowedIPs, blockedIPs);
147
- }
148
-
149
- /**
150
- * Validate IP against rate limits and connection limits
151
- *
152
- * @param ip - The IP address to validate
153
- * @returns Result with allowed status and reason if blocked
154
- */
155
- public validateIP(ip: string): IIpValidationResult {
156
- // Check connection count limit
157
- const connectionResult = checkMaxConnections(
158
- ip,
159
- this.connectionsByIP,
160
- this.maxConnectionsPerIP
161
- );
162
- if (!connectionResult.allowed) {
163
- return connectionResult;
164
- }
165
-
166
- // Check connection rate limit
167
- const rateResult = checkConnectionRate(
168
- ip,
169
- this.connectionsByIP,
170
- this.connectionRateLimitPerMinute
171
- );
172
- if (!rateResult.allowed) {
173
- return rateResult;
174
- }
175
-
176
- return { allowed: true };
177
- }
178
-
179
- /**
180
- * Atomically validate an IP and track the connection if allowed.
181
- * This prevents race conditions where concurrent connections could bypass per-IP limits.
182
- *
183
- * @param ip - The IP address to validate
184
- * @param connectionId - The connection ID to track if validation passes
185
- * @returns Object with validation result and reason
186
- */
187
- public validateAndTrackIP(ip: string, connectionId: string): IIpValidationResult {
188
- // Check connection count limit BEFORE tracking
189
- const connectionResult = checkMaxConnections(
190
- ip,
191
- this.connectionsByIP,
192
- this.maxConnectionsPerIP
193
- );
194
- if (!connectionResult.allowed) {
195
- return connectionResult;
196
- }
197
-
198
- // Check connection rate limit
199
- const rateResult = checkConnectionRate(
200
- ip,
201
- this.connectionsByIP,
202
- this.connectionRateLimitPerMinute
203
- );
204
- if (!rateResult.allowed) {
205
- return rateResult;
206
- }
207
-
208
- // Validation passed - immediately track to prevent race conditions
209
- this.trackConnectionByIP(ip, connectionId);
210
-
211
- return { allowed: true };
212
- }
213
-
214
- /**
215
- * Check if a client is allowed to access a specific route
216
- *
217
- * @param route - The route to check
218
- * @param context - The request context
219
- * @param routeConnectionCount - Current connection count for this route (optional)
220
- * @returns Whether access is allowed
221
- */
222
- public isAllowed(route: IRouteConfig, context: IRouteContext, routeConnectionCount?: number): boolean {
223
- if (!route.security) {
224
- return true; // No security restrictions
225
- }
226
-
227
- // --- IP filtering ---
228
- if (!this.isClientIpAllowed(route, context.clientIp)) {
229
- this.logger?.debug?.(`IP ${context.clientIp} is blocked for route ${route.name || 'unnamed'}`);
230
- return false;
231
- }
232
-
233
- // --- Route-level connection limit ---
234
- if (route.security.maxConnections !== undefined && routeConnectionCount !== undefined) {
235
- if (routeConnectionCount >= route.security.maxConnections) {
236
- this.logger?.debug?.(`Route connection limit (${route.security.maxConnections}) exceeded for route ${route.name || 'unnamed'}`);
237
- return false;
238
- }
239
- }
240
-
241
- // --- Rate limiting ---
242
- if (route.security.rateLimit?.enabled && !this.isWithinRateLimit(route, context)) {
243
- this.logger?.debug?.(`Rate limit exceeded for route ${route.name || 'unnamed'}`);
244
- return false;
245
- }
246
-
247
- return true;
248
- }
249
-
250
- /**
251
- * Check if a client IP is allowed for a route
252
- *
253
- * @param route - The route to check
254
- * @param clientIp - The client IP
255
- * @returns Whether the IP is allowed
256
- */
257
- private isClientIpAllowed(route: IRouteConfig, clientIp: string): boolean {
258
- if (!route.security) {
259
- return true; // No security restrictions
260
- }
261
-
262
- const routeId = route.id || route.name || 'unnamed';
263
-
264
- // Check cache first
265
- if (!this.ipFilterCache.has(routeId)) {
266
- this.ipFilterCache.set(routeId, new Map());
267
- }
268
-
269
- const routeCache = this.ipFilterCache.get(routeId)!;
270
- if (routeCache.has(clientIp)) {
271
- return routeCache.get(clientIp)!;
272
- }
273
-
274
- // Check IP against route security settings
275
- const ipAllowList = route.security.ipAllowList;
276
- const ipBlockList = route.security.ipBlockList;
277
-
278
- const allowed = this.isIPAuthorized(clientIp, ipAllowList, ipBlockList);
279
-
280
- // Cache the result
281
- routeCache.set(clientIp, allowed);
282
-
283
- return allowed;
284
- }
285
-
286
- /**
287
- * Check if request is within rate limit
288
- *
289
- * @param route - The route to check
290
- * @param context - The request context
291
- * @returns Whether the request is within rate limit
292
- */
293
- private isWithinRateLimit(route: IRouteConfig, context: IRouteContext): boolean {
294
- if (!route.security?.rateLimit?.enabled) {
295
- return true;
296
- }
297
-
298
- const rateLimit = route.security.rateLimit;
299
- const routeId = route.id || route.name || 'unnamed';
300
-
301
- // Determine rate limit key (by IP, path, or header)
302
- let key = context.clientIp; // Default to IP
303
-
304
- if (rateLimit.keyBy === 'path' && context.path) {
305
- key = `${context.clientIp}:${context.path}`;
306
- } else if (rateLimit.keyBy === 'header' && rateLimit.headerName && context.headers) {
307
- const headerValue = context.headers[rateLimit.headerName.toLowerCase()];
308
- if (headerValue) {
309
- key = `${context.clientIp}:${headerValue}`;
310
- }
311
- }
312
-
313
- // Get or create rate limit tracking for this route
314
- if (!this.rateLimits.has(routeId)) {
315
- this.rateLimits.set(routeId, new Map());
316
- }
317
-
318
- const routeLimits = this.rateLimits.get(routeId)!;
319
- const now = Date.now();
320
-
321
- // Get or create rate limit tracking for this key
322
- let limit = routeLimits.get(key);
323
- if (!limit || limit.expiry < now) {
324
- // Create new rate limit or reset expired one
325
- limit = {
326
- count: 1,
327
- expiry: now + (rateLimit.window * 1000)
328
- };
329
- routeLimits.set(key, limit);
330
- return true;
331
- }
332
-
333
- // Increment the counter
334
- limit.count++;
335
-
336
- // Check if rate limit is exceeded
337
- return limit.count <= rateLimit.maxRequests;
338
- }
339
-
340
- /**
341
- * Validate HTTP Basic Authentication
342
- *
343
- * @param route - The route to check
344
- * @param authHeader - The Authorization header
345
- * @returns Whether authentication is valid
346
- */
347
- public validateBasicAuth(route: IRouteConfig, authHeader?: string): boolean {
348
- // Skip if basic auth not enabled for route
349
- if (!route.security?.basicAuth?.enabled) {
350
- return true;
351
- }
352
-
353
- // No auth header means auth failed
354
- if (!authHeader) {
355
- return false;
356
- }
357
-
358
- // Parse auth header
359
- const credentials = parseBasicAuthHeader(authHeader);
360
- if (!credentials) {
361
- return false;
362
- }
363
-
364
- // Check credentials against configured users
365
- const { username, password } = credentials;
366
- const users = route.security.basicAuth.users;
367
-
368
- return users.some(user =>
369
- user.username === username && user.password === password
370
- );
371
- }
372
-
373
- /**
374
- * Verify a JWT token against route configuration
375
- *
376
- * @param route - The route to verify the token for
377
- * @param token - The JWT token to verify
378
- * @returns True if the token is valid, false otherwise
379
- */
380
- public verifyJwtToken(route: IRouteConfig, token: string): boolean {
381
- if (!route.security?.jwtAuth?.enabled) {
382
- return true;
383
- }
384
-
385
- try {
386
- const jwtAuth = route.security.jwtAuth;
387
-
388
- // Verify structure (header.payload.signature)
389
- const parts = token.split('.');
390
- if (parts.length !== 3) {
391
- return false;
392
- }
393
-
394
- // Decode payload
395
- const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString());
396
-
397
- // Check expiration
398
- if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {
399
- return false;
400
- }
401
-
402
- // Check issuer
403
- if (jwtAuth.issuer && payload.iss !== jwtAuth.issuer) {
404
- return false;
405
- }
406
-
407
- // Check audience
408
- if (jwtAuth.audience && payload.aud !== jwtAuth.audience) {
409
- return false;
410
- }
411
-
412
- // Note: In a real implementation, you'd also verify the signature
413
- // using the secret and algorithm specified in jwtAuth.
414
- // This requires a proper JWT library for cryptographic verification.
415
-
416
- return true;
417
- } catch (err) {
418
- this.logger?.error?.(`Error verifying JWT: ${err}`);
419
- return false;
420
- }
421
- }
422
-
423
- /**
424
- * Clean up caches to prevent memory leaks
425
- */
426
- private cleanupCaches(): void {
427
- // Clean up rate limits
428
- cleanupExpiredRateLimits(this.rateLimits, this.logger);
429
-
430
- // Clean up IP connection tracking
431
- let cleanedIPs = 0;
432
- for (const [ip, info] of this.connectionsByIP.entries()) {
433
- // Remove IPs with no active connections and no recent timestamps
434
- if (info.connections.size === 0 && info.timestamps.length === 0) {
435
- this.connectionsByIP.delete(ip);
436
- cleanedIPs++;
437
- }
438
- }
439
-
440
- if (cleanedIPs > 0 && this.logger?.debug) {
441
- this.logger.debug(`Cleaned up ${cleanedIPs} IPs with no active connections`);
442
- }
443
-
444
- // IP filter cache doesn't need cleanup (tied to routes)
445
- }
446
-
447
- /**
448
- * Clear all IP tracking data (for shutdown)
449
- */
450
- public clearIPTracking(): void {
451
- this.connectionsByIP.clear();
452
- this.rateLimits.clear();
453
- this.ipFilterCache.clear();
454
-
455
- if (this.cleanupInterval) {
456
- clearInterval(this.cleanupInterval);
457
- this.cleanupInterval = null;
458
- }
459
- }
460
-
461
- /**
462
- * Update routes for security checking
463
- *
464
- * @param routes - New routes to use
465
- */
466
- public setRoutes(routes: IRouteConfig[]): void {
467
- // Only clear the IP filter cache - route-specific
468
- this.ipFilterCache.clear();
469
- }
470
- }