66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
import { auth } from "@/lib/auth";
|
|
import { NextResponse } from "next/server";
|
|
|
|
// Force Node.js runtime for SQLite compatibility
|
|
export const runtime = 'nodejs';
|
|
|
|
export default auth((req) => {
|
|
const { pathname } = req.nextUrl;
|
|
const session = req.auth;
|
|
|
|
// Check if accessing map route (requires authentication only)
|
|
if (pathname.startsWith('/map')) {
|
|
// Require authentication for map access
|
|
if (!session?.user) {
|
|
const loginUrl = new URL('/login', req.url);
|
|
loginUrl.searchParams.set('callbackUrl', pathname);
|
|
return NextResponse.redirect(loginUrl);
|
|
}
|
|
// All authenticated users can access the map
|
|
return NextResponse.next();
|
|
}
|
|
|
|
// Check if accessing admin routes
|
|
if (pathname.startsWith('/admin')) {
|
|
// Require authentication
|
|
if (!session?.user) {
|
|
const loginUrl = new URL('/login', req.url);
|
|
loginUrl.searchParams.set('callbackUrl', pathname);
|
|
return NextResponse.redirect(loginUrl);
|
|
}
|
|
|
|
const userRole = (session.user as any).role;
|
|
|
|
// Define VIEWER-accessible routes (read-only)
|
|
const viewerAllowedRoutes = [
|
|
'/admin', // Dashboard
|
|
'/admin/devices', // Devices list (read-only)
|
|
];
|
|
|
|
// Check if VIEWER is accessing allowed route
|
|
const isViewerAllowedRoute = viewerAllowedRoutes.some(route =>
|
|
pathname === route || pathname.startsWith(route + '/')
|
|
);
|
|
|
|
// VIEWER can only access dashboard and devices (read-only)
|
|
if (userRole === 'VIEWER' && !isViewerAllowedRoute) {
|
|
const unauthorizedUrl = new URL('/unauthorized', req.url);
|
|
unauthorizedUrl.searchParams.set('from', pathname);
|
|
return NextResponse.redirect(unauthorizedUrl);
|
|
}
|
|
|
|
// Non-ADMIN and non-VIEWER users are denied
|
|
if (userRole !== 'ADMIN' && userRole !== 'VIEWER') {
|
|
const unauthorizedUrl = new URL('/unauthorized', req.url);
|
|
unauthorizedUrl.searchParams.set('from', pathname);
|
|
return NextResponse.redirect(unauthorizedUrl);
|
|
}
|
|
}
|
|
|
|
return NextResponse.next();
|
|
});
|
|
|
|
export const config = {
|
|
matcher: ["/admin/:path*", "/map/:path*"],
|
|
};
|