diff --git a/packages/safe-chain/src/registryProxy/certBundle.js b/packages/safe-chain/src/registryProxy/certBundle.js index 42549b9..19dc800 100644 --- a/packages/safe-chain/src/registryProxy/certBundle.js +++ b/packages/safe-chain/src/registryProxy/certBundle.js @@ -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) @@ -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 (err) { + ui.writeVerbose(`Failed to cleanup the create bundle at ${bundlePath}`, err) + } + bundlePath = null; + } } /** diff --git a/packages/safe-chain/src/registryProxy/registryProxy.js b/packages/safe-chain/src/registryProxy/registryProxy.js index 47ec256..2de776e 100644 --- a/packages/safe-chain/src/registryProxy/registryProxy.js +++ b/packages/safe-chain/src/registryProxy/registryProxy.js @@ -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); }); }