169 lines
4.4 KiB
TypeScript
169 lines
4.4 KiB
TypeScript
/**
|
|
* 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<any>[];
|
|
challengePriority?: string[];
|
|
retryOptions?: {
|
|
retries?: number;
|
|
factor?: number;
|
|
minTimeoutMs?: number;
|
|
maxTimeoutMs?: number;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Interface for certificate manager
|
|
*/
|
|
export interface ICertManager {
|
|
init(): Promise<void>;
|
|
get(domainName: string): Promise<ISmartAcmeCert | null>;
|
|
put(cert: ISmartAcmeCert): Promise<ISmartAcmeCert>;
|
|
delete(domainName: string): Promise<void>;
|
|
close?(): Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* Interface for challenge handler
|
|
*/
|
|
export interface IChallengeHandler<T> {
|
|
getSupportedTypes(): string[];
|
|
prepare(ch: T): Promise<void>;
|
|
verify?(ch: T): Promise<void>;
|
|
cleanup(ch: T): Promise<void>;
|
|
checkWetherDomainIsSupported(domain: string): Promise<boolean>;
|
|
}
|
|
|
|
/**
|
|
* 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<IHttp01Challenge> {
|
|
handleRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse, next?: () => void): void;
|
|
}
|
|
|
|
/**
|
|
* SmartAcme main class interface
|
|
*/
|
|
export interface ISmartAcme {
|
|
start(): Promise<void>;
|
|
stop(): Promise<void>;
|
|
getCertificateForDomain(domain: string): Promise<ISmartAcmeCert>;
|
|
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;
|
|
} |