diff --git a/src/dashboardGuard.js b/src/dashboardGuard.js index 6b88f6e9..2732a036 100644 --- a/src/dashboardGuard.js +++ b/src/dashboardGuard.js @@ -46,7 +46,11 @@ const ALWAYS_PROTECTED = [ // User administration is never exposed to normal users, even if dashboard login // is disabled for local single-user deployments. -const ADMIN_ONLY_PATHS = ["/api/users", "/api/tunnel"]; +const ADMIN_ONLY_PATHS = ["/api/users", "/api/tunnel", "/api/combos"]; + +// Combo definitions affect routing and fallback behavior, so only administrators +// may view or change them. +const ADMIN_ONLY_DASHBOARD_PATHS = ["/dashboard/combos"]; // Require auth, but allow through if requireLogin is disabled const PROTECTED_API_PATHS = [ @@ -240,6 +244,11 @@ export async function proxy(request) { // Protect all dashboard routes if (pathname.startsWith("/dashboard")) { + if (ADMIN_ONLY_DASHBOARD_PATHS.some((p) => pathname === p || pathname.startsWith(`${p}/`))) { + if (await isAdmin(request)) return NextResponse.next(); + return NextResponse.redirect(new URL("/dashboard", request.url)); + } + let requireLogin = true; let tunnelDashboardAccess = true; diff --git a/src/shared/components/Sidebar.js b/src/shared/components/Sidebar.js index 069bf61d..b3a9e2f9 100644 --- a/src/shared/components/Sidebar.js +++ b/src/shared/components/Sidebar.js @@ -22,7 +22,7 @@ const navItems = [ { href: "/dashboard/endpoint", label: "Endpoint & Key", icon: "api" }, { href: "/dashboard/providers", label: "Providers", icon: "dns" }, // { href: "/dashboard/basic-chat", label: "Basic Chat", icon: "chat" }, // Hidden - { href: "/dashboard/combos", label: "Combos", icon: "layers" }, + { href: "/dashboard/combos", label: "Combos", icon: "layers", adminOnly: true }, { href: "/dashboard/usage", label: "Usage", icon: "bar_chart" }, { href: "/dashboard/quota", label: "Quota Tracker", icon: "data_usage" }, { href: "/dashboard/token-saver", label: "Token Saver", icon: "savings" }, @@ -165,7 +165,7 @@ export default function Sidebar({ onClose }) { {/* Navigation */}