86 lines
2.8 KiB
TypeScript
86 lines
2.8 KiB
TypeScript
import * as plugins from '../../plugins.js';
|
|
import type { ICertificateData } from './certificate-manager.js';
|
|
|
|
export class CertStore {
|
|
constructor(private certDir: string) {}
|
|
|
|
public async initialize(): Promise<void> {
|
|
await plugins.smartfile.fs.ensureDirSync(this.certDir);
|
|
}
|
|
|
|
public async getCertificate(routeName: string): Promise<ICertificateData | null> {
|
|
const certPath = this.getCertPath(routeName);
|
|
const metaPath = `${certPath}/meta.json`;
|
|
|
|
if (!await plugins.smartfile.fs.fileExistsSync(metaPath)) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const metaFile = await plugins.smartfile.SmartFile.fromFilePath(metaPath);
|
|
const meta = JSON.parse(metaFile.contents.toString());
|
|
|
|
const certFile = await plugins.smartfile.SmartFile.fromFilePath(`${certPath}/cert.pem`);
|
|
const cert = certFile.contents.toString();
|
|
|
|
const keyFile = await plugins.smartfile.SmartFile.fromFilePath(`${certPath}/key.pem`);
|
|
const key = keyFile.contents.toString();
|
|
|
|
let ca: string | undefined;
|
|
const caPath = `${certPath}/ca.pem`;
|
|
if (await plugins.smartfile.fs.fileExistsSync(caPath)) {
|
|
const caFile = await plugins.smartfile.SmartFile.fromFilePath(caPath);
|
|
ca = caFile.contents.toString();
|
|
}
|
|
|
|
return {
|
|
cert,
|
|
key,
|
|
ca,
|
|
expiryDate: new Date(meta.expiryDate),
|
|
issueDate: new Date(meta.issueDate)
|
|
};
|
|
} catch (error) {
|
|
console.error(`Failed to load certificate for ${routeName}: ${error}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async saveCertificate(
|
|
routeName: string,
|
|
certData: ICertificateData
|
|
): Promise<void> {
|
|
const certPath = this.getCertPath(routeName);
|
|
await plugins.smartfile.fs.ensureDirSync(certPath);
|
|
|
|
// Save certificate files
|
|
await plugins.smartfile.memory.toFs(certData.cert, `${certPath}/cert.pem`);
|
|
await plugins.smartfile.memory.toFs(certData.key, `${certPath}/key.pem`);
|
|
|
|
if (certData.ca) {
|
|
await plugins.smartfile.memory.toFs(certData.ca, `${certPath}/ca.pem`);
|
|
}
|
|
|
|
// Save metadata
|
|
const meta = {
|
|
expiryDate: certData.expiryDate.toISOString(),
|
|
issueDate: certData.issueDate.toISOString(),
|
|
savedAt: new Date().toISOString()
|
|
};
|
|
|
|
await plugins.smartfile.memory.toFs(JSON.stringify(meta, null, 2), `${certPath}/meta.json`);
|
|
}
|
|
|
|
public async deleteCertificate(routeName: string): Promise<void> {
|
|
const certPath = this.getCertPath(routeName);
|
|
if (await plugins.smartfile.fs.fileExistsSync(certPath)) {
|
|
await plugins.smartfile.fs.removeManySync([certPath]);
|
|
}
|
|
}
|
|
|
|
private getCertPath(routeName: string): string {
|
|
// Sanitize route name for filesystem
|
|
const safeName = routeName.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
return `${this.certDir}/${safeName}`;
|
|
}
|
|
} |