Emdash source with visual editor image upload fix
Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
97
packages/core/tests/unit/auth/trusted-proxy.test.ts
Normal file
97
packages/core/tests/unit/auth/trusted-proxy.test.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Tests for getTrustedProxyHeaders — resolves the list of trusted client-IP
|
||||
* headers from config, falling back to the EMDASH_TRUSTED_PROXY_HEADERS env
|
||||
* var, then to an empty array.
|
||||
*
|
||||
* The helper lets operators declare which headers they trust when running
|
||||
* behind a reverse proxy. On Cloudflare the `cf` object is used instead and
|
||||
* this list is usually empty.
|
||||
*/
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
_resetTrustedProxyHeadersCache,
|
||||
getTrustedProxyHeaders,
|
||||
} from "../../../src/auth/trusted-proxy.js";
|
||||
|
||||
describe("getTrustedProxyHeaders", () => {
|
||||
const ORIGINAL_ENV = process.env.EMDASH_TRUSTED_PROXY_HEADERS;
|
||||
|
||||
beforeEach(() => {
|
||||
_resetTrustedProxyHeadersCache();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
if (ORIGINAL_ENV === undefined) {
|
||||
delete process.env.EMDASH_TRUSTED_PROXY_HEADERS;
|
||||
} else {
|
||||
process.env.EMDASH_TRUSTED_PROXY_HEADERS = ORIGINAL_ENV;
|
||||
}
|
||||
_resetTrustedProxyHeadersCache();
|
||||
});
|
||||
|
||||
it("returns config value when set", () => {
|
||||
expect(getTrustedProxyHeaders({ trustedProxyHeaders: ["x-real-ip"] })).toEqual(["x-real-ip"]);
|
||||
});
|
||||
|
||||
it("prefers config over env", () => {
|
||||
process.env.EMDASH_TRUSTED_PROXY_HEADERS = "fly-client-ip";
|
||||
expect(getTrustedProxyHeaders({ trustedProxyHeaders: ["x-real-ip"] })).toEqual(["x-real-ip"]);
|
||||
});
|
||||
|
||||
it("falls back to env when config is absent", () => {
|
||||
process.env.EMDASH_TRUSTED_PROXY_HEADERS = "x-real-ip,fly-client-ip";
|
||||
expect(getTrustedProxyHeaders(undefined)).toEqual(["x-real-ip", "fly-client-ip"]);
|
||||
});
|
||||
|
||||
it("trims whitespace and drops empty entries from env", () => {
|
||||
process.env.EMDASH_TRUSTED_PROXY_HEADERS = " x-real-ip , , fly-client-ip ";
|
||||
expect(getTrustedProxyHeaders(undefined)).toEqual(["x-real-ip", "fly-client-ip"]);
|
||||
});
|
||||
|
||||
it("lowercases header names for consistent matching", () => {
|
||||
// Header lookups go through Headers.get() which is case-insensitive,
|
||||
// so we normalise the list here to avoid double-normalising elsewhere.
|
||||
expect(getTrustedProxyHeaders({ trustedProxyHeaders: ["X-Real-IP", "Fly-Client-IP"] })).toEqual(
|
||||
["x-real-ip", "fly-client-ip"],
|
||||
);
|
||||
});
|
||||
|
||||
it("returns empty array when neither config nor env is set", () => {
|
||||
delete process.env.EMDASH_TRUSTED_PROXY_HEADERS;
|
||||
expect(getTrustedProxyHeaders(undefined)).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns empty array when config has empty list", () => {
|
||||
process.env.EMDASH_TRUSTED_PROXY_HEADERS = "x-real-ip";
|
||||
// An explicit empty array means "trust nothing" — do not fall through
|
||||
// to the env. Operators use this to override an inherited env value.
|
||||
expect(getTrustedProxyHeaders({ trustedProxyHeaders: [] })).toEqual([]);
|
||||
});
|
||||
|
||||
// Header names must be valid RFC 7230 tokens; passing anything else into
|
||||
// `Headers.get()` throws. Drop invalid entries silently rather than
|
||||
// taking down every rate-limited endpoint with a 500.
|
||||
it("drops invalid header names from config", () => {
|
||||
expect(
|
||||
getTrustedProxyHeaders({
|
||||
trustedProxyHeaders: ["x-real-ip", "", "invalid name", "bad:colon", "ok-name"],
|
||||
}),
|
||||
).toEqual(["x-real-ip", "ok-name"]);
|
||||
});
|
||||
|
||||
it("drops invalid header names from env", () => {
|
||||
process.env.EMDASH_TRUSTED_PROXY_HEADERS = "x-real-ip, x y z , bad:one, ok-name";
|
||||
expect(getTrustedProxyHeaders(undefined)).toEqual(["x-real-ip", "ok-name"]);
|
||||
});
|
||||
|
||||
it("trims whitespace from config entries before matching", () => {
|
||||
// Common typo: `"x-real-ip "` (trailing space). Previously the raw
|
||||
// value was lowercased but not trimmed, so validation silently
|
||||
// dropped it and per-IP bucketing was disabled.
|
||||
expect(
|
||||
getTrustedProxyHeaders({ trustedProxyHeaders: [" x-real-ip ", "fly-client-ip"] }),
|
||||
).toEqual(["x-real-ip", "fly-client-ip"]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user