@push.rocks/smartproxy 4.2.4 → 4.2.6

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.
@@ -1,22 +1,48 @@
1
1
  import * as plugins from './plugins.js';
2
+ import { IncomingMessage, ServerResponse } from 'http';
2
3
  /**
3
- * Events emitted by the ACME Certificate Manager
4
+ * Custom error classes for better error handling
4
5
  */
5
- export var CertManagerEvents;
6
- (function (CertManagerEvents) {
7
- CertManagerEvents["CERTIFICATE_ISSUED"] = "certificate-issued";
8
- CertManagerEvents["CERTIFICATE_RENEWED"] = "certificate-renewed";
9
- CertManagerEvents["CERTIFICATE_FAILED"] = "certificate-failed";
10
- CertManagerEvents["CERTIFICATE_EXPIRING"] = "certificate-expiring";
11
- CertManagerEvents["MANAGER_STARTED"] = "manager-started";
12
- CertManagerEvents["MANAGER_STOPPED"] = "manager-stopped";
13
- })(CertManagerEvents || (CertManagerEvents = {}));
6
+ export class Port80HandlerError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = 'Port80HandlerError';
10
+ }
11
+ }
12
+ export class CertificateError extends Port80HandlerError {
13
+ constructor(message, domain, isRenewal = false) {
14
+ super(`${message} for domain ${domain}${isRenewal ? ' (renewal)' : ''}`);
15
+ this.domain = domain;
16
+ this.isRenewal = isRenewal;
17
+ this.name = 'CertificateError';
18
+ }
19
+ }
20
+ export class ServerError extends Port80HandlerError {
21
+ constructor(message, code) {
22
+ super(message);
23
+ this.code = code;
24
+ this.name = 'ServerError';
25
+ }
26
+ }
14
27
  /**
15
- * Improved ACME Certificate Manager with event emission and external certificate management
28
+ * Events emitted by the Port80Handler
16
29
  */
