@push.rocks/smartproxy 10.2.0 → 12.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 (59) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/common/port80-adapter.d.ts +11 -0
  3. package/dist_ts/common/port80-adapter.js +61 -0
  4. package/dist_ts/examples/forwarding-example.d.ts +1 -0
  5. package/dist_ts/examples/forwarding-example.js +96 -0
  6. package/dist_ts/index.d.ts +1 -0
  7. package/dist_ts/index.js +3 -1
  8. package/dist_ts/smartproxy/classes.pp.connectionhandler.js +179 -30
  9. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.d.ts +39 -0
  10. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.js +172 -20
  11. package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +3 -11
  12. package/dist_ts/smartproxy/classes.pp.portrangemanager.js +17 -10
  13. package/dist_ts/smartproxy/classes.pp.securitymanager.d.ts +19 -2
  14. package/dist_ts/smartproxy/classes.pp.securitymanager.js +27 -4
  15. package/dist_ts/smartproxy/classes.pp.timeoutmanager.js +3 -3
  16. package/dist_ts/smartproxy/classes.smartproxy.js +45 -13
  17. package/dist_ts/smartproxy/forwarding/domain-config.d.ts +12 -0
  18. package/dist_ts/smartproxy/forwarding/domain-config.js +12 -0
  19. package/dist_ts/smartproxy/forwarding/domain-manager.d.ts +86 -0
  20. package/dist_ts/smartproxy/forwarding/domain-manager.js +241 -0
  21. package/dist_ts/smartproxy/forwarding/forwarding.factory.d.ts +24 -0
  22. package/dist_ts/smartproxy/forwarding/forwarding.factory.js +137 -0
  23. package/dist_ts/smartproxy/forwarding/forwarding.handler.d.ts +55 -0
  24. package/dist_ts/smartproxy/forwarding/forwarding.handler.js +94 -0
  25. package/dist_ts/smartproxy/forwarding/http.handler.d.ts +25 -0
  26. package/dist_ts/smartproxy/forwarding/http.handler.js +123 -0
  27. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.d.ts +24 -0
  28. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.js +154 -0
  29. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.d.ts +36 -0
  30. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.js +229 -0
  31. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.d.ts +35 -0
  32. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.js +254 -0
  33. package/dist_ts/smartproxy/forwarding/index.d.ts +16 -0
  34. package/dist_ts/smartproxy/forwarding/index.js +23 -0
  35. package/dist_ts/smartproxy/types/forwarding.types.d.ts +104 -0
  36. package/dist_ts/smartproxy/types/forwarding.types.js +50 -0
  37. package/package.json +2 -2
  38. package/readme.md +158 -8
  39. package/readme.plan.md +471 -42
  40. package/ts/00_commitinfo_data.ts +1 -1
  41. package/ts/common/port80-adapter.ts +87 -0
  42. package/ts/index.ts +3 -0
  43. package/ts/smartproxy/classes.pp.connectionhandler.ts +231 -44
  44. package/ts/smartproxy/classes.pp.domainconfigmanager.ts +198 -24
  45. package/ts/smartproxy/classes.pp.interfaces.ts +3 -11
  46. package/ts/smartproxy/classes.pp.portrangemanager.ts +17 -10
  47. package/ts/smartproxy/classes.pp.securitymanager.ts +29 -5
  48. package/ts/smartproxy/classes.pp.timeoutmanager.ts +3 -3
  49. package/ts/smartproxy/classes.smartproxy.ts +68 -15
  50. package/ts/smartproxy/forwarding/domain-config.ts +28 -0
  51. package/ts/smartproxy/forwarding/domain-manager.ts +283 -0
  52. package/ts/smartproxy/forwarding/forwarding.factory.ts +155 -0
  53. package/ts/smartproxy/forwarding/forwarding.handler.ts +127 -0
  54. package/ts/smartproxy/forwarding/http.handler.ts +140 -0
  55. package/ts/smartproxy/forwarding/https-passthrough.handler.ts +182 -0
  56. package/ts/smartproxy/forwarding/https-terminate-to-http.handler.ts +264 -0
  57. package/ts/smartproxy/forwarding/https-terminate-to-https.handler.ts +292 -0
  58. package/ts/smartproxy/forwarding/index.ts +52 -0
  59. package/ts/smartproxy/types/forwarding.types.ts +162 -0
