@push.rocks/smartproxy 18.0.2 → 18.2.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 +1 -1
- package/dist_ts/certificate/certificate-manager.d.ts +150 -0
- package/dist_ts/certificate/certificate-manager.js +505 -0
- package/dist_ts/certificate/events/simplified-events.d.ts +56 -0
- package/dist_ts/certificate/events/simplified-events.js +13 -0
- package/dist_ts/certificate/models/certificate-errors.d.ts +69 -0
- package/dist_ts/certificate/models/certificate-errors.js +141 -0
- package/dist_ts/certificate/models/certificate-strategy.d.ts +60 -0
- package/dist_ts/certificate/models/certificate-strategy.js +73 -0
- package/dist_ts/certificate/simplified-certificate-manager.d.ts +150 -0
- package/dist_ts/certificate/simplified-certificate-manager.js +501 -0
- package/dist_ts/http/index.d.ts +1 -9
- package/dist_ts/http/index.js +5 -11
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +4 -2
- package/dist_ts/proxies/network-proxy/network-proxy.js +3 -1
- package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.d.ts +48 -0
- package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.js +76 -0
- package/dist_ts/proxies/network-proxy/websocket-handler.js +41 -4
- package/dist_ts/proxies/smart-proxy/cert-store.d.ts +10 -0
- package/dist_ts/proxies/smart-proxy/cert-store.js +70 -0
- package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +116 -0
- package/dist_ts/proxies/smart-proxy/certificate-manager.js +401 -0
- package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.d.ts +168 -0
- package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.js +642 -0
- package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +26 -0
- package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
- package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.d.ts +65 -0
- package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.js +31 -0
- package/dist_ts/proxies/smart-proxy/models/smartproxy-options.d.ts +102 -0
- package/dist_ts/proxies/smart-proxy/models/smartproxy-options.js +73 -0
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +10 -44
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +66 -202
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +4 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +62 -2
- package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.d.ts +41 -0
- package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.js +132 -0
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +18 -13
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +79 -196
- package/package.json +7 -5
- package/readme.md +224 -10
- package/readme.plan.md +1405 -617
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/http/index.ts +5 -12
- package/ts/plugins.ts +4 -1
- package/ts/proxies/network-proxy/network-proxy.ts +3 -0
- package/ts/proxies/network-proxy/websocket-handler.ts +38 -3
- package/ts/proxies/smart-proxy/cert-store.ts +86 -0
- package/ts/proxies/smart-proxy/certificate-manager.ts +506 -0
- package/ts/proxies/smart-proxy/models/route-types.ts +33 -3
- package/ts/proxies/smart-proxy/network-proxy-bridge.ts +86 -239
- package/ts/proxies/smart-proxy/route-connection-handler.ts +74 -1
- package/ts/proxies/smart-proxy/smart-proxy.ts +105 -222
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured error types for certificate management
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Certificate-specific error class with structured information
|
|
6
|
+
*/
|
|
7
|
+
export class CertificateError extends Error {
|
|
8
|
+
constructor(details) {
|
|
9
|
+
super(details.message);
|
|
10
|
+
this.name = 'CertificateError';
|
|
11
|
+
this.code = details.code;
|
|
12
|
+
this.solution = details.solution;
|
|
13
|
+
this.domain = details.domain;
|
|
14
|
+
this.challengeType = details.challengeType;
|
|
15
|
+
this.details = details.details;
|
|
16
|
+
this.cause = details.cause;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Convert error to JSON for logging
|
|
20
|
+
*/
|
|
21
|
+
toJSON() {
|
|
22
|
+
return {
|
|
23
|
+
name: this.name,
|
|
24
|
+
code: this.code,
|
|
25
|
+
message: this.message,
|
|
26
|
+
solution: this.solution,
|
|
27
|
+
domain: this.domain,
|
|
28
|
+
challengeType: this.challengeType,
|
|
29
|
+
details: this.details,
|
|
30
|
+
cause: this.cause?.message,
|
|
31
|
+
stack: this.stack
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Common certificate error codes
|
|
37
|
+
*/
|
|
38
|
+
export const CertificateErrorCodes = {
|
|
39
|
+
// Configuration errors
|
|
40
|
+
NO_CERT_PROVIDER: 'NO_CERT_PROVIDER',
|
|
41
|
+
INVALID_CERT_PROVIDER: 'INVALID_CERT_PROVIDER',
|
|
42
|
+
MISSING_ACME_EMAIL: 'MISSING_ACME_EMAIL',
|
|
43
|
+
// ACME errors
|
|
44
|
+
ACME_HTTP_CHALLENGE_FAILED: 'ACME_HTTP_CHALLENGE_FAILED',
|
|
45
|
+
ACME_DNS_CHALLENGE_FAILED: 'ACME_DNS_CHALLENGE_FAILED',
|
|
46
|
+
ACME_RATE_LIMITED: 'ACME_RATE_LIMITED',
|
|
47
|
+
ACME_ACCOUNT_ERROR: 'ACME_ACCOUNT_ERROR',
|
|
48
|
+
ACME_VALIDATION_ERROR: 'ACME_VALIDATION_ERROR',
|
|
49
|
+
// Certificate errors
|
|
50
|
+
CERTIFICATE_EXPIRED: 'CERTIFICATE_EXPIRED',
|
|
51
|
+
CERTIFICATE_INVALID: 'CERTIFICATE_INVALID',
|
|
52
|
+
CERTIFICATE_NOT_FOUND: 'CERTIFICATE_NOT_FOUND',
|
|
53
|
+
CERTIFICATE_PARSE_ERROR: 'CERTIFICATE_PARSE_ERROR',
|
|
54
|
+
// Storage errors
|
|
55
|
+
STORAGE_READ_ERROR: 'STORAGE_READ_ERROR',
|
|
56
|
+
STORAGE_WRITE_ERROR: 'STORAGE_WRITE_ERROR',
|
|
57
|
+
STORAGE_PERMISSION_ERROR: 'STORAGE_PERMISSION_ERROR',
|
|
58
|
+
// Network errors
|
|
59
|
+
NETWORK_TIMEOUT: 'NETWORK_TIMEOUT',
|
|
60
|
+
NETWORK_UNREACHABLE: 'NETWORK_UNREACHABLE',
|
|
61
|
+
DNS_RESOLUTION_FAILED: 'DNS_RESOLUTION_FAILED',
|
|
62
|
+
// Domain errors
|
|
63
|
+
INVALID_DOMAIN: 'INVALID_DOMAIN',
|
|
64
|
+
WILDCARD_NOT_SUPPORTED: 'WILDCARD_NOT_SUPPORTED',
|
|
65
|
+
DOMAIN_NOT_CONFIGURED: 'DOMAIN_NOT_CONFIGURED'
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Helper functions for creating common certificate errors
|
|
69
|
+
*/
|
|
70
|
+
export const CertificateErrors = {
|
|
71
|
+
noCertProvider: () => new CertificateError({
|
|
72
|
+
code: CertificateErrorCodes.NO_CERT_PROVIDER,
|
|
73
|
+
message: 'Certificate provider is required when ACME is enabled',
|
|
74
|
+
solution: 'Configure a certProvider in your SmartProxy options'
|
|
75
|
+
}),
|
|
76
|
+
invalidCertProvider: (error) => new CertificateError({
|
|
77
|
+
code: CertificateErrorCodes.INVALID_CERT_PROVIDER,
|
|
78
|
+
message: 'Certificate provider returned invalid response',
|
|
79
|
+
solution: 'Ensure your certProvider returns a valid CertificateStrategy',
|
|
80
|
+
cause: error
|
|
81
|
+
}),
|
|
82
|
+
missingAcmeEmail: () => new CertificateError({
|
|
83
|
+
code: CertificateErrorCodes.MISSING_ACME_EMAIL,
|
|
84
|
+
message: 'ACME email is required for certificate provisioning',
|
|
85
|
+
solution: 'Configure acme.email in your SmartProxy options'
|
|
86
|
+
}),
|
|
87
|
+
acmeHttpChallengeFailed: (domain, details) => new CertificateError({
|
|
88
|
+
code: CertificateErrorCodes.ACME_HTTP_CHALLENGE_FAILED,
|
|
89
|
+
message: `HTTP-01 challenge failed for ${domain}`,
|
|
90
|
+
solution: 'Ensure port 80 is accessible and DNS points to this server',
|
|
91
|
+
domain,
|
|
92
|
+
challengeType: 'http',
|
|
93
|
+
details
|
|
94
|
+
}),
|
|
95
|
+
acmeDnsChallengeFailed: (domain, details) => new CertificateError({
|
|
96
|
+
code: CertificateErrorCodes.ACME_DNS_CHALLENGE_FAILED,
|
|
97
|
+
message: `DNS-01 challenge failed for ${domain}`,
|
|
98
|
+
solution: 'Verify DNS TXT record is correctly set for the domain',
|
|
99
|
+
domain,
|
|
100
|
+
challengeType: 'dns',
|
|
101
|
+
details
|
|
102
|
+
}),
|
|
103
|
+
acmeRateLimited: (domain, resetTime) => new CertificateError({
|
|
104
|
+
code: CertificateErrorCodes.ACME_RATE_LIMITED,
|
|
105
|
+
message: `ACME rate limit exceeded for ${domain}`,
|
|
106
|
+
solution: resetTime
|
|
107
|
+
? `Wait until ${resetTime.toISOString()} before retrying`
|
|
108
|
+
: 'Wait before retrying or use staging environment for testing',
|
|
109
|
+
domain,
|
|
110
|
+
details: { resetTime }
|
|
111
|
+
}),
|
|
112
|
+
certificateExpired: (domain, expiredAt) => new CertificateError({
|
|
113
|
+
code: CertificateErrorCodes.CERTIFICATE_EXPIRED,
|
|
114
|
+
message: `Certificate for ${domain} expired at ${expiredAt.toISOString()}`,
|
|
115
|
+
solution: 'Renew the certificate or configure automatic renewal',
|
|
116
|
+
domain,
|
|
117
|
+
details: { expiredAt }
|
|
118
|
+
}),
|
|
119
|
+
certificateNotFound: (domain) => new CertificateError({
|
|
120
|
+
code: CertificateErrorCodes.CERTIFICATE_NOT_FOUND,
|
|
121
|
+
message: `No certificate found for ${domain}`,
|
|
122
|
+
solution: 'Request a new certificate or provide a static certificate',
|
|
123
|
+
domain
|
|
124
|
+
}),
|
|
125
|
+
wildcardNotSupported: (domain) => new CertificateError({
|
|
126
|
+
code: CertificateErrorCodes.WILDCARD_NOT_SUPPORTED,
|
|
127
|
+
message: `Wildcard domain ${domain} requires DNS-01 challenge`,
|
|
128
|
+
solution: 'Configure your certProvider to return acme-dns strategy for wildcards',
|
|
129
|
+
domain
|
|
130
|
+
}),
|
|
131
|
+
storageError: (operation, path, error) => new CertificateError({
|
|
132
|
+
code: operation === 'read'
|
|
133
|
+
? CertificateErrorCodes.STORAGE_READ_ERROR
|
|
134
|
+
: CertificateErrorCodes.STORAGE_WRITE_ERROR,
|
|
135
|
+
message: `Failed to ${operation} certificate at ${path}`,
|
|
136
|
+
solution: `Check file permissions and ensure directory exists`,
|
|
137
|
+
details: { path },
|
|
138
|
+
cause: error
|
|
139
|
+
})
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydGlmaWNhdGUtZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvY2VydGlmaWNhdGUvbW9kZWxzL2NlcnRpZmljYXRlLWVycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQVlIOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGdCQUFpQixTQUFRLEtBQUs7SUFRekMsWUFBWSxPQUFnQztRQUMxQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7UUFDL0IsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUNqQyxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDN0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBQzNDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztRQUMvQixJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDN0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ksTUFBTTtRQUNYLE9BQU87WUFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDckIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ3ZCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7WUFDakMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU87WUFDMUIsS0FBSyxFQUFFLElBQUksQ0FBQyxL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
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Certificate strategy types for SmartProxy
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Certificate strategy types
|
|
6
|
+
*/
|
|
7
|
+
export type CertificateStrategy = {
|
|
8
|
+
type: 'acme-http';
|
|
9
|
+
} | {
|
|
10
|
+
type: 'acme-dns';
|
|
11
|
+
} | {
|
|
12
|
+
type: 'static';
|
|
13
|
+
cert: string;
|
|
14
|
+
key: string;
|
|
15
|
+
expiresAt?: Date;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'skip';
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Certificate provider function type
|
|
21
|
+
*/
|
|
22
|
+
export type CertProvider = (domain: string) => Promise<CertificateStrategy>;
|
|
23
|
+
/**
|
|
24
|
+
* Helper functions for creating certificate strategies
|
|
25
|
+
*/
|
|
26
|
+
export declare const CertStrategies: {
|
|
27
|
+
/**
|
|
28
|
+
* Use ACME HTTP-01 challenge
|
|
29
|
+
*/
|
|
30
|
+
acmeHttp: () => CertificateStrategy;
|
|
31
|
+
/**
|
|
32
|
+
* Use ACME DNS-01 challenge (required for wildcards)
|
|
33
|
+
*/
|
|
34
|
+
acmeDns: () => CertificateStrategy;
|
|
35
|
+
/**
|
|
36
|
+
* Use static certificate
|
|
37
|
+
*/
|
|
38
|
+
static: (cert: string, key: string, expiresAt?: Date) => CertificateStrategy;
|
|
39
|
+
/**
|
|
40
|
+
* Skip certificate provisioning for this domain
|
|
41
|
+
*/
|
|
42
|
+
skip: () => CertificateStrategy;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Built-in certificate providers
|
|
46
|
+
*/
|
|
47
|
+
export declare const defaultCertProviders: {
|
|
48
|
+
/**
|
|
49
|
+
* Standard ACME provider: HTTP-01 for regular domains, DNS-01 for wildcards
|
|
50
|
+
*/
|
|
51
|
+
standard: (domain: string) => Promise<CertificateStrategy>;
|
|
52
|
+
/**
|
|
53
|
+
* Use static certificates from disk if available, fallback to ACME
|
|
54
|
+
*/
|
|
55
|
+
withStaticFallback: (certDir: string) => (domain: string) => Promise<CertificateStrategy>;
|
|
56
|
+
/**
|
|
57
|
+
* Always skip certificate provisioning
|
|
58
|
+
*/
|
|
59
|
+
skip: () => Promise<CertificateStrategy>;
|
|
60
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Certificate strategy types for SmartProxy
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Helper functions for creating certificate strategies
|
|
6
|
+
*/
|
|
7
|
+
export const CertStrategies = {
|
|
8
|
+
/**
|
|
9
|
+
* Use ACME HTTP-01 challenge
|
|
10
|
+
*/
|
|
11
|
+
acmeHttp: () => ({ type: 'acme-http' }),
|
|
12
|
+
/**
|
|
13
|
+
* Use ACME DNS-01 challenge (required for wildcards)
|
|
14
|
+
*/
|
|
15
|
+
acmeDns: () => ({ type: 'acme-dns' }),
|
|
16
|
+
/**
|
|
17
|
+
* Use static certificate
|
|
18
|
+
*/
|
|
19
|
+
static: (cert, key, expiresAt) => ({
|
|
20
|
+
type: 'static',
|
|
21
|
+
cert,
|
|
22
|
+
key,
|
|
23
|
+
expiresAt
|
|
24
|
+
}),
|
|
25
|
+
/**
|
|
26
|
+
* Skip certificate provisioning for this domain
|
|
27
|
+
*/
|
|
28
|
+
skip: () => ({ type: 'skip' })
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Built-in certificate providers
|
|
32
|
+
*/
|
|
33
|
+
export const defaultCertProviders = {
|
|
34
|
+
/**
|
|
35
|
+
* Standard ACME provider: HTTP-01 for regular domains, DNS-01 for wildcards
|
|
36
|
+
*/
|
|
37
|
+
standard: (domain) => {
|
|
38
|
+
return Promise.resolve(domain.includes('*')
|
|
39
|
+
? CertStrategies.acmeDns()
|
|
40
|
+
: CertStrategies.acmeHttp());
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Use static certificates from disk if available, fallback to ACME
|
|
44
|
+
*/
|
|
45
|
+
withStaticFallback: (certDir) => {
|
|
46
|
+
return async (domain) => {
|
|
47
|
+
const fs = await import('fs/promises');
|
|
48
|
+
const path = await import('path');
|
|
49
|
+
const certPath = path.join(certDir, `${domain}.crt`);
|
|
50
|
+
const keyPath = path.join(certDir, `${domain}.key`);
|
|
51
|
+
try {
|
|
52
|
+
const [cert, key] = await Promise.all([
|
|
53
|
+
fs.readFile(certPath, 'utf-8'),
|
|
54
|
+
fs.readFile(keyPath, 'utf-8')
|
|
55
|
+
]);
|
|
56
|
+
return CertStrategies.static(cert, key);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// File not found, fallback to ACME
|
|
60
|
+
return domain.includes('*')
|
|
61
|
+
? CertStrategies.acmeDns()
|
|
62
|
+
: CertStrategies.acmeHttp();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Always skip certificate provisioning
|
|
68
|
+
*/
|
|
69
|
+
skip: () => {
|
|
70
|
+
return Promise.resolve(CertStrategies.skip());
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydGlmaWNhdGUtc3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jZXJ0aWZpY2F0ZS9tb2RlbHMvY2VydGlmaWNhdGUtc3RyYXRlZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFnQkg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUc7SUFDNUI7O09BRUc7SUFDSCxRQUFRLEVBQUUsR0FBd0IsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFFNUQ7O09BRUc7SUFDSCxPQUFPLEVBQUUsR0FBd0IsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUM7SUFFMUQ7O09BRUc7SUFDSCxNQUFNLEVBQUUsQ0FBQyxJQUFZLEVBQUUsR0FBVyxFQUFFLFNBQWdCLEVBQXVCLEVBQUUsQ0FBQyxDQUFDO1FBQzdFLElBQUksRUFBRSxRQUFRO1FBQ2QsSUFBSTtRQUNKLEdBQUc7UUFDSCxTQUFTO0tBQ1YsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFBSSxFQUFFLEdBQXdCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0NBQ3BELENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHO0lBQ2xDOztPQUVHO0lBQ0gsUUFBUSxFQUFFLENBQUMsTUFBYyxFQUFnQyxFQUFFO1FBQ3pELE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FDcEIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7WUFDbEIsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUU7WUFDMUIsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FDOUIsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILGtCQUFrQixFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUU7UUFDdEMsT0FBTyxLQUFLLEVBQUUsTUFBYyxFQUFnQyxFQUFFO1lBQzVELE1BQU0sRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sSUFBSSxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRWxDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsQ0FBQztZQUNyRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLENBQUM7WUFFcEQsSUFBSSxDQUFDO2dCQUNILE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO29CQUNwQyxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUM7b0JBQzlCLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQztpQkFDOUIsQ0FBQyxDQUFDO2dCQUVILE9BQU8sY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDMUMsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCxtQ0FBbUM7Z0JBQ25DLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7b0JBQ3pCLENBQUMsQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFO29CQUMxQixDQUFDLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2hDLENBQUM7UUFDSCxDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLEVBQUUsR0FBaUMsRUFBRTtRQUN2QyxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQztDQUNGLENBQUMifQ==
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simplified, unified certificate manager for SmartProxy
|
|
3
|
+
*/
|
|
4
|
+
import * as plugins from '../plugins.js';
|
|
5
|
+
import type { CertProvider } from './models/certificate-strategy.js';
|
|
6
|
+
import type { CertificateEventMap, ICertificateEventEmitter } from './events/simplified-events.js';
|
|
7
|
+
import type { IRouteConfig } from '../proxies/smart-proxy/models/route-types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Certificate storage format
|
|
10
|
+
*/
|
|
11
|
+
interface StoredCertificate {
|
|
12
|
+
domain: string;
|
|
13
|
+
certificate: string;
|
|
14
|
+
privateKey: string;
|
|
15
|
+
expiresAt: Date;
|
|
16
|
+
source: 'acme-http' | 'acme-dns' | 'static';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Certificate manager configuration
|
|
20
|
+
*/
|
|
21
|
+
export interface CertificateManagerConfig {
|
|
22
|
+
certProvider: CertProvider;
|
|
23
|
+
acmeEmail: string;
|
|
24
|
+
acmeServer: 'production' | 'staging';
|
|
25
|
+
storageDir?: string;
|
|
26
|
+
renewBeforeDays?: number;
|
|
27
|
+
defaultCertPath?: string;
|
|
28
|
+
defaultKeyPath?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Unified certificate manager
|
|
32
|
+
*/
|
|
33
|
+
export declare class SimplifiedCertificateManager extends plugins.EventEmitter implements ICertificateEventEmitter {
|
|
34
|
+
private config;
|
|
35
|
+
private certificateCache;
|
|
36
|
+
private acmeClient;
|
|
37
|
+
private renewalTimer?;
|
|
38
|
+
private pendingRequests;
|
|
39
|
+
constructor(config: CertificateManagerConfig);
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the certificate manager
|
|
42
|
+
*/
|
|
43
|
+
start(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Stop the certificate manager
|
|
46
|
+
*/
|
|
47
|
+
stop(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a certificate for a domain (main entry point)
|
|
50
|
+
*/
|
|
51
|
+
getCertificate(domain: string): Promise<StoredCertificate>;
|
|
52
|
+
/**
|
|
53
|
+
* Request a new certificate
|
|
54
|
+
*/
|
|
55
|
+
private requestCertificate;
|
|
56
|
+
/**
|
|
57
|
+
* Request certificate via ACME HTTP-01
|
|
58
|
+
*/
|
|
59
|
+
private requestAcmeHttpCertificate;
|
|
60
|
+
/**
|
|
61
|
+
* Request certificate via ACME DNS-01
|
|
62
|
+
*/
|
|
63
|
+
private requestAcmeDnsCertificate;
|
|
64
|
+
/**
|
|
65
|
+
* Renew a certificate
|
|
66
|
+
*/
|
|
67
|
+
renewCertificate(domain: string): Promise<StoredCertificate>;
|
|
68
|
+
/**
|
|
69
|
+
* Check certificates for renewal
|
|
70
|
+
*/
|
|
71
|
+
private checkForRenewals;
|
|
72
|
+
/**
|
|
73
|
+
* Initialize ACME client
|
|
74
|
+
*/
|
|
75
|
+
private initializeAcmeClient;
|
|
76
|
+
/**
|
|
77
|
+
* Load stored certificates from disk
|
|
78
|
+
*/
|
|
79
|
+
private loadStoredCertificates;
|
|
80
|
+
/**
|
|
81
|
+
* Store certificate to disk
|
|
82
|
+
*/
|
|
83
|
+
private storeCertificate;
|
|
84
|
+
/**
|
|
85
|
+
* Ensure storage directory exists
|
|
86
|
+
*/
|
|
87
|
+
private ensureStorageDir;
|
|
88
|
+
/**
|
|
89
|
+
* Get or create ACME account key
|
|
90
|
+
*/
|
|
91
|
+
private getOrCreateAccountKey;
|
|
92
|
+
/**
|
|
93
|
+
* Generate keypair for certificate
|
|
94
|
+
*/
|
|
95
|
+
private generateKeypair;
|
|
96
|
+
/**
|
|
97
|
+
* Generate CSR for domain
|
|
98
|
+
*/
|
|
99
|
+
private generateCsr;
|
|
100
|
+
/**
|
|
101
|
+
* Extract expiry date from certificate
|
|
102
|
+
*/
|
|
103
|
+
private extractExpiryDate;
|
|
104
|
+
/**
|
|
105
|
+
* Check if certificate is valid
|
|
106
|
+
*/
|
|
107
|
+
private isCertificateValid;
|
|
108
|
+
/**
|
|
109
|
+
* Check if certificate should be renewed
|
|
110
|
+
*/
|
|
111
|
+
private shouldRenew;
|
|
112
|
+
/**
|
|
113
|
+
* Check if certificate is expiring soon
|
|
114
|
+
*/
|
|
115
|
+
private isExpiringSoon;
|
|
116
|
+
/**
|
|
117
|
+
* Get days remaining until expiry
|
|
118
|
+
*/
|
|
119
|
+
private getDaysRemaining;
|
|
120
|
+
/**
|
|
121
|
+
* Start renewal timer
|
|
122
|
+
*/
|
|
123
|
+
private startRenewalTimer;
|
|
124
|
+
/**
|
|
125
|
+
* Get default certificate for SNI fallback
|
|
126
|
+
*/
|
|
127
|
+
getDefaultCertificate(): Promise<{
|
|
128
|
+
cert: string;
|
|
129
|
+
key: string;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Set up HTTP challenge responder
|
|
133
|
+
*/
|
|
134
|
+
private setupHttpChallenge;
|
|
135
|
+
/**
|
|
136
|
+
* Clean up HTTP challenge
|
|
137
|
+
*/
|
|
138
|
+
private cleanupHttpChallenge;
|
|
139
|
+
/**
|
|
140
|
+
* Type assertion for event emitter
|
|
141
|
+
*/
|
|
142
|
+
on<K extends keyof CertificateEventMap>(event: K, listener: (data: CertificateEventMap[K]) => void): this;
|
|
143
|
+
off<K extends keyof CertificateEventMap>(event: K, listener: (data: CertificateEventMap[K]) => void): this;
|
|
144
|
+
emit<K extends keyof CertificateEventMap>(event: K, data: CertificateEventMap[K]): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* Update routes (placeholder for future implementation)
|
|
147
|
+
*/
|
|
148
|
+
updateRoutes(routes: IRouteConfig[]): Promise<void>;
|
|
149
|
+
}
|
|
150
|
+
export {};
|