76 lines
2.6 KiB
TypeScript
76 lines
2.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 {
|
|
// Decode the user string if it's URL encoded
|
|
const decodedUserStr = decodeURIComponent(userStr);
|
|
const user = JSON.parse(decodedUserStr);
|
|
// Check for admin status using multiple possible field names
|
|
// Admin users must be verified (is_verified or isVerified must be true)
|
|
const isVerified = user.is_verified === true || user.isVerified === true;
|
|
const hasAdminRole =
|
|
user.is_admin === true ||
|
|
user.isAdmin === true ||
|
|
user.is_staff === true ||
|
|
user.isStaff === true ||
|
|
user.is_superuser === true ||
|
|
user.isSuperuser === true;
|
|
|
|
// User is admin only if they have admin role AND are verified
|
|
isAdmin = hasAdminRole && isVerified;
|
|
} catch {
|
|
// Invalid user data - silently fail and treat as non-admin
|
|
}
|
|
}
|
|
|
|
// Protected routes
|
|
const isProtectedRoute = pathname.startsWith("/user") || pathname.startsWith("/admin");
|
|
const isAdminRoute = pathname.startsWith("/admin");
|
|
const isUserRoute = pathname.startsWith("/user");
|
|
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) {
|
|
// Redirect based on user role
|
|
const redirectPath = isAdmin ? "/admin/dashboard" : "/user/dashboard";
|
|
return NextResponse.redirect(new URL(redirectPath, request.url));
|
|
}
|
|
|
|
// Redirect admin users away from user routes
|
|
if (isUserRoute && isAuthenticated && isAdmin) {
|
|
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("/user/dashboard", request.url));
|
|
}
|
|
|
|
return NextResponse.next();
|
|
}
|
|
|
|
export const config = {
|
|
matcher: [
|
|
"/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
|
],
|
|
};
|
|
|