@push.rocks/smartproxy 16.0.2 → 16.0.3

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 (115) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/core/models/index.d.ts +2 -0
  3. package/dist_ts/core/models/index.js +3 -1
  4. package/dist_ts/core/models/route-context.d.ts +62 -0
  5. package/dist_ts/core/models/route-context.js +43 -0
  6. package/dist_ts/core/models/socket-augmentation.d.ts +12 -0
  7. package/dist_ts/core/models/socket-augmentation.js +18 -0
  8. package/dist_ts/core/utils/event-system.d.ts +200 -0
  9. package/dist_ts/core/utils/event-system.js +224 -0
  10. package/dist_ts/core/utils/index.d.ts +7 -0
  11. package/dist_ts/core/utils/index.js +8 -1
  12. package/dist_ts/core/utils/route-manager.d.ts +118 -0
  13. package/dist_ts/core/utils/route-manager.js +383 -0
  14. package/dist_ts/core/utils/route-utils.d.ts +94 -0
  15. package/dist_ts/core/utils/route-utils.js +264 -0
  16. package/dist_ts/core/utils/security-utils.d.ts +111 -0
  17. package/dist_ts/core/utils/security-utils.js +212 -0
  18. package/dist_ts/core/utils/shared-security-manager.d.ts +110 -0
  19. package/dist_ts/core/utils/shared-security-manager.js +252 -0
  20. package/dist_ts/core/utils/template-utils.d.ts +37 -0
  21. package/dist_ts/core/utils/template-utils.js +104 -0
  22. package/dist_ts/core/utils/websocket-utils.d.ts +23 -0
  23. package/dist_ts/core/utils/websocket-utils.js +86 -0
  24. package/dist_ts/http/router/index.d.ts +5 -1
  25. package/dist_ts/http/router/index.js +4 -2
  26. package/dist_ts/http/router/route-router.d.ts +108 -0
  27. package/dist_ts/http/router/route-router.js +393 -0
  28. package/dist_ts/index.d.ts +8 -2
  29. package/dist_ts/index.js +10 -3
  30. package/dist_ts/proxies/index.d.ts +7 -2
  31. package/dist_ts/proxies/index.js +10 -4
  32. package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +21 -0
  33. package/dist_ts/proxies/network-proxy/certificate-manager.js +92 -1
  34. package/dist_ts/proxies/network-proxy/context-creator.d.ts +34 -0
  35. package/dist_ts/proxies/network-proxy/context-creator.js +108 -0
  36. package/dist_ts/proxies/network-proxy/function-cache.d.ts +90 -0
  37. package/dist_ts/proxies/network-proxy/function-cache.js +198 -0
  38. package/dist_ts/proxies/network-proxy/http-request-handler.d.ts +40 -0
  39. package/dist_ts/proxies/network-proxy/http-request-handler.js +256 -0
  40. package/dist_ts/proxies/network-proxy/http2-request-handler.d.ts +24 -0
  41. package/dist_ts/proxies/network-proxy/http2-request-handler.js +201 -0
  42. package/dist_ts/proxies/network-proxy/models/types.d.ts +73 -1
  43. package/dist_ts/proxies/network-proxy/models/types.js +242 -1
  44. package/dist_ts/proxies/network-proxy/network-proxy.d.ts +23 -20
  45. package/dist_ts/proxies/network-proxy/network-proxy.js +147 -60
  46. package/dist_ts/proxies/network-proxy/request-handler.d.ts +38 -5
  47. package/dist_ts/proxies/network-proxy/request-handler.js +584 -198
  48. package/dist_ts/proxies/network-proxy/security-manager.d.ts +65 -0
  49. package/dist_ts/proxies/network-proxy/security-manager.js +255 -0
  50. package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +13 -2
  51. package/dist_ts/proxies/network-proxy/websocket-handler.js +238 -20
  52. package/dist_ts/proxies/smart-proxy/index.d.ts +1 -1
  53. package/dist_ts/proxies/smart-proxy/index.js +3 -3
  54. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +3 -5
  55. package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +56 -3
  56. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +4 -57
  57. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +19 -228
  58. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +81 -0
  59. package/dist_ts/proxies/smart-proxy/port-manager.js +166 -0
  60. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +5 -0
  61. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +131 -15
  62. package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +3 -1
  63. package/dist_ts/proxies/smart-proxy/route-helpers/index.js +5 -3
  64. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +5 -178
  65. package/dist_ts/proxies/smart-proxy/route-helpers.js +8 -296
  66. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +11 -2
  67. package/dist_ts/proxies/smart-proxy/route-manager.js +79 -10
  68. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +29 -2
  69. package/dist_ts/proxies/smart-proxy/smart-proxy.js +48 -43
  70. package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +67 -1
  71. package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +120 -1
  72. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +3 -3
  73. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +27 -5
  74. package/package.json +1 -1
  75. package/readme.md +102 -14
  76. package/readme.plan.md +103 -168
  77. package/ts/00_commitinfo_data.ts +1 -1
  78. package/ts/core/models/index.ts +2 -0
  79. package/ts/core/models/route-context.ts +113 -0
  80. package/ts/core/models/socket-augmentation.ts +33 -0
  81. package/ts/core/utils/event-system.ts +376 -0
  82. package/ts/core/utils/index.ts +7 -0
  83. package/ts/core/utils/route-manager.ts +489 -0
  84. package/ts/core/utils/route-utils.ts +312 -0
  85. package/ts/core/utils/security-utils.ts +309 -0
  86. package/ts/core/utils/shared-security-manager.ts +333 -0
  87. package/ts/core/utils/template-utils.ts +124 -0
  88. package/ts/core/utils/websocket-utils.ts +81 -0
  89. package/ts/http/router/index.ts +8 -1
  90. package/ts/http/router/route-router.ts +482 -0
  91. package/ts/index.ts +14 -2
  92. package/ts/proxies/index.ts +12 -3
  93. package/ts/proxies/network-proxy/certificate-manager.ts +114 -10
  94. package/ts/proxies/network-proxy/context-creator.ts +145 -0
  95. package/ts/proxies/network-proxy/function-cache.ts +259 -0
  96. package/ts/proxies/network-proxy/http-request-handler.ts +330 -0
  97. package/ts/proxies/network-proxy/http2-request-handler.ts +255 -0
  98. package/ts/proxies/network-proxy/models/types.ts +312 -1
  99. package/ts/proxies/network-proxy/network-proxy.ts +195 -86
  100. package/ts/proxies/network-proxy/request-handler.ts +698 -246
  101. package/ts/proxies/network-proxy/security-manager.ts +298 -0
  102. package/ts/proxies/network-proxy/websocket-handler.ts +276 -33
  103. package/ts/proxies/smart-proxy/index.ts +2 -12
  104. package/ts/proxies/smart-proxy/models/interfaces.ts +7 -4
  105. package/ts/proxies/smart-proxy/models/route-types.ts +78 -10
  106. package/ts/proxies/smart-proxy/network-proxy-bridge.ts +20 -257
  107. package/ts/proxies/smart-proxy/port-manager.ts +195 -0
  108. package/ts/proxies/smart-proxy/route-connection-handler.ts +156 -21
  109. package/ts/proxies/smart-proxy/route-manager.ts +98 -14
  110. package/ts/proxies/smart-proxy/smart-proxy.ts +56 -55
  111. package/ts/proxies/smart-proxy/utils/route-helpers.ts +167 -1
  112. package/ts/proxies/smart-proxy/utils/route-validators.ts +24 -5
  113. package/ts/proxies/smart-proxy/domain-config-manager.ts.bak +0 -441
  114. package/ts/proxies/smart-proxy/route-helpers/index.ts +0 -9
  115. package/ts/proxies/smart-proxy/route-helpers.ts +0 -498
