mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-14 02:42:24 +03:00
Merged as a reduced diff, and worth recording why. The two-arm `ALWAYS_PROTECTED` read this PR proposed had already landed in #12605 while this branch was open — the tip carries `coveredByAlwaysProtected()` with both arms and the new error wording. I ran the gate on the current tip to be sure: `PASS — all security tier annotations match routeGuard.ts`. Merging the whole branch would have reintroduced the same logic under a different comment. What was genuinely missing, and is what merged: - **`tests/unit/openapi-security-tiers-gate.test.ts`** — executes the real gate and asserts exit 0 with no "NOT covered" line. #12605 fixed the defect but left no guard, so the LOCAL_ONLY-arm bug (#12350) could reappear on the ALWAYS_PROTECTED arm exactly as it did the first time. 1/1 green. - **The parse guard** — `ALWAYS_PROTECTED_PATTERNS.length === 0` now fails the constant-parse check with its own count in the message. Without it, a regex array that stops parsing degrades into "every pattern-covered route is an annotation mismatch" instead of saying so. A note for the record: my first read of this PR was wrong. I ran the gate in the main checkout, which was 11 commits behind `origin/release/v3.8.51`, saw the pre-#12605 failure, and classified this as fixing a live red. It was not — the checkout was stale. Corrected before anything was merged.
39 lines
1.6 KiB
TypeScript
39 lines
1.6 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { execFileSync } from "node:child_process";
|
|
import { fileURLToPath } from "node:url";
|
|
import { dirname, join } from "node:path";
|
|
|
|
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
const GATE = join(ROOT, "scripts", "check", "check-openapi-security-tiers.mjs");
|
|
|
|
function runGate(): { code: number; out: string } {
|
|
try {
|
|
const out = execFileSync(process.execPath, [GATE], {
|
|
cwd: ROOT,
|
|
encoding: "utf8",
|
|
stdio: ["ignore", "pipe", "pipe"],
|
|
});
|
|
return { code: 0, out };
|
|
} catch (err) {
|
|
const e = err as { status?: number; stdout?: string; stderr?: string };
|
|
return { code: e.status ?? 1, out: `${e.stdout ?? ""}${e.stderr ?? ""}` };
|
|
}
|
|
}
|
|
|
|
// routeGuard protects a path when EITHER list matches — `isAlwaysProtectedPath`
|
|
// ORs ALWAYS_PROTECTED_API_PATHS with ALWAYS_PROTECTED_API_PATTERNS. The gate
|
|
// used to read only the prefix array, so every regex-covered route was reported
|
|
// as an annotation mismatch: the four `{claude,codex}-auth/{export,apply-local}`
|
|
// routes turned release/v3.8.51 red while being correctly protected at runtime.
|
|
// Same defect class the LOCAL_ONLY arm already had (#12350).
|
|
test("openapi-security-tiers accepts routes covered only by ALWAYS_PROTECTED_API_PATTERNS", () => {
|
|
const { code, out } = runGate();
|
|
|
|
assert.ok(
|
|
!/has x-always-protected but is NOT/.test(out),
|
|
`gate reported an always-protected route as uncovered:\n${out}`
|
|
);
|
|
assert.equal(code, 0, `gate must pass on a clean tree, got exit ${code}:\n${out}`);
|
|
});
|