@push.rocks/smartproxy 20.0.0 → 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ts/index.ts CHANGED
@@ -32,7 +32,6 @@ export * from './core/models/common-types.js';
32
32
  export type { IAcmeOptions } from './proxies/smart-proxy/models/interfaces.js';
33
33
 
34
34
  // Modular exports for new architecture
35
- export * as forwarding from './forwarding/index.js';
36
35
  // Certificate module has been removed - use SmartCertManager instead
37
36
  export * as tls from './tls/index.js';
38
37
  export * as routing from './routing/index.js';
@@ -16,7 +16,6 @@ export interface IAcmeOptions {
16
16
  routeForwards?: any[];
17
17
  }
18
18
  import type { IRouteConfig } from './route-types.js';
19
- import type { TForwardingType } from '../../../forwarding/config/forwarding-types.js';
20
19
 
21
20
  /**
22
21
  * Provision object for static or HTTP-01 certificate
@@ -1,6 +1,5 @@
1
1
  import * as plugins from '../../../plugins.js';
2
2
  // Certificate types removed - use local definition
3
- import type { TForwardingType } from '../../../forwarding/config/forwarding-types.js';
4
3
  import type { PortRange } from '../../../proxies/nftables-proxy/models/interfaces.js';
5
4
  import type { IRouteContext } from '../../../core/models/route-context.js';
6
5
 
@@ -14,23 +14,12 @@ export * from './route-validators.js';
14
14
  // Export route utilities for route operations
15
15
  export * from './route-utils.js';
16
16
 
17
- // Export route patterns with renamed exports to avoid conflicts
18
- import {
19
- createWebSocketRoute as createWebSocketPatternRoute,
20
- createLoadBalancerRoute as createLoadBalancerPatternRoute,
21
- createApiGatewayRoute,
22
- addRateLimiting,
23
- addBasicAuth,
24
- addJwtAuth
25
- } from './route-patterns.js';
26
-
17
+ // Export additional functions from route-helpers that weren't already exported
27
18
  export {
28
- createWebSocketPatternRoute,
29
- createLoadBalancerPatternRoute,
30
19
  createApiGatewayRoute,
31
20
  addRateLimiting,
32
21
  addBasicAuth,
33
22
  addJwtAuth
34
- };
23
+ } from './route-helpers.js';
35
24
 
36
25
  // Migration utilities have been removed as they are no longer needed
@@ -20,6 +20,7 @@
20
20
 
21
21
  import * as plugins from '../../../plugins.js';
22
22
  import type { IRouteConfig, IRouteMatch, IRouteAction, IRouteTarget, TPortRange, IRouteContext } from '../models/route-types.js';
23
+ import { mergeRouteConfigs } from './route-utils.js';
23
24
 
24
25
  /**
25
26
  * Create an HTTP-only route configuration
@@ -211,26 +212,62 @@ export function createCompleteHttpsServer(
211
212
  /**
212
213
  * Create a load balancer route (round-robin between multiple backend hosts)
213
214
  * @param domains Domain(s) to match
214
- * @param hosts Array of backend hosts to load balance between
215
- * @param port Backend port
216
- * @param options Additional route options
215
+ * @param backendsOrHosts Array of backend servers OR array of host strings (legacy)
216
+ * @param portOrOptions Port number (legacy) OR options object
217
+ * @param options Additional route options (legacy)
217
218
  * @returns Route configuration object
218
219
  */
