/** * Type definitions for SmartAcme interfaces used by ChallengeResponder * These reflect the actual SmartAcme API based on the documentation * * Also includes route-based interfaces for Port80Handler to extract domains * that need certificate management from route configurations. */ import * as plugins from '../../plugins.js'; import type { IRouteConfig } from '../../proxies/smart-proxy/models/route-types.js'; /** * Structure for SmartAcme certificate result */ export interface ISmartAcmeCert { id?: string; domainName: string; created?: number | Date | string; privateKey: string; publicKey: string; csr?: string; validUntil: number | Date | string; } /** * Structure for SmartAcme options */ export interface ISmartAcmeOptions { accountEmail: string; certManager: ICertManager; environment: 'production' | 'integration'; challengeHandlers: IChallengeHandler[]; challengePriority?: string[]; retryOptions?: { retries?: number; factor?: number; minTimeoutMs?: number; maxTimeoutMs?: number; }; } /** * Interface for certificate manager */ export interface ICertManager { init(): Promise; get(domainName: string): Promise; put(cert: ISmartAcmeCert): Promise; delete(domainName: string): Promise; close?(): Promise; } /** * Interface for challenge handler */ export interface IChallengeHandler { getSupportedTypes(): string[]; prepare(ch: T): Promise; verify?(ch: T): Promise; cleanup(ch: T): Promise; checkWetherDomainIsSupported(domain: string): Promise; } /** * HTTP-01 challenge type */ export interface IHttp01Challenge { type: string; // 'http-01' token: string; keyAuthorization: string; webPath: string; } /** * HTTP-01 Memory Handler Interface */ export interface IHttp01MemoryHandler extends IChallengeHandler { handleRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse, next?: () => void): void; } /** * SmartAcme main class interface */ export interface ISmartAcme { start(): Promise; stop(): Promise; getCertificateForDomain(domain: string): Promise; on?(event: string, listener: (data: any) => void): void; eventEmitter?: plugins.EventEmitter; } /** * Port80Handler route options */ export interface IPort80RouteOptions { // The domain for the certificate domain: string; // Whether to redirect HTTP to HTTPS sslRedirect: boolean; // Whether to enable ACME certificate management acmeMaintenance: boolean; // Optional target for forwarding HTTP requests forward?: { ip: string; port: number; }; // Optional target for forwarding ACME challenge requests acmeForward?: { ip: string; port: number; }; // Reference to the route that requested this certificate routeReference?: { routeId?: string; routeName?: string; }; } /** * Extract domains that need certificate management from routes * @param routes Route configurations to extract domains from * @returns Array of Port80RouteOptions for each domain */ export function extractPort80RoutesFromRoutes(routes: IRouteConfig[]): IPort80RouteOptions[] { const result: IPort80RouteOptions[] = []; for (const route of routes) { // Skip routes that don't have domains or TLS configuration if (!route.match.domains || !route.action.tls) continue; // Skip routes that don't terminate TLS if (route.action.tls.mode !== 'terminate' && route.action.tls.mode !== 'terminate-and-reencrypt') continue; // Only routes with automatic certificates need ACME if (route.action.tls.certificate !== 'auto') continue; // Get domains from route const domains = Array.isArray(route.match.domains) ? route.match.domains : [route.match.domains]; // Create Port80RouteOptions for each domain for (const domain of domains) { // Skip wildcards (we can't get certificates for them) if (domain.includes('*')) continue; // Create Port80RouteOptions const options: IPort80RouteOptions = { domain, sslRedirect: true, // Default to true for HTTPS routes acmeMaintenance: true, // Default to true for auto certificates // Add route reference routeReference: { routeName: route.name } }; // Add domain to result result.push(options); } } return result; }