54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
|
|
import { NextResponse } from "next/server";
|
||
|
|
import type { NextRequest } from "next/server";
|
||
|
|
|
||
|
|
export function middleware(request: NextRequest) {
|
||
|
|
const { pathname } = request.nextUrl;
|
||
|
|
|
||
|
|
// Get tokens from cookies
|
||
|
|
const accessToken = request.cookies.get("auth_access_token")?.value;
|
||
|
|
const userStr = request.cookies.get("auth_user")?.value;
|
||
|
|
|
||
|
|
const isAuthenticated = !!accessToken;
|
||
|
|
let isAdmin = false;
|
||
|
|
|
||
|
|
if (userStr) {
|
||
|
|
try {
|
||
|
|
const user = JSON.parse(userStr);
|
||
|
|
isAdmin = user.is_admin === true;
|
||
|
|
} catch {
|
||
|
|
// Invalid user data
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Protected routes
|
||
|
|
const isProtectedRoute = pathname.startsWith("/user") || pathname.startsWith("/admin");
|
||
|
|
const isAdminRoute = pathname.startsWith("/admin");
|
||
|
|
const isAuthRoute = pathname.startsWith("/login") || pathname.startsWith("/signup");
|
||
|
|
|
||
|
|
// Redirect unauthenticated users away from protected routes
|
||
|
|
if (isProtectedRoute && !isAuthenticated) {
|
||
|
|
const loginUrl = new URL("/login", request.url);
|
||
|
|
loginUrl.searchParams.set("redirect", pathname);
|
||
|
|
return NextResponse.redirect(loginUrl);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Redirect authenticated users away from auth routes
|
||
|
|
if (isAuthRoute && isAuthenticated) {
|
||
|
|
return NextResponse.redirect(new URL("/admin/dashboard", request.url));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Redirect non-admin users away from admin routes
|
||
|
|
if (isAdminRoute && (!isAuthenticated || !isAdmin)) {
|
||
|
|
return NextResponse.redirect(new URL("/admin/dashboard", request.url));
|
||
|
|
}
|
||
|
|
|
||
|
|
return NextResponse.next();
|
||
|
|
}
|
||
|
|
|
||
|
|
export const config = {
|
||
|
|
matcher: [
|
||
|
|
"/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
||
|
|
],
|
||
|
|
};
|
||
|
|
|