fix(dcrouter): persist proxy certificate validity dates and improve certificate status initialization
This commit is contained in:
@@ -445,8 +445,8 @@ export class DcRouter {
|
||||
if (routes.length > 0 || this.options.smartProxyConfig) {
|
||||
console.log('Setting up SmartProxy with combined configuration');
|
||||
|
||||
// Track domains loaded from cert store so we can populate certificateStatusMap after start
|
||||
const loadedCertDomains: string[] = [];
|
||||
// Track cert entries loaded from cert store so we can populate certificateStatusMap after start
|
||||
const loadedCertEntries: Array<{domain: string; publicKey: string; validUntil?: number; validFrom?: number}> = [];
|
||||
|
||||
// Create SmartProxy configuration
|
||||
const smartProxyConfig: plugins.smartproxy.ISmartProxyOptions = {
|
||||
@@ -461,14 +461,21 @@ export class DcRouter {
|
||||
const data = await this.storageManager.getJSON(key);
|
||||
if (data) {
|
||||
certs.push(data);
|
||||
loadedCertDomains.push(data.domain);
|
||||
loadedCertEntries.push({ domain: data.domain, publicKey: data.publicKey, validUntil: data.validUntil, validFrom: data.validFrom });
|
||||
}
|
||||
}
|
||||
return certs;
|
||||
},
|
||||
save: async (domain: string, publicKey: string, privateKey: string, ca?: string) => {
|
||||
let validUntil: number | undefined;
|
||||
let validFrom: number | undefined;
|
||||
try {
|
||||
const x509 = new plugins.crypto.X509Certificate(publicKey);
|
||||
validUntil = new Date(x509.validTo).getTime();
|
||||
validFrom = new Date(x509.validFrom).getTime();
|
||||
} catch { /* PEM parsing failed */ }
|
||||
await this.storageManager.setJSON(`/proxy-certs/${domain}`, {
|
||||
domain, publicKey, privateKey, ca,
|
||||
domain, publicKey, privateKey, ca, validUntil, validFrom,
|
||||
});
|
||||
},
|
||||
remove: async (domain: string) => {
|
||||
@@ -587,22 +594,46 @@ export class DcRouter {
|
||||
console.log('[DcRouter] SmartProxy started successfully');
|
||||
|
||||
// Populate certificateStatusMap for certs loaded from store at startup
|
||||
for (const domain of loadedCertDomains) {
|
||||
if (!this.certificateStatusMap.has(domain)) {
|
||||
const routeNames = this.findRouteNamesForDomain(domain);
|
||||
for (const entry of loadedCertEntries) {
|
||||
if (!this.certificateStatusMap.has(entry.domain)) {
|
||||
const routeNames = this.findRouteNamesForDomain(entry.domain);
|
||||
let expiryDate: string | undefined;
|
||||
let issuedAt: string | undefined;
|
||||
try {
|
||||
const cleanDomain = domain.replace(/^\*\.?/, '');
|
||||
const certMeta = await this.storageManager.getJSON(`/certs/${cleanDomain}`);
|
||||
if (certMeta?.validUntil) {
|
||||
expiryDate = new Date(certMeta.validUntil).toISOString();
|
||||
}
|
||||
if (certMeta?.created) {
|
||||
issuedAt = new Date(certMeta.created).toISOString();
|
||||
}
|
||||
} catch { /* no metadata available */ }
|
||||
this.certificateStatusMap.set(domain, {
|
||||
|
||||
// Use validUntil/validFrom from stored proxy-certs data if available
|
||||
if (entry.validUntil) {
|
||||
expiryDate = new Date(entry.validUntil).toISOString();
|
||||
}
|
||||
if (entry.validFrom) {
|
||||
issuedAt = new Date(entry.validFrom).toISOString();
|
||||
}
|
||||
|
||||
// Try SmartAcme /certs/ metadata as secondary source
|
||||
if (!expiryDate) {
|
||||
try {
|
||||
const cleanDomain = entry.domain.replace(/^\*\.?/, '');
|
||||
const certMeta = await this.storageManager.getJSON(`/certs/${cleanDomain}`);
|
||||
if (certMeta?.validUntil) {
|
||||
expiryDate = new Date(certMeta.validUntil).toISOString();
|
||||
}
|
||||
if (certMeta?.created && !issuedAt) {
|
||||
issuedAt = new Date(certMeta.created).toISOString();
|
||||
}
|
||||
} catch { /* no metadata available */ }
|
||||
}
|
||||
|
||||
// Fallback: parse X509 from PEM to get expiry
|
||||
if (!expiryDate && entry.publicKey) {
|
||||
try {
|
||||
const x509 = new plugins.crypto.X509Certificate(entry.publicKey);
|
||||
expiryDate = new Date(x509.validTo).toISOString();
|
||||
if (!issuedAt) {
|
||||
issuedAt = new Date(x509.validFrom).toISOString();
|
||||
}
|
||||
} catch { /* PEM parsing failed */ }
|
||||
}
|
||||
|
||||
this.certificateStatusMap.set(entry.domain, {
|
||||
status: 'valid',
|
||||
routeNames,
|
||||
expiryDate,
|
||||
@@ -611,8 +642,8 @@ export class DcRouter {
|
||||
});
|
||||
}
|
||||
}
|
||||
if (loadedCertDomains.length > 0) {
|
||||
console.log(`[DcRouter] Populated certificate status for ${loadedCertDomains.length} store-loaded domain(s)`);
|
||||
if (loadedCertEntries.length > 0) {
|
||||
console.log(`[DcRouter] Populated certificate status for ${loadedCertEntries.length} store-loaded domain(s)`);
|
||||
}
|
||||
|
||||
console.log(`SmartProxy started with ${routes.length} routes`);
|
||||
|
||||
Reference in New Issue
Block a user