From f99da731182d3feba5325bb9f6a5db2562f4f488 Mon Sep 17 00:00:00 2001 From: muken Date: Sun, 28 Jun 2026 22:41:08 -0500 Subject: [PATCH] fix: login redirect, admin auth guard, JWT_SECRET env --- src/app/admin/page.tsx | 123 ++++++++++++++++++++++++++++------------- src/middleware.ts | 27 ++------- 2 files changed, 90 insertions(+), 60 deletions(-) diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 02118f9..03f3ef7 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -1481,6 +1481,8 @@ export default function AdminPage() { const [activeSection, setActiveSection] = useState('dashboard'); const [sidebarOpen, setSidebarOpen] = useState(false); const [toasts, setToasts] = useState<{ id: number; message: string; type: string }[]>([]); + const [authChecked, setAuthChecked] = useState(false); + const [isAuthenticated, setIsAuthenticated] = useState(false); const [slides, setSlides] = useState([]); const [rooms, setRooms] = useState([]); @@ -1504,8 +1506,20 @@ export default function AdminPage() { setToasts(prev => prev.filter(t => t.id !== id)); }, []); + /* ── Auth check ── */ + useEffect(() => { + fetch('/api/auth/me', { credentials: 'include' }) + .then(r => r.json()) + .then(data => { + if (data.authenticated) setIsAuthenticated(true); + setAuthChecked(true); + }) + .catch(() => setAuthChecked(true)); + }, []); + /* ── Data fetching ── */ useEffect(() => { + if (!isAuthenticated) return; const fetchAll = async () => { try { const [slidesRes, roomsRes, calRes, socialRes, menuRes, placesRes, reviewsRes, imagesRes] = await Promise.all([ @@ -1529,7 +1543,7 @@ export default function AdminPage() { } catch (err) { console.error('Failed to load admin data:', err); } }; fetchAll(); - }, []); + }, [isAuthenticated]); const deleteImage = async (id: number) => { try { @@ -1567,47 +1581,78 @@ export default function AdminPage() { {/* Toasts */} {toasts.map(t => removeToast(t.id)} />)} - {/* Mobile sidebar toggle */} -
{/* placeholder */} + {/* Auth loading */} + {!authChecked && ( +
+
+
+
Checking authentication...
+
+
+ )} - {/* Sidebar */} - + )} - {/* Main content */} -
-
- {renderSection()} -
-
+ {/* Authenticated - show admin panel */} + {authChecked && isAuthenticated && ( + <> + {/* Mobile sidebar toggle */} +
{/* placeholder */} + + {/* Sidebar */} + + + {/* Main content */} +
+
+ {renderSection()} +
+
+ + )}
); } diff --git a/src/middleware.ts b/src/middleware.ts index f78019b..bdcc5ec 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -6,29 +6,14 @@ import type { NextRequest } from 'next/server'; // In a production environment, you would want to verify the token export function middleware(request: NextRequest) { const { pathname } = request.nextUrl; + const token = request.cookies.get('session')?.value; - // Protect admin routes - if (pathname.startsWith('/admin')) { - // Get session token from cookies - const token = request.cookies.get('session')?.value; - - // If no token, redirect to login - if (!token) { - return NextResponse.redirect(new URL('/login', request.url)); - } - - // Note: In a real implementation, you would verify the token here - // For now, we're just checking that a token exists - } + // Protect admin routes - let page handle auth UI + // No redirect here; the admin page shows login prompt if not authenticated - // Redirect authenticated users from login page to home - if (pathname === '/login') { - const token = request.cookies.get('session')?.value; - if (token) { - // In a real implementation, you would verify the token and check role - // For now, we'll just redirect to home - return NextResponse.redirect(new URL('/', request.url)); - } + // If logged in and trying to access login, redirect to admin + if (pathname === '/login' && token) { + return NextResponse.redirect(new URL('/admin', request.url)); } return NextResponse.next();