Initial commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import createIntlMiddleware from 'next-intl/middleware';
|
||||
import { routing } from './i18n/routing';
|
||||
import type { NextRequest } from 'next/server';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getToken } from 'next-auth/jwt';
|
||||
|
||||
const protectedRoutes: Record<string, string[]> = {
|
||||
'/example': ['ad'],
|
||||
'/dashboard': [],
|
||||
};
|
||||
|
||||
const intlMiddleware = createIntlMiddleware(routing);
|
||||
|
||||
export default async function middleware(req: NextRequest) {
|
||||
const pathname = req.nextUrl.pathname;
|
||||
const segments = pathname.split('/');
|
||||
const locale = segments[1];
|
||||
const pathWithoutLocale = '/' + segments.slice(2).join('/');
|
||||
|
||||
const matchedRoute = Object.keys(protectedRoutes).find((route) => {
|
||||
return (
|
||||
pathWithoutLocale === route || pathWithoutLocale.startsWith(route + '/')
|
||||
);
|
||||
});
|
||||
|
||||
// Short-circuit: skip token fetch entirely for public routes
|
||||
if (!matchedRoute) {
|
||||
return intlMiddleware(req);
|
||||
}
|
||||
|
||||
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
|
||||
|
||||
if (!token) {
|
||||
const url = req.nextUrl.clone();
|
||||
url.pathname = '/api/auth/signin';
|
||||
url.searchParams.set('callbackUrl', pathname);
|
||||
return NextResponse.redirect(url);
|
||||
}
|
||||
|
||||
const requiredRoles = protectedRoutes[matchedRoute];
|
||||
if (requiredRoles.length > 0) {
|
||||
const userRoles = token.roles ?? [];
|
||||
const hasRole = requiredRoles.some((role) => userRoles.includes(role));
|
||||
if (!hasRole) {
|
||||
const url = req.nextUrl.clone();
|
||||
url.pathname = `/${locale}/403`;
|
||||
return NextResponse.redirect(url);
|
||||
}
|
||||
}
|
||||
|
||||
return intlMiddleware(req);
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ['/((?!api|trpc|_next|_vercel|.*\\..*).*)'],
|
||||
};
|
||||
Reference in New Issue
Block a user