@@ -1,5 +1,7 @@
1
1
  import * as plugins from '../../../plugins.js';
2
2
  import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
3
+ import type { IRouteConfig } from '../../smart-proxy/models/route-types.js';
4
+ import type { IRouteContext } from '../../../core/models/route-context.js';
3
5
 
4
6
  /**
5
7
  * Configuration options for NetworkProxy
@@ -24,8 +26,15 @@ export interface INetworkProxyOptions {
24
26
  // Protocol to use when proxying to backends: HTTP/1.x or HTTP/2
25
27
  backendProtocol?: 'http1' | 'http2';
26
28
 
29
+ // Function cache options
30
+ functionCacheSize?: number; // Maximum number of cached function results (default: 1000)
31
+ functionCacheTtl?: number; // Time to live for cached function results in ms (default: 5000)
32
+
27
33
  // ACME certificate management options
28
34
  acme?: IAcmeOptions;
35
+
36
+ // Direct route configurations
37
+ routes?: IRouteConfig[];
29
38
  }
30
39
 
31
40
  /**
@@ -38,20 +47,39 @@ export interface ICertificateEntry {
38
47
  }
39
48
 
40
49
  /**
41
- * Interface for reverse proxy configuration
50
+ * @deprecated Use IRouteConfig instead. This interface will be removed in a future release.
51
+ *
52
+ * IMPORTANT: This is a legacy interface maintained only for backward compatibility.
53
+ * New code should use IRouteConfig for all configuration purposes.
54
+ *
55
+ * @see IRouteConfig for the modern, recommended configuration format
42
56
  */
