53 lines
1.4 KiB
TypeScript
53 lines
1.4 KiB
TypeScript
/**
|
|
* Middleware
|
|
*
|
|
* Protects routes that require authentication
|
|
*/
|
|
|
|
import { NextResponse } from 'next/server';
|
|
import type { NextRequest } from 'next/server';
|
|
|
|
// Exact-match public paths (no sub-path matching)
|
|
const exactPublicPaths = ['/'];
|
|
|
|
// Prefix-match public paths (plus their sub-paths)
|
|
const prefixPublicPaths = [
|
|
'/login',
|
|
'/register',
|
|
'/forgot-password',
|
|
'/reset-password',
|
|
'/verify-email',
|
|
'/about',
|
|
'/careers',
|
|
'/blog',
|
|
'/press',
|
|
'/contact',
|
|
'/carrier',
|
|
];
|
|
|
|
export function middleware(request: NextRequest) {
|
|
const { pathname } = request.nextUrl;
|
|
|
|
// Check if path is public
|
|
const isPublicPath =
|
|
exactPublicPaths.includes(pathname) ||
|
|
prefixPublicPaths.some(path => pathname === path || pathname.startsWith(path + '/'));
|
|
|
|
// Get token from cookie (synced by client.ts setAuthTokens)
|
|
const token = request.cookies.get('accessToken')?.value;
|
|
|
|
// Redirect to login if accessing protected route without token
|
|
if (!isPublicPath && !token) {
|
|
const loginUrl = new URL('/login', request.url);
|
|
loginUrl.searchParams.set('redirect', pathname);
|
|
return NextResponse.redirect(loginUrl);
|
|
}
|
|
|
|
return NextResponse.next();
|
|
}
|
|
|
|
export const config = {
|
|
// Exclude Next.js internals, API routes, and all public static assets
|
|
matcher: ['/((?!_next/static|_next/image|api|assets|favicon\\.ico|manifest\\.json|.*\\.(?:png|jpg|jpeg|gif|webp|svg|ico|mp4|mp3|pdf|txt|xml|csv|json)$).*)'],
|
|
};
|