feat(certs): persist ACME certificates in StorageManager, add storage-backed cert manager, default storage to filesystem, and improve certificate status reporting

This commit is contained in:
2026-02-14 14:27:58 +00:00
parent dfb268bbfc
commit 28a38252da
8 changed files with 114 additions and 11 deletions

View File

@@ -13,6 +13,7 @@ import {
import { logger } from './logger.js';
// Import storage manager
import { StorageManager, type IStorageConfig } from './storage/index.js';
import { StorageBackedCertManager } from './classes.storage-cert-manager.js';
// Import cache system
import { CacheDb, CacheCleaner, type ICacheDbOptions } from './cache/index.js';
@@ -204,7 +205,14 @@ export class DcRouter {
this.options = {
...optionsArg
};
// Default storage to filesystem if not configured
if (!this.options.storage) {
this.options.storage = {
fsPath: plugins.path.join(paths.dcrouterHomeDir, 'storage'),
};
}
// Initialize storage manager
this.storageManager = new StorageManager(this.options.storage);
}
@@ -437,14 +445,33 @@ export class DcRouter {
const smartProxyConfig: plugins.smartproxy.ISmartProxyOptions = {
...this.options.smartProxyConfig,
routes,
acme: acmeConfig
acme: acmeConfig,
certStore: {
loadAll: async () => {
const keys = await this.storageManager.list('/proxy-certs/');
const certs: Array<{ domain: string; publicKey: string; privateKey: string; ca?: string }> = [];
for (const key of keys) {
const data = await this.storageManager.getJSON(key);
if (data) certs.push(data);
}
return certs;
},
save: async (domain: string, publicKey: string, privateKey: string, ca?: string) => {
await this.storageManager.setJSON(`/proxy-certs/${domain}`, {
domain, publicKey, privateKey, ca,
});
},
remove: async (domain: string) => {
await this.storageManager.delete(`/proxy-certs/${domain}`);
},
},
};
// If we have DNS challenge handlers, create SmartAcme and wire to certProvisionFunction
if (challengeHandlers.length > 0) {
this.smartAcme = new plugins.smartacme.SmartAcme({
accountEmail: acmeConfig?.accountEmail || this.options.tls?.contactEmail || 'admin@example.com',
certManager: new plugins.smartacme.certmanagers.MemoryCertManager(),
certManager: new StorageBackedCertManager(this.storageManager),
environment: 'production',
challengeHandlers: challengeHandlers,
challengePriority: ['dns-01'],