193 lines
6.0 KiB
TypeScript
193 lines
6.0 KiB
TypeScript
import * as plugins from '../../plugins.js';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { type IHttpProxyOptions, type ICertificateEntry, type ILogger, createLogger } from './models/types.js';
|
|
import type { IRouteConfig } from '../smart-proxy/models/route-types.js';
|
|
|
|
/**
|
|
* @deprecated This class is deprecated. Use SmartCertManager instead.
|
|
*
|
|
* This is a stub implementation that maintains backward compatibility
|
|
* while the functionality has been moved to SmartCertManager.
|
|
*/
|
|
export class CertificateManager {
|
|
private defaultCertificates: { key: string; cert: string };
|
|
private certificateCache: Map<string, ICertificateEntry> = new Map();
|
|
private certificateStoreDir: string;
|
|
private logger: ILogger;
|
|
private httpsServer: plugins.https.Server | null = null;
|
|
|
|
constructor(private options: IHttpProxyOptions) {
|
|
this.certificateStoreDir = path.resolve(options.acme?.certificateStore || './certs');
|
|
this.logger = createLogger(options.logLevel || 'info');
|
|
|
|
this.logger.warn('CertificateManager is deprecated - use SmartCertManager instead');
|
|
|
|
// Ensure certificate store directory exists
|
|
try {
|
|
if (!fs.existsSync(this.certificateStoreDir)) {
|
|
fs.mkdirSync(this.certificateStoreDir, { recursive: true });
|
|
this.logger.info(`Created certificate store directory: ${this.certificateStoreDir}`);
|
|
}
|
|
} catch (error) {
|
|
this.logger.warn(`Failed to create certificate store directory: ${error}`);
|
|
}
|
|
|
|
this.loadDefaultCertificates();
|
|
}
|
|
|
|
/**
|
|
* Loads default certificates from the filesystem
|
|
*/
|
|
public loadDefaultCertificates(): void {
|
|
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');
|
|
} catch (error) {
|
|
this.logger.error(`Failed to load default certificates: ${error}`);
|
|
this.generateSelfSignedCertificate();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates self-signed certificates as fallback
|
|
*/
|
|
private generateSelfSignedCertificate(): void {
|
|
// Generate a self-signed certificate using forge or similar
|
|
// For now, just use a placeholder
|
|
const selfSignedCert = `-----BEGIN CERTIFICATE-----
|
|
MIIBkTCB+wIJAKHHIgIIA0/cMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAlVT
|
|
MB4XDTE0MDEwMTAwMDAwMFoXDTI0MDEwMTAwMDAwMFowDTELMAkGA1UEBhMCVVMw
|
|
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMRiH0VwnOH3jCV7c6JFZWYrvuqy
|
|
-----END CERTIFICATE-----`;
|
|
|
|
const selfSignedKey = `-----BEGIN PRIVATE KEY-----
|
|
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMRiH0VwnOH3jCV7
|
|
c6JFZWYrvuqyALCLXj0pcr1iqNdHjegNXnkl5zjdaUjq4edNOKl7M1AlFiYjG2xk
|
|
-----END PRIVATE KEY-----`;
|
|
|
|
this.defaultCertificates = {
|
|
key: selfSignedKey,
|
|
cert: selfSignedCert
|
|
};
|
|
|
|
this.logger.warn('Using self-signed certificate as fallback');
|
|
}
|
|
|
|
/**
|
|
* Gets the default certificates
|
|
*/
|
|
public getDefaultCertificates(): { key: string; cert: string } {
|
|
return this.defaultCertificates;
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use SmartCertManager instead
|
|
*/
|
|
public setExternalPort80Handler(handler: any): void {
|
|
this.logger.warn('setExternalPort80Handler is deprecated - use SmartCertManager instead');
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use SmartCertManager instead
|
|
*/
|
|
public async updateRoutes(routes: IRouteConfig[]): Promise<void> {
|
|
this.logger.warn('updateRoutes is deprecated - use SmartCertManager instead');
|
|
}
|
|
|
|
/**
|
|
* Handles SNI callback to provide appropriate certificate
|
|
*/
|
|
public handleSNI(domain: string, cb: (err: Error | null, ctx: plugins.tls.SecureContext) => void): void {
|
|
const certificate = this.getCachedCertificate(domain);
|
|
|
|
if (certificate) {
|
|
const context = plugins.tls.createSecureContext({
|
|
key: certificate.key,
|
|
cert: certificate.cert
|
|
});
|
|
cb(null, context);
|
|
return;
|
|
}
|
|
|
|
// Use default certificate if no domain-specific certificate found
|
|
const defaultContext = plugins.tls.createSecureContext({
|
|
key: this.defaultCertificates.key,
|
|
cert: this.defaultCertificates.cert
|
|
});
|
|
cb(null, defaultContext);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
private getCachedCertificate(domain: string): ICertificateEntry | null {
|
|
return this.certificateCache.get(domain) || null;
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use SmartCertManager instead
|
|
*/
|
|
public async initializePort80Handler(): Promise<any> {
|
|
this.logger.warn('initializePort80Handler is deprecated - use SmartCertManager instead');
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use SmartCertManager instead
|
|
*/
|
|
public async stopPort80Handler(): Promise<void> {
|
|
this.logger.warn('stopPort80Handler is deprecated - use SmartCertManager instead');
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use SmartCertManager instead
|
|
*/
|
|
public registerDomainsWithPort80Handler(domains: string[]): void {
|
|
this.logger.warn('registerDomainsWithPort80Handler is deprecated - use SmartCertManager instead');
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use SmartCertManager instead
|
|
*/
|
|
public registerRoutesWithPort80Handler(routes: IRouteConfig[]): void {
|
|
this.logger.warn('registerRoutesWithPort80Handler is deprecated - use SmartCertManager instead');
|
|
}
|
|
|
|
/**
|
|
* Sets the HTTPS server for certificate updates
|
|
*/
|
|
public setHttpsServer(server: plugins.https.Server): void {
|
|
this.httpsServer = server;
|
|
}
|
|
|
|
/**
|
|
* Gets statistics for metrics
|
|
*/
|
|
public getStats() {
|
|
return {
|
|
cachedCertificates: this.certificateCache.size,
|
|
defaultCertEnabled: true
|
|
};
|
|
}
|
|
} |