@push.rocks/smartproxy 7.2.0 → 10.0.1

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 (41) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/classes.router.d.ts +9 -10
  3. package/dist_ts/classes.router.js +3 -5
  4. package/dist_ts/common/acmeFactory.d.ts +9 -0
  5. package/dist_ts/common/acmeFactory.js +20 -0
  6. package/dist_ts/common/eventUtils.d.ts +15 -0
  7. package/dist_ts/common/eventUtils.js +19 -0
  8. package/dist_ts/common/types.d.ts +82 -0
  9. package/dist_ts/common/types.js +17 -0
  10. package/dist_ts/networkproxy/classes.np.certificatemanager.js +23 -19
  11. package/dist_ts/networkproxy/classes.np.types.d.ts +5 -10
  12. package/dist_ts/networkproxy/classes.np.types.js +1 -1
  13. package/dist_ts/plugins.d.ts +2 -1
  14. package/dist_ts/plugins.js +3 -2
  15. package/dist_ts/port80handler/classes.port80handler.d.ts +8 -91
  16. package/dist_ts/port80handler/classes.port80handler.js +34 -222
  17. package/dist_ts/smartproxy/classes.pp.certprovisioner.d.ts +54 -0
  18. package/dist_ts/smartproxy/classes.pp.certprovisioner.js +166 -0
  19. package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +2 -33
  20. package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +2 -1
  21. package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +11 -11
  22. package/dist_ts/smartproxy/classes.pp.portrangemanager.js +1 -11
  23. package/dist_ts/smartproxy/classes.smartproxy.d.ts +1 -4
  24. package/dist_ts/smartproxy/classes.smartproxy.js +62 -213
  25. package/package.json +2 -1
  26. package/readme.md +254 -453
  27. package/readme.plan.md +27 -29
  28. package/ts/00_commitinfo_data.ts +1 -1
  29. package/ts/classes.router.ts +13 -15
  30. package/ts/common/acmeFactory.ts +23 -0
  31. package/ts/common/eventUtils.ts +34 -0
  32. package/ts/common/types.ts +89 -0
  33. package/ts/networkproxy/classes.np.certificatemanager.ts +23 -19
  34. package/ts/networkproxy/classes.np.types.ts +6 -10
  35. package/ts/plugins.ts +13 -2
  36. package/ts/port80handler/classes.port80handler.ts +44 -310
  37. package/ts/smartproxy/classes.pp.certprovisioner.ts +188 -0
  38. package/ts/smartproxy/classes.pp.interfaces.ts +3 -36
  39. package/ts/smartproxy/classes.pp.networkproxybridge.ts +11 -10
  40. package/ts/smartproxy/classes.pp.portrangemanager.ts +0 -10
  41. package/ts/smartproxy/classes.smartproxy.ts +73 -222
@@ -21,6 +21,7 @@ export interface IDomainConfig {
21
21
  }
22
22
 
23
23
  /** Port proxy settings including global allowed port ranges */
