test(authz): pin the GET-exemption set by membership, not by count (#11531) (#11580)

Merged via /merge-batch (lote 2026-08-26, v3.8.51). Boarded no worktree combinado junto com outras ~30 PRs; validação única: typecheck/complexity/cognitive-complexity/changelog-integrity verdes, file-size rebaseado onde necessário (crescimento legítimo), lint com os mesmos 228 achados pré-existentes confirmados via sonda contra o tip puro (não introduzidos por este lote), e ~370 testes focados (unit + vitest) passando. Obrigado pela contribuição.
This commit is contained in:
Nguyen Thanh Dat
2026-08-26 18:10:29 +07:00
committed by GitHub
parent 1ea13454d5
commit 8cb2d0c047
2 changed files with 18 additions and 3 deletions

View File

@@ -0,0 +1 @@
- **test(authz):** pin `LOCAL_ONLY_API_GET_EXEMPTIONS` by exact membership instead of by entry count, so the guard names the offending path and also catches a substitution ([#11580](https://github.com/diegosouzapw/OmniRoute/pull/11580))

View File

@@ -85,13 +85,27 @@ describe("isLocalOnlyPath — GET exemption for /api/system/version (#5083)", ()
assert.equal(isLocalOnlyPath("/api/db-backups/exportAll", "GET"), true);
});
// ── EXEMPTION SET IS EXPORTED AND CONTAINS EXACTLY /api/system/version ───
// ── EXEMPTION SET IS EXPORTED AND HOLDS EXACTLY THE REVIEWED PATHS ───────
test("LOCAL_ONLY_API_GET_EXEMPTIONS contains /api/system/version", () => {
assert.ok(LOCAL_ONLY_API_GET_EXEMPTIONS.has("/api/system/version"));
});
test("LOCAL_ONLY_API_GET_EXEMPTIONS has exactly 1 entry", () => {
assert.equal(LOCAL_ONLY_API_GET_EXEMPTIONS.size, 1);
// Every entry here opens a local-only path to LAN/remote GET, so the set must
// never grow by accident. Pinned by membership rather than by `size`: a count
// cannot say WHICH path appeared, and it cannot see a substitution at all —
// swapping /api/system/version for some other route keeps size at 1 and passes.
// Adding a path is still meant to fail here; the fix is to add it to this list
// in the same change, with the reason it is safe for a read-only method.
//
// /api/system/version — GET only reads package.json + the npm registry (#5083)
// /api/tunnels/cloudflared — GET is tunnel status; POST still spawns cloudflared
// and stays local-only (#11531, and see
// route-guard-tunnel-processes-local-only.test.ts)
test("LOCAL_ONLY_API_GET_EXEMPTIONS holds exactly the reviewed paths", () => {
assert.deepEqual([...LOCAL_ONLY_API_GET_EXEMPTIONS].sort(), [
"/api/system/version",
"/api/tunnels/cloudflared",
]);
});
});