43
57
  export interface IReverseProxyConfig {
58
+ /** Target hostnames/IPs to proxy requests to */
44
59
  destinationIps: string[];
60
+
61
+ /** Target ports to proxy requests to */
45
62
  destinationPorts: number[];
63
+
64
+ /** Hostname to match for routing */
46
65
  hostName: string;
66
+
67
+ /** SSL private key for this host (PEM format) */
47
68
  privateKey: string;
69
+
70
+ /** SSL public key/certificate for this host (PEM format) */
48
71
  publicKey: string;
72
+
73
+ /** Basic authentication configuration */
49
74
  authentication?: {
50
75
  type: 'Basic';
51
76
  user: string;
52
77
  pass: string;
53
78
  };
79
+
80
+ /** Whether to rewrite the Host header to match the target */
54
81
  rewriteHostHeader?: boolean;
82
+
55
83
  /**
56
84
  * Protocol to use when proxying to this backend: 'http1' or 'http2'.
57
85
  * Overrides the global backendProtocol option if set.
@@ -59,6 +87,289 @@ export interface IReverseProxyConfig {
59
87
  backendProtocol?: 'http1' | 'http2';
60
88
  }
61
89
 
90
+ /**
91
+ * Convert a legacy IReverseProxyConfig to the modern IRouteConfig format
92
+ *
93
+ * @deprecated This function is maintained for backward compatibility.
94
+ * New code should create IRouteConfig objects directly.
95
+ *
96
+ * @param legacyConfig The legacy configuration to convert
97
+ * @param proxyPort The port the proxy listens on
98
+ * @returns A modern route configuration equivalent to the legacy config
99
+ */
100
+ export function convertLegacyConfigToRouteConfig(
101
+ legacyConfig: IReverseProxyConfig,
102
+ proxyPort: number
103
+ ): IRouteConfig {
104
+ // Create basic route configuration
105
+ const routeConfig: IRouteConfig = {
106
+ // Match properties
107
+ match: {
108
+ ports: proxyPort,
109
+ domains: legacyConfig.hostName
110
+ },
111
+
112
+ // Action properties
113
+ action: {
114
+ type: 'forward',
115
+ target: {
116
+ host: legacyConfig.destinationIps,
117
+ port: legacyConfig.destinationPorts[0]
118
+ },
119
+
120
+ // TLS mode is always 'terminate' for legacy configs
121
+ tls: {
122
+ mode: 'terminate',
123
+ certificate: {
124
+ key: legacyConfig.privateKey,
125
+ cert: legacyConfig.publicKey
126
+ }
127
+ },
128
+
129
+ // Advanced options
130
+ advanced: {
131
+ // Rewrite host header if specified
132
+ headers: legacyConfig.rewriteHostHeader ? { 'host': '{domain}' } : {}
133
+ }
134
+ },
135
+
136
+ // Metadata
137
+ name: `Legacy Config - ${legacyConfig.hostName}`,
138
+ priority: 0, // Default priority
139
+ enabled: true
140
+ };
141
+
142
+ // Add authentication if present
143
+ if (legacyConfig.authentication) {
144
+ routeConfig.action.security = {
145
+ authentication: {
146
+ type: 'basic',
147
+ credentials: [{
148
+ username: legacyConfig.authentication.user,
149
+ password: legacyConfig.authentication.pass
150
+ }]
151
+ }
152
+ };
153
+ }
154
+
155
+ // Add backend protocol if specified
156
+ if (legacyConfig.backendProtocol) {
157
+ if (!routeConfig.action.options) {
158
+ routeConfig.action.options = {};
159
+ }
160
+ routeConfig.action.options.backendProtocol = legacyConfig.backendProtocol;
161
+ }
162
+
163
+ return routeConfig;
164
+ }
165
+
166
+ /**
167
+ * Route manager for NetworkProxy
168
+ * Handles route matching and configuration
169
+ */
170
+ export class RouteManager {
171
+ private routes: IRouteConfig[] = [];
172
+ private logger: ILogger;
173
+
174
+ constructor(logger: ILogger) {
175
+ this.logger = logger;
176
+ }
177
+
178
+ /**
179
+ * Update the routes configuration
180
+ */
181
+ public updateRoutes(routes: IRouteConfig[]): void {
182
+ // Sort routes by priority (higher first)
183
+ this.routes = [...routes].sort((a, b) => {
184
+ const priorityA = a.priority ?? 0;
185
+ const priorityB = b.priority ?? 0;
186
+ return priorityB - priorityA;
187
+ });
188
+
189
+ this.logger.info(`Updated RouteManager with ${this.routes.length} routes`);
190
+ }
191
+
192
+ /**
193
+ * Get all routes
194
+ */
195
+ public getRoutes(): IRouteConfig[] {
196
+ return [...this.routes];
197
+ }
198
+
199
+ /**
200
+ * Find the first matching route for a context
201
+ */
202
+ public findMatchingRoute(context: IRouteContext): IRouteConfig | null {
203
+ for (const route of this.routes) {
204
+ if (this.matchesRoute(route, context)) {
205
+ return route;
206
+ }
207
+ }
208
+ return null;
209
+ }
210
+
211
+ /**
212
+ * Check if a route matches the given context
213
+ */
214
+ private matchesRoute(route: IRouteConfig, context: IRouteContext): boolean {
215
+ // Skip disabled routes
216
+ if (route.enabled === false) {
217
+ return false;
218
+ }
219
+
220
+ // Check domain match if specified
221
+ if (route.match.domains && context.domain) {
222
+ const domains = Array.isArray(route.match.domains)
223
+ ? route.match.domains
224
+ : [route.match.domains];
225
+
226
+ if (!domains.some(domainPattern => this.matchDomain(domainPattern, context.domain!))) {
227
+ return false;
228
+ }
229
+ }
230
+
231
+ // Check path match if specified
232
+ if (route.match.path && context.path) {
233
+ if (!this.matchPath(route.match.path, context.path)) {
234
+ return false;
235
+ }
236
+ }
237
+
238
+ // Check client IP match if specified
239
+ if (route.match.clientIp && context.clientIp) {
240
+ if (!route.match.clientIp.some(ip => this.matchIp(ip, context.clientIp))) {
241
+ return false;
242
+ }
243
+ }
244
+
245
+ // Check TLS version match if specified
246
+ if (route.match.tlsVersion && context.tlsVersion) {
247
+ if (!route.match.tlsVersion.includes(context.tlsVersion)) {
248
+ return false;
249
+ }
250
+ }
251
+
252
+ // All criteria matched
253
+ return true;
254
+ }
255
+
256
+ /**
257
+ * Match a domain pattern against a domain
258
+ */
259
+ private matchDomain(pattern: string, domain: string): boolean {
260
+ if (pattern === domain) {
261
+ return true;
262
+ }
263
+
264
+ if (pattern.includes('*')) {
265
+ const regexPattern = pattern
266
+ .replace(/\./g, '\\.')
267
+ .replace(/\*/g, '.*');
268
+
269
+ const regex = new RegExp(`^${regexPattern}$`, 'i');
270
+ return regex.test(domain);
271
+ }
272
+
273
+ return false;
274
+ }
275
+
276
+ /**
277
+ * Match a path pattern against a path
278
+ */
279
+ private matchPath(pattern: string, path: string): boolean {
280
+ if (pattern === path) {
281
+ return true;
282
+ }
283
+
284
+ if (pattern.endsWith('*')) {
285
+ const prefix = pattern.slice(0, -1);
286
+ return path.startsWith(prefix);
287
+ }
288
+
289
+ return false;
290
+ }
291
+
292
+ /**
293
+ * Match an IP pattern against an IP
294
+ * Supports exact matches, wildcard patterns, and CIDR notation
295
+ */
296
+ private matchIp(pattern: string, ip: string): boolean {
297
+ // Exact match
298
+ if (pattern === ip) {
299
+ return true;
300
+ }
301
+
302
+ // Wildcard matching (e.g., 192.168.0.*)
303
+ if (pattern.includes('*')) {
304
+ const regexPattern = pattern
305
+ .replace(/\./g, '\\.')
306
+ .replace(/\*/g, '.*');
307
+
308
+ const regex = new RegExp(`^${regexPattern}$`);
309
+ return regex.test(ip);
310
+ }
311
+
312
+ // CIDR matching (e.g., 192.168.0.0/24)
313
+ if (pattern.includes('/')) {
314
+ try {
315
+ const [subnet, bits] = pattern.split('/');
316
+
317
+ // Convert IP addresses to numeric format for comparison
318
+ const ipBinary = this.ipToBinary(ip);
319
+ const subnetBinary = this.ipToBinary(subnet);
320
+
321
+ if (!ipBinary || !subnetBinary) {
322
+ return false;
323
+ }
324
+
325
+ // Get the subnet mask from CIDR notation
326
+ const mask = parseInt(bits, 10);
327
+ if (isNaN(mask) || mask < 0 || mask > 32) {
328
+ return false;
329
+ }
330
+
331
+ // Check if the first 'mask' bits match between IP and subnet
332
+ return ipBinary.slice(0, mask) === subnetBinary.slice(0, mask);
333
+ } catch (error) {
334
+ // If we encounter any error during CIDR matching, return false
335
+ return false;
336
+ }
337
+ }
338
+
339
+ return false;
340
+ }
341
+
342
+ /**
343
+ * Convert an IP address to its binary representation
344
+ * @param ip The IP address to convert
345
+ * @returns Binary string representation or null if invalid
346
+ */
347
+ private ipToBinary(ip: string): string | null {
348
+ // Handle IPv4 addresses only for now
349
+ const parts = ip.split('.');
350
+
351
+ // Validate IP format
352
+ if (parts.length !== 4) {
353
+ return null;
354
+ }
355
+
356
+ // Convert each octet to 8-bit binary and concatenate
357
+ try {
358
+ return parts
359
+ .map(part => {
360
+ const num = parseInt(part, 10);
361
+ if (isNaN(num) || num < 0 || num > 255) {
362
+ throw new Error('Invalid IP octet');
363
+ }
364
+ return num.toString(2).padStart(8, '0');
365
+ })
366
+ .join('');
367
+ } catch (error) {
368
+ return null;
369
+ }
370
+ }
371
+ }
372
+
62
373
  /**
63
374
  * Interface for connection tracking in the pool
64
375
  */