@push.rocks/smartproxy 18.2.0 → 19.2.2

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 (63) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/common/eventUtils.d.ts +1 -2
  3. package/dist_ts/common/eventUtils.js +2 -1
  4. package/dist_ts/core/models/common-types.d.ts +1 -1
  5. package/dist_ts/core/models/common-types.js +1 -1
  6. package/dist_ts/core/utils/event-utils.d.ts +9 -9
  7. package/dist_ts/core/utils/event-utils.js +6 -14
  8. package/dist_ts/http/models/http-types.d.ts +13 -1
  9. package/dist_ts/http/models/http-types.js +1 -1
  10. package/dist_ts/index.d.ts +4 -6
  11. package/dist_ts/index.js +4 -10
  12. package/dist_ts/proxies/index.d.ts +3 -2
  13. package/dist_ts/proxies/index.js +4 -5
  14. package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +31 -49
  15. package/dist_ts/proxies/network-proxy/certificate-manager.js +77 -374
  16. package/dist_ts/proxies/network-proxy/models/types.d.ts +12 -1
  17. package/dist_ts/proxies/network-proxy/models/types.js +1 -1
  18. package/dist_ts/proxies/network-proxy/network-proxy.d.ts +2 -7
  19. package/dist_ts/proxies/network-proxy/network-proxy.js +10 -19
  20. package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +6 -0
  21. package/dist_ts/proxies/smart-proxy/certificate-manager.js +24 -5
  22. package/dist_ts/proxies/smart-proxy/models/index.d.ts +1 -1
  23. package/dist_ts/proxies/smart-proxy/models/index.js +1 -5
  24. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +30 -1
  25. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +4 -0
  26. package/dist_ts/proxies/smart-proxy/route-manager.js +7 -1
  27. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +4 -0
  28. package/dist_ts/proxies/smart-proxy/smart-proxy.js +112 -26
  29. package/package.json +1 -2
  30. package/readme.hints.md +31 -1
  31. package/readme.md +82 -6
  32. package/readme.plan.md +109 -1417
  33. package/ts/00_commitinfo_data.ts +1 -1
  34. package/ts/common/eventUtils.ts +2 -2
  35. package/ts/core/models/common-types.ts +1 -1
  36. package/ts/core/utils/event-utils.ts +12 -21
  37. package/ts/http/models/http-types.ts +8 -4
  38. package/ts/index.ts +11 -14
  39. package/ts/proxies/index.ts +7 -4
  40. package/ts/proxies/network-proxy/certificate-manager.ts +92 -417
  41. package/ts/proxies/network-proxy/models/types.ts +14 -2
  42. package/ts/proxies/network-proxy/network-proxy.ts +10 -19
  43. package/ts/proxies/smart-proxy/certificate-manager.ts +31 -4
  44. package/ts/proxies/smart-proxy/models/index.ts +2 -1
  45. package/ts/proxies/smart-proxy/models/interfaces.ts +31 -2
  46. package/ts/proxies/smart-proxy/models/route-types.ts +1 -1
  47. package/ts/proxies/smart-proxy/route-manager.ts +7 -0
  48. package/ts/proxies/smart-proxy/smart-proxy.ts +142 -25
  49. package/ts/certificate/acme/acme-factory.ts +0 -48
  50. package/ts/certificate/acme/challenge-handler.ts +0 -110
  51. package/ts/certificate/acme/index.ts +0 -3
  52. package/ts/certificate/events/certificate-events.ts +0 -36
  53. package/ts/certificate/index.ts +0 -75
  54. package/ts/certificate/models/certificate-types.ts +0 -109
  55. package/ts/certificate/providers/cert-provisioner.ts +0 -519
  56. package/ts/certificate/providers/index.ts +0 -3
  57. package/ts/certificate/storage/file-storage.ts +0 -234
  58. package/ts/certificate/storage/index.ts +0 -3
  59. package/ts/certificate/utils/certificate-helpers.ts +0 -50
  60. package/ts/http/port80/acme-interfaces.ts +0 -169
  61. package/ts/http/port80/challenge-responder.ts +0 -246
  62. package/ts/http/port80/index.ts +0 -13
  63. package/ts/http/port80/port80-handler.ts +0 -728
