import * as plugins from '../../plugins.js'; import * as fs from 'fs'; import * as path from 'path'; import { fileURLToPath } from 'url'; import { AsyncFileSystem } from '../../core/utils/fs-utils.js'; import type { ILogger, ICertificateEntry } from './models/types.js'; /** * Interface for default certificate data */ export interface IDefaultCertificates { key: string; cert: string; } /** * Provides default SSL certificates for HttpProxy. * This is a minimal replacement for the deprecated CertificateManager. * * For production certificate management, use SmartCertManager instead. */ export class DefaultCertificateProvider { private defaultCertificates: IDefaultCertificates | null = null; private certificateCache: Map = new Map(); private initialized = false; constructor(private logger?: ILogger) {} /** * Load default certificates asynchronously (preferred) */ public async loadDefaultCertificatesAsync(): Promise { if (this.defaultCertificates) { return this.defaultCertificates; } const __dirname = path.dirname(fileURLToPath(import.meta.url)); const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs'); try { const [key, cert] = await Promise.all([ AsyncFileSystem.readFile(path.join(certPath, 'key.pem')), AsyncFileSystem.readFile(path.join(certPath, 'cert.pem')) ]); this.defaultCertificates = { key, cert }; this.logger?.info?.('Loaded default certificates from filesystem'); this.initialized = true; return this.defaultCertificates; } catch (error) { this.logger?.warn?.(`Failed to load default certificates: ${error}`); this.defaultCertificates = this.generateFallbackCertificate(); this.initialized = true; return this.defaultCertificates; } } /** * Load default certificates synchronously (for backward compatibility) * @deprecated Use loadDefaultCertificatesAsync instead */ public loadDefaultCertificatesSync(): IDefaultCertificates { if (this.defaultCertificates) { return this.defaultCertificates; } const __dirname = path.dirname(fileURLToPath(import.meta.url)); const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs'); try { this.defaultCertificates = { key: fs.readFileSync(path.join(certPath, 'key.pem'), 'utf8'), cert: fs.readFileSync(path.join(certPath, 'cert.pem'), 'utf8') }; this.logger?.info?.('Loaded default certificates from filesystem (sync)'); } catch (error) { this.logger?.warn?.(`Failed to load default certificates: ${error}`); this.defaultCertificates = this.generateFallbackCertificate(); } this.initialized = true; return this.defaultCertificates; } /** * Gets the default certificates (loads synchronously if not already loaded) */ public getDefaultCertificates(): IDefaultCertificates { if (!this.defaultCertificates) { return this.loadDefaultCertificatesSync(); } return this.defaultCertificates; } /** * Updates a certificate in the cache */ public updateCertificate(domain: string, cert: string, key: string): void { this.certificateCache.set(domain, { cert, key, expires: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days }); this.logger?.info?.(`Certificate updated for ${domain}`); } /** * Gets a cached certificate */ public getCachedCertificate(domain: string): ICertificateEntry | null { return this.certificateCache.get(domain) || null; } /** * Gets statistics for metrics */ public getStats(): { cachedCertificates: number; defaultCertEnabled: boolean } { return { cachedCertificates: this.certificateCache.size, defaultCertEnabled: this.defaultCertificates !== null }; } /** * Generate a fallback self-signed certificate placeholder * Note: This is just a placeholder - real apps should provide proper certificates */ private generateFallbackCertificate(): IDefaultCertificates { this.logger?.warn?.('Using fallback self-signed certificate placeholder'); // Minimal self-signed certificate for fallback only // In production, proper certificates should be provided via SmartCertManager const selfSignedCert = `-----BEGIN CERTIFICATE----- MIIBkTCB+wIJAKHHIgIIA0/cMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAlVT MB4XDTE0MDEwMTAwMDAwMFoXDTI0MDEwMTAwMDAwMFowDTELMAkGA1UEBhMCVVMw gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMRiH0VwnOH3jCV7c6JFZWYrvuqy -----END CERTIFICATE-----`; const selfSignedKey = `-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMRiH0VwnOH3jCV7 c6JFZWYrvuqyALCLXj0pcr1iqNdHjegNXnkl5zjdaUjq4edNOKl7M1AlFiYjG2xk -----END PRIVATE KEY-----`; return { key: selfSignedKey, cert: selfSignedCert }; } }