package/readme.plan.md CHANGED
@@ -1,42 +1,471 @@
1
- # Plan: On-Demand Certificate Retrieval in NetworkProxy
2
-
3
- When a TLS connection arrives with an SNI for a domain that has no certificate yet, we want to automatically kick off certificate issuance (ACME HTTP-01 or DNS-01) so the domain is provisioned on the fly without prior manual configuration.
4
-
5
- ## Goals
6
- - Automatically initiate certificate issuance upon first TLS handshake for an unprovisioned domain.
7
- - Use Port80Handler (HTTP-01) or custom `certProvisionFunction` (e.g., DNS-01) to retrieve the certificate.
8
- - Continue the TLS handshake immediately using the default certificate, then swap to the new certificate on subsequent connections.
9
- - For HTTP traffic on port 80, register the domain for ACME and return a 503 until the challenge is complete.
10
-
11
- ## Plan
12
- 1. Detect missing certificate in SNI callback:
13
- - In `ts/networkproxy/classes.np.networkproxy.ts` (or within `CertificateManager.handleSNI`), after looking up `certificateCache`, if no cert is found:
14
- - Call `port80Handler.addDomain({ domainName, sslRedirect: false, acmeMaintenance: true })` to trigger dynamic provisioning.
15
- - Emit a `certificateRequested` event for observability.
16
- - Immediately call `cb(null, defaultSecureContext)` so the handshake uses the default cert.
17
-
18
- 2. HTTP-01 fallback on port 80:
19
- - In `ts/port80handler/classes.port80handler.ts``, in `handleRequest()`, when a request arrives for a new domain not in `domainCertificates`:
20
- - Call `addDomain({ domainName, sslRedirect: false, acmeMaintenance: true })`.
21
- - Return HTTP 503 with a message like “Certificate issuance in progress.”
22
-
23
- 3. CertProvisioner & events:
24
- - Ensure `CertProvisioner` is subscribed to `Port80Handler` for newly added domains.
25
- - After certificate issuance completes, `Port80Handler` emits `CERTIFICATE_ISSUED`, `CertificateManager` caches and writes disk, and future SNI callbacks will serve the new cert.
26
-
27
- 4. Metrics and cleanup:
28
- - Track dynamic requests count via a `certificateRequested` event or metric.
29
- - Handle error paths: if ACME/DNS fails, emit `CERTIFICATE_FAILED` and continue serving default cert.
30
-
31
- 5. Tests:
32
- - Simulate a TLS ClientHello for an unconfigured domain:
33
- Verify `port80Handler.addDomain` is called and `certificateRequested` event emitted.
34
- Confirm handshake completes with default cert context.
35
- - Simulate HTTP-01 challenge flow for a new domain:
36
- Verify on first HTTP request, `addDomain` is invoked and 503 returned.
37
- • After manually injecting a challenge in `Http01MemoryHandler`, verify 200 with key authorization.
38
- - Simulate successful ACME response and ensure SNI now returns the real cert.
39
-
40
- 6. Final validation:
41
- - Run `pnpm test` to ensure all existing tests pass.
42
- - Add new unit/integration tests for the dynamic provisioning flow.
1
+ # SmartProxy Unified Forwarding Configuration Plan
2
+
3
+ ## Project Goal
4
+ Create a clean, use-case driven forwarding configuration interface for SmartProxy that elegantly handles all forwarding scenarios: SNI-based forwarding, termination-based forwarding (NetworkProxy), HTTP forwarding, and ACME challenge forwarding.
5
+
6
+ ## Current State
7
+ Currently, SmartProxy has several different forwarding mechanisms configured separately:
8
+ 1. **HTTPS/SNI forwarding** via `IDomainConfig` properties
9
+ 2. **NetworkProxy forwarding** via `useNetworkProxy` in domain configs
10
+ 3. **HTTP forwarding** via Port80Handler's `forward` configuration
11
+ 4. **ACME challenge forwarding** via `acmeForward` configuration
12
+
13
+ This separation creates configuration complexity and reduced cohesion between related settings.
14
+
15
+ ## Proposed Solution: Clean Use-Case Driven Forwarding Interface
16
+
17
+ ### Phase 1: Design Streamlined Forwarding Interface
18
+
19
+ - [ ] Create a use-case driven `IForwardConfig` interface that simplifies configuration:
20
+
21
+ ```typescript
22
+ export interface IForwardConfig {
23
+ // Define the primary forwarding type - use-case driven approach
24
+ type: 'http-only' | 'https-passthrough' | 'https-terminate-to-http' | 'https-terminate-to-https';
25
+
26
+ // Target configuration
27
+ target: {
28
+ host: string | string[]; // Support single host or round-robin
29
+ port: number;
30
+ };
31
+
32
+ // HTTP-specific options
33
+ http?: {
34
+ enabled?: boolean; // Defaults to true for http-only, optional for others
35
+ redirectToHttps?: boolean; // Redirect HTTP to HTTPS
36
+ headers?: Record<string, string>; // Custom headers for HTTP responses
37
+ };
38
+
39
+ // HTTPS-specific options
40
+ https?: {
41
+ customCert?: { // Use custom cert instead of auto-provisioned
42
+ key: string;
43
+ cert: string;
44
+ };
45
+ forwardSni?: boolean; // Forward SNI info in passthrough mode
46
+ };
47
+
48
+ // ACME certificate handling
49
+ acme?: {
50
+ enabled?: boolean; // Enable ACME certificate provisioning
51
+ maintenance?: boolean; // Auto-renew certificates
52
+ production?: boolean; // Use production ACME servers
53
+ forwardChallenges?: { // Forward ACME challenges
54
+ host: string;
55
+ port: number;
56
+ useTls?: boolean;
57
+ };
58
+ };
59
+
60
+ // Security options
61
+ security?: {
62
+ allowedIps?: string[]; // IPs allowed to connect
63
+ blockedIps?: string[]; // IPs blocked from connecting
64
+ maxConnections?: number; // Max simultaneous connections
65
+ };
66
+
67
+ // Advanced options
68
+ advanced?: {
69
+ portRanges?: Array<{ from: number; to: number }>; // Allowed port ranges
70
+ networkProxyPort?: number; // Custom NetworkProxy port if using terminate mode
71
+ keepAlive?: boolean; // Enable TCP keepalive
72
+ timeout?: number; // Connection timeout in ms
73
+ headers?: Record<string, string>; // Custom headers with support for variables like {sni}
74
+ };
75
+ }
76
+ ```
77
+
78
+ ### Phase 2: Create New Domain Configuration Interface
79
+
80
+ - [ ] Replace existing `IDomainConfig` interface with a new one using the forwarding pattern:
81
+
82
+ ```typescript
83
+ export interface IDomainConfig {
84
+ // Core properties
85
+ domains: string[]; // Domain patterns to match
86
+
87
+ // Unified forwarding configuration
88
+ forwarding: IForwardConfig;
89
+ }
90
+ ```
91
+
92
+ ### Phase 3: Implement Forwarding Handler System
93
+
94
+ - [ ] Create an implementation strategy focused on the new forwarding types:
95
+
96
+ ```typescript
97
+ /**
98
+ * Base class for all forwarding handlers
99
+ */
100
+ abstract class ForwardingHandler {
101
+ constructor(protected config: IForwardConfig) {}
102
+
103
+ abstract handleConnection(socket: Socket): void;
104
+ abstract handleHttpRequest(req: IncomingMessage, res: ServerResponse): void;
105
+ }
106
+
107
+ /**
108
+ * Factory for creating the appropriate handler based on forwarding type
109
+ */
110
+ class ForwardingHandlerFactory {
111
+ public static createHandler(config: IForwardConfig): ForwardingHandler {
112
+ switch (config.type) {
113
+ case 'http-only':
114
+ return new HttpForwardingHandler(config);
115
+
116
+ case 'https-passthrough':
117
+ return new HttpsPassthroughHandler(config);
118
+
119
+ case 'https-terminate-to-http':
120
+ return new HttpsTerminateToHttpHandler(config);
121
+
122
+ case 'https-terminate-to-https':
123
+ return new HttpsTerminateToHttpsHandler(config);
124
+
125
+ default:
126
+ throw new Error(`Unknown forwarding type: ${config.type}`);
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ ## Usage Examples for Common Scenarios
133
+
134
+ ### 1. Basic HTTP Server
135
+
136
+ ```typescript
137
+ {
138
+ domains: ['example.com'],
139
+ forwarding: {
140
+ type: 'http-only',
141
+ target: {
142
+ host: 'localhost',
143
+ port: 3000
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ ### 2. HTTPS Termination with HTTP Backend
150
+
151
+ ```typescript
152
+ {
153
+ domains: ['secure.example.com'],
154
+ forwarding: {
155
+ type: 'https-terminate-to-http',
156
+ target: {
157
+ host: 'localhost',
158
+ port: 3000
159
+ },
160
+ acme: {
161
+ production: true // Use production Let's Encrypt
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ ### 3. HTTPS Termination with HTTPS Backend
168
+
169
+ ```typescript
170
+ {
171
+ domains: ['secure-backend.example.com'],
172
+ forwarding: {
173
+ type: 'https-terminate-to-https',
174
+ target: {
175
+ host: 'internal-api',
176
+ port: 8443
177
+ },
178
+ http: {
179
+ redirectToHttps: true // Redirect HTTP requests to HTTPS
180
+ }
181
+ }
182
+ }
183
+ ```
184
+
185
+ ### 4. SNI Passthrough
186
+
187
+ ```typescript
188
+ {
189
+ domains: ['passthrough.example.com'],
190
+ forwarding: {
191
+ type: 'https-passthrough',
192
+ target: {
193
+ host: '10.0.0.5',
194
+ port: 443
195
+ }
196
+ }
197
+ }
198
+ ```
199
+
200
+ ### 5. Mixed HTTP/HTTPS with Custom ACME Forwarding
201
+
202
+ ```typescript
203
+ {
204
+ domains: ['mixed.example.com'],
205
+ forwarding: {
206
+ type: 'https-terminate-to-http',
207
+ target: {
208
+ host: 'localhost',
209
+ port: 3000
210
+ },
211
+ http: {
212
+ redirectToHttps: false // Allow both HTTP and HTTPS access
213
+ },
214
+ acme: {
215
+ enabled: true,
216
+ maintenance: true,
217
+ forwardChallenges: {
218
+ host: '192.168.1.100',
219
+ port: 8080
220
+ }
221
+ }
222
+ }
223
+ }
224
+ ```
225
+
226
+ ### 6. Load-Balanced Backend
227
+
228
+ ```typescript
229
+ {
230
+ domains: ['api.example.com'],
231
+ forwarding: {
232
+ type: 'https-terminate-to-https',
233
+ target: {
234
+ host: ['10.0.0.10', '10.0.0.11', '10.0.0.12'], // Round-robin
235
+ port: 8443
236
+ },
237
+ security: {
238
+ allowedIps: ['10.0.0.*', '192.168.1.*'] // Restrict access
239
+ }
240
+ }
241
+ }
242
+ ```
243
+
244
+ ### 7. Advanced Proxy Chain with Custom Headers
245
+
246
+ ```typescript
247
+ {
248
+ domains: ['secure-chain.example.com'],
249
+ forwarding: {
250
+ type: 'https-terminate-to-https',
251
+ target: {
252
+ host: 'backend-gateway.internal',
253
+ port: 443
254
+ },
255
+ advanced: {
256
+ // Pass original client info to backend
257
+ headers: {
258
+ 'X-Original-SNI': '{sni}',
259
+ 'X-Client-IP': '{clientIp}'
260
+ }
261
+ }
262
+ }
263
+ }
264
+ ```
265
+
266
+ ## Implementation Plan
267
+
268
+ ### Task 1: Core Types and Interfaces (Week 1)
269
+ - [ ] Create the new `IForwardConfig` interface in `classes.pp.interfaces.ts`
270
+ - [ ] Design the new `IDomainConfig` interface using the forwarding property
271
+ - [ ] Define the internal data types for expanded configuration
272
+
273
+ ### Task 2: Forwarding Handlers (Week 1-2)
274
+ - [ ] Create abstract `ForwardingHandler` base class
275
+ - [ ] Implement concrete handlers for each forwarding type:
276
+ - [ ] `HttpForwardingHandler` - For HTTP-only configurations
277
+ - [ ] `HttpsPassthroughHandler` - For SNI passthrough
278
+ - [ ] `HttpsTerminateToHttpHandler` - For TLS termination to HTTP backends
279
+ - [ ] `HttpsTerminateToHttpsHandler` - For TLS termination to HTTPS backends
280
+ - [ ] Implement `ForwardingHandlerFactory` to create the appropriate handler
281
+
282
+ ### Task 3: SmartProxy Integration (Week 2-3)
283
+ - [ ] Update `SmartProxy` class to use the new forwarding system
284
+ - [ ] Modify `ConnectionHandler` to delegate to forwarding handlers
285
+ - [ ] Refactor domain configuration processing to use forwarding types
286
+ - [ ] Update `Port80Handler` integration to work with the new system
287
+
288
+ ### Task 4: Certificate Management (Week 3)
289
+ - [ ] Create a certificate management system that works with forwarding types
290
+ - [ ] Implement automatic ACME provisioning based on forwarding type
291
+ - [ ] Add custom certificate support
292
+
293
+ ### Task 5: Testing & Helper Functions (Week 4)
294
+ - [ ] Create helper functions for common forwarding patterns
295
+ - [ ] Implement comprehensive test suite for each forwarding handler
296
+ - [ ] Add validation for forwarding configurations
297
+
298
+ ### Task 6: Documentation (Week 4)
299
+ - [ ] Create detailed documentation for the new forwarding system
300
+ - [ ] Document the forwarding types and their use cases
301
+ - [ ] Update README with the new configuration examples
302
+
303
+ ## Detailed Type Documentation
304
+
305
+ ### Core Forwarding Types
306
+
307
+ ```typescript
308
+ /**
309
+ * The primary forwarding types supported by SmartProxy
310
+ */
311
+ export type ForwardingType =
312
+ | 'http-only' // HTTP forwarding only (no HTTPS)
313
+ | 'https-passthrough' // Pass-through TLS traffic (SNI forwarding)
314
+ | 'https-terminate-to-http' // Terminate TLS and forward to HTTP backend
315
+ | 'https-terminate-to-https'; // Terminate TLS and forward to HTTPS backend
316
+ ```
317
+
318
+ ### Type-Specific Behavior
319
+
320
+ Each forwarding type has specific default behavior:
321
+
322
+ #### HTTP-Only
323
+ - Handles only HTTP traffic
324
+ - No TLS/HTTPS support
325
+ - No certificate management
326
+
327
+ #### HTTPS Passthrough
328
+ - Forwards raw TLS traffic to backend (no termination)
329
+ - Passes SNI information through
330
+ - No HTTP support (TLS only)
331
+ - No certificate management
332
+
333
+ #### HTTPS Terminate to HTTP
334
+ - Terminates TLS at SmartProxy
335
+ - Connects to backend using HTTP (non-TLS)
336
+ - Manages certificates automatically (ACME)
337
+ - Supports HTTP requests with option to redirect to HTTPS
338
+
339
+ #### HTTPS Terminate to HTTPS
340
+ - Terminates client TLS at SmartProxy
341
+ - Creates new TLS connection to backend
342
+ - Manages certificates automatically (ACME)
343
+ - Supports HTTP requests with option to redirect to HTTPS
344
+
345
+ ## Handler Implementation Strategy
346
+
347
+ ```typescript
348
+ /**
349
+ * Handler for HTTP-only forwarding
350
+ */
351
+ class HttpForwardingHandler extends ForwardingHandler {
352
+ public handleConnection(socket: Socket): void {
353
+ // Process HTTP connection
354
+ // For HTTP-only, we'll mostly defer to handleHttpRequest
355
+ }
356
+
357
+ public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
358
+ // Forward HTTP request to target
359
+ const target = this.getTargetFromConfig();
360
+ this.proxyRequest(req, res, target);
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Handler for HTTPS passthrough (SNI forwarding)
366
+ */
367
+ class HttpsPassthroughHandler extends ForwardingHandler {
368
+ public handleConnection(socket: Socket): void {
369
+ // Extract SNI from TLS ClientHello if needed
370
+ // Forward raw TLS traffic to target without termination
371
+ const target = this.getTargetFromConfig();
372
+ this.forwardTlsConnection(socket, target);
373
+ }
374
+
375
+ public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
376
+ // HTTP not supported in SNI passthrough mode
377
+ res.statusCode = 404;
378
+ res.end('HTTP not supported for this domain');
379
+ }
380
+ }
381
+
382
+ /**
383
+ * Handler for HTTPS termination with HTTP backend
384
+ */
385
+ class HttpsTerminateToHttpHandler extends ForwardingHandler {
386
+ private tlsContext: SecureContext;
387
+
388
+ public async initialize(): Promise<void> {
389
+ // Set up TLS termination context
390
+ this.tlsContext = await this.createTlsContext();
391
+ }
392
+
393
+ public handleConnection(socket: Socket): void {
394
+ // Terminate TLS
395
+ const tlsSocket = this.createTlsSocket(socket, this.tlsContext);
396
+
397
+ // Forward to HTTP backend after TLS termination
398
+ tlsSocket.on('data', (data) => {
399
+ this.forwardToHttpBackend(data);
400
+ });
401
+ }
402
+
403
+ public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
404
+ if (this.config.http?.redirectToHttps) {
405
+ // Redirect to HTTPS if configured
406
+ this.redirectToHttps(req, res);
407
+ } else {
408
+ // Handle HTTP request
409
+ const target = this.getTargetFromConfig();
410
+ this.proxyRequest(req, res, target);
411
+ }
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Handler for HTTPS termination with HTTPS backend
417
+ */
418
+ class HttpsTerminateToHttpsHandler extends ForwardingHandler {
419
+ private tlsContext: SecureContext;
420
+
421
+ public async initialize(): Promise<void> {
422
+ // Set up TLS termination context
423
+ this.tlsContext = await this.createTlsContext();
424
+ }
425
+
426
+ public handleConnection(socket: Socket): void {
427
+ // Terminate client TLS
428
+ const tlsSocket = this.createTlsSocket(socket, this.tlsContext);
429
+
430
+ // Create new TLS connection to backend
431
+ tlsSocket.on('data', (data) => {
432
+ this.forwardToHttpsBackend(data);
433
+ });
434
+ }
435
+
436
+ public handleHttpRequest(req: IncomingMessage, res: ServerResponse): void {
437
+ if (this.config.http?.redirectToHttps) {
438
+ // Redirect to HTTPS if configured
439
+ this.redirectToHttps(req, res);
440
+ } else {
441
+ // Handle HTTP request via HTTPS to backend
442
+ const target = this.getTargetFromConfig();
443
+ this.proxyRequestOverHttps(req, res, target);
444
+ }
445
+ }
446
+ }
447
+ ```
448
+
449
+ ## Benefits of This Approach
450
+
451
+ 1. **Clean, Type-Driven Design**
452
+ - Forwarding types clearly express intent
453
+ - No backward compatibility compromises
454
+ - Code structure follows the domain model
455
+
456
+ 2. **Explicit Configuration**
457
+ - Configuration directly maps to behavior
458
+ - Reduced chance of unexpected behavior
459
+
460
+ 3. **Modular Implementation**
461
+ - Each forwarding type handled by dedicated class
462
+ - Clear separation of concerns
463
+ - Easier to test and extend
464
+
465
+ 4. **Simplified Mental Model**
466
+ - Users think in terms of use cases, not low-level settings
467
+ - Configuration matches mental model
468
+
469
+ 5. **Future-Proof**
470
+ - Easy to add new forwarding types
471
+ - Clean extension points for new features
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '10.2.0',
6
+ version: '12.0.0',
7
7
  description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
8
8
  }
@@ -0,0 +1,87 @@
1
+ import * as plugins from '../plugins.js';
2
+
3
+ import type {
4
+ IForwardConfig as ILegacyForwardConfig,
5
+ IDomainOptions
6
+ } from './types.js';
7
+
8
+ import type {
9
+ IForwardConfig
10
+ } from '../smartproxy/types/forwarding.types.js';
11
+
12
+ /**
13
+ * Converts a forwarding configuration target to the legacy format
14
+ * for Port80Handler
15
+ */
16
+ export function convertToLegacyForwardConfig(
17
+ forwardConfig: IForwardConfig
18
+ ): ILegacyForwardConfig {
19
+ // Determine host from the target configuration
20
+ const host = Array.isArray(forwardConfig.target.host)
21
+ ? forwardConfig.target.host[0] // Use the first host in the array
22
+ : forwardConfig.target.host;
23
+
24
+ return {
25
+ ip: host,
26
+ port: forwardConfig.target.port
27
+ };
28
+ }
29
+
30
+ /**
31
+ * Creates Port80Handler domain options from a domain name and forwarding config
32
+ */
33
+ export function createPort80HandlerOptions(
34
+ domain: string,
35
+ forwardConfig: IForwardConfig
36
+ ): IDomainOptions {
37
+ // Determine if we should redirect HTTP to HTTPS
38
+ let sslRedirect = false;
39
+ if (forwardConfig.http?.redirectToHttps) {
40
+ sslRedirect = true;
41
+ }
42
+
43
+ // Determine if ACME maintenance should be enabled
44
+ // Enable by default for termination types, unless explicitly disabled
45
+ const requiresTls =
46
+ forwardConfig.type === 'https-terminate-to-http' ||
47
+ forwardConfig.type === 'https-terminate-to-https';
48
+
49
+ const acmeMaintenance =
50
+ requiresTls &&
51
+ forwardConfig.acme?.enabled !== false;
52
+
53
+ // Set up forwarding configuration
54
+ const options: IDomainOptions = {
55
+ domainName: domain,
56
+ sslRedirect,
57
+ acmeMaintenance
58
+ };
59
+
60
+ // Add ACME challenge forwarding if configured
61
+ if (forwardConfig.acme?.forwardChallenges) {
62
+ options.acmeForward = {
63
+ ip: Array.isArray(forwardConfig.acme.forwardChallenges.host)
64
+ ? forwardConfig.acme.forwardChallenges.host[0]
65
+ : forwardConfig.acme.forwardChallenges.host,
66
+ port: forwardConfig.acme.forwardChallenges.port
67
+ };
68
+ }
69
+
70
+ // Add HTTP forwarding if this is an HTTP-only config or if HTTP is enabled
71
+ const supportsHttp =
72
+ forwardConfig.type === 'http-only' ||
73
+ (forwardConfig.http?.enabled !== false &&
74
+ (forwardConfig.type === 'https-terminate-to-http' ||
75
+ forwardConfig.type === 'https-terminate-to-https'));
76
+
77
+ if (supportsHttp) {
78
+ options.forward = {
79
+ ip: Array.isArray(forwardConfig.target.host)
80
+ ? forwardConfig.target.host[0]
81
+ : forwardConfig.target.host,
82
+ port: forwardConfig.target.port
83
+ };
84
+ }
85
+
86
+ return options;
87
+ }
package/ts/index.ts CHANGED
@@ -7,3 +7,6 @@ export * from './smartproxy/classes.pp.snihandler.js';
7
7
  export * from './smartproxy/classes.pp.interfaces.js';
8
8
 
9
9
  export * from './common/types.js';
10
+
11
+ // Export forwarding system
12
+ export * as forwarding from './smartproxy/forwarding/index.js';