Feat : Add support for the new "alicode-intl" provider

This commit is contained in:
decolua
2026-03-07 10:08:55 +07:00
parent 0cf78fd76a
commit 758224749d
13 changed files with 227 additions and 119 deletions
+31 -84
View File
@@ -5,7 +5,7 @@ const os = require("os");
const net = require("net");
const https = require("https");
const crypto = require("crypto");
const { addDNSEntry, removeDNSEntry, removeAllDNSEntries, checkAllDNSStatus } = require("./dns/dnsConfig");
const { addDNSEntry, removeDNSEntry, removeAllDNSEntries, checkAllDNSStatus, executeElevatedPowerShell, TOOL_HOSTS } = require("./dns/dnsConfig");
const IS_WIN = process.platform === "win32";
const { generateCert } = require("./cert/generate");
@@ -345,49 +345,23 @@ async function startServer(apiKey, sudoPassword) {
// Step 2: Spawn server (Root CA already installed in Step 1.5)
if (IS_WIN) {
const hostsFile = path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts");
const flagFile = path.join(os.tmpdir(), `mitm_ready_${Date.now()}.flag`);
const psSQ = (s) => s.replace(/'/g, "''");
const nodePs = psSQ(process.execPath);
const serverPs = psSQ(SERVER_PATH);
const flagPs = psSQ(flagFile);
const psScript = [
`$ErrorActionPreference = 'Stop'`,
`$conn = Get-NetTCPConnection -LocalPort 443 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1`,
`if ($conn -and $conn.OwningProcess -gt 4) { Stop-Process -Id $conn.OwningProcess -Force -ErrorAction SilentlyContinue }`,
`Start-Sleep -Milliseconds 500`,
`$nodeCmd = 'set ROUTER_API_KEY=${psSQ(apiKey)}&& set NODE_ENV=production&& "${nodePs}" "${serverPs}"'`,
`Start-Process cmd -ArgumentList '/c',$nodeCmd -WindowStyle Hidden`,
`Start-Sleep -Milliseconds 500`,
`Set-Content -Path '${flagPs}' -Value 'ready' -Encoding UTF8`,
].join("\n");
const tmpPs1 = path.join(os.tmpdir(), `mitm_start_${Date.now()}.ps1`);
fs.writeFileSync(tmpPs1, psScript, "utf8");
const vbs = [
`Set oShell = CreateObject("Shell.Application")`,
`Dim ps`,
`ps = Chr(34) & "powershell.exe" & Chr(34)`,
`Dim args`,
`args = "-NoProfile -ExecutionPolicy Bypass -File " & Chr(34) & "${tmpPs1}" & Chr(34)`,
`oShell.ShellExecute ps, args, "", "runas", 1`,
].join("\r\n");
const tmpVbs = path.join(os.tmpdir(), `mitm_uac_${Date.now()}.vbs`);
fs.writeFileSync(tmpVbs, vbs, "utf8");
spawn("wscript.exe", [tmpVbs], { stdio: "ignore", windowsHide: true, detached: true }).unref();
await new Promise((resolve, reject) => {
const deadline = Date.now() + 90000;
const poll = () => {
if (fs.existsSync(flagFile)) {
try { fs.unlinkSync(flagFile); fs.unlinkSync(tmpPs1); fs.unlinkSync(tmpVbs); } catch { /* ignore */ }
return resolve();
}
if (Date.now() > deadline) return reject(new Error("Timed out waiting for UAC confirmation."));
setTimeout(poll, 500);
};
poll();
});
await executeElevatedPowerShell(tmpPs1, 90000);
if (_updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
} else {
@@ -451,38 +425,27 @@ async function startServer(apiKey, sudoPassword) {
* Stop MITM server — removes ALL tool DNS entries first, then kills server
*/
async function stopServer(sudoPassword) {
// Remove all DNS entries first (before killing server)
console.log("[MITM] Removing all DNS entries before stopping server...");
await removeAllDNSEntries(sudoPassword);
console.log("[MITM] Stopping server...");
// Kill server process
const proc = serverProcess;
if (proc && !proc.killed) {
console.log("Stopping MITM server...");
killProcess(proc.pid, false, sudoPassword);
await new Promise(resolve => setTimeout(resolve, 1000));
if (isProcessAlive(proc.pid)) killProcess(proc.pid, true, sudoPassword);
serverProcess = null;
serverPid = null;
} else {
try {
if (fs.existsSync(PID_FILE)) {
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
if (savedPid && isProcessAlive(savedPid)) {
console.log(`Killing MITM server (PID: ${savedPid})...`);
killProcess(savedPid, false, sudoPassword);
await new Promise(resolve => setTimeout(resolve, 1000));
if (isProcessAlive(savedPid)) killProcess(savedPid, true, sudoPassword);
}
}
} catch { /* ignore */ }
serverProcess = null;
serverPid = null;
const pidToKill = proc && !proc.killed
? proc.pid
: (() => { try { return parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10); } catch { return null; } })();
if (pidToKill && isProcessAlive(pidToKill)) {
console.log(`Killing MITM server (PID: ${pidToKill})...`);
killProcess(pidToKill, false, sudoPassword);
await new Promise(r => setTimeout(r, 1000));
if (isProcessAlive(pidToKill)) killProcess(pidToKill, true, sudoPassword);
}
serverProcess = null;
serverPid = null;
if (IS_WIN) {
// Single elevated script: clean DNS + flush — 1 UAC prompt only
const hostsFile = path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts");
const psSQ = (s) => s.replace(/'/g, "''");
const { TOOL_HOSTS } = require("./dns/dnsConfig");
const allHosts = Object.values(TOOL_HOSTS).flat();
let hostsContent = "";
@@ -490,41 +453,25 @@ async function stopServer(sudoPassword) {
const filtered = hostsContent.split(/\r?\n/)
.filter(l => !allHosts.some(h => l.includes(h)))
.join("\r\n");
const tmpHosts = path.join(os.tmpdir(), "mitm_hosts_clean.tmp");
const tmpHosts = path.join(os.tmpdir(), `mitm_hosts_clean_${Date.now()}.tmp`);
fs.writeFileSync(tmpHosts, filtered, "utf8");
const flagFile = path.join(os.tmpdir(), "mitm_stop_done.flag");
const psScript = [
`Copy-Item -Path '${psSQ(tmpHosts)}' -Destination '${psSQ(hostsFile)}' -Force`,
`& ipconfig /flushdns | Out-Null`,
`Remove-Item '${psSQ(tmpHosts)}' -ErrorAction SilentlyContinue`,
`Set-Content -Path '${psSQ(flagFile)}' -Value 'done' -Encoding UTF8`,
`$ErrorActionPreference = 'Stop'`,
`try {`,
` Copy-Item -Path '${psSQ(tmpHosts)}' -Destination '${psSQ(hostsFile)}' -Force -ErrorAction Stop`,
` ipconfig /flushdns | Out-Null`,
` Remove-Item '${psSQ(tmpHosts)}' -ErrorAction SilentlyContinue`,
`} catch {`,
` Remove-Item '${psSQ(tmpHosts)}' -ErrorAction SilentlyContinue`,
`}`,
].join("\n");
const tmpPs1 = path.join(os.tmpdir(), "mitm_stop.ps1");
const tmpPs1 = path.join(os.tmpdir(), `mitm_stop_${Date.now()}.ps1`);
fs.writeFileSync(tmpPs1, psScript, "utf8");
const vbs = [
`Set oShell = CreateObject("Shell.Application")`,
`Dim args`,
`args = "-NoProfile -ExecutionPolicy Bypass -File " & Chr(34) & "${tmpPs1}" & Chr(34)`,
`oShell.ShellExecute "powershell.exe", args, "", "runas", 1`,
].join("\r\n");
const tmpVbs = path.join(os.tmpdir(), "mitm_stop_uac.vbs");
fs.writeFileSync(tmpVbs, vbs, "utf8");
spawn("wscript.exe", [tmpVbs], { stdio: "ignore", windowsHide: true, detached: true }).unref();
await new Promise((resolve) => {
const deadline = Date.now() + 30000;
const poll = () => {
if (fs.existsSync(flagFile)) {
try { fs.unlinkSync(flagFile); fs.unlinkSync(tmpPs1); fs.unlinkSync(tmpVbs); } catch { /* ignore */ }
return resolve();
}
if (Date.now() > deadline) return resolve();
setTimeout(poll, 500);
};
poll();
});
await executeElevatedPowerShell(tmpPs1, 30000);
} else {
await removeAllDNSEntries(sudoPassword);
}
try { fs.unlinkSync(PID_FILE); } catch { /* ignore */ }