BREAKING CHANGE(acme): Refactor ACME configuration and certificate provisioning by replacing legacy port80HandlerConfig with unified acme options and updating CertProvisioner event subscriptions

This commit is contained in:
2025-05-02 14:58:33 +00:00
parent edd8ca8d70
commit 878e76ab23
13 changed files with 285 additions and 292 deletions

View File

@ -1,5 +1,14 @@
import * as plugins from '../plugins.js';
import { IncomingMessage, ServerResponse } from 'http';
import { Port80HandlerEvents } from '../common/types.js';
import type {
IForwardConfig,
IDomainOptions,
ICertificateData,
ICertificateFailure,
ICertificateExpiring,
IAcmeOptions
} from '../common/types.js';
// (fs and path I/O moved to CertProvisioner)
// ACME HTTP-01 challenge handler storing tokens in memory (diskless)
class DisklessHttp01Handler {
@ -45,24 +54,6 @@ export class ServerError extends Port80HandlerError {
}
}
/**
* Domain forwarding configuration
*/
export interface IForwardConfig {
ip: string;
port: number;
}
/**
* Domain configuration options
*/
export interface IDomainOptions {
domainName: string;
sslRedirect: boolean; // if true redirects the request to port 443
acmeMaintenance: boolean; // tries to always have a valid cert for this domain
forward?: IForwardConfig; // forwards all http requests to that target
acmeForward?: IForwardConfig; // forwards letsencrypt requests to this config
}
/**
* Represents a domain configuration with certificate status information
@ -80,55 +71,8 @@ interface IDomainCertificate {
/**
* Configuration options for the Port80Handler
*/
interface IPort80HandlerOptions {
port?: number;
contactEmail?: string;
useProduction?: boolean;
httpsRedirectPort?: number;
enabled?: boolean; // Whether ACME is enabled at all
// (Persistence moved to CertProvisioner)
}
// Port80Handler options moved to common types
/**
* Certificate data that can be emitted via events or set from outside
*/
export interface ICertificateData {
domain: string;
certificate: string;
privateKey: string;
expiryDate: Date;
}
/**
* Events emitted by the Port80Handler
*/
export enum Port80HandlerEvents {
CERTIFICATE_ISSUED = 'certificate-issued',
CERTIFICATE_RENEWED = 'certificate-renewed',
CERTIFICATE_FAILED = 'certificate-failed',
CERTIFICATE_EXPIRING = 'certificate-expiring',
MANAGER_STARTED = 'manager-started',
MANAGER_STOPPED = 'manager-stopped',
REQUEST_FORWARDED = 'request-forwarded',
}
/**
* Certificate failure payload type
*/
export interface ICertificateFailure {
domain: string;
error: string;
isRenewal: boolean;
}
/**
* Certificate expiry payload type
*/
export interface ICertificateExpiring {
domain: string;
expiryDate: Date;
daysRemaining: number;
}
/**
* Port80Handler with ACME certificate management and request forwarding capabilities
@ -144,13 +88,13 @@ export class Port80Handler extends plugins.EventEmitter {
// Renewal scheduling is handled externally by SmartProxy
// (Removed internal renewal timer)
private isShuttingDown: boolean = false;
private options: Required<IPort80HandlerOptions>;
private options: Required<IAcmeOptions>;
/**
* Creates a new Port80Handler
* @param options Configuration options
*/
constructor(options: IPort80HandlerOptions = {}) {
constructor(options: IAcmeOptions = {}) {
super();
this.domainCertificates = new Map<string, IDomainCertificate>();
@ -160,7 +104,13 @@ export class Port80Handler extends plugins.EventEmitter {
contactEmail: options.contactEmail ?? 'admin@example.com',
useProduction: options.useProduction ?? false, // Safer default: staging
httpsRedirectPort: options.httpsRedirectPort ?? 443,
enabled: options.enabled ?? true // Enable by default
enabled: options.enabled ?? true, // Enable by default
certificateStore: options.certificateStore ?? './certs',
skipConfiguredCerts: options.skipConfiguredCerts ?? false,
renewThresholdDays: options.renewThresholdDays ?? 30,
renewCheckIntervalHours: options.renewCheckIntervalHours ?? 24,
autoRenew: options.autoRenew ?? true,
domainForwards: options.domainForwards ?? []
};
}
@ -810,7 +760,7 @@ export class Port80Handler extends plugins.EventEmitter {
* Gets configuration details
* @returns Current configuration
*/
public getConfig(): Required<IPort80HandlerOptions> {
public getConfig(): Required<IAcmeOptions> {
return { ...this.options };
}