Files
OmniRoute/src/proxy.ts
T
diegosouzapw 71d14209a4 feat: OmniRoute v1.0.0 — Intelligent AI Gateway & Universal LLM Proxy
OmniRoute is an intelligent API gateway that unifies 20+ AI providers behind a single
OpenAI-compatible endpoint. Features include intelligent routing with 6 strategies,
multi-format translation (OpenAI/Claude/Gemini/Responses API), circuit breakers,
semantic caching, combo fallback chains, real-time health monitoring, and a full
dashboard with provider management, analytics, and CLI tool integration.

Key highlights:
- 20+ providers (Claude Code, Codex, Gemini CLI, GitHub Copilot, iFlow, Qwen, Kiro, etc.)
- 6 routing strategies (Fill First, Round Robin, P2C, Random, Least Used, Cost Optimized)
- Export/Import database backup with full archive support
- Translator Playground with 4 modes (Playground, Chat Tester, Test Bench, Live Monitor)
- 100% TypeScript across src/ and open-sse/
- Docker support with multi-stage builds
- Comprehensive documentation and 9 dashboard screenshots
2026-02-18 00:02:15 -03:00

79 lines
2.5 KiB
TypeScript

import { NextResponse } from "next/server";
import { jwtVerify } from "jose";
import { generateRequestId } from "./shared/utils/requestId";
import { getSettings } from "./lib/localDb";
// FASE-01: Fail-fast — no hardcoded fallback. Server must have JWT_SECRET configured.
if (!process.env.JWT_SECRET) {
console.error("[SECURITY] JWT_SECRET is not set. Authentication will fail.");
}
const SECRET = new TextEncoder().encode(process.env.JWT_SECRET);
export async function proxy(request) {
const { pathname } = request.nextUrl;
// Pipeline: Add request ID header for end-to-end tracing
const requestId = generateRequestId();
const response = NextResponse.next();
response.headers.set("X-Request-Id", requestId);
// Protect all dashboard routes (except onboarding)
if (pathname.startsWith("/dashboard")) {
// Always allow onboarding — it has its own setupComplete guard
if (pathname.startsWith("/dashboard/onboarding")) {
return response;
}
const token = request.cookies.get("auth_token")?.value;
if (token) {
try {
await jwtVerify(token, SECRET);
return response;
} catch (err) {
// FASE-01: Log auth errors instead of silently redirecting
console.error("[Middleware] auth_error: JWT verification failed:", err.message, {
path: pathname,
tokenPresent: true,
requestId,
});
return NextResponse.redirect(new URL("/login", request.url));
}
}
try {
// Direct import — no HTTP self-fetch overhead
const settings = await getSettings();
// Skip auth if login is not required
if (settings.requireLogin === false) {
return response;
}
// Skip auth if no password has been set yet (fresh install with no env override)
// This prevents an unresolvable loop where requireLogin=true but no password exists
if (!settings.password && !process.env.INITIAL_PASSWORD) {
return response;
}
} catch (err) {
// FASE-01: Log settings fetch errors instead of silencing them
console.error("[Middleware] settings_error: Settings read failed:", err.message, {
path: pathname,
requestId,
});
// On error, require login
}
return NextResponse.redirect(new URL("/login", request.url));
}
// Redirect / to /dashboard if logged in, or /dashboard if it's the root
if (pathname === "/") {
return NextResponse.redirect(new URL("/dashboard", request.url));
}
return response;
}
export const config = {
matcher: ["/", "/dashboard/:path*"],
};