feat: add default nordvpn credential paths
This commit is contained in:
@@ -59,6 +59,11 @@ Optional credential file env vars:
|
||||
- `NORDVPN_TOKEN_FILE`
|
||||
- `NORDVPN_PASSWORD_FILE`
|
||||
|
||||
Default OpenClaw credential paths:
|
||||
|
||||
- token: `~/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt`
|
||||
- password: `~/.openclaw/workspace/.clawdbot/credentials/nordvpn/password.txt`
|
||||
|
||||
## Verification Behavior
|
||||
|
||||
`status`, `verify`, and `connect` report machine-readable JSON including:
|
||||
@@ -79,7 +84,7 @@ Use `verify` when you want an explicit post-connect location check without chang
|
||||
For an automated macOS flow:
|
||||
|
||||
1. `node scripts/nordvpn-client.js install`
|
||||
2. set `NORDVPN_TOKEN` or `NORDVPN_TOKEN_FILE`
|
||||
2. put your token in `~/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt` or set `NORDVPN_TOKEN` / `NORDVPN_TOKEN_FILE`
|
||||
3. `node scripts/nordvpn-client.js login`
|
||||
4. `node scripts/nordvpn-client.js connect --country "Italy"` or `--city "Milan"`
|
||||
5. `node scripts/nordvpn-client.js verify`
|
||||
|
||||
@@ -12,6 +12,16 @@ const WG_STATE_DIR = path.join(STATE_DIR, "wireguard");
|
||||
const WG_CONFIG_PATH = path.join(WG_STATE_DIR, `${MAC_WG_INTERFACE}.conf`);
|
||||
const AUTH_CACHE_PATH = path.join(STATE_DIR, "auth.json");
|
||||
const LAST_CONNECTION_PATH = path.join(STATE_DIR, "last-connection.json");
|
||||
const OPENCLAW_NORDVPN_CREDENTIALS_DIR = path.join(
|
||||
os.homedir(),
|
||||
".openclaw",
|
||||
"workspace",
|
||||
".clawdbot",
|
||||
"credentials",
|
||||
"nordvpn"
|
||||
);
|
||||
const DEFAULT_TOKEN_FILE = path.join(OPENCLAW_NORDVPN_CREDENTIALS_DIR, "token.txt");
|
||||
const DEFAULT_PASSWORD_FILE = path.join(OPENCLAW_NORDVPN_CREDENTIALS_DIR, "password.txt");
|
||||
const DEFAULT_DNS_IPV4 = "103.86.96.100";
|
||||
const DEFAULT_DNS_IPV6 = "2400:bb40:4444::100";
|
||||
const CLIENT_IPV4 = "10.5.0.2";
|
||||
@@ -39,9 +49,11 @@ function usage() {
|
||||
env: [
|
||||
"NORDVPN_TOKEN",
|
||||
"NORDVPN_TOKEN_FILE",
|
||||
`default token file: ${DEFAULT_TOKEN_FILE}`,
|
||||
"NORDVPN_USERNAME",
|
||||
"NORDVPN_PASSWORD",
|
||||
"NORDVPN_PASSWORD_FILE",
|
||||
`default password file: ${DEFAULT_PASSWORD_FILE}`,
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -75,13 +87,22 @@ function detectPlatform() {
|
||||
|
||||
function readSecret(envName, fileEnvName) {
|
||||
if (process.env[envName]) return process.env[envName];
|
||||
const filePath = process.env[fileEnvName];
|
||||
if (!filePath) return "";
|
||||
try {
|
||||
return fs.readFileSync(filePath, "utf8").trim();
|
||||
} catch {
|
||||
return "";
|
||||
|
||||
const candidates = [];
|
||||
if (process.env[fileEnvName]) candidates.push(process.env[fileEnvName]);
|
||||
if (envName === "NORDVPN_TOKEN") candidates.push(DEFAULT_TOKEN_FILE);
|
||||
if (envName === "NORDVPN_PASSWORD") candidates.push(DEFAULT_PASSWORD_FILE);
|
||||
|
||||
for (const candidate of candidates) {
|
||||
try {
|
||||
const value = fs.readFileSync(candidate, "utf8").trim();
|
||||
if (value) return value;
|
||||
} catch {
|
||||
// Continue.
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function normalizeLocation(value) {
|
||||
@@ -370,7 +391,7 @@ function buildStateSummary(installProbe, ipInfo) {
|
||||
? installProbe.wireguard.sudoReady
|
||||
? "Use token-based WireGuard automation on macOS."
|
||||
: "WireGuard tooling and token are available, but connect/disconnect require non-interactive sudo for wg-quick. Authorize sudo for wg-quick, then rerun login/connect."
|
||||
: "Set NORDVPN_TOKEN or NORDVPN_TOKEN_FILE for automated macOS NordLynx/WireGuard connects.";
|
||||
: `Set NORDVPN_TOKEN, NORDVPN_TOKEN_FILE, or place the token at ${DEFAULT_TOKEN_FILE} for automated macOS NordLynx/WireGuard connects.`;
|
||||
} else if (installProbe.platform === "darwin" && installProbe.appInstalled) {
|
||||
controlMode = "app-manual";
|
||||
automaticControl = false;
|
||||
@@ -378,7 +399,7 @@ function buildStateSummary(installProbe, ipInfo) {
|
||||
connectMode = "app-manual";
|
||||
recommendedAction = installProbe.tokenAvailable
|
||||
? "NordVPN.app is installed, but automated macOS connects also require wireguard-go and wireguard-tools. Run 'node scripts/nordvpn-client.js install' to install them with Homebrew."
|
||||
: "NordVPN.app is installed. For automated macOS connects, run 'node scripts/nordvpn-client.js install' to install wireguard-go and wireguard-tools with Homebrew, then set NORDVPN_TOKEN or NORDVPN_TOKEN_FILE and run login.";
|
||||
: `NordVPN.app is installed. For automated macOS connects, run 'node scripts/nordvpn-client.js install' to install wireguard-go and wireguard-tools with Homebrew, then set NORDVPN_TOKEN, NORDVPN_TOKEN_FILE, or place the token at ${DEFAULT_TOKEN_FILE} and run login.`;
|
||||
} else if (installProbe.platform === "darwin" && installProbe.brewPath) {
|
||||
controlMode = "wireguard-bootstrap";
|
||||
automaticControl = false;
|
||||
@@ -759,7 +780,7 @@ async function runSudoWireguard(installProbe, action) {
|
||||
async function connectViaMacWireguard(installProbe, target) {
|
||||
const token = readSecret("NORDVPN_TOKEN", "NORDVPN_TOKEN_FILE");
|
||||
if (!token) {
|
||||
throw new Error("macOS NordLynx/WireGuard automation requires NORDVPN_TOKEN or NORDVPN_TOKEN_FILE.");
|
||||
throw new Error(`macOS NordLynx/WireGuard automation requires NORDVPN_TOKEN, NORDVPN_TOKEN_FILE, or a token at ${DEFAULT_TOKEN_FILE}.`);
|
||||
}
|
||||
if (!installProbe.wireguard || !installProbe.wireguard.dependenciesReady) {
|
||||
throw new Error("wireguard-go and wireguard-tools are required on macOS. Run install first.");
|
||||
@@ -912,7 +933,13 @@ async function loginNordvpn(installProbe) {
|
||||
backend: "wireguard",
|
||||
validatedAt: new Date().toISOString(),
|
||||
hasNordlynxPrivateKey: Boolean(credentials.nordlynx_private_key),
|
||||
tokenSource: process.env.NORDVPN_TOKEN ? "env:NORDVPN_TOKEN" : process.env.NORDVPN_TOKEN_FILE ? "file:NORDVPN_TOKEN_FILE" : "unknown",
|
||||
tokenSource: process.env.NORDVPN_TOKEN
|
||||
? "env:NORDVPN_TOKEN"
|
||||
: process.env.NORDVPN_TOKEN_FILE
|
||||
? "file:NORDVPN_TOKEN_FILE"
|
||||
: fileExists(DEFAULT_TOKEN_FILE)
|
||||
? `default:${DEFAULT_TOKEN_FILE}`
|
||||
: "unknown",
|
||||
};
|
||||
writeJsonFile(AUTH_CACHE_PATH, cache);
|
||||
return {
|
||||
@@ -932,7 +959,7 @@ async function loginNordvpn(installProbe) {
|
||||
backend: "app-manual",
|
||||
manualActionRequired: true,
|
||||
message:
|
||||
"Opened NordVPN.app. Complete login in the app/browser flow, or set NORDVPN_TOKEN / NORDVPN_TOKEN_FILE to use the automated macOS WireGuard backend.",
|
||||
`Opened NordVPN.app. Complete login in the app/browser flow, or set NORDVPN_TOKEN, NORDVPN_TOKEN_FILE, or place the token at ${DEFAULT_TOKEN_FILE} to use the automated macOS WireGuard backend.`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1007,7 +1034,7 @@ async function main() {
|
||||
} else if (platform === "darwin" && installProbe.appInstalled) {
|
||||
connectResult = await connectViaMacApp(target);
|
||||
} else if (platform === "darwin" && !installProbe.tokenAvailable) {
|
||||
throw new Error("macOS automated NordLynx/WireGuard connects require NORDVPN_TOKEN or NORDVPN_TOKEN_FILE.");
|
||||
throw new Error(`macOS automated NordLynx/WireGuard connects require NORDVPN_TOKEN, NORDVPN_TOKEN_FILE, or a token at ${DEFAULT_TOKEN_FILE}.`);
|
||||
} else if (platform === "darwin") {
|
||||
throw new Error("No usable macOS NordVPN backend is ready. Run install to bootstrap WireGuard tooling.");
|
||||
} else if (!installProbe.installed) {
|
||||
|
||||
Reference in New Issue
Block a user