219
220
  export function createLoadBalancerRoute(
220
221
  domains: string | string[],
221
- hosts: string[],
222
- port: number,
223
- options: {
222
+ backendsOrHosts: Array<{ host: string; port: number }> | string[],
223
+ portOrOptions?: number | {
224
224
  tls?: {
225
225
  mode: 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
226
226
  certificate?: 'auto' | { key: string; cert: string };
227
227
  };
228
+ useTls?: boolean;
229
+ certificate?: 'auto' | { key: string; cert: string };
230
+ algorithm?: 'round-robin' | 'least-connections' | 'ip-hash';
231
+ healthCheck?: {
232
+ path: string;
233
+ interval: number;
234
+ timeout: number;
235
+ unhealthyThreshold: number;
236
+ healthyThreshold: number;
237
+ };
228
238
  [key: string]: any;
229
- } = {}
239
+ },
240
+ options?: {
241
+ tls?: {
242
+ mode: 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
243
+ certificate?: 'auto' | { key: string; cert: string };
244
+ };
245
+ [key: string]: any;
246
+ }
230
247
  ): IRouteConfig {
248
+ // Handle legacy signature: (domains, hosts[], port, options)
249
+ let backends: Array<{ host: string; port: number }>;
250
+ let finalOptions: any;
251
+
252
+ if (Array.isArray(backendsOrHosts) && backendsOrHosts.length > 0 && typeof backendsOrHosts[0] === 'string') {
253
+ // Legacy signature
254
+ const hosts = backendsOrHosts as string[];
255
+ const port = portOrOptions as number;
256
+ backends = hosts.map(host => ({ host, port }));
257
+ finalOptions = options || {};
258
+ } else {
259
+ // New signature
260
+ backends = backendsOrHosts as Array<{ host: string; port: number }>;
261
+ finalOptions = (portOrOptions as any) || {};
262
+ }
263
+
264
+ // Extract hosts and ensure all backends use the same port
265
+ const port = backends[0].port;
266
+ const hosts = backends.map(backend => backend.host);
267
+
231
268
  // Create route match
232
269
  const match: IRouteMatch = {
233
- ports: options.match?.ports || (options.tls ? 443 : 80),
270
+ ports: finalOptions.match?.ports || (finalOptions.tls || finalOptions.useTls ? 443 : 80),
234
271
  domains
235
272
  };
236
273
 
@@ -247,10 +284,18 @@ export function createLoadBalancerRoute(
247
284
  };
248
285
 
249
286
  // Add TLS configuration if provided
250
- if (options.tls) {
287
+ if (finalOptions.tls || finalOptions.useTls) {
251
288
  action.tls = {
252
- mode: options.tls.mode,
253
- certificate: options.tls.certificate || 'auto'
289
+ mode: finalOptions.tls?.mode || 'terminate',
290
+ certificate: finalOptions.tls?.certificate || finalOptions.certificate || 'auto'
291
+ };
292
+ }
293
+
294
+ // Add load balancing options
295
+ if (finalOptions.algorithm || finalOptions.healthCheck) {
296
+ action.loadBalancing = {
297
+ algorithm: finalOptions.algorithm || 'round-robin',
298
+ healthCheck: finalOptions.healthCheck
254
299
  };
255
300
  }
256
301
 
@@ -258,8 +303,8 @@ export function createLoadBalancerRoute(
258
303
  return {
259
304
  match,
260
305
  action,
261
- name: options.name || `Load Balancer for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
262
- ...options
306
+ name: finalOptions.name || `Load Balancer for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
307
+ ...finalOptions
263
308
  };
264
309
  }
265
310
 
@@ -339,16 +384,26 @@ export function createApiRoute(
339
384
  /**
340
385
  * Create a WebSocket route configuration
341
386
  * @param domains Domain(s) to match
342
- * @param wsPath WebSocket path (e.g., "/ws")
343
- * @param target Target WebSocket server host and port
344
- * @param options Additional route options
387
+ * @param targetOrPath Target server OR WebSocket path (legacy)
388
+ * @param targetOrOptions Target server (legacy) OR options
389
+ * @param options Additional route options (legacy)
345
390
  * @returns Route configuration object
346
391
  */
347
392
  export function createWebSocketRoute(
348
393
  domains: string | string[],
349
- wsPath: string,
350
- target: { host: string | string[]; port: number },
351
- options: {
394
+ targetOrPath: { host: string | string[]; port: number } | string,
395
+ targetOrOptions?: { host: string | string[]; port: number } | {
396
+ useTls?: boolean;
397
+ certificate?: 'auto' | { key: string; cert: string };
398
+ path?: string;
399
+ httpPort?: number | number[];
400
+ httpsPort?: number | number[];
401
+ pingInterval?: number;
402
+ pingTimeout?: number;
403
+ name?: string;
404
+ [key: string]: any;
405
+ },
406
+ options?: {
352
407
  useTls?: boolean;
353
408
  certificate?: 'auto' | { key: string; cert: string };
354
409
  httpPort?: number | number[];
@@ -357,16 +412,33 @@ export function createWebSocketRoute(
357
412
  pingTimeout?: number;
358
413
  name?: string;
359
414
  [key: string]: any;
360
- } = {}
415
+ }
361
416
  ): IRouteConfig {
417
+ // Handle different signatures
418
+ let target: { host: string | string[]; port: number };
419
+ let wsPath: string;
420
+ let finalOptions: any;
421
+
422
+ if (typeof targetOrPath === 'string') {
423
+ // Legacy signature: (domains, path, target, options)
424
+ wsPath = targetOrPath;
425
+ target = targetOrOptions as { host: string | string[]; port: number };
426
+ finalOptions = options || {};
427
+ } else {
428
+ // New signature: (domains, target, options)
429
+ target = targetOrPath;
430
+ finalOptions = (targetOrOptions as any) || {};
431
+ wsPath = finalOptions.path || '/ws';
432
+ }
433
+
362
434
  // Normalize WebSocket path
363
435
  const normalizedPath = wsPath.startsWith('/') ? wsPath : `/${wsPath}`;
364
436
 
365
437
  // Create route match
366
438
  const match: IRouteMatch = {
367
- ports: options.useTls
368
- ? (options.httpsPort || 443)
369
- : (options.httpPort || 80),
439
+ ports: finalOptions.useTls
440
+ ? (finalOptions.httpsPort || 443)
441
+ : (finalOptions.httpPort || 80),
370
442
  domains,
371
443
  path: normalizedPath
372
444
  };
@@ -377,16 +449,16 @@ export function createWebSocketRoute(
377
449
  targets: [target],
378
450
  websocket: {
379
451
  enabled: true,
380
- pingInterval: options.pingInterval || 30000, // 30 seconds
381
- pingTimeout: options.pingTimeout || 5000 // 5 seconds
452
+ pingInterval: finalOptions.pingInterval || 30000, // 30 seconds
453
+ pingTimeout: finalOptions.pingTimeout || 5000 // 5 seconds
382
454
  }
383
455
  };
384
456
 
385
457
  // Add TLS configuration if using HTTPS
386
- if (options.useTls) {
458
+ if (finalOptions.useTls) {
387
459
  action.tls = {
388
460
  mode: 'terminate',
389
- certificate: options.certificate || 'auto'
461
+ certificate: finalOptions.certificate || 'auto'
390
462
  };
391
463
  }
392
464
 
@@ -394,9 +466,9 @@ export function createWebSocketRoute(
394
466
  return {
395
467
  match,
396
468
  action,
397
- name: options.name || `WebSocket Route ${normalizedPath} for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
398
- priority: options.priority || 100, // Higher priority for WebSocket routes
399
- ...options
469
+ name: finalOptions.name || `WebSocket Route ${normalizedPath} for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
470
+ priority: finalOptions.priority || 100, // Higher priority for WebSocket routes
471
+ ...finalOptions
400
472
  };
401
473
  }
402
474
 
@@ -1030,3 +1102,152 @@ export const SocketHandlers = {
1030
1102
  });
1031
1103
  }
1032
1104
  };
1105
+
1106
+ /**
1107
+ * Create an API Gateway route pattern
1108
+ * @param domains Domain(s) to match
1109
+ * @param apiBasePath Base path for API endpoints (e.g., '/api')
1110
+ * @param target Target host and port
1111
+ * @param options Additional route options
1112
+ * @returns API route configuration
1113
+ */
1114
+ export function createApiGatewayRoute(
1115
+ domains: string | string[],
1116
+ apiBasePath: string,
1117
+ target: { host: string | string[]; port: number },
1118
+ options: {
1119
+ useTls?: boolean;
1120
+ certificate?: 'auto' | { key: string; cert: string };
1121
+ addCorsHeaders?: boolean;
1122
+ [key: string]: any;
1123
+ } = {}
1124
+ ): IRouteConfig {
1125
+ // Normalize apiBasePath to ensure it starts with / and doesn't end with /
1126
+ const normalizedPath = apiBasePath.startsWith('/')
1127
+ ? apiBasePath
1128
+ : `/${apiBasePath}`;
1129
+
1130
+ // Add wildcard to path to match all API endpoints
1131
+ const apiPath = normalizedPath.endsWith('/')
1132
+ ? `${normalizedPath}*`
1133
+ : `${normalizedPath}/*`;
1134
+
1135
+ // Create base route
1136
+ const baseRoute = options.useTls
1137
+ ? createHttpsTerminateRoute(domains, target, {
1138
+ certificate: options.certificate || 'auto'
1139
+ })
1140
+ : createHttpRoute(domains, target);
1141
+
1142
+ // Add API-specific configurations
1143
+ const apiRoute: Partial<IRouteConfig> = {
1144
+ match: {
1145
+ ...baseRoute.match,
1146
+ path: apiPath
1147
+ },
1148
+ name: options.name || `API Gateway: ${apiPath} -> ${Array.isArray(target.host) ? target.host.join(', ') : target.host}:${target.port}`,
1149
+ priority: options.priority || 100 // Higher priority for specific path matching
1150
+ };
1151
+
1152
+ // Add CORS headers if requested
1153
+ if (options.addCorsHeaders) {
1154
+ apiRoute.headers = {
1155
+ response: {
1156
+ 'Access-Control-Allow-Origin': '*',
1157
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
1158
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
1159
+ 'Access-Control-Max-Age': '86400'
1160
+ }
1161
+ };
1162
+ }
1163
+
1164
+ return mergeRouteConfigs(baseRoute, apiRoute);
1165
+ }
1166
+
1167
+ /**
1168
+ * Create a rate limiting route pattern
1169
+ * @param baseRoute Base route to add rate limiting to
1170
+ * @param rateLimit Rate limiting configuration
1171
+ * @returns Route with rate limiting
1172
+ */
1173
+ export function addRateLimiting(
1174
+ baseRoute: IRouteConfig,
1175
+ rateLimit: {
1176
+ maxRequests: number;
1177
+ window: number; // Time window in seconds
1178
+ keyBy?: 'ip' | 'path' | 'header';
1179
+ headerName?: string; // Required if keyBy is 'header'
1180
+ errorMessage?: string;
1181
+ }
1182
+ ): IRouteConfig {
1183
+ return mergeRouteConfigs(baseRoute, {
1184
+ security: {
1185
+ rateLimit: {
1186
+ enabled: true,
1187
+ maxRequests: rateLimit.maxRequests,
1188
+ window: rateLimit.window,
1189
+ keyBy: rateLimit.keyBy || 'ip',
1190
+ headerName: rateLimit.headerName,
1191
+ errorMessage: rateLimit.errorMessage || 'Rate limit exceeded. Please try again later.'
1192
+ }
1193
+ }
1194
+ });
1195
+ }
1196
+
1197
+ /**
1198
+ * Create a basic authentication route pattern
1199
+ * @param baseRoute Base route to add authentication to
1200
+ * @param auth Authentication configuration
1201
+ * @returns Route with basic authentication
1202
+ */
1203
+ export function addBasicAuth(
1204
+ baseRoute: IRouteConfig,
1205
+ auth: {
1206
+ users: Array<{ username: string; password: string }>;
1207
+ realm?: string;
1208
+ excludePaths?: string[];
1209
+ }
1210
+ ): IRouteConfig {
1211
+ return mergeRouteConfigs(baseRoute, {
1212
+ security: {
1213
+ basicAuth: {
1214
+ enabled: true,
1215
+ users: auth.users,
1216
+ realm: auth.realm || 'Restricted Area',
1217
+ excludePaths: auth.excludePaths || []
1218
+ }
1219
+ }
1220
+ });
1221
+ }
1222
+
1223
+ /**
1224
+ * Create a JWT authentication route pattern
1225
+ * @param baseRoute Base route to add JWT authentication to
1226
+ * @param jwt JWT authentication configuration
1227
+ * @returns Route with JWT authentication
1228
+ */
1229
+ export function addJwtAuth(
1230
+ baseRoute: IRouteConfig,
1231
+ jwt: {
1232
+ secret: string;
1233
+ algorithm?: string;
1234
+ issuer?: string;
1235
+ audience?: string;
1236
+ expiresIn?: number; // Time in seconds
1237
+ excludePaths?: string[];
1238
+ }
1239
+ ): IRouteConfig {
1240
+ return mergeRouteConfigs(baseRoute, {
1241
+ security: {
1242
+ jwtAuth: {
1243
+ enabled: true,
1244
+ secret: jwt.secret,
1245
+ algorithm: jwt.algorithm || 'HS256',
1246
+ issuer: jwt.issuer,
1247
+ audience: jwt.audience,
1248
+ expiresIn: jwt.expiresIn,
1249
+ excludePaths: jwt.excludePaths || []
1250
+ }
1251
+ }
1252
+ });
1253
+ }
@@ -1,76 +0,0 @@
1
- import type * as plugins from '../../plugins.js';
2
-
3
- /**
4
- * The primary forwarding types supported by SmartProxy
5
- * Used for configuration compatibility
6
- */
7
- export type TForwardingType =
8
- | 'http-only' // HTTP forwarding only (no HTTPS)
9
- | 'https-passthrough' // Pass-through TLS traffic (SNI forwarding)
10
- | 'https-terminate-to-http' // Terminate TLS and forward to HTTP backend
11
- | 'https-terminate-to-https'; // Terminate TLS and forward to HTTPS backend
12
-
13
- /**
14
- * Event types emitted by forwarding handlers
15
- */
16
- export enum ForwardingHandlerEvents {
17
- CONNECTED = 'connected',
18
- DISCONNECTED = 'disconnected',
19
- ERROR = 'error',
20
- DATA_FORWARDED = 'data-forwarded',
21
- HTTP_REQUEST = 'http-request',
22
- HTTP_RESPONSE = 'http-response',
23
- CERTIFICATE_NEEDED = 'certificate-needed',
24
- CERTIFICATE_LOADED = 'certificate-loaded'
25
- }
26
-
27
- /**
28
- * Base interface for forwarding handlers
29
- */
30
- export interface IForwardingHandler extends plugins.EventEmitter {
31
- initialize(): Promise<void>;
32
- handleConnection(socket: plugins.net.Socket): void;
33
- handleHttpRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void;
34
- }
35
-
36
- // Route-based helpers are now available directly from route-patterns.ts
37
- import {
38
- createHttpRoute,
39
- createHttpsTerminateRoute,
40
- createHttpsPassthroughRoute,
41
- createHttpToHttpsRedirect,
42
- createCompleteHttpsServer,
43
- createLoadBalancerRoute
44
- } from '../../proxies/smart-proxy/utils/route-patterns.js';
45
-
46
- export {
47
- createHttpRoute,
48
- createHttpsTerminateRoute,
49
- createHttpsPassthroughRoute,
50
- createHttpToHttpsRedirect,
51
- createCompleteHttpsServer,
52
- createLoadBalancerRoute
53
- };
54
-
55
- // Note: Legacy helper functions have been removed
56
- // Please use the route-based helpers instead:
57
- // - createHttpRoute
58
- // - createHttpsTerminateRoute
59
- // - createHttpsPassthroughRoute
60
- // - createHttpToHttpsRedirect
61
- import type { IRouteConfig } from '../../proxies/smart-proxy/models/route-types.js';
62
-
63
- // For backward compatibility, kept only the basic configuration interface
64
- export interface IForwardConfig {
65
- type: TForwardingType;
66
- target: {
67
- host: string | string[];
68
- port: number | 'preserve' | ((ctx: any) => number);
69
- };
70
- http?: any;
71
- https?: any;
72
- acme?: any;
73
- security?: any;
74
- advanced?: any;
75
- [key: string]: any;
76
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * Forwarding configuration exports
3
- *
4
- * Note: The legacy domain-based configuration has been replaced by route-based configuration.
5
- * See /ts/proxies/smart-proxy/models/route-types.ts for the new route-based configuration.
6
- */
7
-
8
- export type {
9
- TForwardingType,
10
- IForwardConfig,
11
- IForwardingHandler
12
- } from './forwarding-types.js';
13
-
14
- export {
15
- ForwardingHandlerEvents
16
- } from './forwarding-types.js';
17
-
18
- // Import route helpers from route-patterns instead of deleted route-helpers
19
- export {
20
- createHttpRoute,
21
- createHttpsTerminateRoute,
22
- createHttpsPassthroughRoute,
23
- createHttpToHttpsRedirect,
24
- createCompleteHttpsServer,
25
- createLoadBalancerRoute
26
- } from '../../proxies/smart-proxy/utils/route-patterns.js';