fix: force mac nordvpn disconnect teardown
This commit is contained in:
@@ -365,6 +365,12 @@ function cleanupMacWireguardState(paths = {}) {
|
|||||||
return { cleaned };
|
return { cleaned };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldAttemptMacWireguardDisconnect(wireguardState) {
|
||||||
|
if (!wireguardState) return false;
|
||||||
|
if (wireguardState.active) return true;
|
||||||
|
return Boolean(wireguardState.configPath || wireguardState.endpoint || wireguardState.lastConnection);
|
||||||
|
}
|
||||||
|
|
||||||
function fetchJson(url, headers = {}) {
|
function fetchJson(url, headers = {}) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const targetUrl = new URL(url);
|
const targetUrl = new URL(url);
|
||||||
@@ -1107,20 +1113,35 @@ async function disconnectNordvpn(installProbe) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (installProbe.platform === "darwin" && installProbe.wireguard && installProbe.wireguard.dependenciesReady) {
|
if (installProbe.platform === "darwin" && installProbe.wireguard && installProbe.wireguard.dependenciesReady) {
|
||||||
if (!installProbe.wireguard.active) {
|
if (!shouldAttemptMacWireguardDisconnect(installProbe.wireguard)) {
|
||||||
const cleaned = cleanupMacWireguardState();
|
|
||||||
const tailscale = await resumeMacTailscaleIfNeeded();
|
const tailscale = await resumeMacTailscaleIfNeeded();
|
||||||
return {
|
return {
|
||||||
backend: "wireguard",
|
backend: "wireguard",
|
||||||
changed: false,
|
changed: false,
|
||||||
stateCleaned: cleaned.cleaned,
|
|
||||||
tailscaleRestored: tailscale.restored,
|
tailscaleRestored: tailscale.restored,
|
||||||
message: "No active macOS WireGuard NordVPN connection found.",
|
message: "No active macOS WireGuard NordVPN connection found.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const down = await runSudoWireguard(installProbe, "down");
|
const down = await runSudoWireguard(installProbe, "down");
|
||||||
if (!down.ok) {
|
if (!down.ok) {
|
||||||
throw new Error((down.stderr || down.stdout || down.error).trim() || "wg-quick down failed");
|
const message = (down.stderr || down.stdout || down.error).trim();
|
||||||
|
const normalized = message.toLowerCase();
|
||||||
|
if (
|
||||||
|
normalized.includes("is not a known interface") ||
|
||||||
|
normalized.includes("unable to access interface") ||
|
||||||
|
normalized.includes("not found")
|
||||||
|
) {
|
||||||
|
const cleaned = cleanupMacWireguardState();
|
||||||
|
const tailscale = await resumeMacTailscaleIfNeeded();
|
||||||
|
return {
|
||||||
|
backend: "wireguard",
|
||||||
|
changed: false,
|
||||||
|
stateCleaned: cleaned.cleaned,
|
||||||
|
tailscaleRestored: tailscale.restored,
|
||||||
|
message: "No active macOS WireGuard NordVPN connection found.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error(message || "wg-quick down failed");
|
||||||
}
|
}
|
||||||
const cleaned = cleanupMacWireguardState();
|
const cleaned = cleanupMacWireguardState();
|
||||||
const tailscale = await resumeMacTailscaleIfNeeded();
|
const tailscale = await resumeMacTailscaleIfNeeded();
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ module.exports = {
|
|||||||
typeof getMacTailscalePath === "function" ? getMacTailscalePath : undefined,
|
typeof getMacTailscalePath === "function" ? getMacTailscalePath : undefined,
|
||||||
isMacTailscaleActive:
|
isMacTailscaleActive:
|
||||||
typeof isMacTailscaleActive === "function" ? isMacTailscaleActive : undefined,
|
typeof isMacTailscaleActive === "function" ? isMacTailscaleActive : undefined,
|
||||||
|
shouldAttemptMacWireguardDisconnect:
|
||||||
|
typeof shouldAttemptMacWireguardDisconnect === "function" ? shouldAttemptMacWireguardDisconnect : undefined,
|
||||||
detectMacWireguardActiveFromIfconfig:
|
detectMacWireguardActiveFromIfconfig:
|
||||||
typeof detectMacWireguardActiveFromIfconfig === "function" ? detectMacWireguardActiveFromIfconfig : undefined,
|
typeof detectMacWireguardActiveFromIfconfig === "function" ? detectMacWireguardActiveFromIfconfig : undefined,
|
||||||
resolveHostnameWithFallback:
|
resolveHostnameWithFallback:
|
||||||
@@ -130,6 +132,41 @@ test("cleanupMacWireguardState removes stale config and last-connection files",
|
|||||||
assert.equal(fs.existsSync(lastConnectionPath), false);
|
assert.equal(fs.existsSync(lastConnectionPath), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("shouldAttemptMacWireguardDisconnect does not trust active=false when residual state exists", () => {
|
||||||
|
const { shouldAttemptMacWireguardDisconnect } = loadInternals();
|
||||||
|
assert.equal(typeof shouldAttemptMacWireguardDisconnect, "function");
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
shouldAttemptMacWireguardDisconnect({
|
||||||
|
active: false,
|
||||||
|
configPath: "/Users/stefano/.nordvpn-client/wireguard/nordvpnctl.conf",
|
||||||
|
endpoint: null,
|
||||||
|
lastConnection: null,
|
||||||
|
}),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
shouldAttemptMacWireguardDisconnect({
|
||||||
|
active: false,
|
||||||
|
configPath: null,
|
||||||
|
endpoint: null,
|
||||||
|
lastConnection: { country: "Italy" },
|
||||||
|
}),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
shouldAttemptMacWireguardDisconnect({
|
||||||
|
active: false,
|
||||||
|
configPath: null,
|
||||||
|
endpoint: null,
|
||||||
|
lastConnection: null,
|
||||||
|
}),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("isMacTailscaleActive treats Running backend as active", () => {
|
test("isMacTailscaleActive treats Running backend as active", () => {
|
||||||
const { isMacTailscaleActive } = loadInternals();
|
const { isMacTailscaleActive } = loadInternals();
|
||||||
assert.equal(typeof isMacTailscaleActive, "function");
|
assert.equal(typeof isMacTailscaleActive, "function");
|
||||||
|
|||||||
Reference in New Issue
Block a user