Fix MITM window

This commit is contained in:
decolua
2026-03-16 09:11:19 +07:00
parent 65af4328fd
commit 62d7e61907
8 changed files with 105 additions and 136 deletions

View File

@@ -45,7 +45,7 @@ function checkCertInstalledMac(certPath) {
function checkCertInstalledWindows(certPath) {
return new Promise((resolve) => {
// Check Root store for our Root CA by common name
exec("certutil -store Root \"9Router MITM Root CA\"", (error) => {
exec("certutil -store Root \"9Router MITM Root CA\"", { windowsHide: true }, (error) => {
resolve(!error);
});
});
@@ -88,11 +88,10 @@ async function installCertMac(sudoPassword, certPath) {
}
async function installCertWindows(certPath) {
const escaped = certPath.replace(/'/g, "''");
const psCommand = `Start-Process certutil -ArgumentList '-addstore','Root','${escaped}' -Verb RunAs -Wait -WindowStyle Hidden`;
// Process already has admin rights — run certutil directly, no UAC needed
return new Promise((resolve, reject) => {
exec(
`powershell -NonInteractive -WindowStyle Hidden -Command "${psCommand}"`,
`certutil -addstore Root "${certPath}"`,
{ windowsHide: true },
(error) => {
if (error) reject(new Error(`Failed to install certificate: ${error.message}`));
@@ -133,10 +132,10 @@ async function uninstallCertMac(sudoPassword, certPath) {
}
async function uninstallCertWindows() {
const psCommand = `Start-Process certutil -ArgumentList '-delstore','Root','9Router MITM Root CA' -Verb RunAs -Wait -WindowStyle Hidden`;
// Process already has admin rights — run certutil directly, no UAC needed
return new Promise((resolve, reject) => {
exec(
`powershell -NonInteractive -WindowStyle Hidden -Command "${psCommand}"`,
`certutil -delstore Root "9Router MITM Root CA"`,
{ windowsHide: true },
(error) => {
if (error) reject(new Error(`Failed to uninstall certificate: ${error.message}`));

View File

@@ -7,14 +7,33 @@ const ROOT_CA_KEY_PATH = path.join(MITM_DIR, "rootCA.key");
const ROOT_CA_CERT_PATH = path.join(MITM_DIR, "rootCA.crt");
/**
* Generate Root CA certificate (only once)
* Check if cert file is expired or expiring within 30 days
*/
function isCertExpired(certPath) {
try {
const cert = forge.pki.certificateFromPem(fs.readFileSync(certPath, "utf8"));
const expiryThreshold = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
return cert.validity.notAfter < expiryThreshold;
} catch {
return true; // treat unreadable cert as expired
}
}
/**
* Generate Root CA certificate (only once, auto-regenerate if expired)
* This Root CA will sign all dynamic leaf certificates
*/
async function generateRootCA() {
if (fs.existsSync(ROOT_CA_KEY_PATH) && fs.existsSync(ROOT_CA_CERT_PATH)) {
const exists = fs.existsSync(ROOT_CA_KEY_PATH) && fs.existsSync(ROOT_CA_CERT_PATH);
if (exists && !isCertExpired(ROOT_CA_CERT_PATH)) {
console.log("✅ Root CA already exists");
return { key: ROOT_CA_KEY_PATH, cert: ROOT_CA_CERT_PATH };
}
if (exists) {
console.log("🔐 Root CA expired or expiring soon — regenerating...");
try { fs.unlinkSync(ROOT_CA_KEY_PATH); } catch { /* ignore */ }
try { fs.unlinkSync(ROOT_CA_CERT_PATH); } catch { /* ignore */ }
}
if (!fs.existsSync(MITM_DIR)) {
fs.mkdirSync(MITM_DIR, { recursive: true });
@@ -148,6 +167,7 @@ module.exports = {
generateRootCA,
loadRootCA,
generateLeafCert,
isCertExpired,
ROOT_CA_CERT_PATH,
ROOT_CA_KEY_PATH
};