mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 21:02:12 +03:00
fix(api): auth on compression run-telemetry + document OMNIROUTE_EVAL_CREDENTIALS (#4694, #4720) (#4796)
Integrated into release/v3.8.36 — auth on compression run-telemetry + OMNIROUTE_EVAL_CREDENTIALS doc, release-green validated (typecheck + 3 tests + env-doc-sync)
This commit is contained in:
committed by
GitHub
parent
502f43c283
commit
fcf162d3fe
@@ -598,6 +598,11 @@ PROVIDER_LIMITS_SYNC_SPACING_MS=1500
|
||||
# Used by: scripts/postinstall.mjs.
|
||||
#OMNIROUTE_SKIP_POSTINSTALL=0
|
||||
|
||||
# Operator-supplied JSON credentials for the offline compression-eval CLI
|
||||
# (parsed with JSON.parse; leave unset for a dry run). Developer tooling only.
|
||||
# Used by: scripts/compression-eval/index.ts. Default: {} (empty).
|
||||
#OMNIROUTE_EVAL_CREDENTIALS={}
|
||||
|
||||
# Skip the DB healthcheck entirely on startup (useful for short-lived tasks / tests).
|
||||
# Used by: src/lib/db/core.ts, src/lib/db/healthCheck.ts. Set to 1 to disable. Default: 0.
|
||||
#OMNIROUTE_SKIP_DB_HEALTHCHECK=0
|
||||
|
||||
@@ -1082,3 +1082,12 @@ is developer tooling only.
|
||||
| `OMNIROUTE_URL` | `http://localhost:20128` | `scripts/ad-hoc/regen-opencode-config.ts` | Base URL of the OmniRoute instance to query for `/v1/models`. |
|
||||
| `OMNIROUTE_KEY` | _(unset)_ | `scripts/ad-hoc/regen-opencode-config.ts` | API key to authenticate against the OmniRoute `/v1/models` endpoint. Falls back to `OPENCODE_API_KEY` when unset. |
|
||||
| `OPENCODE_API_KEY` | _(unset)_ | `scripts/ad-hoc/regen-opencode-config.ts` | OpenCode-style API key (`sk-...`) written into the regenerated `opencode.json`. Falls back to `OMNIROUTE_KEY` when unset. |
|
||||
|
||||
### Compression offline-eval harness (ad-hoc tooling)
|
||||
|
||||
Used by `scripts/compression-eval/index.ts`, the offline compression evaluation CLI.
|
||||
Not required for normal operation — developer tooling only.
|
||||
|
||||
| Variable | Default | Source File | Description |
|
||||
| --------------------------- | ------------ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `OMNIROUTE_EVAL_CREDENTIALS` | `{}` (empty) | `scripts/compression-eval/index.ts` | Operator-supplied JSON credentials for the provider exercised by the offline compression-eval CLI (parsed with `JSON.parse`). Leave unset for a dry run. |
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { isAuthenticated } from "@/shared/utils/apiAuth";
|
||||
import { getCompressionRunTelemetrySummary } from "@/lib/db/compressionRunTelemetry";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET() {
|
||||
export async function GET(request: NextRequest) {
|
||||
if (!(await isAuthenticated(request))) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
try {
|
||||
const summary = getCompressionRunTelemetrySummary();
|
||||
return NextResponse.json(summary);
|
||||
|
||||
45
tests/unit/compression-run-telemetry-auth.test.ts
Normal file
45
tests/unit/compression-run-telemetry-auth.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Security regression (#4694 sibling-path gate parity): the compression
|
||||
* run-telemetry route MUST authenticate before disclosing telemetry, mirroring
|
||||
* its sibling `settings/compression/route.ts`. A behavioral 401 test would need
|
||||
* full DB/settings bootstrap (isAuthenticated reads settings), so this is a
|
||||
* source guard that fails if the auth gate is removed or reordered after the
|
||||
* data call — the same wiring-guard pattern used elsewhere in the suite.
|
||||
*/
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, join } from "node:path";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const ROUTE = join(
|
||||
__dirname,
|
||||
"../../src/app/api/settings/compression/run-telemetry/route.ts"
|
||||
);
|
||||
|
||||
test("run-telemetry GET imports isAuthenticated from the shared auth util", () => {
|
||||
const src = readFileSync(ROUTE, "utf8");
|
||||
assert.match(src, /import\s*\{[^}]*\bisAuthenticated\b[^}]*\}\s*from\s*["']@\/shared\/utils\/apiAuth["']/);
|
||||
});
|
||||
|
||||
test("run-telemetry GET gates on auth and returns 401 before reading telemetry", () => {
|
||||
const src = readFileSync(ROUTE, "utf8");
|
||||
|
||||
const authIdx = src.indexOf("isAuthenticated(request)");
|
||||
const unauthorizedIdx = src.search(/status:\s*401/);
|
||||
const dataIdx = src.indexOf("getCompressionRunTelemetrySummary(");
|
||||
|
||||
assert.ok(authIdx > 0, "must call isAuthenticated(request)");
|
||||
assert.ok(unauthorizedIdx > 0, "must return a 401 on failed auth");
|
||||
assert.ok(dataIdx > 0, "must call getCompressionRunTelemetrySummary");
|
||||
|
||||
// The auth check and its 401 must come BEFORE the telemetry read.
|
||||
assert.ok(authIdx < dataIdx, "auth check must precede the telemetry read");
|
||||
assert.ok(unauthorizedIdx < dataIdx, "401 response must precede the telemetry read");
|
||||
});
|
||||
|
||||
test("run-telemetry GET receives the request object (so auth can read it)", () => {
|
||||
const src = readFileSync(ROUTE, "utf8");
|
||||
assert.match(src, /export\s+async\s+function\s+GET\s*\(\s*request\s*:/);
|
||||
});
|
||||
Reference in New Issue
Block a user