Cleanup generated cert bundles

This commit is contained in:
Sander Declerck 2026-03-19 11:08:38 +01:00
parent 6c6ce796d9
commit 527e3cd70a
No known key found for this signature in database
2 changed files with 32 additions and 6 deletions

View file

@ -8,6 +8,9 @@ import { X509Certificate } from "node:crypto";
import { getCaCertPath } from "./certUtils.js";
import { ui } from "../environment/userInteraction.js";
/** @type {string | null} */
let bundlePath = null;
/**
* Check if a PEM string contains only parsable cert blocks.
* @param {string} pem - PEM-encoded certificate string
@ -54,6 +57,11 @@ function isParsable(pem) {
* @returns {string} Path to the combined CA bundle PEM file
*/
export function getCombinedCaBundlePath() {
if (bundlePath)
{
return bundlePath;
}
const parts = [];
// 1) Safe Chain CA (for MITM'd registries)
@ -62,7 +70,7 @@ export function getCombinedCaBundlePath() {
const safeChainPem = fs.readFileSync(safeChainPath, "utf8");
if (isParsable(safeChainPem)) parts.push(safeChainPem.trim());
} catch {
// Ignore if Safe Chain CA is not available
// Ignore if Safe Chain CA. is not available
}
// 2) certifi (Mozilla CA bundle for all public HTTPS)
@ -99,9 +107,23 @@ export function getCombinedCaBundlePath() {
}
const combined = parts.filter(Boolean).join("\n");
const target = path.join(os.tmpdir(), `safe-chain-ca-bundle-${Date.now()}.pem`);
fs.writeFileSync(target, combined, { encoding: "utf8" });
return target;
bundlePath = path.join(os.tmpdir(), `safe-chain-ca-bundle-${Date.now()}.pem`);
fs.writeFileSync(bundlePath, combined, { encoding: "utf8" });
return bundlePath;
}
/**
* Remove the generated CA bundle file from disk.
*/
export function cleanupCertBundle() {
if (bundlePath) {
try {
fs.unlinkSync(bundlePath);
} catch {
// Ignore errors (file may already be gone)
}
bundlePath = null;
}
}
/**

View file

@ -2,7 +2,7 @@ import * as http from "http";
import { tunnelRequest } from "./tunnelRequestHandler.js";
import { mitmConnect } from "./mitmRequestHandler.js";
import { handleHttpProxyRequest } from "./plainHttpProxy.js";
import { getCombinedCaBundlePath } from "./certBundle.js";
import { getCombinedCaBundlePath, cleanupCertBundle } from "./certBundle.js";
import { ui } from "../environment/userInteraction.js";
import chalk from "chalk";
import { createInterceptorForUrl } from "./interceptors/createInterceptorForEcoSystem.js";
@ -115,12 +115,16 @@ function stopServer(server) {
return new Promise((resolve) => {
try {
server.close(() => {
cleanupCertBundle();
resolve();
});
} catch {
resolve();
}
setTimeout(() => resolve(), SERVER_STOP_TIMEOUT_MS);
setTimeout(() => {
cleanupCertBundle();
resolve();
}, SERVER_STOP_TIMEOUT_MS);
});
}