17
- export class AcmeCertManager extends plugins.EventEmitter {
30
+ export var Port80HandlerEvents;
31
+ (function (Port80HandlerEvents) {
32
+ Port80HandlerEvents["CERTIFICATE_ISSUED"] = "certificate-issued";
33
+ Port80HandlerEvents["CERTIFICATE_RENEWED"] = "certificate-renewed";
34
+ Port80HandlerEvents["CERTIFICATE_FAILED"] = "certificate-failed";
35
+ Port80HandlerEvents["CERTIFICATE_EXPIRING"] = "certificate-expiring";
36
+ Port80HandlerEvents["MANAGER_STARTED"] = "manager-started";
37
+ Port80HandlerEvents["MANAGER_STOPPED"] = "manager-stopped";
38
+ Port80HandlerEvents["REQUEST_FORWARDED"] = "request-forwarded";
39
+ })(Port80HandlerEvents || (Port80HandlerEvents = {}));
40
+ /**
41
+ * Port80Handler with ACME certificate management and request forwarding capabilities
42
+ */
43
+ export class Port80Handler extends plugins.EventEmitter {
18
44
  /**
19
- * Creates a new ACME Certificate Manager
45
+ * Creates a new Port80Handler
20
46
  * @param options Configuration options
21
47
  */
22
48
  constructor(options = {}) {
@@ -32,7 +58,7 @@ export class AcmeCertManager extends plugins.EventEmitter {
32
58
  port: options.port ?? 80,
33
59
  contactEmail: options.contactEmail ?? 'admin@example.com',
34
60
  useProduction: options.useProduction ?? false, // Safer default: staging
35
- renewThresholdDays: options.renewThresholdDays ?? 30,
61
+ renewThresholdDays: options.renewThresholdDays ?? 10, // Changed to 10 days as per requirements
36
62
  httpsRedirectPort: options.httpsRedirectPort ?? 443,
37
63
  renewCheckIntervalHours: options.renewCheckIntervalHours ?? 24,
38
64
  };
@@ -42,34 +68,43 @@ export class AcmeCertManager extends plugins.EventEmitter {
42
68
  */
43
69
  async start() {
44
70
  if (this.server) {
45
- throw new Error('Server is already running');
71
+ throw new ServerError('Server is already running');
46
72
  }
47
73
  if (this.isShuttingDown) {
48
- throw new Error('Server is shutting down');
74
+ throw new ServerError('Server is shutting down');
49
75
  }
50
76
  return new Promise((resolve, reject) => {
51
77
  try {
52
78
  this.server = plugins.http.createServer((req, res) => this.handleRequest(req, res));
53
79
  this.server.on('error', (error) => {
54
80
  if (error.code === 'EACCES') {
55
- reject(new Error(`Permission denied to bind to port ${this.options.port}. Try running with elevated privileges or use a port > 1024.`));
81
+ reject(new ServerError(`Permission denied to bind to port ${this.options.port}. Try running with elevated privileges or use a port > 1024.`, error.code));
56
82
  }
57
83
  else if (error.code === 'EADDRINUSE') {
58
- reject(new Error(`Port ${this.options.port} is already in use.`));
84
+ reject(new ServerError(`Port ${this.options.port} is already in use.`, error.code));
59
85
  }
60
86
  else {
61
- reject(error);
87
+ reject(new ServerError(error.message, error.code));
62
88
  }
63
89
  });
64
90
  this.server.listen(this.options.port, () => {
65
- console.log(`AcmeCertManager is listening on port ${this.options.port}`);
91
+ console.log(`Port80Handler is listening on port ${this.options.port}`);
66
92
  this.startRenewalTimer();
67
- this.emit(CertManagerEvents.MANAGER_STARTED, this.options.port);
93
+ this.emit(Port80HandlerEvents.MANAGER_STARTED, this.options.port);
94
+ // Start certificate process for domains with acmeMaintenance enabled
95
+ for (const [domain, domainInfo] of this.domainCertificates.entries()) {
96
+ if (domainInfo.options.acmeMaintenance && !domainInfo.certObtained && !domainInfo.obtainingInProgress) {
97
+ this.obtainCertificate(domain).catch(err => {
98
+ console.error(`Error obtaining initial certificate for ${domain}:`, err);
99
+ });
100
+ }
101
+ }
68
102
  resolve();
69
103
  });
70
104
  }
71
105
  catch (error) {
72
- reject(error);
106
+ const message = error instanceof Error ? error.message : 'Unknown error starting server';
107
+ reject(new ServerError(message));
73
108
  }
74
109
  });
75
110
  }
@@ -91,7 +126,7 @@ export class AcmeCertManager extends plugins.EventEmitter {
91
126
  this.server.close(() => {
92
127
  this.server = null;
93
128
  this.isShuttingDown = false;
94
- this.emit(CertManagerEvents.MANAGER_STOPPED);
129
+ this.emit(Port80HandlerEvents.MANAGER_STOPPED);
95
130
  resolve();
96
131
  });
97
132
  }
@@ -102,13 +137,38 @@ export class AcmeCertManager extends plugins.EventEmitter {
102
137
  });
103
138
  }
104
139
  /**
105
- * Adds a domain to be managed for certificates
106
- * @param domain The domain to add
140
+ * Adds a domain with configuration options
141
+ * @param options Domain configuration options
107
142
  */
108
- addDomain(domain) {
109
- if (!this.domainCertificates.has(domain)) {
110
- this.domainCertificates.set(domain, { certObtained: false, obtainingInProgress: false });
111
- console.log(`Domain added: ${domain}`);
143
+ addDomain(options) {
144
+ if (!options.domainName || typeof options.domainName !== 'string') {
145
+ throw new Port80HandlerError('Invalid domain name');
146
+ }
147
+ const domainName = options.domainName;
148
+ if (!this.domainCertificates.has(domainName)) {
149
+ this.domainCertificates.set(domainName, {
150
+ options,
151
+ certObtained: false,
152
+ obtainingInProgress: false
153
+ });
154
+ console.log(`Domain added: ${domainName} with configuration:`, {
155
+ sslRedirect: options.sslRedirect,
156
+ acmeMaintenance: options.acmeMaintenance,
157
+ hasForward: !!options.forward,
158
+ hasAcmeForward: !!options.acmeForward
159
+ });
160
+ // If acmeMaintenance is enabled, start certificate process immediately
161
+ if (options.acmeMaintenance && this.server) {
162
+ this.obtainCertificate(domainName).catch(err => {
163
+ console.error(`Error obtaining initial certificate for ${domainName}:`, err);
164
+ });
165
+ }
166
+ }
167
+ else {
168
+ // Update existing domain with new options
169
+ const existing = this.domainCertificates.get(domainName);
170
+ existing.options = options;
171
+ console.log(`Domain ${domainName} configuration updated`);
112
172
  }
113
173
  }
114
174
  /**
@@ -128,9 +188,22 @@ export class AcmeCertManager extends plugins.EventEmitter {
128
188
  * @param expiryDate Optional expiry date
129
189
  */
130
190
  setCertificate(domain, certificate, privateKey, expiryDate) {
191
+ if (!domain || !certificate || !privateKey) {
192
+ throw new Port80HandlerError('Domain, certificate and privateKey are required');
193
+ }
131
194
  let domainInfo = this.domainCertificates.get(domain);
132
195
  if (!domainInfo) {
133
- domainInfo = { certObtained: false, obtainingInProgress: false };
196
+ // Create default domain options if not already configured
197
+ const defaultOptions = {
198
+ domainName: domain,
199
+ sslRedirect: true,
200
+ acmeMaintenance: true
201
+ };
202
+ domainInfo = {
203
+ options: defaultOptions,
204
+ certObtained: false,
205
+ obtainingInProgress: false
206
+ };
134
207
  this.domainCertificates.set(domain, domainInfo);
135
208
  }
136
209
  domainInfo.certificate = certificate;
@@ -141,26 +214,16 @@ export class AcmeCertManager extends plugins.EventEmitter {
141
214
  domainInfo.expiryDate = expiryDate;
142
215
  }
143
216
  else {
144
- // Try to extract expiry date from certificate
145
- try {
146
- // This is a simplistic approach - in a real implementation, use a proper
147
- // certificate parsing library like node-forge or x509
148
- const matches = certificate.match(/Not After\s*:\s*(.*?)(?:\n|$)/i);
149
- if (matches && matches[1]) {
150
- domainInfo.expiryDate = new Date(matches[1]);
151
- }
152
- }
153
- catch (error) {
154
- console.warn(`Failed to extract expiry date from certificate for ${domain}`);
155
- }
217
+ // Extract expiry date from certificate
218
+ domainInfo.expiryDate = this.extractExpiryDateFromCertificate(certificate, domain);
156
219
  }
157
220
  console.log(`Certificate set for ${domain}`);
158
221
  // Emit certificate event
159
- this.emitCertificateEvent(CertManagerEvents.CERTIFICATE_ISSUED, {
222
+ this.emitCertificateEvent(Port80HandlerEvents.CERTIFICATE_ISSUED, {
160
223
  domain,
161
224
  certificate,
162
225
  privateKey,
163
- expiryDate: domainInfo.expiryDate || new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days default
226
+ expiryDate: domainInfo.expiryDate || this.getDefaultExpiryDate()
164
227
  });
165
228
  }
166
229
  /**
@@ -176,7 +239,7 @@ export class AcmeCertManager extends plugins.EventEmitter {
176
239
  domain,
177
240
  certificate: domainInfo.certificate,
178
241
  privateKey: domainInfo.privateKey,
179
- expiryDate: domainInfo.expiryDate || new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days default
242
+ expiryDate: domainInfo.expiryDate || this.getDefaultExpiryDate()
180
243
  };
181
244
  }
182
245
  /**
@@ -187,20 +250,26 @@ export class AcmeCertManager extends plugins.EventEmitter {
187
250
  if (this.acmeClient) {
188
251
  return this.acmeClient;
189
252
  }
190
- // Generate a new account key
191
- this.accountKey = (await plugins.acme.forge.createPrivateKey()).toString();
192
- this.acmeClient = new plugins.acme.Client({
193
- directoryUrl: this.options.useProduction
194
- ? plugins.acme.directory.letsencrypt.production
195
- : plugins.acme.directory.letsencrypt.staging,
196
- accountKey: this.accountKey,
197
- });
198
- // Create a new account
199
- await this.acmeClient.createAccount({
200
- termsOfServiceAgreed: true,
201
- contact: [`mailto:${this.options.contactEmail}`],
202
- });
203
- return this.acmeClient;
253
+ try {
254
+ // Generate a new account key
255
+ this.accountKey = (await plugins.acme.forge.createPrivateKey()).toString();
256
+ this.acmeClient = new plugins.acme.Client({
257
+ directoryUrl: this.options.useProduction
258
+ ? plugins.acme.directory.letsencrypt.production
259
+ : plugins.acme.directory.letsencrypt.staging,
260
+ accountKey: this.accountKey,
261
+ });
262
+ // Create a new account
263
+ await this.acmeClient.createAccount({
264
+ termsOfServiceAgreed: true,
265
+ contact: [`mailto:${this.options.contactEmail}`],
266
+ });
267
+ return this.acmeClient;
268
+ }
269
+ catch (error) {
270
+ const message = error instanceof Error ? error.message : 'Unknown error initializing ACME client';
271
+ throw new Port80HandlerError(`Failed to initialize ACME client: ${message}`);
272
+ }
204
273
  }
205
274
  /**
206
275
  * Handles incoming HTTP requests
@@ -216,36 +285,111 @@ export class AcmeCertManager extends plugins.EventEmitter {
216
285
  }
217
286
  // Extract domain (ignoring any port in the Host header)
218
287
  const domain = hostHeader.split(':')[0];
219
- // If the request is for an ACME HTTP-01 challenge, handle it
220
- if (req.url && req.url.startsWith('/.well-known/acme-challenge/')) {
221
- this.handleAcmeChallenge(req, res, domain);
222
- return;
223
- }
288
+ // Check if domain is configured
224
289
  if (!this.domainCertificates.has(domain)) {
225
290
  res.statusCode = 404;
226
291
  res.end('Domain not configured');
227
292
  return;
228
293
  }
229
294
  const domainInfo = this.domainCertificates.get(domain);
230
- // If certificate exists, redirect to HTTPS
231
- if (domainInfo.certObtained) {
295
+ const options = domainInfo.options;
296
+ // If the request is for an ACME HTTP-01 challenge, handle it
297
+ if (req.url && req.url.startsWith('/.well-known/acme-challenge/') && (options.acmeMaintenance || options.acmeForward)) {
298
+ // Check if we should forward ACME requests
299
+ if (options.acmeForward) {
300
+ this.forwardRequest(req, res, options.acmeForward, 'ACME challenge');
301
+ return;
302
+ }
303
+ this.handleAcmeChallenge(req, res, domain);
304
+ return;
305
+ }
306
+ // Check if we should forward non-ACME requests
307
+ if (options.forward) {
308
+ this.forwardRequest(req, res, options.forward, 'HTTP');
309
+ return;
310
+ }
311
+ // If certificate exists and sslRedirect is enabled, redirect to HTTPS
312
+ if (domainInfo.certObtained && options.sslRedirect) {
232
313
  const httpsPort = this.options.httpsRedirectPort;
233
314
  const portSuffix = httpsPort === 443 ? '' : `:${httpsPort}`;
234
315
  const redirectUrl = `https://${domain}${portSuffix}${req.url || '/'}`;
235
316
  res.statusCode = 301;
236
317
  res.setHeader('Location', redirectUrl);
237
318
  res.end(`Redirecting to ${redirectUrl}`);
319
+ return;
238
320
  }
239
- else {
321
+ // Handle case where certificate maintenance is enabled but not yet obtained
322
+ if (options.acmeMaintenance && !domainInfo.certObtained) {
240
323
  // Trigger certificate issuance if not already running
241
324
  if (!domainInfo.obtainingInProgress) {
242
325
  this.obtainCertificate(domain).catch(err => {
243
- this.emit(CertManagerEvents.CERTIFICATE_FAILED, { domain, error: err.message });
326
+ const errorMessage = err instanceof Error ? err.message : 'Unknown error';
327
+ this.emit(Port80HandlerEvents.CERTIFICATE_FAILED, {
328
+ domain,
329
+ error: errorMessage,
330
+ isRenewal: false
331
+ });
244
332
  console.error(`Error obtaining certificate for ${domain}:`, err);
245
333
  });
246
334
  }
247
335
  res.statusCode = 503;
248
336
  res.end('Certificate issuance in progress, please try again later.');
337
+ return;
338
+ }
339
+ // Default response for unhandled request
340
+ res.statusCode = 404;
341
+ res.end('No handlers configured for this request');
342
+ }
343
+ /**
344
+ * Forwards an HTTP request to the specified target
345
+ * @param req The original request
346
+ * @param res The response object
347
+ * @param target The forwarding target (IP and port)
348
+ * @param requestType Type of request for logging
349
+ */
350
+ forwardRequest(req, res, target, requestType) {
351
+ const options = {
352
+ hostname: target.ip,
353
+ port: target.port,
354
+ path: req.url,
355
+ method: req.method,
356
+ headers: { ...req.headers }
357
+ };
358
+ const domain = req.headers.host?.split(':')[0] || 'unknown';
359
+ console.log(`Forwarding ${requestType} request for ${domain} to ${target.ip}:${target.port}`);
360
+ const proxyReq = plugins.http.request(options, (proxyRes) => {
361
+ // Copy status code
362
+ res.statusCode = proxyRes.statusCode || 500;
363
+ // Copy headers
364
+ for (const [key, value] of Object.entries(proxyRes.headers)) {
365
+ if (value)
366
+ res.setHeader(key, value);
367
+ }
368
+ // Pipe response data
369
+ proxyRes.pipe(res);
370
+ this.emit(Port80HandlerEvents.REQUEST_FORWARDED, {
371
+ domain,
372
+ requestType,
373
+ target: `${target.ip}:${target.port}`,
374
+ statusCode: proxyRes.statusCode
375
+ });
376
+ });
377
+ proxyReq.on('error', (error) => {
378
+ console.error(`Error forwarding request to ${target.ip}:${target.port}:`, error);
379
+ if (!res.headersSent) {
380
+ res.statusCode = 502;
381
+ res.end(`Proxy error: ${error.message}`);
382
+ }
383
+ else {
384
+ res.end();
385
+ }
386
+ });
387
+ // Pipe original request to proxy request
388
+ if (req.readable) {
389
+ req.pipe(proxyReq);
390
+ }
391
+ else {
392
+ proxyReq.end();
249
393
  }
250
394
  }
251
395
  /**
@@ -284,7 +428,12 @@ export class AcmeCertManager extends plugins.EventEmitter {
284
428
  // Get the domain info
285
429
  const domainInfo = this.domainCertificates.get(domain);
286
430
  if (!domainInfo) {
287
- throw new Error(`Domain not found: ${domain}`);
431
+ throw new CertificateError('Domain not found', domain, isRenewal);
432
+ }
433
+ // Verify that acmeMaintenance is enabled
434
+ if (!domainInfo.options.acmeMaintenance) {
435
+ console.log(`Skipping certificate issuance for ${domain} - acmeMaintenance is disabled`);
436
+ return;
288
437
  }
289
438
  // Prevent concurrent certificate issuance
290
439
  if (domainInfo.obtainingInProgress) {
@@ -301,35 +450,8 @@ export class AcmeCertManager extends plugins.EventEmitter {
301
450
  });
302
451
  // Get the authorizations for the order
303
452
  const authorizations = await client.getAuthorizations(order);
304
- for (const authz of authorizations) {
305
- const challenge = authz.challenges.find(ch => ch.type === 'http-01');
306
- if (!challenge) {
307
- throw new Error('HTTP-01 challenge not found');
308
- }
309
- // Get the key authorization for the challenge
310
- const keyAuthorization = await client.getChallengeKeyAuthorization(challenge);
311
- // Store the challenge data
312
- domainInfo.challengeToken = challenge.token;
313
- domainInfo.challengeKeyAuthorization = keyAuthorization;
314
- // ACME client type definition workaround - use compatible approach
315
- // First check if challenge verification is needed
316
- const authzUrl = authz.url;
317
- try {
318
- // Check if authzUrl exists and perform verification
319
- if (authzUrl) {
320
- await client.verifyChallenge(authz, challenge);
321
- }
322
- // Complete the challenge
323
- await client.completeChallenge(challenge);
324
- // Wait for validation
325
- await client.waitForValidStatus(challenge);
326
- console.log(`HTTP-01 challenge completed for ${domain}`);
327
- }
328
- catch (error) {
329
- console.error(`Challenge error for ${domain}:`, error);
330
- throw error;
331
- }
332
- }
453
+ // Process each authorization
454
+ await this.processAuthorizations(client, domain, authorizations);
333
455
  // Generate a CSR and private key
334
456
  const [csrBuffer, privateKeyBuffer] = await plugins.acme.forge.createCsr({
335
457
  commonName: domain,
@@ -348,26 +470,17 @@ export class AcmeCertManager extends plugins.EventEmitter {
348
470
  delete domainInfo.challengeToken;
349
471
  delete domainInfo.challengeKeyAuthorization;
350
472
  // Extract expiry date from certificate
351
- try {
352
- const matches = certificate.match(/Not After\s*:\s*(.*?)(?:\n|$)/i);
353
- if (matches && matches[1]) {
354
- domainInfo.expiryDate = new Date(matches[1]);
355
- console.log(`Certificate for ${domain} will expire on ${domainInfo.expiryDate.toISOString()}`);
356
- }
357
- }
358
- catch (error) {
359
- console.warn(`Failed to extract expiry date from certificate for ${domain}`);
360
- }
473
+ domainInfo.expiryDate = this.extractExpiryDateFromCertificate(certificate, domain);
361
474
  console.log(`Certificate ${isRenewal ? 'renewed' : 'obtained'} for ${domain}`);
362
475
  // Emit the appropriate event
363
476
  const eventType = isRenewal
364
- ? CertManagerEvents.CERTIFICATE_RENEWED
365
- : CertManagerEvents.CERTIFICATE_ISSUED;
477
+ ? Port80HandlerEvents.CERTIFICATE_RENEWED
478
+ : Port80HandlerEvents.CERTIFICATE_ISSUED;
366
479
  this.emitCertificateEvent(eventType, {
367
480
  domain,
368
481
  certificate,
369
482
  privateKey,
370
- expiryDate: domainInfo.expiryDate || new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days default
483
+ expiryDate: domainInfo.expiryDate || this.getDefaultExpiryDate()
371
484
  });
372
485
  }
373
486
  catch (error) {
@@ -381,17 +494,60 @@ export class AcmeCertManager extends plugins.EventEmitter {
381
494
  console.error(`Error during certificate issuance for ${domain}:`, error);
382
495
  }
383
496
  // Emit failure event
384
- this.emit(CertManagerEvents.CERTIFICATE_FAILED, {
497
+ this.emit(Port80HandlerEvents.CERTIFICATE_FAILED, {
385
498
  domain,
386
499
  error: error.message || 'Unknown error',
387
500
  isRenewal
388
501
  });
502
+ throw new CertificateError(error.message || 'Certificate issuance failed', domain, isRenewal);
389
503
  }
390
504
  finally {
391
505
  // Reset flag whether successful or not
392
506
  domainInfo.obtainingInProgress = false;
393
507
  }
394
508
  }
509
+ /**
510
+ * Process ACME authorizations by verifying and completing challenges
511
+ * @param client ACME client
512
+ * @param domain Domain name
513
+ * @param authorizations Authorizations to process
514
+ */
515
+ async processAuthorizations(client, domain, authorizations) {
516
+ const domainInfo = this.domainCertificates.get(domain);
517
+ if (!domainInfo) {
518
+ throw new CertificateError('Domain not found during authorization', domain);
519
+ }
520
+ for (const authz of authorizations) {
521
+ const challenge = authz.challenges.find(ch => ch.type === 'http-01');
522
+ if (!challenge) {
523
+ throw new CertificateError('HTTP-01 challenge not found', domain);
524
+ }
525
+ // Get the key authorization for the challenge
526
+ const keyAuthorization = await client.getChallengeKeyAuthorization(challenge);
527
+ // Store the challenge data
528
+ domainInfo.challengeToken = challenge.token;
529
+ domainInfo.challengeKeyAuthorization = keyAuthorization;
530
+ // ACME client type definition workaround - use compatible approach
531
+ // First check if challenge verification is needed
532
+ const authzUrl = authz.url;
533
+ try {
534
+ // Check if authzUrl exists and perform verification
535
+ if (authzUrl) {
536
+ await client.verifyChallenge(authz, challenge);
537
+ }
538
+ // Complete the challenge
539
+ await client.completeChallenge(challenge);
540
+ // Wait for validation
541
+ await client.waitForValidStatus(challenge);
542
+ console.log(`HTTP-01 challenge completed for ${domain}`);
543
+ }
544
+ catch (error) {
545
+ const errorMessage = error instanceof Error ? error.message : 'Unknown challenge error';
546
+ console.error(`Challenge error for ${domain}:`, error);
547
+ throw new CertificateError(`Challenge verification failed: ${errorMessage}`, domain);
548
+ }
549
+ }
550
+ }
395
551
  /**
396
552
  * Starts the certificate renewal timer
397
553
  */
@@ -419,6 +575,10 @@ export class AcmeCertManager extends plugins.EventEmitter {
419
575
  const now = new Date();
420
576
  const renewThresholdMs = this.options.renewThresholdDays * 24 * 60 * 60 * 1000;
421
577
  for (const [domain, domainInfo] of this.domainCertificates.entries()) {
578
+ // Skip domains with acmeMaintenance disabled
579
+ if (!domainInfo.options.acmeMaintenance) {
580
+ continue;
581
+ }
422
582
  // Skip domains without certificates or already in renewal
423
583
  if (!domainInfo.certObtained || domainInfo.obtainingInProgress) {
424
584
  continue;
@@ -431,18 +591,54 @@ export class AcmeCertManager extends plugins.EventEmitter {
431
591
  // Check if certificate is near expiry
432
592
  if (timeUntilExpiry <= renewThresholdMs) {
433
593
  console.log(`Certificate for ${domain} expires soon, renewing...`);
434
- this.emit(CertManagerEvents.CERTIFICATE_EXPIRING, {
594
+ const daysRemaining = Math.ceil(timeUntilExpiry / (24 * 60 * 60 * 1000));
595
+ this.emit(Port80HandlerEvents.CERTIFICATE_EXPIRING, {
435
596
  domain,
436
597
  expiryDate: domainInfo.expiryDate,
437
- daysRemaining: Math.ceil(timeUntilExpiry / (24 * 60 * 60 * 1000))
598
+ daysRemaining
438
599
  });
439
600
  // Start renewal process
440
601
  this.obtainCertificate(domain, true).catch(err => {
441
- console.error(`Error renewing certificate for ${domain}:`, err);
602
+ const errorMessage = err instanceof Error ? err.message : 'Unknown error';
603
+ console.error(`Error renewing certificate for ${domain}:`, errorMessage);
442
604
  });
443
605
  }
444
606
  }
445
607
  }
608
+ /**
609
+ * Extract expiry date from certificate using a more robust approach
610
+ * @param certificate Certificate PEM string
611
+ * @param domain Domain for logging
612
+ * @returns Extracted expiry date or default
613
+ */
614
+ extractExpiryDateFromCertificate(certificate, domain) {
615
+ try {
616
+ // This is still using regex, but in a real implementation you would use
617
+ // a library like node-forge or x509 to properly parse the certificate
618
+ const matches = certificate.match(/Not After\s*:\s*(.*?)(?:\n|$)/i);
619
+ if (matches && matches[1]) {
620
+ const expiryDate = new Date(matches[1]);
621
+ // Validate that we got a valid date
622
+ if (!isNaN(expiryDate.getTime())) {
623
+ console.log(`Certificate for ${domain} will expire on ${expiryDate.toISOString()}`);
624
+ return expiryDate;
625
+ }
626
+ }
627
+ console.warn(`Could not extract valid expiry date from certificate for ${domain}, using default`);
628
+ return this.getDefaultExpiryDate();
629
+ }
630
+ catch (error) {
631
+ console.warn(`Failed to extract expiry date from certificate for ${domain}, using default`);
632
+ return this.getDefaultExpiryDate();
633
+ }
634
+ }
635
+ /**
636
+ * Get a default expiry date (90 days from now)
637
+ * @returns Default expiry date
638
+ */
639
+ getDefaultExpiryDate() {
640
+ return new Date(Date.now() + 90 * 24 * 60 * 60 * 1000); // 90 days default
641
+ }
446
642
  /**
447
643
  * Emits a certificate event with the certificate data
448
644
  * @param eventType The event type to emit
@@ -452,4 +648,4 @@ export class AcmeCertManager extends plugins.EventEmitter {
452
648
  this.emit(eventType, data);
453
649
  }
454
650
  }
455
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0ODBoYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5wb3J0ODBoYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBc0N4Qzs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLGlCQU9YO0FBUEQsV0FBWSxpQkFBaUI7SUFDM0IsOERBQXlDLENBQUE7SUFDekMsZ0VBQTJDLENBQUE7SUFDM0MsOERBQXlDLENBQUE7SUFDekMsa0VBQTZDLENBQUE7SUFDN0Msd0RBQW1DLENBQUE7SUFDbkMsd0RBQW1DLENBQUE7QUFDckMsQ0FBQyxFQVBXLGlCQUFpQixLQUFqQixpQkFBaUIsUUFPNUI7QUFFRDs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFnQixTQUFRLE9BQU8sQ0FBQyxZQUFZO0lBU3ZEOzs7T0FHRztJQUNILFlBQVksVUFBbUMsRUFBRTtRQUMvQyxLQUFLLEVBQUUsQ0FBQztRQVpGLFdBQU0sR0FBK0IsSUFBSSxDQUFDO1FBQzFDLGVBQVUsR0FBK0IsSUFBSSxDQUFDO1FBQzlDLGVBQVUsR0FBa0IsSUFBSSxDQUFDO1FBQ2pDLGlCQUFZLEdBQTBCLElBQUksQ0FBQztRQUMzQyxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQVN0QyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7UUFFaEUsa0JBQWtCO1FBQ2xCLElBQUksQ0FBQyxPQUFPLEdBQUc7WUFDYixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFO1lBQ3hCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWSxJQUFJLG1CQUFtQjtZQUN6RCxhQUFhLEVBQUUsT0FBTyxDQUFDLGFBQWEsSUFBSSxLQUFLLEVBQUUseUJBQXlCO1lBQ3hFLGtCQUFrQixFQUFFLE9BQU8sQ0FBQyxrQkFBa0IsSUFBSSxFQUFFO1lBQ3BELGlCQUFpQixFQUFF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
651
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0ODBoYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5wb3J0ODBoYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXZEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGtCQUFtQixTQUFRLEtBQUs7SUFDM0MsWUFBWSxPQUFlO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsb0JBQW9CLENBQUM7SUFDbkMsQ0FBQztDQUNGO0FBRUQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLGtCQUFrQjtJQUN0RCxZQUNFLE9BQWUsRUFDQyxNQUFjLEVBQ2QsWUFBcUIsS0FBSztRQUUxQyxLQUFLLENBQUMsR0FBRyxPQUFPLGVBQWUsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBSHpELFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxjQUFTLEdBQVQsU0FBUyxDQUFpQjtRQUcxQyxJQUFJLENBQUMsSUFBSSxHQUFHLGtCQUFrQixDQUFDO0lBQ2pDLENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxXQUFZLFNBQVEsa0JBQWtCO0lBQ2pELFlBQVksT0FBZSxFQUFrQixJQUFhO1FBQ3hELEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUQ0QixTQUFJLEdBQUosSUFBSSxDQUFTO1FBRXhELElBQUksQ0FBQyxJQUFJLEdBQUcsYUFBYSxDQUFDO0lBQzVCLENBQUM7Q0FDRjtBQTBERDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLG1CQVFYO0FBUkQsV0FBWSxtQkFBbUI7SUFDN0IsZ0VBQXlDLENBQUE7SUFDekMsa0VBQTJDLENB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