Fix NordVPN DNS and Tailscale recovery interlock
This commit is contained in:
@@ -11,6 +11,10 @@ function loadInternals() {
|
||||
module.exports = {
|
||||
buildMacTailscaleState:
|
||||
typeof buildMacTailscaleState === "function" ? buildMacTailscaleState : undefined,
|
||||
markMacTailscaleRecoverySuppressed:
|
||||
typeof markMacTailscaleRecoverySuppressed === "function" ? markMacTailscaleRecoverySuppressed : undefined,
|
||||
clearMacTailscaleRecoverySuppressed:
|
||||
typeof clearMacTailscaleRecoverySuppressed === "function" ? clearMacTailscaleRecoverySuppressed : undefined,
|
||||
buildMacDnsState:
|
||||
typeof buildMacDnsState === "function" ? buildMacDnsState : undefined,
|
||||
buildWireguardConfig:
|
||||
@@ -57,6 +61,8 @@ module.exports = {
|
||||
typeof detectMacWireguardActiveFromIfconfig === "function" ? detectMacWireguardActiveFromIfconfig : undefined,
|
||||
resolveHostnameWithFallback:
|
||||
typeof resolveHostnameWithFallback === "function" ? resolveHostnameWithFallback : undefined,
|
||||
verifySystemHostnameResolution:
|
||||
typeof verifySystemHostnameResolution === "function" ? verifySystemHostnameResolution : undefined,
|
||||
verifyConnectionWithRetry:
|
||||
typeof verifyConnectionWithRetry === "function" ? verifyConnectionWithRetry : undefined,
|
||||
};`;
|
||||
@@ -203,6 +209,19 @@ test("buildMacTailscaleState records whether tailscale was active", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("tailscale recovery suppression marker can be created and cleared", () => {
|
||||
const { markMacTailscaleRecoverySuppressed, clearMacTailscaleRecoverySuppressed } = loadInternals();
|
||||
assert.equal(typeof markMacTailscaleRecoverySuppressed, "function");
|
||||
assert.equal(typeof clearMacTailscaleRecoverySuppressed, "function");
|
||||
|
||||
const markerPath = path.join(process.env.HOME || "", ".nordvpn-client", "tailscale-suppressed");
|
||||
clearMacTailscaleRecoverySuppressed();
|
||||
markMacTailscaleRecoverySuppressed();
|
||||
assert.equal(fs.existsSync(markerPath), true);
|
||||
clearMacTailscaleRecoverySuppressed();
|
||||
assert.equal(fs.existsSync(markerPath), false);
|
||||
});
|
||||
|
||||
test("shouldResumeMacTailscale only resumes when previously active and not already running", () => {
|
||||
const { shouldResumeMacTailscale } = loadInternals();
|
||||
assert.equal(typeof shouldResumeMacTailscale, "function");
|
||||
@@ -542,6 +561,10 @@ test("sanitizeOutputPayload redacts local path metadata from normal JSON output"
|
||||
wireguard: {
|
||||
configPath: "/Users/stefano/.nordvpn-client/wireguard/nordvpnctl.conf",
|
||||
helperPath: "/Users/stefano/.openclaw/workspace/skills/nordvpn-client/scripts/nordvpn-wireguard-helper.sh",
|
||||
helperSecurity: {
|
||||
hardened: false,
|
||||
reason: "Helper must be root-owned before privileged actions are trusted.",
|
||||
},
|
||||
authCache: {
|
||||
tokenSource: "default:/Users/stefano/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt",
|
||||
},
|
||||
@@ -553,6 +576,7 @@ test("sanitizeOutputPayload redacts local path metadata from normal JSON output"
|
||||
assert.equal(sanitized.appPath, null);
|
||||
assert.equal(sanitized.wireguard.configPath, null);
|
||||
assert.equal(sanitized.wireguard.helperPath, null);
|
||||
assert.equal(sanitized.wireguard.helperSecurity, null);
|
||||
assert.equal(sanitized.wireguard.authCache.tokenSource, null);
|
||||
assert.equal(sanitized.wireguard.endpoint, "jp454.nordvpn.com:51820");
|
||||
});
|
||||
@@ -606,3 +630,42 @@ test("resolveHostnameWithFallback uses fallback resolvers when system lookup fai
|
||||
assert.equal(address, "104.26.9.44");
|
||||
assert.deepEqual(calls, ["1.1.1.1:ipapi.co", "8.8.8.8:ipapi.co"]);
|
||||
});
|
||||
|
||||
test("verifySystemHostnameResolution succeeds when any system lookup resolves", async () => {
|
||||
const { verifySystemHostnameResolution } = loadInternals();
|
||||
assert.equal(typeof verifySystemHostnameResolution, "function");
|
||||
|
||||
const calls = [];
|
||||
const result = await verifySystemHostnameResolution(["www.google.com", "api.openai.com"], {
|
||||
timeoutMs: 5,
|
||||
lookup: async (hostname) => {
|
||||
calls.push(hostname);
|
||||
if (hostname === "www.google.com") {
|
||||
throw new Error("ENOTFOUND");
|
||||
}
|
||||
return { address: "104.18.33.45", family: 4 };
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(result.ok, true);
|
||||
assert.equal(result.hostname, "api.openai.com");
|
||||
assert.equal(result.address, "104.18.33.45");
|
||||
assert.deepEqual(calls, ["www.google.com", "api.openai.com"]);
|
||||
});
|
||||
|
||||
test("verifySystemHostnameResolution fails when all hostnames fail system lookup", async () => {
|
||||
const { verifySystemHostnameResolution } = loadInternals();
|
||||
assert.equal(typeof verifySystemHostnameResolution, "function");
|
||||
|
||||
const result = await verifySystemHostnameResolution(["www.google.com", "api.openai.com"], {
|
||||
timeoutMs: 5,
|
||||
lookup: async (hostname) => {
|
||||
throw new Error(`${hostname}: timeout`);
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(result.ok, false);
|
||||
assert.equal(result.hostname, "");
|
||||
assert.match(result.error, /www\.google\.com/);
|
||||
assert.match(result.error, /api\.openai\.com/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user