141 lines
6.1 KiB
JavaScript
141 lines
6.1 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import test from "node:test";
|
|
import {
|
|
MINIMUM_CLOUD_DAEMON_VERSION,
|
|
checksumVerificationCommand,
|
|
parseDaemonReleaseEnvironment,
|
|
} from "../app/daemon-release.ts";
|
|
import { classifyReportedDaemonVersion } from "../release/daemon-version.ts";
|
|
|
|
const SHA = {
|
|
windows: "1".repeat(64),
|
|
linuxAmd64: "2".repeat(64),
|
|
linuxArm64: "A".repeat(64),
|
|
};
|
|
|
|
function validConfig(overrides = {}) {
|
|
return {
|
|
NEKONEST_CLOUD_DAEMON_RELEASE_VERSION: MINIMUM_CLOUD_DAEMON_VERSION,
|
|
NEKONEST_CLOUD_DAEMON_WINDOWS_AMD64_SHA256: SHA.windows,
|
|
NEKONEST_CLOUD_DAEMON_LINUX_AMD64_SHA256: SHA.linuxAmd64,
|
|
NEKONEST_CLOUD_DAEMON_LINUX_ARM64_SHA256: SHA.linuxArm64,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
test("keeps daemon downloads closed until a complete compatible catalog exists", () => {
|
|
assert.deepEqual(parseDaemonReleaseEnvironment({}), {
|
|
available: false,
|
|
reason: "not_configured",
|
|
minimumVersion: "0.2.6",
|
|
});
|
|
assert.equal(
|
|
parseDaemonReleaseEnvironment(validConfig({ NEKONEST_CLOUD_DAEMON_RELEASE_VERSION: "0.2.5" })).reason,
|
|
"incompatible_version",
|
|
);
|
|
assert.equal(
|
|
parseDaemonReleaseEnvironment(validConfig({ NEKONEST_CLOUD_DAEMON_LINUX_ARM64_SHA256: "bad" })).reason,
|
|
"invalid_config",
|
|
);
|
|
assert.equal(
|
|
parseDaemonReleaseEnvironment(validConfig({ NEKONEST_CLOUD_DAEMON_RELEASE_BASE_URL: "http://mirror.example.test/release" })).reason,
|
|
"invalid_config",
|
|
);
|
|
assert.equal(
|
|
parseDaemonReleaseEnvironment(validConfig({ NEKONEST_CLOUD_DAEMON_RELEASE_BASE_URL: "https://user:pass@download.example.test/release" })).reason,
|
|
"invalid_config",
|
|
);
|
|
assert.equal(
|
|
parseDaemonReleaseEnvironment(validConfig({ NEKONEST_CLOUD_DAEMON_RELEASE_BASE_URL: "https://download.example.test/release?token=secret" })).reason,
|
|
"invalid_config",
|
|
);
|
|
});
|
|
|
|
test("accepts legacy unreported versions but rejects malformed and known-old reports", () => {
|
|
assert.deepEqual(classifyReportedDaemonVersion(undefined), {
|
|
state: "unreported",
|
|
version: null,
|
|
});
|
|
assert.deepEqual(classifyReportedDaemonVersion(" "), {
|
|
state: "unreported",
|
|
version: null,
|
|
});
|
|
assert.deepEqual(classifyReportedDaemonVersion("0.2.5"), {
|
|
state: "incompatible",
|
|
version: "0.2.5",
|
|
});
|
|
assert.deepEqual(classifyReportedDaemonVersion("0.2.6"), {
|
|
state: "compatible",
|
|
version: "0.2.6",
|
|
});
|
|
assert.deepEqual(classifyReportedDaemonVersion("1.0.0"), {
|
|
state: "compatible",
|
|
version: "1.0.0",
|
|
});
|
|
for (const version of ["v0.2.6", "0.2", "0.2.6-beta.1", "00.2.6", "1.02.3"]) {
|
|
assert.deepEqual(classifyReportedDaemonVersion(version), {
|
|
state: "invalid",
|
|
version: null,
|
|
});
|
|
}
|
|
});
|
|
|
|
test("registration accepts an optional daemon version and stores it in the atomic host claim", async () => {
|
|
const [route, repository, pairing] = await Promise.all([
|
|
readFile(new URL("../app/api/internal/relay/register-device/route.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../db/repository.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../db/pairing.ts", import.meta.url), "utf8"),
|
|
]);
|
|
assert.match(route, /daemon_version\?: string/);
|
|
assert.match(route, /daemonVersion: payload\.daemon_version \?\? ""/);
|
|
assert.match(repository, /classifyReportedDaemonVersion\(input\.daemonVersion\)/);
|
|
assert.match(repository, /protocol_upgrade_required/);
|
|
assert.match(pairing, /daemon_version = COALESCE\(excluded\.daemon_version, hosts\.daemon_version\)/);
|
|
});
|
|
|
|
test("publishes exact versioned URLs and normalized platform checksums", () => {
|
|
const release = parseDaemonReleaseEnvironment(validConfig());
|
|
assert.equal(release.available, true);
|
|
if (!release.available) return;
|
|
assert.equal(release.version, "0.2.6");
|
|
assert.equal(release.assets.length, 3);
|
|
assert.equal(release.assets[0].downloadUrl, "https://github.com/klarkxy/nekonest/releases/download/v0.2.6/nekonest-daemon-windows-amd64.zip");
|
|
assert.equal(release.assets[2].sha256, "a".repeat(64));
|
|
assert.equal(release.checksumsUrl, "https://github.com/klarkxy/nekonest/releases/download/v0.2.6/checksums.txt");
|
|
});
|
|
|
|
test("supports an HTTPS domestic mirror without weakening digest verification", () => {
|
|
const release = parseDaemonReleaseEnvironment(validConfig({
|
|
NEKONEST_CLOUD_DAEMON_RELEASE_BASE_URL: "https://download.example.cn/nekonest/v0.2.6/",
|
|
}));
|
|
assert.equal(release.available, true);
|
|
if (!release.available) return;
|
|
assert.equal(release.assets[1].downloadUrl, "https://download.example.cn/nekonest/v0.2.6/nekonest-daemon-linux-amd64.tar.gz");
|
|
assert.match(checksumVerificationCommand(release.assets[0]), /Get-FileHash[\s\S]*SHA-256 不匹配/);
|
|
assert.match(checksumVerificationCommand(release.assets[1]), /sha256sum -c -/);
|
|
});
|
|
|
|
test("download page distinguishes checksums from publisher code signing", async () => {
|
|
const [page, pairingPage, pairingForm, shell, plan] = await Promise.all([
|
|
readFile(new URL("../app/download/page.tsx", import.meta.url), "utf8"),
|
|
readFile(new URL("../app/dashboard/hosts/new/page.tsx", import.meta.url), "utf8"),
|
|
readFile(new URL("../app/dashboard/hosts/new/PairingForm.tsx", import.meta.url), "utf8"),
|
|
readFile(new URL("../app/components/Shells.tsx", import.meta.url), "utf8"),
|
|
readFile(new URL("../docs/implementation-plan.md", import.meta.url), "utf8"),
|
|
]);
|
|
assert.match(page, /摘要校验不是代码签名/);
|
|
assert.match(page, /不提供“先下最新版试试”的按钮/);
|
|
assert.match(page, /已下载,开始配对/);
|
|
assert.match(pairingPage, /先下载兼容 daemon/);
|
|
assert.match(pairingPage, /getDaemonReleaseState/);
|
|
assert.match(pairingPage, /releaseAvailable=\{daemonRelease\.available\}/);
|
|
assert.match(pairingForm, /公开 daemon 下载尚未就绪/);
|
|
assert.match(pairingForm, /我已有经过核验的兼容闭测构建/);
|
|
assert.match(pairingForm, /!releaseAvailable && !closedBetaBuildConfirmed/);
|
|
assert.match(pairingForm, /disabled=\{loading \|\| \(!releaseAvailable && !closedBetaBuildConfirmed\)\}/);
|
|
assert.match(shell, /href="\/download"/);
|
|
assert.match(plan, /fail-closed 发布清单/);
|
|
assert.match(plan, /取得并核验兼容闭测构建/);
|
|
});
|