op-packages/luci-theme-aurora/.dev/scripts/setup.js
github-actions[bot] 5c17703277 🌴 Sync 2026-07-07 04:15:13
2026-07-07 04:15:13 +08:00

94 lines
2.7 KiB
JavaScript

/**
* One-shot dev environment setup: writes .env and installs an SSH key on the
* router so ut-sync works without any manual ssh configuration.
*
* Usage: pnpm setup (asks for the router IP, then one router password prompt)
*/
import { spawnSync } from "node:child_process";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { homedir } from "node:os";
import { join, resolve } from "node:path";
import { createInterface } from "node:readline/promises";
const SSH_OPTS = [
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=/dev/null",
];
function canAuth(host) {
return (
spawnSync(
"ssh",
[...SSH_OPTS, "-o", "BatchMode=yes", "-o", "ConnectTimeout=5", host, "echo ok"],
{ stdio: "ignore" },
).status === 0
);
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
const ip =
(await rl.question("Router IP [192.168.1.1]: ")).trim() || "192.168.1.1";
rl.close();
const host = `root@${ip}`;
const sshDir = join(homedir(), ".ssh");
let pubKeyPath = ["id_ed25519.pub", "id_rsa.pub", "id_ecdsa.pub"]
.map((f) => join(sshDir, f))
.find((f) => existsSync(f));
if (!pubKeyPath) {
console.log("No SSH key found — generating ~/.ssh/id_ed25519 ...");
const keygen = spawnSync(
"ssh-keygen",
["-t", "ed25519", "-N", "", "-f", join(sshDir, "id_ed25519")],
{ stdio: "inherit" },
);
if (keygen.status !== 0) {
console.error("✗ ssh-keygen failed.");
process.exit(1);
}
pubKeyPath = join(sshDir, "id_ed25519.pub");
}
if (canAuth(host)) {
console.log(`✓ Passwordless SSH to ${host} already works.`);
} else {
console.log(
`Installing ${pubKeyPath} on the router (enter the router password once):`,
);
const pubKey = readFileSync(pubKeyPath, "utf-8").trim();
const install = spawnSync(
"ssh",
[
...SSH_OPTS,
host,
`mkdir -p /etc/dropbear && echo '${pubKey}' >> /etc/dropbear/authorized_keys && chmod 600 /etc/dropbear/authorized_keys`,
],
{ stdio: "inherit" },
);
if (install.status !== 0 || !canAuth(host)) {
console.error(
`✗ Key install failed. Check that the device at ${ip} is reachable and the password is correct, then re-run pnpm setup.`,
);
process.exit(1);
}
console.log("✓ Passwordless SSH configured.");
}
const envPath = resolve(process.cwd(), ".env");
const kept = existsSync(envPath)
? readFileSync(envPath, "utf-8")
.split("\n")
.filter((l) => l && !l.startsWith("VITE_OPENWRT_HOST="))
: [];
writeFileSync(
envPath,
[`VITE_OPENWRT_HOST=${ip}`, ...kept].join("\n") + "\n",
);
console.log(`✓ Wrote .env (VITE_OPENWRT_HOST=${ip})`);
console.log("Done — run `pnpm dev`.");