From 2a72f9111cba98d09221dfe2285ca23dfd1e468e Mon Sep 17 00:00:00 2001 From: stealthiq <79656108+StealthIQ@users.noreply.github.com> Date: Sat, 21 Feb 2026 07:00:50 +0530 Subject: [PATCH 1/3] fix: auto-generate JWT_SECRET at startup if not provided - Add ensureJwtSecret() in instrumentation.ts to generate random 64-char secret - Mark JWT_SECRET as non-required in secretsValidator - Remove fatal error log for missing JWT_SECRET in proxy.ts Fixes login failure when running via CLI without JWT_SECRET env var. --- src/instrumentation.ts | 11 +++++++++++ src/proxy.ts | 7 +------ src/shared/utils/secretsValidator.ts | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/instrumentation.ts b/src/instrumentation.ts index 9f2a5ee5ecf..d537bd46808 100644 --- a/src/instrumentation.ts +++ b/src/instrumentation.ts @@ -8,9 +8,20 @@ * @see https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation */ +import crypto from "crypto"; + +function ensureJwtSecret(): void { + if (!process.env.JWT_SECRET || process.env.JWT_SECRET.trim() === "") { + const generated = crypto.randomBytes(48).toString("base64"); + process.env.JWT_SECRET = generated; + console.log("[STARTUP] JWT_SECRET auto-generated (random 64-char secret)"); + } +} + export async function register() { // Only run on the server (not during build or in Edge runtime) if (process.env.NEXT_RUNTIME === "nodejs") { + ensureJwtSecret(); // Console log file capture (must be first — before any logging occurs) const { initConsoleInterceptor } = await import("@/lib/consoleInterceptor"); initConsoleInterceptor(); diff --git a/src/proxy.ts b/src/proxy.ts index 8faf273d783..413f16815cc 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -6,12 +6,7 @@ import { isPublicRoute, verifyAuth, isAuthRequired } from "./shared/utils/apiAut import { checkBodySize, getBodySizeLimit } from "./shared/middleware/bodySizeGuard"; import { isDraining } from "./lib/gracefulShutdown"; -// 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); +const SECRET = new TextEncoder().encode(process.env.JWT_SECRET || ""); export async function proxy(request) { const { pathname } = request.nextUrl; diff --git a/src/shared/utils/secretsValidator.ts b/src/shared/utils/secretsValidator.ts index c753885638c..f2926356db9 100644 --- a/src/shared/utils/secretsValidator.ts +++ b/src/shared/utils/secretsValidator.ts @@ -32,8 +32,8 @@ const SECRET_RULES = [ { name: "JWT_SECRET", minLength: 32, - required: true, - description: "JWT signing secret for dashboard authentication", + required: false, + description: "JWT signing secret for dashboard authentication (auto-generated if not set)", generateHint: "openssl rand -base64 48", }, { From 12b1f69241dc757c8a3d6115a02492b13a3b9a6b Mon Sep 17 00:00:00 2001 From: stealthiq <79656108+StealthIQ@users.noreply.github.com> Date: Sat, 21 Feb 2026 07:04:17 +0530 Subject: [PATCH 2/3] feat: improve auth flow and login page UX - Add setupComplete to settings validation schema for proper persistence - Support ?tab= query param in settings page for direct tab navigation - Redesign login page with professional two-column layout - Add context-aware states for onboarding/password setup flows - Smooth animations and refined visual hierarchy --- .../(dashboard)/dashboard/settings/page.tsx | 8 +- src/app/login/page.tsx | 220 +++++++++++++++--- src/shared/validation/schemas.ts | 1 + 3 files changed, 194 insertions(+), 35 deletions(-) diff --git a/src/app/(dashboard)/dashboard/settings/page.tsx b/src/app/(dashboard)/dashboard/settings/page.tsx index 84973345607..1a2ab3d7a26 100644 --- a/src/app/(dashboard)/dashboard/settings/page.tsx +++ b/src/app/(dashboard)/dashboard/settings/page.tsx @@ -1,6 +1,7 @@ "use client"; import { useState } from "react"; +import { useSearchParams } from "next/navigation"; import { cn } from "@/shared/utils/cn"; import { APP_CONFIG } from "@/shared/constants/config"; import SystemStorageTab from "./components/SystemStorageTab"; @@ -25,7 +26,10 @@ const tabs = [ ]; export default function SettingsPage() { - const [activeTab, setActiveTab] = useState("general"); + const searchParams = useSearchParams(); + const tabParam = searchParams.get("tab"); + const [userSelectedTab, setUserSelectedTab] = useState(null); + const activeTab = userSelectedTab || tabs.find((t) => t.id === tabParam)?.id || "general"; return (
Loading...
+Enter your password to access the dashboard
+ if (!hasPassword && !setupComplete) { + return ( ++ Let's get your OmniRoute instance configured +
++ Run the onboarding wizard to set up your password and connect your first AI + provider. +
+ ++ OmniRoute — Unified AI API Proxy +
+Password protection is not enabled
++ Set a password to protect your dashboard and secure your API endpoints from + unauthorized access. +
+ ++ OmniRoute — Unified AI API Proxy +