24
+ import type { IAcmeOptions } from '../common/types.js';
24
25
  export interface IPortProxySettings {
25
26
  fromPort: number;
26
27
  toPort: number;
@@ -83,43 +84,9 @@ export interface IPortProxySettings {
83
84
  useNetworkProxy?: number[]; // Array of ports to forward to NetworkProxy
84
85
  networkProxyPort?: number; // Port where NetworkProxy is listening (default: 8443)
85
86
 
86
- // Port80Handler configuration (replaces ACME configuration)
87
- port80HandlerConfig?: {
88
- enabled?: boolean; // Whether to enable automatic certificate management
89
- port?: number; // Port to listen on for ACME challenges (default: 80)
90
- contactEmail?: string; // Email for Let's Encrypt account
91
- useProduction?: boolean; // Whether to use Let's Encrypt production (default: false for staging)
92
- renewThresholdDays?: number; // Days before expiry to renew certificates (default: 30)
93
- autoRenew?: boolean; // Whether to automatically renew certificates (default: true)
94
- certificateStore?: string; // Directory to store certificates (default: ./certs)
95
- skipConfiguredCerts?: boolean; // Skip domains that already have certificates
96
- httpsRedirectPort?: number; // Port to redirect HTTP requests to HTTPS (default: 443)
97
- renewCheckIntervalHours?: number; // How often to check for renewals (default: 24)
98
- // Domain-specific forwarding configurations
99
- domainForwards?: Array<{
100
- domain: string;
101
- forwardConfig?: {
102
- ip: string;
103
- port: number;
104
- };
105
- acmeForwardConfig?: {
106
- ip: string;
107
- port: number;
108
- };
109
- }>;
110
- };
87
+ // ACME configuration options for SmartProxy
88
+ acme?: IAcmeOptions;
111
89
 
112
- // Legacy ACME configuration (deprecated, use port80HandlerConfig instead)
113
- acme?: {
114
- enabled?: boolean;
115
- port?: number;
116
- contactEmail?: string;
117
- useProduction?: boolean;
118
- renewThresholdDays?: number;
119
- autoRenew?: boolean;
120
- certificateStore?: string;
121
- skipConfiguredCerts?: boolean;
122
- };
123
90
  /**
124
91
  * Optional certificate provider callback. Return 'http01' to use HTTP-01 challenges,
125
92
  * or a static certificate object for immediate provisioning.
@@ -1,6 +1,9 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import { NetworkProxy } from '../networkproxy/classes.np.networkproxy.js';
3
- import { Port80Handler, Port80HandlerEvents, type ICertificateData } from '../port80handler/classes.port80handler.js';
3
+ import { Port80Handler } from '../port80handler/classes.port80handler.js';
4
+ import { Port80HandlerEvents } from '../common/types.js';
5
+ import { subscribeToPort80Handler } from '../common/eventUtils.js';
6
+ import type { ICertificateData } from '../common/types.js';
4
7
  import type { IConnectionRecord, IPortProxySettings, IDomainConfig } from './classes.pp.interfaces.js';
5
8
 
6
9
  /**
@@ -18,9 +21,11 @@ export class NetworkProxyBridge {
18
21
  public setPort80Handler(handler: Port80Handler): void {
19
22
  this.port80Handler = handler;
20
23
 
21
- // Register for certificate events
22
- handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, this.handleCertificateEvent.bind(this));
23
- handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, this.handleCertificateEvent.bind(this));
24
+ // Subscribe to certificate events
25
+ subscribeToPort80Handler(handler, {
26
+ onCertificateIssued: this.handleCertificateEvent.bind(this),
27
+ onCertificateRenewed: this.handleCertificateEvent.bind(this)
28
+ });
24
29
 
25
30
  // If NetworkProxy is already initialized, connect it with Port80Handler
26
31
  if (this.networkProxy) {
@@ -43,10 +48,6 @@ export class NetworkProxyBridge {
43
48
  useExternalPort80Handler: !!this.port80Handler // Use Port80Handler if available
44
49
  };
45
50
 
46
- // Copy ACME settings for backward compatibility (if port80HandlerConfig not set)
47
- if (!this.settings.port80HandlerConfig && this.settings.acme) {
48
- networkProxyOptions.acme = { ...this.settings.acme };
49
- }
50
51
 
51
52
  this.networkProxy = new NetworkProxy(networkProxyOptions);
52
53
 
@@ -288,7 +289,7 @@ export class NetworkProxyBridge {
288
289
  );
289
290
 
290
291
  // Log ACME-eligible domains
291
- const acmeEnabled = this.settings.port80HandlerConfig?.enabled || this.settings.acme?.enabled;
292
+ const acmeEnabled = !!this.settings.acme?.enabled;
292
293
  if (acmeEnabled) {
293
294
  const acmeEligibleDomains = proxyConfigs
294
295
  .filter((config) => !config.hostName.includes('*')) // Exclude wildcards
@@ -349,7 +350,7 @@ export class NetworkProxyBridge {
349
350
  return false;
350
351
  }
351
352
 
352
- if (!this.settings.port80HandlerConfig?.enabled && !this.settings.acme?.enabled) {
353
+ if (!this.settings.acme?.enabled) {
353
354
  console.log('Cannot request certificate - ACME is not enabled');
354
355
  return false;
355
356
  }
@@ -117,10 +117,6 @@ export class PortRangeManager {
117
117
  }
118
118
  }
119
119
 
120
- // Add ACME HTTP challenge port if enabled
121
- if (this.settings.acme?.enabled && this.settings.acme.port) {
122
- ports.add(this.settings.acme.port);
123
- }
124
120
 
125
121
  // Add global port ranges
126
122
  if (this.settings.globalPortRanges) {
@@ -202,12 +198,6 @@ export class PortRangeManager {
202
198
  warnings.push(`NetworkProxy port ${this.settings.networkProxyPort} is also used in port ranges`);
203
199
  }
204
200
 
205
- // Check ACME port
206
- if (this.settings.acme?.enabled && this.settings.acme.port) {
207
- if (portMappings.has(this.settings.acme.port)) {
208
- warnings.push(`ACME HTTP challenge port ${this.settings.acme.port} is also used in port ranges`);
209
- }
210
- }
211
201
 
212
202
  return warnings;
213
203
  }
@@ -8,9 +8,10 @@ import { NetworkProxyBridge } from './classes.pp.networkproxybridge.js';
8
8
  import { TimeoutManager } from './classes.pp.timeoutmanager.js';
9
9
  import { PortRangeManager } from './classes.pp.portrangemanager.js';
10
10
  import { ConnectionHandler } from './classes.pp.connectionhandler.js';
11
- import { Port80Handler, Port80HandlerEvents, type ICertificateData } from '../port80handler/classes.port80handler.js';
12
- import * as path from 'path';
13
- import * as fs from 'fs';
11
+ import { Port80Handler } from '../port80handler/classes.port80handler.js';
12
+ import { CertProvisioner } from './classes.pp.certprovisioner.js';
13
+ import type { ICertificateData } from '../common/types.js';
14
+ import { buildPort80Handler } from '../common/acmeFactory.js';
14
15
 
15
16
  /**
16
17
  * SmartProxy - Main class that coordinates all components
@@ -32,6 +33,8 @@ export class SmartProxy extends plugins.EventEmitter {
32
33
 
33
34
  // Port80Handler for ACME certificate management
34
35
  private port80Handler: Port80Handler | null = null;
36
+ // CertProvisioner for unified certificate workflows
37
+ private certProvisioner?: CertProvisioner;
35
38
 
36
39
  constructor(settingsArg: IPortProxySettings) {
37
40
  super();
@@ -63,41 +66,25 @@ export class SmartProxy extends plugins.EventEmitter {
63
66
  keepAliveInactivityMultiplier: settingsArg.keepAliveInactivityMultiplier || 6,
64
67
  extendedKeepAliveLifetime: settingsArg.extendedKeepAliveLifetime || 7 * 24 * 60 * 60 * 1000,
65
68
  networkProxyPort: settingsArg.networkProxyPort || 8443,
66
- port80HandlerConfig: settingsArg.port80HandlerConfig || {},
69
+ acme: settingsArg.acme || {},
67
70
  globalPortRanges: settingsArg.globalPortRanges || [],
68
71
  };
69
72
 
70
- // Set port80HandlerConfig defaults, using legacy acme config if available
71
- if (!this.settings.port80HandlerConfig || Object.keys(this.settings.port80HandlerConfig).length === 0) {
72
- if (this.settings.acme) {
73
- // Migrate from legacy acme config
74
- this.settings.port80HandlerConfig = {
75
- enabled: this.settings.acme.enabled,
76
- port: this.settings.acme.port || 80,
77
- contactEmail: this.settings.acme.contactEmail || 'admin@example.com',
78
- useProduction: this.settings.acme.useProduction || false,
79
- renewThresholdDays: this.settings.acme.renewThresholdDays || 30,
80
- autoRenew: this.settings.acme.autoRenew !== false, // Default to true
81
- certificateStore: this.settings.acme.certificateStore || './certs',
82
- skipConfiguredCerts: this.settings.acme.skipConfiguredCerts || false,
83
- httpsRedirectPort: this.settings.fromPort,
84
- renewCheckIntervalHours: 24
85
- };
86
- } else {
87
- // Set defaults if no config provided
88
- this.settings.port80HandlerConfig = {
89
- enabled: false,
90
- port: 80,
91
- contactEmail: 'admin@example.com',
92
- useProduction: false,
93
- renewThresholdDays: 30,
94
- autoRenew: true,
95
- certificateStore: './certs',
96
- skipConfiguredCerts: false,
97
- httpsRedirectPort: this.settings.fromPort,
98
- renewCheckIntervalHours: 24
99
- };
100
- }
73
+ // Set default ACME options if not provided
74
+ if (!this.settings.acme || Object.keys(this.settings.acme).length === 0) {
75
+ this.settings.acme = {
76
+ enabled: false,
77
+ port: 80,
78
+ contactEmail: 'admin@example.com',
79
+ useProduction: false,
80
+ renewThresholdDays: 30,
81
+ autoRenew: true,
82
+ certificateStore: './certs',
83
+ skipConfiguredCerts: false,
84
+ httpsRedirectPort: this.settings.fromPort,
85
+ renewCheckIntervalHours: 24,
86
+ domainForwards: []
87
+ };
101
88
  }
102
89
 
103
90
  // Initialize component managers
@@ -135,127 +122,20 @@ export class SmartProxy extends plugins.EventEmitter {
135
122
  * Initialize the Port80Handler for ACME certificate management
136
123
  */
137
124
  private async initializePort80Handler(): Promise<void> {
138
- const config = this.settings.port80HandlerConfig;
139
-
140
- if (!config || !config.enabled) {
141
- console.log('Port80Handler is disabled in configuration');
125
+ const config = this.settings.acme!;
126
+ if (!config.enabled) {
127
+ console.log('ACME is disabled in configuration');
142
128
  return;
143
129
  }
144
130
 
145
131
  try {
146
- // Ensure the certificate store directory exists
147
- if (config.certificateStore) {
148
- const certStorePath = path.resolve(config.certificateStore);
149
- if (!fs.existsSync(certStorePath)) {
150
- fs.mkdirSync(certStorePath, { recursive: true });
151
- console.log(`Created certificate store directory: ${certStorePath}`);
152
- }
153
- }
154
-
155
- // Create Port80Handler with options from config
156
- this.port80Handler = new Port80Handler({
157
- port: config.port,
158
- contactEmail: config.contactEmail,
159
- useProduction: config.useProduction,
160
- renewThresholdDays: config.renewThresholdDays,
161
- httpsRedirectPort: config.httpsRedirectPort || this.settings.fromPort,
162
- renewCheckIntervalHours: config.renewCheckIntervalHours,
163
- enabled: config.enabled,
164
- autoRenew: config.autoRenew,
165
- certificateStore: config.certificateStore,
166
- skipConfiguredCerts: config.skipConfiguredCerts
167
- });
168
-
169
- // Register domain forwarding configurations
170
- if (config.domainForwards) {
171
- for (const forward of config.domainForwards) {
172
- this.port80Handler.addDomain({
173
- domainName: forward.domain,
174
- sslRedirect: true,
175
- acmeMaintenance: true,
176
- forward: forward.forwardConfig,
177
- acmeForward: forward.acmeForwardConfig
178
- });
179
-
180
- console.log(`Registered domain forwarding for ${forward.domain}`);
181
- }
182
- }
183
-
184
- // Provision certificates per domain via certProvider or HTTP-01
185
- for (const domainConfig of this.settings.domainConfigs) {
186
- for (const domain of domainConfig.domains) {
187
- // Skip wildcard domains
188
- if (domain.includes('*')) continue;
189
- // Determine provisioning method
190
- let provision = 'http01' as string | plugins.tsclass.network.ICert;
191
- if (this.settings.certProvider) {
192
- try {
193
- provision = await this.settings.certProvider(domain);
194
- } catch (err) {
195
- console.log(`certProvider error for ${domain}: ${err}`);
196
- }
197
- }
198
- if (provision === 'http01') {
199
- this.port80Handler.addDomain({
200
- domainName: domain,
201
- sslRedirect: true,
202
- acmeMaintenance: true
203
- });
204
- console.log(`Registered domain ${domain} with Port80Handler for HTTP-01`);
205
- } else {
206
- // Static certificate provided
207
- const certObj = provision as plugins.tsclass.network.ICert;
208
- const certData: ICertificateData = {
209
- domain: certObj.domainName,
210
- certificate: certObj.publicKey,
211
- privateKey: certObj.privateKey,
212
- expiryDate: new Date(certObj.validUntil)
213
- };
214
- this.networkProxyBridge.applyExternalCertificate(certData);
215
- console.log(`Applied static certificate for ${domain} from certProvider`);
216
- }
217
- }
218
- }
219
-
220
- // Set up event listeners
221
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, (certData) => {
222
- console.log(`Certificate issued for ${certData.domain}, valid until ${certData.expiryDate.toISOString()}`);
223
- // Re-emit on SmartProxy
224
- this.emit('certificate', {
225
- domain: certData.domain,
226
- publicKey: certData.certificate,
227
- privateKey: certData.privateKey,
228
- expiryDate: certData.expiryDate,
229
- source: 'http01',
230
- isRenewal: false
231
- });
232
- });
233
-
234
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, (certData) => {
235
- console.log(`Certificate renewed for ${certData.domain}, valid until ${certData.expiryDate.toISOString()}`);
236
- // Re-emit on SmartProxy
237
- this.emit('certificate', {
238
- domain: certData.domain,
239
- publicKey: certData.certificate,
240
- privateKey: certData.privateKey,
241
- expiryDate: certData.expiryDate,
242
- source: 'http01',
243
- isRenewal: true
244
- });
245
- });
246
-
247
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, (failureData) => {
248
- console.log(`Certificate ${failureData.isRenewal ? 'renewal' : 'issuance'} failed for ${failureData.domain}: ${failureData.error}`);
132
+ // Build and start the Port80Handler
133
+ this.port80Handler = buildPort80Handler({
134
+ ...config,
135
+ httpsRedirectPort: config.httpsRedirectPort || this.settings.fromPort
249
136
  });
250
-
251
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_EXPIRING, (expiryData) => {
252
- console.log(`Certificate for ${expiryData.domain} is expiring in ${expiryData.daysRemaining} days`);
253
- });
254
-
255
- // Share Port80Handler with NetworkProxyBridge
137
+ // Share Port80Handler with NetworkProxyBridge before start
256
138
  this.networkProxyBridge.setPort80Handler(this.port80Handler);
257
-
258
- // Start Port80Handler
259
139
  await this.port80Handler.start();
260
140
  console.log(`Port80Handler started on port ${config.port}`);
261
141
  } catch (err) {
@@ -275,6 +155,37 @@ export class SmartProxy extends plugins.EventEmitter {
275
155
 
276
156
  // Initialize Port80Handler if enabled
277
157
  await this.initializePort80Handler();
158
+ // Initialize CertProvisioner for unified certificate workflows
159
+ if (this.port80Handler) {
160
+ const acme = this.settings.acme!;
161
+ this.certProvisioner = new CertProvisioner(
162
+ this.settings.domainConfigs,
163
+ this.port80Handler,
164
+ this.networkProxyBridge,
165
+ this.settings.certProvider,
166
+ acme.renewThresholdDays!,
167
+ acme.renewCheckIntervalHours!,
168
+ acme.autoRenew!,
169
+ acme.domainForwards?.map(f => ({
170
+ domain: f.domain,
171
+ forwardConfig: f.forwardConfig,
172
+ acmeForwardConfig: f.acmeForwardConfig,
173
+ sslRedirect: f.sslRedirect || false
174
+ })) || []
175
+ );
176
+ this.certProvisioner.on('certificate', (certData) => {
177
+ this.emit('certificate', {
178
+ domain: certData.domain,
179
+ publicKey: certData.certificate,
180
+ privateKey: certData.privateKey,
181
+ expiryDate: certData.expiryDate,
182
+ source: certData.source,
183
+ isRenewal: certData.isRenewal
184
+ });
185
+ });
186
+ await this.certProvisioner.start();
187
+ console.log('CertProvisioner started');
188
+ }
278
189
 
279
190
  // Initialize and start NetworkProxy if needed
280
191
  if (
@@ -403,6 +314,11 @@ export class SmartProxy extends plugins.EventEmitter {
403
314
  public async stop() {
404
315
  console.log('PortProxy shutting down...');
405
316
  this.isShuttingDown = true;
317
+ // Stop CertProvisioner if active
318
+ if (this.certProvisioner) {
319
+ await this.certProvisioner.stop();
320
+ console.log('CertProvisioner stopped');
321
+ }
406
322
 
407
323
  // Stop the Port80Handler if running
408
324
  if (this.port80Handler) {
@@ -469,7 +385,7 @@ export class SmartProxy extends plugins.EventEmitter {
469
385
  }
470
386
 
471
387
  // If Port80Handler is running, provision certificates per new domain
472
- if (this.port80Handler && this.settings.port80HandlerConfig?.enabled) {
388
+ if (this.port80Handler && this.settings.acme?.enabled) {
473
389
  for (const domainConfig of newDomainConfigs) {
474
390
  for (const domain of domainConfig.domains) {
475
391
  if (domain.includes('*')) continue;
@@ -505,72 +421,6 @@ export class SmartProxy extends plugins.EventEmitter {
505
421
  }
506
422
  }
507
423
 
508
- /**
509
- * Updates the Port80Handler configuration
510
- */
511
- public async updatePort80HandlerConfig(config: IPortProxySettings['port80HandlerConfig']): Promise<void> {
512
- if (!config) return;
513
-
514
- console.log('Updating Port80Handler configuration');
515
-
516
- // Update the settings
517
- this.settings.port80HandlerConfig = {
518
- ...this.settings.port80HandlerConfig,
519
- ...config
520
- };
521
-
522
- // Check if we need to restart Port80Handler
523
- let needsRestart = false;
524
-
525
- // Restart if enabled state changed
526
- if (this.port80Handler && config.enabled === false) {
527
- needsRestart = true;
528
- } else if (!this.port80Handler && config.enabled === true) {
529
- needsRestart = true;
530
- } else if (this.port80Handler && (
531
- config.port !== undefined ||
532
- config.contactEmail !== undefined ||
533
- config.useProduction !== undefined ||
534
- config.renewThresholdDays !== undefined ||
535
- config.renewCheckIntervalHours !== undefined
536
- )) {
537
- // Restart if critical settings changed
538
- needsRestart = true;
539
- }
540
-
541
- if (needsRestart) {
542
- // Stop if running
543
- if (this.port80Handler) {
544
- try {
545
- await this.port80Handler.stop();
546
- this.port80Handler = null;
547
- console.log('Stopped Port80Handler for configuration update');
548
- } catch (err) {
549
- console.log(`Error stopping Port80Handler: ${err}`);
550
- }
551
- }
552
-
553
- // Start with new config if enabled
554
- if (this.settings.port80HandlerConfig.enabled) {
555
- await this.initializePort80Handler();
556
- console.log('Restarted Port80Handler with new configuration');
557
- }
558
- } else if (this.port80Handler) {
559
- // Just update domain forwards if they changed
560
- if (config.domainForwards) {
561
- for (const forward of config.domainForwards) {
562
- this.port80Handler.addDomain({
563
- domainName: forward.domain,
564
- sslRedirect: true,
565
- acmeMaintenance: true,
566
- forward: forward.forwardConfig,
567
- acmeForward: forward.acmeForwardConfig
568
- });
569
- }
570
- console.log('Updated domain forwards in Port80Handler');
571
- }
572
- }
573
- }
574
424
 
575
425
  /**
576
426
  * Request a certificate for a specific domain
@@ -664,7 +514,7 @@ export class SmartProxy extends plugins.EventEmitter {
664
514
  networkProxyConnections,
665
515
  terminationStats,
666
516
  acmeEnabled: !!this.port80Handler,
667
- port80HandlerPort: this.port80Handler ? this.settings.port80HandlerConfig?.port : null
517
+ port80HandlerPort: this.port80Handler ? this.settings.acme?.port : null
668
518
  };
669
519
  }
670
520
 
@@ -715,7 +565,7 @@ export class SmartProxy extends plugins.EventEmitter {
715
565
  status: 'valid',
716
566
  expiryDate: expiryDate.toISOString(),
717
567
  daysRemaining,
718
- renewalNeeded: daysRemaining <= this.settings.port80HandlerConfig.renewThresholdDays
568
+ renewalNeeded: daysRemaining <= (this.settings.acme?.renewThresholdDays ?? 0)
719
569
  };
720
570
  } else {
721
571
  certificateStatus[domain] = {
@@ -725,11 +575,12 @@ export class SmartProxy extends plugins.EventEmitter {
725
575
  }
726
576
  }
727
577
 
578
+ const acme = this.settings.acme!;
728
579
  return {
729
580
  enabled: true,
730
- port: this.settings.port80HandlerConfig.port,
731
- useProduction: this.settings.port80HandlerConfig.useProduction,
732
- autoRenew: this.settings.port80HandlerConfig.autoRenew,
581
+ port: acme.port!,
582
+ useProduction: acme.useProduction!,
583
+ autoRenew: acme.autoRenew!,
733
584
  certificates: certificateStatus
734
585
  };
735
586
  }