mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-19 13:23:50 +03:00
Merged as part of the owner batch of 2026-09-11. This PR had a live worktree in another session, so it sat outside the main 39. Merged on your explicit call, validated first rather than taken on trust: boarded with the other 10 worktree-held PRs into a consolidated worktree off `release/v3.8.51`. - ESLint over every changed file: no errors - `typecheck:core` clean; `check:dashboard-typecheck` OK; `check:changelog-integrity` OK - complexity 2821 / baseline 3218 and cognitive-complexity 1272 / baseline 1437 - 203 of 208 assertions green. The 5 remaining (`guide-settings-route` ×4, `hard-session-lease-bypass-inventory` ×1) reproduce on the pure tip with nothing from this batch applied. - `imageGeneration.ts` rebaselined 3259 → 3293 for #12945's image-only-model guard, landed separately in #13392 so nothing was pushed onto a live branch. ⚠️ base-red inherited: #12732 — provider count 356 vs 358 and `open-sse/utils/stream.ts` 3115 > frozen 3098, both reproducing on the pure tip.
58 lines
2.3 KiB
TypeScript
58 lines
2.3 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
process.env.OMNIROUTE_API_KEY = "test-configured-key-12888";
|
|
process.env.JWT_SECRET = "test-jwt-secret-for-probe-12888";
|
|
|
|
const { authenticateA2ARequest, resolveA2AOwner } = await import("../../src/lib/a2a/authenticate.ts");
|
|
const { isDashboardSessionAuthenticated } = await import("../../src/shared/utils/apiAuth.ts");
|
|
const { SignJWT } = await import("jose");
|
|
|
|
async function buildSessionRequest(): Promise<unknown> {
|
|
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
|
|
const sessionToken = await new SignJWT({ authenticated: true })
|
|
.setProtectedHeader({ alg: "HS256" })
|
|
.setExpirationTime("30d")
|
|
.sign(secret);
|
|
|
|
return {
|
|
headers: new Headers({ cookie: `auth_token=${sessionToken}` }),
|
|
cookies: { get: () => undefined },
|
|
nextUrl: { searchParams: new URLSearchParams() },
|
|
url: "http://localhost:20128/a2a",
|
|
};
|
|
}
|
|
|
|
test("A2A route accepts a dashboard-session-authenticated request with no Authorization header (bug #12888)", async () => {
|
|
const fakeRequest = await buildSessionRequest();
|
|
|
|
const dashboardSessionOk = await isDashboardSessionAuthenticated(fakeRequest as never);
|
|
assert.equal(dashboardSessionOk, true, "expected the dashboard session cookie itself to be valid");
|
|
|
|
const a2aAuthOk = await authenticateA2ARequest(fakeRequest as never);
|
|
assert.equal(
|
|
a2aAuthOk,
|
|
true,
|
|
"/a2a should accept the dashboard's own session-authenticated requests " +
|
|
"(matching /api/v1/* behavior) but currently requires an explicit Authorization header"
|
|
);
|
|
});
|
|
|
|
test("A2A route still rejects a request with neither a valid API key nor a valid session cookie", async () => {
|
|
const fakeRequest = {
|
|
headers: new Headers(),
|
|
cookies: { get: () => undefined },
|
|
nextUrl: { searchParams: new URLSearchParams() },
|
|
url: "http://localhost:20128/a2a",
|
|
};
|
|
|
|
const a2aAuthOk = await authenticateA2ARequest(fakeRequest as never);
|
|
assert.equal(a2aAuthOk, false, "unauthenticated, keyless requests must still be rejected");
|
|
});
|
|
|
|
test("resolveA2AOwner() returns a stable 'dashboard' owner id for a session-authenticated caller with no API key", async () => {
|
|
const fakeRequest = await buildSessionRequest();
|
|
const owner = await resolveA2AOwner(fakeRequest as never);
|
|
assert.equal(owner, "dashboard");
|
|
});
|