@@ -1,75 +0,0 @@
1
- /**
2
- * Certificate management module for SmartProxy
3
- * Provides certificate provisioning, storage, and management capabilities
4
- */
5
-
6
- // Certificate types and models
7
- export * from './models/certificate-types.js';
8
-
9
- // Certificate events
10
- export * from './events/certificate-events.js';
11
-
12
- // Certificate providers
13
- export * from './providers/cert-provisioner.js';
14
-
15
- // ACME related exports
16
- export * from './acme/acme-factory.js';
17
- export * from './acme/challenge-handler.js';
18
-
19
- // Certificate utilities
20
- export * from './utils/certificate-helpers.js';
21
-
22
- // Certificate storage
23
- export * from './storage/file-storage.js';
24
-
25
- // Convenience function to create a certificate provisioner with common settings
26
- import { CertProvisioner } from './providers/cert-provisioner.js';
27
- import type { TCertProvisionObject } from './providers/cert-provisioner.js';
28
- import { buildPort80Handler } from './acme/acme-factory.js';
29
- import type { IAcmeOptions, IRouteForwardConfig } from './models/certificate-types.js';
30
- import type { IRouteConfig } from '../proxies/smart-proxy/models/route-types.js';
31
-
32
- /**
33
- * Interface for NetworkProxyBridge used by CertProvisioner
34
- */
35
- interface ICertNetworkProxyBridge {
36
- applyExternalCertificate(certData: any): void;
37
- }
38
-
39
- /**
40
- * Creates a complete certificate provisioning system with default settings
41
- * @param routeConfigs Route configurations that may need certificates
42
- * @param acmeOptions ACME options for certificate provisioning
43
- * @param networkProxyBridge Bridge to apply certificates to network proxy
44
- * @param certProvider Optional custom certificate provider
45
- * @returns Configured CertProvisioner
46
- */
47
- export function createCertificateProvisioner(
48
- routeConfigs: IRouteConfig[],
49
- acmeOptions: IAcmeOptions,
50
- networkProxyBridge: ICertNetworkProxyBridge,
51
- certProvider?: (domain: string) => Promise<TCertProvisionObject>
52
- ): CertProvisioner {
53
- // Build the Port80Handler for ACME challenges
54
- const port80Handler = buildPort80Handler(acmeOptions);
55
-
56
- // Extract ACME-specific configuration
57
- const {
58
- renewThresholdDays = 30,
59
- renewCheckIntervalHours = 24,
60
- autoRenew = true,
61
- routeForwards = []
62
- } = acmeOptions;
63
-
64
- // Create and return the certificate provisioner
65
- return new CertProvisioner(
66
- routeConfigs,
67
- port80Handler,
68
- networkProxyBridge,
69
- certProvider,
70
- renewThresholdDays,
71
- renewCheckIntervalHours,
72
- autoRenew,
73
- routeForwards
74
- );
75
- }
@@ -1,109 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import type { IRouteConfig } from '../../proxies/smart-proxy/models/route-types.js';
3
-
4
- /**
5
- * Certificate data structure containing all necessary information
6
- * about a certificate
7
- */
8
- export interface ICertificateData {
9
- domain: string;
10
- certificate: string;
11
- privateKey: string;
12
- expiryDate: Date;
13
- // Optional source and renewal information for event emissions
14
- source?: 'static' | 'http01' | 'dns01';
15
- isRenewal?: boolean;
16
- // Reference to the route that requested this certificate (if available)
17
- routeReference?: {
18
- routeId?: string;
19
- routeName?: string;
20
- };
21
- }
22
-
23
- /**
24
- * Certificates pair (private and public keys)
25
- */
26
- export interface ICertificates {
27
- privateKey: string;
28
- publicKey: string;
29
- }
30
-
31
- /**
32
- * Certificate failure payload type
33
- */
34
- export interface ICertificateFailure {
35
- domain: string;
36
- error: string;
37
- isRenewal: boolean;
38
- routeReference?: {
39
- routeId?: string;
40
- routeName?: string;
41
- };
42
- }
43
-
44
- /**
45
- * Certificate expiry payload type
46
- */
47
- export interface ICertificateExpiring {
48
- domain: string;
49
- expiryDate: Date;
50
- daysRemaining: number;
51
- routeReference?: {
52
- routeId?: string;
53
- routeName?: string;
54
- };
55
- }
56
-
57
- /**
58
- * Route-specific forwarding configuration for ACME challenges
59
- */
60
- export interface IRouteForwardConfig {
61
- domain: string;
62
- target: {
63
- host: string;
64
- port: number;
65
- };
66
- sslRedirect?: boolean;
67
- }
68
-
69
- /**
70
- * Domain configuration options for Port80Handler
71
- *
72
- * This is used internally by the Port80Handler to manage domains
73
- * but will eventually be replaced with route-based options.
74
- */
75
- export interface IDomainOptions {
76
- domainName: string;
77
- sslRedirect: boolean; // if true redirects the request to port 443
78
- acmeMaintenance: boolean; // tries to always have a valid cert for this domain
79
- forward?: {
80
- ip: string;
81
- port: number;
82
- }; // forwards all http requests to that target
83
- acmeForward?: {
84
- ip: string;
85
- port: number;
86
- }; // forwards letsencrypt requests to this config
87
- routeReference?: {
88
- routeId?: string;
89
- routeName?: string;
90
- };
91
- }
92
-
93
- /**
94
- * Unified ACME configuration options used across proxies and handlers
95
- */
96
- export interface IAcmeOptions {
97
- accountEmail?: string; // Email for Let's Encrypt account
98
- enabled?: boolean; // Whether ACME is enabled
99
- port?: number; // Port to listen on for ACME challenges (default: 80)
100
- useProduction?: boolean; // Use production environment (default: staging)
101
- httpsRedirectPort?: number; // Port to redirect HTTP requests to HTTPS (default: 443)
102
- renewThresholdDays?: number; // Days before expiry to renew certificates
103
- renewCheckIntervalHours?: number; // How often to check for renewals (in hours)
104
- autoRenew?: boolean; // Whether to automatically renew certificates
105
- certificateStore?: string; // Directory to store certificates
106
- skipConfiguredCerts?: boolean; // Skip domains with existing certificates
107
- routeForwards?: IRouteForwardConfig[]; // Route-specific forwarding configs
108
- }
109
-
@@ -1,519 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import type { IRouteConfig } from '../../proxies/smart-proxy/models/route-types.js';
3
- import type { ICertificateData, IRouteForwardConfig, IDomainOptions } from '../models/certificate-types.js';
4
- import { Port80HandlerEvents, CertProvisionerEvents } from '../events/certificate-events.js';
5
- import { Port80Handler } from '../../http/port80/port80-handler.js';
6
-
7
- // Interface for NetworkProxyBridge
8
- interface INetworkProxyBridge {
9
- applyExternalCertificate(certData: ICertificateData): void;
10
- }
11
-
12
- /**
13
- * Type for static certificate provisioning
14
- */
15
- export type TCertProvisionObject = plugins.tsclass.network.ICert | 'http01' | 'dns01';
16
-
17
- /**
18
- * Interface for routes that need certificates
19
- */
20
- interface ICertRoute {
21
- domain: string;
22
- route: IRouteConfig;
23
- tlsMode: 'terminate' | 'terminate-and-reencrypt';
24
- }
25
-
26
- /**
27
- * CertProvisioner manages certificate provisioning and renewal workflows,
28
- * unifying static certificates and HTTP-01 challenges via Port80Handler.
29
- *
30
- * This class directly works with route configurations instead of converting to domain configs.
31
- */
32
- export class CertProvisioner extends plugins.EventEmitter {
33
- private routeConfigs: IRouteConfig[];
34
- private certRoutes: ICertRoute[] = [];
35
- private port80Handler: Port80Handler;
36
- private networkProxyBridge: INetworkProxyBridge;
37
- private certProvisionFunction?: (domain: string) => Promise<TCertProvisionObject>;
38
- private routeForwards: IRouteForwardConfig[];
39
- private renewThresholdDays: number;
40
- private renewCheckIntervalHours: number;
41
- private autoRenew: boolean;
42
- private renewManager?: plugins.taskbuffer.TaskManager;
43
- // Track provisioning type per domain
44
- private provisionMap: Map<string, { type: 'http01' | 'dns01' | 'static', routeRef?: ICertRoute }>;
45
-
46
- /**
47
- * Extract routes that need certificates
48
- * @param routes Route configurations
49
- */
50
- private extractCertificateRoutesFromRoutes(routes: IRouteConfig[]): ICertRoute[] {
51
- const certRoutes: ICertRoute[] = [];
52
-
53
- // Process all HTTPS routes that need certificates
54
- for (const route of routes) {
55
- // Only process routes with TLS termination that need certificates
56
- if (route.action.type === 'forward' &&
57
- route.action.tls &&
58
- (route.action.tls.mode === 'terminate' || route.action.tls.mode === 'terminate-and-reencrypt') &&
59
- route.match.domains) {
60
-
61
- // Extract domains from the route
62
- const domains = Array.isArray(route.match.domains)
63
- ? route.match.domains
64
- : [route.match.domains];
65
-
66
- // For each domain in the route, create a certRoute entry
67
- for (const domain of domains) {
68
- // Skip wildcard domains that can't use ACME unless we have a certProvider
69
- if (domain.includes('*') && (!this.certProvisionFunction || this.certProvisionFunction.length === 0)) {
70
- console.warn(`Skipping wildcard domain that requires a certProvisionFunction: ${domain}`);
71
- continue;
72
- }
73
-
74
- certRoutes.push({
75
- domain,
76
- route,
77
- tlsMode: route.action.tls.mode
78
- });
79
- }
80
- }
81
- }
82
-
83
- return certRoutes;
84
- }
85
-
86
- /**
87
- * Constructor for CertProvisioner
88
- *
89
- * @param routeConfigs Array of route configurations
90
- * @param port80Handler HTTP-01 challenge handler instance
91
- * @param networkProxyBridge Bridge for applying external certificates
92
- * @param certProvider Optional callback returning a static cert or 'http01'
93
- * @param renewThresholdDays Days before expiry to trigger renewals
94
- * @param renewCheckIntervalHours Interval in hours to check for renewals
95
- * @param autoRenew Whether to automatically schedule renewals
96
- * @param routeForwards Route-specific forwarding configs for ACME challenges
97
- */
98
- constructor(
99
- routeConfigs: IRouteConfig[],
100
- port80Handler: Port80Handler,
101
- networkProxyBridge: INetworkProxyBridge,
102
- certProvider?: (domain: string) => Promise<TCertProvisionObject>,
103
- renewThresholdDays: number = 30,
104
- renewCheckIntervalHours: number = 24,
105
- autoRenew: boolean = true,
106
- routeForwards: IRouteForwardConfig[] = []
107
- ) {
108
- super();
109
- this.routeConfigs = routeConfigs;
110
- this.port80Handler = port80Handler;
111
- this.networkProxyBridge = networkProxyBridge;
112
- this.certProvisionFunction = certProvider;
113
- this.renewThresholdDays = renewThresholdDays;
114
- this.renewCheckIntervalHours = renewCheckIntervalHours;
115
- this.autoRenew = autoRenew;
116
- this.provisionMap = new Map();
117
- this.routeForwards = routeForwards;
118
-
119
- // Extract certificate routes during instantiation
120
- this.certRoutes = this.extractCertificateRoutesFromRoutes(routeConfigs);
121
- }
122
-
123
- /**
124
- * Start initial provisioning and schedule renewals.
125
- */
126
- public async start(): Promise<void> {
127
- // Subscribe to Port80Handler certificate events
128
- this.setupEventSubscriptions();
129
-
130
- // Apply route forwarding for ACME challenges
131
- this.setupForwardingConfigs();
132
-
133
- // Initial provisioning for all domains in routes
134
- await this.provisionAllCertificates();
135
-
136
- // Schedule renewals if enabled
137
- if (this.autoRenew) {
138
- this.scheduleRenewals();
139
- }
140
- }
141
-
142
- /**
143
- * Set up event subscriptions for certificate events
144
- */
145
- private setupEventSubscriptions(): void {
146
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, (data: ICertificateData) => {
147
- // Add route reference if we have it
148
- const routeRef = this.findRouteForDomain(data.domain);
149
- const enhancedData: ICertificateData = {
150
- ...data,
151
- source: 'http01',
152
- isRenewal: false,
153
- routeReference: routeRef ? {
154
- routeId: routeRef.route.name,
155
- routeName: routeRef.route.name
156
- } : undefined
157
- };
158
-
159
- this.emit(CertProvisionerEvents.CERTIFICATE_ISSUED, enhancedData);
160
- });
161
-
162
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, (data: ICertificateData) => {
163
- // Add route reference if we have it
164
- const routeRef = this.findRouteForDomain(data.domain);
165
- const enhancedData: ICertificateData = {
166
- ...data,
167
- source: 'http01',
168
- isRenewal: true,
169
- routeReference: routeRef ? {
170
- routeId: routeRef.route.name,
171
- routeName: routeRef.route.name
172
- } : undefined
173
- };
174
-
175
- this.emit(CertProvisionerEvents.CERTIFICATE_RENEWED, enhancedData);
176
- });
177
-
178
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, (error) => {
179
- this.emit(CertProvisionerEvents.CERTIFICATE_FAILED, error);
180
- });
181
- }
182
-
183
- /**
184
- * Find a route for a given domain
185
- */
186
- private findRouteForDomain(domain: string): ICertRoute | undefined {
187
- return this.certRoutes.find(certRoute => certRoute.domain === domain);
188
- }
189
-
190
- /**
191
- * Set up forwarding configurations for the Port80Handler
192
- */
193
- private setupForwardingConfigs(): void {
194
- for (const config of this.routeForwards) {
195
- const domainOptions: IDomainOptions = {
196
- domainName: config.domain,
197
- sslRedirect: config.sslRedirect || false,
198
- acmeMaintenance: false,
199
- forward: config.target ? {
200
- ip: config.target.host,
201
- port: config.target.port
202
- } : undefined
203
- };
204
- this.port80Handler.addDomain(domainOptions);
205
- }
206
- }
207
-
208
- /**
209
- * Provision certificates for all routes that need them
210
- */
211
- private async provisionAllCertificates(): Promise<void> {
212
- for (const certRoute of this.certRoutes) {
213
- await this.provisionCertificateForRoute(certRoute);
214
- }
215
- }
216
-
217
- /**
218
- * Provision a certificate for a route
219
- */
220
- private async provisionCertificateForRoute(certRoute: ICertRoute): Promise<void> {
221
- const { domain, route } = certRoute;
222
- const isWildcard = domain.includes('*');
223
- let provision: TCertProvisionObject = 'http01';
224
-
225
- // Try to get a certificate from the provision function
226
- if (this.certProvisionFunction) {
227
- try {
228
- provision = await this.certProvisionFunction(domain);
229
- } catch (err) {
230
- console.error(`certProvider error for ${domain} on route ${route.name || 'unnamed'}:`, err);
231
- }
232
- } else if (isWildcard) {
233
- // No certProvider: cannot handle wildcard without DNS-01 support
234
- console.warn(`Skipping wildcard domain without certProvisionFunction: ${domain}`);
235
- return;
236
- }
237
-
238
- // Store the route reference with the provision type
239
- this.provisionMap.set(domain, {
240
- type: provision === 'http01' || provision === 'dns01' ? provision : 'static',
241
- routeRef: certRoute
242
- });
243
-
244
- // Handle different provisioning methods
245
- if (provision === 'http01') {
246
- if (isWildcard) {
247
- console.warn(`Skipping HTTP-01 for wildcard domain: ${domain}`);
248
- return;
249
- }
250
-
251
- this.port80Handler.addDomain({
252
- domainName: domain,
253
- sslRedirect: true,
254
- acmeMaintenance: true,
255
- routeReference: {
256
- routeId: route.name || domain,
257
- routeName: route.name
258
- }
259
- });
260
- } else if (provision === 'dns01') {
261
- // DNS-01 challenges would be handled by the certProvisionFunction
262
- // DNS-01 handling would go here if implemented
263
- console.log(`DNS-01 challenge type set for ${domain}`);
264
- } else {
265
- // Static certificate (e.g., DNS-01 provisioned or user-provided)
266
- const certObj = provision as plugins.tsclass.network.ICert;
267
- const certData: ICertificateData = {
268
- domain: certObj.domainName,
269
- certificate: certObj.publicKey,
270
- privateKey: certObj.privateKey,
271
- expiryDate: new Date(certObj.validUntil),
272
- source: 'static',
273
- isRenewal: false,
274
- routeReference: {
275
- routeId: route.name || domain,
276
- routeName: route.name
277
- }
278
- };
279
-
280
- this.networkProxyBridge.applyExternalCertificate(certData);
281
- this.emit(CertProvisionerEvents.CERTIFICATE_ISSUED, certData);
282
- }
283
- }
284
-
285
- /**
286
- * Schedule certificate renewals using a task manager
287
- */
288
- private scheduleRenewals(): void {
289
- this.renewManager = new plugins.taskbuffer.TaskManager();
290
-
291
- const renewTask = new plugins.taskbuffer.Task({
292
- name: 'CertificateRenewals',
293
- taskFunction: async () => await this.performRenewals()
294
- });
295
-
296
- const hours = this.renewCheckIntervalHours;
297
- const cronExpr = `0 0 */${hours} * * *`;
298
-
299
- this.renewManager.addAndScheduleTask(renewTask, cronExpr);
300
- this.renewManager.start();
301
- }
302
-
303
- /**
304
- * Perform renewals for all domains that need it
305
- */
306
- private async performRenewals(): Promise<void> {
307
- for (const [domain, info] of this.provisionMap.entries()) {
308
- // Skip wildcard domains for HTTP-01 challenges
309
- if (domain.includes('*') && info.type === 'http01') continue;
310
-
311
- try {
312
- await this.renewCertificateForDomain(domain, info.type, info.routeRef);
313
- } catch (err) {
314
- console.error(`Renewal error for ${domain}:`, err);
315
- }
316
- }
317
- }
318
-
319
- /**
320
- * Renew a certificate for a specific domain
321
- * @param domain Domain to renew
322
- * @param provisionType Type of provisioning for this domain
323
- * @param certRoute The route reference for this domain
324
- */
325
- private async renewCertificateForDomain(
326
- domain: string,
327
- provisionType: 'http01' | 'dns01' | 'static',
328
- certRoute?: ICertRoute
329
- ): Promise<void> {
330
- if (provisionType === 'http01') {
331
- await this.port80Handler.renewCertificate(domain);
332
- } else if ((provisionType === 'static' || provisionType === 'dns01') && this.certProvisionFunction) {
333
- const provision = await this.certProvisionFunction(domain);
334
-
335
- if (provision !== 'http01' && provision !== 'dns01') {
336
- const certObj = provision as plugins.tsclass.network.ICert;
337
- const routeRef = certRoute?.route;
338
-
339
- const certData: ICertificateData = {
340
- domain: certObj.domainName,
341
- certificate: certObj.publicKey,
342
- privateKey: certObj.privateKey,
343
- expiryDate: new Date(certObj.validUntil),
344
- source: 'static',
345
- isRenewal: true,
346
- routeReference: routeRef ? {
347
- routeId: routeRef.name || domain,
348
- routeName: routeRef.name
349
- } : undefined
350
- };
351
-
352
- this.networkProxyBridge.applyExternalCertificate(certData);
353
- this.emit(CertProvisionerEvents.CERTIFICATE_RENEWED, certData);
354
- }
355
- }
356
- }
357
-
358
- /**
359
- * Stop all scheduled renewal tasks.
360
- */
361
- public async stop(): Promise<void> {
362
- if (this.renewManager) {
363
- this.renewManager.stop();
364
- }
365
- }
366
-
367
- /**
368
- * Request a certificate on-demand for the given domain.
369
- * This will look for a matching route configuration and provision accordingly.
370
- *
371
- * @param domain Domain name to provision
372
- */
373
- public async requestCertificate(domain: string): Promise<void> {
374
- const isWildcard = domain.includes('*');
375
- // Find matching route
376
- const certRoute = this.findRouteForDomain(domain);
377
-
378
- // Determine provisioning method
379
- let provision: TCertProvisionObject = 'http01';
380
-
381
- if (this.certProvisionFunction) {
382
- provision = await this.certProvisionFunction(domain);
383
- } else if (isWildcard) {
384
- // Cannot perform HTTP-01 on wildcard without certProvider
385
- throw new Error(`Cannot request certificate for wildcard domain without certProvisionFunction: ${domain}`);
386
- }
387
-
388
- if (provision === 'http01') {
389
- if (isWildcard) {
390
- throw new Error(`Cannot request HTTP-01 certificate for wildcard domain: ${domain}`);
391
- }
392
- await this.port80Handler.renewCertificate(domain);
393
- } else if (provision === 'dns01') {
394
- // DNS-01 challenges would be handled by external mechanisms
395
- console.log(`DNS-01 challenge requested for ${domain}`);
396
- } else {
397
- // Static certificate (e.g., DNS-01 provisioned) supports wildcards
398
- const certObj = provision as plugins.tsclass.network.ICert;
399
- const certData: ICertificateData = {
400
- domain: certObj.domainName,
401
- certificate: certObj.publicKey,
402
- privateKey: certObj.privateKey,
403
- expiryDate: new Date(certObj.validUntil),
404
- source: 'static',
405
- isRenewal: false,
406
- routeReference: certRoute ? {
407
- routeId: certRoute.route.name || domain,
408
- routeName: certRoute.route.name
409
- } : undefined
410
- };
411
-
412
- this.networkProxyBridge.applyExternalCertificate(certData);
413
- this.emit(CertProvisionerEvents.CERTIFICATE_ISSUED, certData);
414
- }
415
- }
416
-
417
- /**
418
- * Add a new domain for certificate provisioning
419
- *
420
- * @param domain Domain to add
421
- * @param options Domain configuration options
422
- */
423
- public async addDomain(domain: string, options?: {
424
- sslRedirect?: boolean;
425
- acmeMaintenance?: boolean;
426
- routeId?: string;
427
- routeName?: string;
428
- }): Promise<void> {
429
- const domainOptions: IDomainOptions = {
430
- domainName: domain,
431
- sslRedirect: options?.sslRedirect ?? true,
432
- acmeMaintenance: options?.acmeMaintenance ?? true,
433
- routeReference: {
434
- routeId: options?.routeId,
435
- routeName: options?.routeName
436
- }
437
- };
438
-
439
- this.port80Handler.addDomain(domainOptions);
440
-
441
- // Find matching route or create a generic one
442
- const existingRoute = this.findRouteForDomain(domain);
443
- if (existingRoute) {
444
- await this.provisionCertificateForRoute(existingRoute);
445
- } else {
446
- // We don't have a route, just provision the domain
447
- const isWildcard = domain.includes('*');
448
- let provision: TCertProvisionObject = 'http01';
449
-
450
- if (this.certProvisionFunction) {
451
- provision = await this.certProvisionFunction(domain);
452
- } else if (isWildcard) {
453
- throw new Error(`Cannot request certificate for wildcard domain without certProvisionFunction: ${domain}`);
454
- }
455
-
456
- this.provisionMap.set(domain, {
457
- type: provision === 'http01' || provision === 'dns01' ? provision : 'static'
458
- });
459
-
460
- if (provision !== 'http01' && provision !== 'dns01') {
461
- const certObj = provision as plugins.tsclass.network.ICert;
462
- const certData: ICertificateData = {
463
- domain: certObj.domainName,
464
- certificate: certObj.publicKey,
465
- privateKey: certObj.privateKey,
466
- expiryDate: new Date(certObj.validUntil),
467
- source: 'static',
468
- isRenewal: false,
469
- routeReference: {
470
- routeId: options?.routeId,
471
- routeName: options?.routeName
472
- }
473
- };
474
-
475
- this.networkProxyBridge.applyExternalCertificate(certData);
476
- this.emit(CertProvisionerEvents.CERTIFICATE_ISSUED, certData);
477
- }
478
- }
479
- }
480
-
481
- /**
482
- * Update routes with new configurations
483
- * This replaces all existing routes with new ones and re-provisions certificates as needed
484
- *
485
- * @param newRoutes New route configurations to use
486
- */
487
- public async updateRoutes(newRoutes: IRouteConfig[]): Promise<void> {
488
- // Store the new route configs
489
- this.routeConfigs = newRoutes;
490
-
491
- // Extract new certificate routes
492
- const newCertRoutes = this.extractCertificateRoutesFromRoutes(newRoutes);
493
-
494
- // Find domains that no longer need certificates
495
- const oldDomains = new Set(this.certRoutes.map(r => r.domain));
496
- const newDomains = new Set(newCertRoutes.map(r => r.domain));
497
-
498
- // Domains to remove
499
- const domainsToRemove = [...oldDomains].filter(d => !newDomains.has(d));
500
-
501
- // Remove obsolete domains from provision map
502
- for (const domain of domainsToRemove) {
503
- this.provisionMap.delete(domain);
504
- }
505
-
506
- // Update the cert routes
507
- this.certRoutes = newCertRoutes;
508
-
509
- // Provision certificates for new routes
510
- for (const certRoute of newCertRoutes) {
511
- if (!oldDomains.has(certRoute.domain)) {
512
- await this.provisionCertificateForRoute(certRoute);
513
- }
514
- }
515
- }
516
- }
517
-
518
- // Type alias for backward compatibility
519
- export type TSmartProxyCertProvisionObject = TCertProvisionObject;
@@ -1,3 +0,0 @@
1
- /**
2
- * Certificate providers
3
- */