104 lines
4.3 KiB
TypeScript
104 lines
4.3 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import path from "node:path";
|
|
import { test } from "node:test";
|
|
import Database from "better-sqlite3";
|
|
|
|
// Start with the real deployed schema rather than the new migration output.
|
|
test("existing v4 boots and custom nodes stay outside HY2 polling/auth while retaining credentials", async () => {
|
|
const dir = mkdtempSync(path.join(tmpdir(), "hy2-custom-store-"));
|
|
process.env.DATABASE_PATH = path.join(dir, "remote-v4.db");
|
|
process.env.ADMIN_USERNAME = "test-admin";
|
|
process.env.ADMIN_PASSWORD = "test-admin-local-only";
|
|
process.env.POLLER_ENABLED = "false";
|
|
const legacy = new Database(process.env.DATABASE_PATH);
|
|
legacy.exec(readFileSync("tests/fixtures/remote-v4-schema.sql", "utf8"));
|
|
legacy.exec(`INSERT INTO hy2_nodes (id,slug,name,auth_token,traffic_stats_url,traffic_stats_secret,created_at,updated_at,server_host)
|
|
VALUES (91,'existing-hy2','Existing HY2','test-auth','http://stats.example:9999','test-stats','2026-01-01','2026-01-01','hy2.example');`);
|
|
const yaml =
|
|
'# original comment\n- name: "Remote Custom"\n type: anytls\n password: "test-pass"\n server: custom.example\n port: 443\n';
|
|
legacy
|
|
.prepare(
|
|
`INSERT INTO hy2_nodes (id,slug,name,auth_token,traffic_stats_url,traffic_stats_secret,created_at,updated_at,node_type,custom_config_yaml,client_name)
|
|
VALUES (92,'existing-custom','Display','test-original-auth','','test-original-stats','2026-01-01','2026-01-01','custom',?,'Old alias')`,
|
|
)
|
|
.run(yaml);
|
|
legacy.exec(
|
|
`INSERT INTO app_settings VALUES ('main_proxy_group_member_slugs_json','["existing-custom","existing-hy2"]','2026-01-01')`,
|
|
);
|
|
const before = legacy.prepare("SELECT * FROM hy2_nodes ORDER BY id").all();
|
|
legacy.close();
|
|
const { ensureDb } = await import("../../lib/db");
|
|
const store = await import("../../lib/store");
|
|
const { verifyNodeToken } = await import("../../lib/hy2");
|
|
const db = await ensureDb();
|
|
try {
|
|
assert.deepEqual(
|
|
db.prepare("SELECT * FROM hy2_nodes ORDER BY id").all(),
|
|
before,
|
|
);
|
|
assert.deepEqual(
|
|
(await store.getSubscriptionSettings()).mainProxyGroupMemberSlugs,
|
|
["existing-custom", "existing-hy2"],
|
|
);
|
|
assert.deepEqual(
|
|
(await store.listEnabledNodesForPolling()).map((node) => node.id),
|
|
[91],
|
|
);
|
|
assert.equal((await store.listSubscriptionNodes()).length, 2);
|
|
assert.equal(
|
|
(await verifyNodeToken("existing-custom", "test-original-auth")).reason,
|
|
"node_not_hy2",
|
|
);
|
|
assert.equal((await verifyNodeToken("existing-hy2", "test-auth")).ok, true);
|
|
const custom = (await store.getNodeBySlug("existing-custom"))!;
|
|
assert.equal(store.getNodeProxyName(custom), "Remote Custom");
|
|
const input = {
|
|
nodeType: "custom" as const,
|
|
slug: "existing-custom",
|
|
name: "Display",
|
|
authToken: "",
|
|
hy2Listen: "",
|
|
serverHost: "",
|
|
serverPort: 443,
|
|
clientName: "",
|
|
bandwidthUpMbps: 30,
|
|
bandwidthDownMbps: 30,
|
|
skipCertVerify: false,
|
|
sni: null,
|
|
customConfigYaml: yaml.replace("Remote Custom", "Updated Custom"),
|
|
trafficStatsUrl: "",
|
|
trafficStatsListen: ":9999",
|
|
trafficStatsSecret: "",
|
|
enabled: true,
|
|
pollIntervalSeconds: 15,
|
|
};
|
|
await store.updateNode({ ...input, id: custom.id });
|
|
const saved = (await store.getNodeBySlug("existing-custom"))!;
|
|
assert.equal(saved.id, 92);
|
|
assert.equal(saved.custom_config_yaml, input.customConfigYaml);
|
|
assert.equal(saved.auth_token, "test-original-auth");
|
|
assert.equal(saved.traffic_stats_secret, "test-original-stats");
|
|
assert.equal(store.getNodeProxyName(saved), "Updated Custom");
|
|
await assert.rejects(() =>
|
|
store.updateNode({
|
|
...input,
|
|
id: 92,
|
|
customConfigYaml: "name: [invalid",
|
|
}),
|
|
);
|
|
assert.deepEqual(await store.getNodeBySlug("existing-custom"), saved);
|
|
await store.updateNode({ ...input, id: 92, enabled: false });
|
|
assert.deepEqual(
|
|
(await store.listSubscriptionNodes()).map((node) => node.id),
|
|
[91],
|
|
);
|
|
} finally {
|
|
db.close();
|
|
global.__hy2PanelDb = undefined;
|
|
global.__hy2PanelDbInit = undefined;
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|