import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { jwtVerify } from 'jose'; export async function middleware(request: NextRequest) { const token = request.cookies.get('token')?.value; const { pathname } = request.nextUrl; // Define public paths that don't require authentication const publicPaths = ['/']; const isPublicPath = publicPaths.includes(pathname); // Check if the path is an API route or static file const isApiRoute = pathname.startsWith('/api/'); const isStaticFile = pathname.match(/\.(jpg|jpeg|png|gif|ico|css|js)$/); // Skip middleware for API routes and static files if (isApiRoute || isStaticFile) { return NextResponse.next(); } // If trying to access public route with valid token, redirect to dashboard if (token && isPublicPath) { try { await jwtVerify( token, new TextEncoder().encode(process.env.JWT_SECRET || 'your-secret-key') ); return NextResponse.redirect(new URL('/dashboard', request.url)); } catch (error) { // If token is invalid, clear it and stay on public page const response = NextResponse.next(); response.cookies.set('token', '', { expires: new Date(0), path: '/', httpOnly: true, secure: false, sameSite: 'lax' }); return response; } } // If the path is protected (dashboard routes) and user is not logged in, redirect to home if (pathname.startsWith('/dashboard') && !token) { return NextResponse.redirect(new URL('/', request.url)); } // If the path is protected and user is logged in, verify token if (pathname.startsWith('/dashboard') && token) { try { // Verify the token await jwtVerify( token, new TextEncoder().encode(process.env.JWT_SECRET || 'your-secret-key') ); return NextResponse.next(); } catch (error) { // If token is invalid, redirect to home const response = NextResponse.redirect(new URL('/', request.url)); response.cookies.set('token', '', { expires: new Date(0), path: '/', httpOnly: true, secure: false, sameSite: 'lax' }); return response; } } return NextResponse.next(); } // Configure which paths the middleware should run on export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - api (API routes) * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) */ '/((?!api|_next/static|_next/image|favicon.ico).*)', ], };