test: align health-autopilot cross-site + chat-pipeline Accept tests with #5278/#5309

- provider-health-autopilot: cross-site mutation rejection moved from the route
  handler into the authz pipeline (#5278); drive the assertion through
  runAuthzPipeline (the real enforcement point) → 403 + connection untouched.
- chat-pipeline: a mixed 'application/json, text/event-stream' Accept now resolves
  to JSON (#5305/#5309 Vercel/OpenAI SDK non-stream signature); the SSE-opt-in test
  now sends a pure 'text/event-stream' Accept, the case #5309 keeps as streaming.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-29 08:07:23 -03:00
parent 7ccd1b2342
commit 165c823f5a
2 changed files with 22 additions and 4 deletions

View File

@@ -1135,9 +1135,13 @@ test("chat pipeline treats Accept text/event-stream as streaming mode and return
globalThis.fetch = async () => buildOpenAIStreamResponse("Accept header stream");
// #5305/#5309: only a PURE `text/event-stream` Accept (without application/json)
// forces SSE when `stream` is omitted. A mixed `application/json, text/event-stream`
// Accept is the Vercel/OpenAI SDK non-stream signature and now resolves to JSON, so
// this SSE-opt-in test must send the pure-SSE Accept header.
const response = await handleChat(
buildRequest({
headers: { Accept: "application/json, text/event-stream" },
headers: { Accept: "text/event-stream" },
body: {
model: "openai/gpt-4o-mini",
messages: [{ role: "user", content: "Stream via Accept" }],

View File

@@ -3,6 +3,7 @@ import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { NextRequest } from "next/server";
import { makeManagementSessionRequest } from "../helpers/managementSession.ts";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-health-autopilot-"));
@@ -19,6 +20,7 @@ const autopilot = await import("../../src/lib/monitoring/providerHealthAutopilot
const actionsRoute = await import("../../src/app/api/providers/health-autopilot/actions/route.ts");
const reportRoute = await import("../../src/app/api/providers/health-autopilot/route.ts");
const routeGuard = await import("../../src/server/authz/routeGuard.ts");
const authzPipeline = await import("../../src/server/authz/pipeline.ts");
const accountFallback = await import("@omniroute/open-sse/services/accountFallback");
const PROVIDER = "autopilot-test-provider";
@@ -173,6 +175,12 @@ test("provider health autopilot action clears cooldown with stale-state protecti
});
test("provider health autopilot action rejects cross-site mutations", async () => {
// Cross-site origin validation for browser mutations is centralized in the authz
// pipeline (#5278): the per-route same-origin check was removed from the actions
// handler and is now enforced by validateBrowserMutationOrigin inside runAuthzPipeline
// for MANAGEMENT routes with an unsafe method + dashboard session. Drive the request
// through the pipeline (the real enforcement point) and assert it is blocked with 403
// before the route runs, leaving the connection untouched.
await enableManagementAuth();
const connection = await createCooldownConnection();
const report = await autopilot.buildProviderHealthAutopilotReport({
@@ -182,8 +190,9 @@ test("provider health autopilot action rejects cross-site mutations", async () =
const action = findAction(report, "clear_connection_cooldown");
assert.ok(action);
const response = await actionsRoute.POST(
await makeManagementSessionRequest("http://localhost/api/providers/health-autopilot/actions", {
const rawRequest = await makeManagementSessionRequest(
"http://localhost/api/providers/health-autopilot/actions",
{
method: "POST",
headers: { origin: "https://evil.example", "sec-fetch-site": "cross-site" },
body: {
@@ -192,10 +201,15 @@ test("provider health autopilot action rejects cross-site mutations", async () =
preconditionsHash: action.preconditionsHash,
confirm: true,
},
})
}
);
const response = await authzPipeline.runAuthzPipeline(new NextRequest(rawRequest), {
enforce: true,
});
assert.equal(response.status, 403);
assert.equal(response.headers.get("x-omniroute-route-class"), "MANAGEMENT");
// The pipeline blocks before the route handler runs, so the cooldown is untouched.
const unchanged = (await providersDb.getProviderConnectionById(String(connection.id))) as Record<
string,
unknown