feat: support direct IP service access
TallyNote release / linux-x64 (push) Successful in 7m17s

This commit is contained in:
Qiufeng
2026-09-01 20:57:56 +08:00
parent bcc63b8117
commit eeeec54d10
12 changed files with 365 additions and 27 deletions
+22 -1
View File
@@ -5,7 +5,7 @@ import { tmpdir } from "node:os";
import path from "node:path";
import { loadConfig, prepareDataDirectories } from "../server/config.js";
const keys = ["TALLYNOTE_DATA_DIR", "TALLYNOTE_PUBLIC_ORIGIN", "TALLYNOTE_COOKIE_SECURE", "TALLYNOTE_TRUST_PROXY", "NODE_ENV", "TALLYNOTE_ENV", "TALLYNOTE_UPDATE_STRATEGY", "TALLYNOTE_UPDATE_ALLOWED_HOSTS", "TALLYNOTE_UPDATE_REQUIRE_SIGNATURE", "TALLYNOTE_UPDATE_PUBLIC_KEY", "TALLYNOTE_UPDATE_PUBLIC_KEY_FILE"];
const keys = ["TALLYNOTE_DATA_DIR", "TALLYNOTE_HOST", "TALLYNOTE_PORT", "TALLYNOTE_PUBLIC_ORIGIN", "TALLYNOTE_COOKIE_SECURE", "TALLYNOTE_ALLOW_INSECURE_HTTP", "TALLYNOTE_TRUST_PROXY", "NODE_ENV", "TALLYNOTE_ENV", "TALLYNOTE_UPDATE_STRATEGY", "TALLYNOTE_UPDATE_ALLOWED_HOSTS", "TALLYNOTE_UPDATE_REQUIRE_SIGNATURE", "TALLYNOTE_UPDATE_PUBLIC_KEY", "TALLYNOTE_UPDATE_PUBLIC_KEY_FILE"];
afterEach(() => { for (const key of keys) delete process.env[key]; });
@@ -13,11 +13,32 @@ describe("部署安全配置", () => {
it("公网 HTTP 或 HTTPS 非安全 Cookie 一律拒绝", () => {
process.env.TALLYNOTE_PUBLIC_ORIGIN = "http://example.test";
expect(() => loadConfig()).toThrow(/HTTPS/);
process.env.TALLYNOTE_ALLOW_INSECURE_HTTP = "true";
expect(loadConfig().allowInsecureHttp).toBe(true);
process.env.TALLYNOTE_COOKIE_SECURE = "true";
expect(() => loadConfig()).toThrow(/安全 Cookie/);
process.env.TALLYNOTE_PUBLIC_ORIGIN = "https://example.test";
process.env.TALLYNOTE_COOKIE_SECURE = "false";
expect(() => loadConfig()).toThrow(/安全 Cookie/);
});
it("允许显式配置服务器 IP 的直连 HTTP,并拒绝通配 Origin", () => {
process.env.TALLYNOTE_HOST = "0.0.0.0";
process.env.TALLYNOTE_PORT = "3000";
process.env.TALLYNOTE_PUBLIC_ORIGIN = "http://192.0.2.10:3000";
process.env.TALLYNOTE_ALLOW_INSECURE_HTTP = "true";
process.env.TALLYNOTE_COOKIE_SECURE = "false";
expect(loadConfig()).toMatchObject({ host: "0.0.0.0", port: 3000, publicOrigin: "http://192.0.2.10:3000", allowInsecureHttp: true });
process.env.TALLYNOTE_PUBLIC_ORIGIN = "http://0.0.0.0:3000";
expect(() => loadConfig()).toThrow(/通配监听地址/);
});
it("为 IPv6 监听地址生成合法的默认 Origin", () => {
process.env.TALLYNOTE_HOST = "::1";
process.env.TALLYNOTE_PORT = "3000";
expect(loadConfig().publicOrigin).toBe("http://[::1]:3000");
});
it("生产环境不接受任意 trust proxy", () => {
process.env.NODE_ENV = "production";
process.env.TALLYNOTE_TRUST_PROXY = "true";