@push.rocks/smartproxy 7.1.2 → 10.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/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/classes.router.d.ts +9 -10
- package/dist_ts/classes.router.js +3 -5
- package/dist_ts/common/acmeFactory.d.ts +9 -0
- package/dist_ts/common/acmeFactory.js +20 -0
- package/dist_ts/common/eventUtils.d.ts +15 -0
- package/dist_ts/common/eventUtils.js +19 -0
- package/dist_ts/common/types.d.ts +82 -0
- package/dist_ts/common/types.js +17 -0
- package/dist_ts/networkproxy/classes.np.certificatemanager.js +23 -19
- package/dist_ts/networkproxy/classes.np.networkproxy.d.ts +1 -0
- package/dist_ts/networkproxy/classes.np.networkproxy.js +5 -1
- package/dist_ts/networkproxy/classes.np.types.d.ts +5 -10
- package/dist_ts/networkproxy/classes.np.types.js +1 -1
- package/dist_ts/plugins.d.ts +6 -3
- package/dist_ts/plugins.js +7 -4
- package/dist_ts/port80handler/classes.port80handler.d.ts +14 -111
- package/dist_ts/port80handler/classes.port80handler.js +94 -373
- package/dist_ts/smartproxy/classes.pp.certprovisioner.d.ts +54 -0
- package/dist_ts/smartproxy/classes.pp.certprovisioner.js +166 -0
- package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +11 -33
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +5 -0
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +21 -11
- package/dist_ts/smartproxy/classes.pp.portrangemanager.js +1 -11
- package/dist_ts/smartproxy/classes.smartproxy.d.ts +3 -5
- package/dist_ts/smartproxy/classes.smartproxy.js +94 -180
- package/package.json +12 -10
- package/readme.hints.md +64 -1
- package/readme.md +253 -408
- package/readme.plan.md +29 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.router.ts +13 -15
- package/ts/common/acmeFactory.ts +23 -0
- package/ts/common/eventUtils.ts +34 -0
- package/ts/common/types.ts +89 -0
- package/ts/networkproxy/classes.np.certificatemanager.ts +23 -19
- package/ts/networkproxy/classes.np.networkproxy.ts +4 -0
- package/ts/networkproxy/classes.np.types.ts +6 -10
- package/ts/plugins.ts +17 -4
- package/ts/port80handler/classes.port80handler.ts +108 -509
- package/ts/smartproxy/classes.pp.certprovisioner.ts +188 -0
- package/ts/smartproxy/classes.pp.interfaces.ts +13 -36
- package/ts/smartproxy/classes.pp.networkproxybridge.ts +22 -10
- package/ts/smartproxy/classes.pp.portrangemanager.ts +0 -10
- package/ts/smartproxy/classes.smartproxy.ts +103 -195
package/readme.plan.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Project Simplification Plan
|
|
2
|
+
|
|
3
|
+
This document outlines a roadmap to simplify and refactor the SmartProxy & NetworkProxy codebase for better maintainability, reduced duplication, and clearer configuration.
|
|
4
|
+
|
|
5
|
+
## Goals
|
|
6
|
+
- Eliminate duplicate code and shared types
|
|
7
|
+
- Unify certificate management flow across components
|
|
8
|
+
- Simplify configuration schemas and option handling
|
|
9
|
+
- Centralize plugin imports and module interfaces
|
|
10
|
+
- Strengthen type safety and linting
|
|
11
|
+
- Improve test coverage and CI integration
|
|
12
|
+
|
|
13
|
+
## Plan
|
|
14
|
+
- [x] Extract all shared interfaces and types (e.g., certificate, proxy, domain configs) into a common `ts/common` module
|
|
15
|
+
- [x] Consolidate ACME/Port80Handler logic:
|
|
16
|
+
- [x] Merge standalone Port80Handler into a single certificate service
|
|
17
|
+
- [x] Remove duplicate ACME setup in SmartProxy and NetworkProxy
|
|
18
|
+
- [x] Unify configuration options:
|
|
19
|
+
- [x] Merge `INetworkProxyOptions.acme`, `IPort80HandlerOptions`, and `port80HandlerConfig` into one schema
|
|
20
|
+
- [x] Deprecate old option names and provide clear upgrade path
|
|
21
|
+
- [ ] Centralize plugin imports in `ts/plugins.ts` and update all modules to use it
|
|
22
|
+
- [x] Remove legacy or unused code paths (e.g., old HTTP/2 fallback logic if obsolete)
|
|
23
|
+
- [ ] Enhance and expand test coverage:
|
|
24
|
+
- Add unit tests for certificate issuance, renewal, and error handling
|
|
25
|
+
- Add integration tests for HTTP challenge routing and request forwarding
|
|
26
|
+
- [ ] Update main README.md with architecture overview and configuration guide
|
|
27
|
+
- [ ] Review and prune external dependencies no longer needed
|
|
28
|
+
|
|
29
|
+
Once these steps are complete, the project will be cleaner, easier to understand, and simpler to extend.
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartproxy',
|
|
6
|
-
version: '
|
|
6
|
+
version: '10.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
|
}
|
package/ts/classes.router.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as url from 'url';
|
|
3
|
-
import * as tsclass from '@tsclass/tsclass';
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Optional path pattern configuration that can be added to proxy configs
|
|
@@ -13,7 +11,7 @@ export interface IPathPatternConfig {
|
|
|
13
11
|
* Interface for router result with additional metadata
|
|
14
12
|
*/
|
|
15
13
|
export interface IRouterResult {
|
|
16
|
-
config: tsclass.network.IReverseProxyConfig;
|
|
14
|
+
config: plugins.tsclass.network.IReverseProxyConfig;
|
|
17
15
|
pathMatch?: string;
|
|
18
16
|
pathParams?: Record<string, string>;
|
|
19
17
|
pathRemainder?: string;
|
|
@@ -36,11 +34,11 @@ export interface IRouterResult {
|
|
|
36
34
|
*/
|
|
37
35
|
export class ProxyRouter {
|
|
38
36
|
// Store original configs for reference
|
|
39
|
-
private reverseProxyConfigs: tsclass.network.IReverseProxyConfig[] = [];
|
|
37
|
+
private reverseProxyConfigs: plugins.tsclass.network.IReverseProxyConfig[] = [];
|
|
40
38
|
// Default config to use when no match is found (optional)
|
|
41
|
-
private defaultConfig?: tsclass.network.IReverseProxyConfig;
|
|
39
|
+
private defaultConfig?: plugins.tsclass.network.IReverseProxyConfig;
|
|
42
40
|
// Store path patterns separately since they're not in the original interface
|
|
43
|
-
private pathPatterns: Map<tsclass.network.IReverseProxyConfig, string> = new Map();
|
|
41
|
+
private pathPatterns: Map<plugins.tsclass.network.IReverseProxyConfig, string> = new Map();
|
|
44
42
|
// Logger interface
|
|
45
43
|
private logger: {
|
|
46
44
|
error: (message: string, data?: any) => void;
|
|
@@ -50,7 +48,7 @@ export class ProxyRouter {
|
|
|
50
48
|
};
|
|
51
49
|
|
|
52
50
|
constructor(
|
|
53
|
-
configs?: tsclass.network.IReverseProxyConfig[],
|
|
51
|
+
configs?: plugins.tsclass.network.IReverseProxyConfig[],
|
|
54
52
|
logger?: {
|
|
55
53
|
error: (message: string, data?: any) => void;
|
|
56
54
|
warn: (message: string, data?: any) => void;
|
|
@@ -68,7 +66,7 @@ export class ProxyRouter {
|
|
|
68
66
|
* Sets a new set of reverse configs to be routed to
|
|
69
67
|
* @param reverseCandidatesArg Array of reverse proxy configurations
|
|
70
68
|
*/
|
|
71
|
-
public setNewProxyConfigs(reverseCandidatesArg: tsclass.network.IReverseProxyConfig[]): void {
|
|
69
|
+
public setNewProxyConfigs(reverseCandidatesArg: plugins.tsclass.network.IReverseProxyConfig[]): void {
|
|
72
70
|
this.reverseProxyConfigs = [...reverseCandidatesArg];
|
|
73
71
|
|
|
74
72
|
// Find default config if any (config with "*" as hostname)
|
|
@@ -82,7 +80,7 @@ export class ProxyRouter {
|
|
|
82
80
|
* @param req The incoming HTTP request
|
|
83
81
|
* @returns The matching proxy config or undefined if no match found
|
|
84
82
|
*/
|
|
85
|
-
public routeReq(req: http.IncomingMessage): tsclass.network.IReverseProxyConfig {
|
|
83
|
+
public routeReq(req: plugins.http.IncomingMessage): plugins.tsclass.network.IReverseProxyConfig {
|
|
86
84
|
const result = this.routeReqWithDetails(req);
|
|
87
85
|
return result ? result.config : undefined;
|
|
88
86
|
}
|
|
@@ -92,7 +90,7 @@ export class ProxyRouter {
|
|
|
92
90
|
* @param req The incoming HTTP request
|
|
93
91
|
* @returns Detailed routing result including matched config and path information
|
|
94
92
|
*/
|
|
95
|
-
public routeReqWithDetails(req: http.IncomingMessage): IRouterResult | undefined {
|
|
93
|
+
public routeReqWithDetails(req: plugins.http.IncomingMessage): IRouterResult | undefined {
|
|
96
94
|
// Extract and validate host header
|
|
97
95
|
const originalHost = req.headers.host;
|
|
98
96
|
if (!originalHost) {
|
|
@@ -101,7 +99,7 @@ export class ProxyRouter {
|
|
|
101
99
|
}
|
|
102
100
|
|
|
103
101
|
// Parse URL for path matching
|
|
104
|
-
const parsedUrl = url.parse(req.url || '/');
|
|
102
|
+
const parsedUrl = plugins.url.parse(req.url || '/');
|
|
105
103
|
const urlPath = parsedUrl.pathname || '/';
|
|
106
104
|
|
|
107
105
|
// Extract hostname without port
|
|
@@ -351,7 +349,7 @@ export class ProxyRouter {
|
|
|
351
349
|
* Gets all currently active proxy configurations
|
|
352
350
|
* @returns Array of all active configurations
|
|
353
351
|
*/
|
|
354
|
-
public getProxyConfigs(): tsclass.network.IReverseProxyConfig[] {
|
|
352
|
+
public getProxyConfigs(): plugins.tsclass.network.IReverseProxyConfig[] {
|
|
355
353
|
return [...this.reverseProxyConfigs];
|
|
356
354
|
}
|
|
357
355
|
|
|
@@ -375,7 +373,7 @@ export class ProxyRouter {
|
|
|
375
373
|
* @param pathPattern Optional path pattern for route matching
|
|
376
374
|
*/
|
|
377
375
|
public addProxyConfig(
|
|
378
|
-
config: tsclass.network.IReverseProxyConfig,
|
|
376
|
+
config: plugins.tsclass.network.IReverseProxyConfig,
|
|
379
377
|
pathPattern?: string
|
|
380
378
|
): void {
|
|
381
379
|
this.reverseProxyConfigs.push(config);
|
|
@@ -393,7 +391,7 @@ export class ProxyRouter {
|
|
|
393
391
|
* @returns Boolean indicating if the config was found and updated
|
|
394
392
|
*/
|
|
395
393
|
public setPathPattern(
|
|
396
|
-
config: tsclass.network.IReverseProxyConfig,
|
|
394
|
+
config: plugins.tsclass.network.IReverseProxyConfig,
|
|
397
395
|
pathPattern: string
|
|
398
396
|
): boolean {
|
|
399
397
|
const exists = this.reverseProxyConfigs.includes(config);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import type { IAcmeOptions } from './types.js';
|
|
4
|
+
import { Port80Handler } from '../port80handler/classes.port80handler.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Factory to create a Port80Handler with common setup.
|
|
8
|
+
* Ensures the certificate store directory exists and instantiates the handler.
|
|
9
|
+
* @param options Port80Handler configuration options
|
|
10
|
+
* @returns A new Port80Handler instance
|
|
11
|
+
*/
|
|
12
|
+
export function buildPort80Handler(
|
|
13
|
+
options: IAcmeOptions
|
|
14
|
+
): Port80Handler {
|
|
15
|
+
if (options.certificateStore) {
|
|
16
|
+
const certStorePath = path.resolve(options.certificateStore);
|
|
17
|
+
if (!fs.existsSync(certStorePath)) {
|
|
18
|
+
fs.mkdirSync(certStorePath, { recursive: true });
|
|
19
|
+
console.log(`Created certificate store directory: ${certStorePath}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return new Port80Handler(options);
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Port80Handler } from '../port80handler/classes.port80handler.js';
|
|
2
|
+
import { Port80HandlerEvents } from './types.js';
|
|
3
|
+
import type { ICertificateData, ICertificateFailure, ICertificateExpiring } from './types.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Subscribers callback definitions for Port80Handler events
|
|
7
|
+
*/
|
|
8
|
+
export interface Port80HandlerSubscribers {
|
|
9
|
+
onCertificateIssued?: (data: ICertificateData) => void;
|
|
10
|
+
onCertificateRenewed?: (data: ICertificateData) => void;
|
|
11
|
+
onCertificateFailed?: (data: ICertificateFailure) => void;
|
|
12
|
+
onCertificateExpiring?: (data: ICertificateExpiring) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Subscribes to Port80Handler events based on provided callbacks
|
|
17
|
+
*/
|
|
18
|
+
export function subscribeToPort80Handler(
|
|
19
|
+
handler: Port80Handler,
|
|
20
|
+
subscribers: Port80HandlerSubscribers
|
|
21
|
+
): void {
|
|
22
|
+
if (subscribers.onCertificateIssued) {
|
|
23
|
+
handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, subscribers.onCertificateIssued);
|
|
24
|
+
}
|
|
25
|
+
if (subscribers.onCertificateRenewed) {
|
|
26
|
+
handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, subscribers.onCertificateRenewed);
|
|
27
|
+
}
|
|
28
|
+
if (subscribers.onCertificateFailed) {
|
|
29
|
+
handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, subscribers.onCertificateFailed);
|
|
30
|
+
}
|
|
31
|
+
if (subscribers.onCertificateExpiring) {
|
|
32
|
+
handler.on(Port80HandlerEvents.CERTIFICATE_EXPIRING, subscribers.onCertificateExpiring);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for certificate management and domain options
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Domain forwarding configuration
|
|
7
|
+
*/
|
|
8
|
+
export interface IForwardConfig {
|
|
9
|
+
ip: string;
|
|
10
|
+
port: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Domain configuration options
|
|
15
|
+
*/
|
|
16
|
+
export interface IDomainOptions {
|
|
17
|
+
domainName: string;
|
|
18
|
+
sslRedirect: boolean; // if true redirects the request to port 443
|
|
19
|
+
acmeMaintenance: boolean; // tries to always have a valid cert for this domain
|
|
20
|
+
forward?: IForwardConfig; // forwards all http requests to that target
|
|
21
|
+
acmeForward?: IForwardConfig; // forwards letsencrypt requests to this config
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Certificate data that can be emitted via events or set from outside
|
|
26
|
+
*/
|
|
27
|
+
export interface ICertificateData {
|
|
28
|
+
domain: string;
|
|
29
|
+
certificate: string;
|
|
30
|
+
privateKey: string;
|
|
31
|
+
expiryDate: Date;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Events emitted by the Port80Handler
|
|
36
|
+
*/
|
|
37
|
+
export enum Port80HandlerEvents {
|
|
38
|
+
CERTIFICATE_ISSUED = 'certificate-issued',
|
|
39
|
+
CERTIFICATE_RENEWED = 'certificate-renewed',
|
|
40
|
+
CERTIFICATE_FAILED = 'certificate-failed',
|
|
41
|
+
CERTIFICATE_EXPIRING = 'certificate-expiring',
|
|
42
|
+
MANAGER_STARTED = 'manager-started',
|
|
43
|
+
MANAGER_STOPPED = 'manager-stopped',
|
|
44
|
+
REQUEST_FORWARDED = 'request-forwarded',
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Certificate failure payload type
|
|
49
|
+
*/
|
|
50
|
+
export interface ICertificateFailure {
|
|
51
|
+
domain: string;
|
|
52
|
+
error: string;
|
|
53
|
+
isRenewal: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Certificate expiry payload type
|
|
58
|
+
*/
|
|
59
|
+
export interface ICertificateExpiring {
|
|
60
|
+
domain: string;
|
|
61
|
+
expiryDate: Date;
|
|
62
|
+
daysRemaining: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Forwarding configuration for specific domains in ACME setup
|
|
66
|
+
*/
|
|
67
|
+
export interface IDomainForwardConfig {
|
|
68
|
+
domain: string;
|
|
69
|
+
forwardConfig?: IForwardConfig;
|
|
70
|
+
acmeForwardConfig?: IForwardConfig;
|
|
71
|
+
sslRedirect?: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Unified ACME configuration options used across proxies and handlers
|
|
76
|
+
*/
|
|
77
|
+
export interface IAcmeOptions {
|
|
78
|
+
enabled?: boolean; // Whether ACME is enabled
|
|
79
|
+
port?: number; // Port to listen on for ACME challenges (default: 80)
|
|
80
|
+
contactEmail?: string; // Email for Let's Encrypt account
|
|
81
|
+
useProduction?: boolean; // Use production environment (default: staging)
|
|
82
|
+
httpsRedirectPort?: number; // Port to redirect HTTP requests to HTTPS (default: 443)
|
|
83
|
+
renewThresholdDays?: number; // Days before expiry to renew certificates
|
|
84
|
+
renewCheckIntervalHours?: number; // How often to check for renewals (in hours)
|
|
85
|
+
autoRenew?: boolean; // Whether to automatically renew certificates
|
|
86
|
+
certificateStore?: string; // Directory to store certificates
|
|
87
|
+
skipConfiguredCerts?: boolean; // Skip domains with existing certificates
|
|
88
|
+
domainForwards?: IDomainForwardConfig[]; // Domain-specific forwarding configs
|
|
89
|
+
}
|
|
@@ -3,7 +3,11 @@ import * as fs from 'fs';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { type INetworkProxyOptions, type ICertificateEntry, type ILogger, createLogger } from './classes.np.types.js';
|
|
6
|
-
import { Port80Handler
|
|
6
|
+
import { Port80Handler } from '../port80handler/classes.port80handler.js';
|
|
7
|
+
import { Port80HandlerEvents } from '../common/types.js';
|
|
8
|
+
import { buildPort80Handler } from '../common/acmeFactory.js';
|
|
9
|
+
import { subscribeToPort80Handler } from '../common/eventUtils.js';
|
|
10
|
+
import type { IDomainOptions } from '../common/types.js';
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* Manages SSL certificates for NetworkProxy including ACME integration
|
|
@@ -101,12 +105,14 @@ export class CertificateManager {
|
|
|
101
105
|
this.port80Handler = handler;
|
|
102
106
|
this.externalPort80Handler = true;
|
|
103
107
|
|
|
104
|
-
//
|
|
105
|
-
this.port80Handler
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
// Subscribe to Port80Handler events
|
|
109
|
+
subscribeToPort80Handler(this.port80Handler, {
|
|
110
|
+
onCertificateIssued: this.handleCertificateIssued.bind(this),
|
|
111
|
+
onCertificateRenewed: this.handleCertificateIssued.bind(this),
|
|
112
|
+
onCertificateFailed: this.handleCertificateFailed.bind(this),
|
|
113
|
+
onCertificateExpiring: (data) => {
|
|
114
|
+
this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
|
|
115
|
+
}
|
|
110
116
|
});
|
|
111
117
|
|
|
112
118
|
this.logger.info('External Port80Handler connected to CertificateManager');
|
|
@@ -348,26 +354,24 @@ export class CertificateManager {
|
|
|
348
354
|
return null;
|
|
349
355
|
}
|
|
350
356
|
|
|
351
|
-
//
|
|
352
|
-
this.port80Handler =
|
|
357
|
+
// Build and configure Port80Handler
|
|
358
|
+
this.port80Handler = buildPort80Handler({
|
|
353
359
|
port: this.options.acme.port,
|
|
354
360
|
contactEmail: this.options.acme.contactEmail,
|
|
355
361
|
useProduction: this.options.acme.useProduction,
|
|
356
|
-
renewThresholdDays: this.options.acme.renewThresholdDays,
|
|
357
362
|
httpsRedirectPort: this.options.port, // Redirect to our HTTPS port
|
|
358
|
-
renewCheckIntervalHours: 24, // Check daily for renewals
|
|
359
363
|
enabled: this.options.acme.enabled,
|
|
360
|
-
autoRenew: this.options.acme.autoRenew,
|
|
361
364
|
certificateStore: this.options.acme.certificateStore,
|
|
362
365
|
skipConfiguredCerts: this.options.acme.skipConfiguredCerts
|
|
363
366
|
});
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
367
|
+
// Subscribe to Port80Handler events
|
|
368
|
+
subscribeToPort80Handler(this.port80Handler, {
|
|
369
|
+
onCertificateIssued: this.handleCertificateIssued.bind(this),
|
|
370
|
+
onCertificateRenewed: this.handleCertificateIssued.bind(this),
|
|
371
|
+
onCertificateFailed: this.handleCertificateFailed.bind(this),
|
|
372
|
+
onCertificateExpiring: (data) => {
|
|
373
|
+
this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
|
|
374
|
+
}
|
|
371
375
|
});
|
|
372
376
|
|
|
373
377
|
// Start the handler
|
|
@@ -12,6 +12,10 @@ import { Port80Handler } from '../port80handler/classes.port80handler.js';
|
|
|
12
12
|
* automatic certificate management, and high-performance connection pooling.
|
|
13
13
|
*/
|
|
14
14
|
export class NetworkProxy implements IMetricsTracker {
|
|
15
|
+
// Provide a minimal JSON representation to avoid circular references during deep equality checks
|
|
16
|
+
public toJSON(): any {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
15
19
|
// Configuration
|
|
16
20
|
public options: INetworkProxyOptions;
|
|
17
21
|
public proxyConfigs: IReverseProxyConfig[] = [];
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for NetworkProxy
|
|
5
|
+
*/
|
|
6
|
+
import type { IAcmeOptions } from '../common/types.js';
|
|
7
|
+
|
|
3
8
|
/**
|
|
4
9
|
* Configuration options for NetworkProxy
|
|
5
10
|
*/
|
|
@@ -24,16 +29,7 @@ export interface INetworkProxyOptions {
|
|
|
24
29
|
backendProtocol?: 'http1' | 'http2';
|
|
25
30
|
|
|
26
31
|
// ACME certificate management options
|
|
27
|
-
acme?:
|
|
28
|
-
enabled?: boolean; // Whether to enable automatic certificate management
|
|
29
|
-
port?: number; // Port to listen on for ACME challenges (default: 80)
|
|
30
|
-
contactEmail?: string; // Email for Let's Encrypt account
|
|
31
|
-
useProduction?: boolean; // Whether to use Let's Encrypt production (default: false for staging)
|
|
32
|
-
renewThresholdDays?: number; // Days before expiry to renew certificates (default: 30)
|
|
33
|
-
autoRenew?: boolean; // Whether to automatically renew certificates (default: true)
|
|
34
|
-
certificateStore?: string; // Directory to store certificates (default: ./certs)
|
|
35
|
-
skipConfiguredCerts?: boolean; // Skip domains that already have certificates configured
|
|
36
|
-
};
|
|
32
|
+
acme?: IAcmeOptions;
|
|
37
33
|
}
|
|
38
34
|
|
|
39
35
|
/**
|
package/ts/plugins.ts
CHANGED
|
@@ -7,7 +7,6 @@ import * as tls from 'tls';
|
|
|
7
7
|
import * as url from 'url';
|
|
8
8
|
import * as http2 from 'http2';
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
export { EventEmitter, http, https, net, tls, url, http2 };
|
|
12
11
|
|
|
13
12
|
// tsclass scope
|
|
@@ -22,13 +21,27 @@ import * as smartpromise from '@push.rocks/smartpromise';
|
|
|
22
21
|
import * as smartrequest from '@push.rocks/smartrequest';
|
|
23
22
|
import * as smartstring from '@push.rocks/smartstring';
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
import * as smartacme from '@push.rocks/smartacme';
|
|
25
|
+
import * as smartacmePlugins from '@push.rocks/smartacme/dist_ts/smartacme.plugins.js';
|
|
26
|
+
import * as smartacmeHandlers from '@push.rocks/smartacme/dist_ts/handlers/index.js';
|
|
27
|
+
import * as taskbuffer from '@push.rocks/taskbuffer';
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
lik,
|
|
31
|
+
smartdelay,
|
|
32
|
+
smartrequest,
|
|
33
|
+
smartpromise,
|
|
34
|
+
smartstring,
|
|
35
|
+
smartacme,
|
|
36
|
+
smartacmePlugins,
|
|
37
|
+
smartacmeHandlers,
|
|
38
|
+
taskbuffer,
|
|
39
|
+
};
|
|
26
40
|
|
|
27
41
|
// third party scope
|
|
28
|
-
import * as acme from 'acme-client';
|
|
29
42
|
import prettyMs from 'pretty-ms';
|
|
30
43
|
import * as ws from 'ws';
|
|
31
44
|
import wsDefault from 'ws';
|
|
32
45
|
import { minimatch } from 'minimatch';
|
|
33
46
|
|
|
34
|
-
export {
|
|
47
|
+
export { prettyMs, ws, wsDefault, minimatch };
|