Files
finanzas/middleware.ts

78 lines
2.1 KiB
TypeScript

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { jwtVerify } from 'jose';
const SECRET_KEY = new TextEncoder().encode(process.env.JWT_SECRET || 'fallback-secret-key-change-me');
export async function middleware(request: NextRequest) {
const session = request.cookies.get('session')?.value;
const { pathname } = request.nextUrl;
// Paths that are always public
const publicPaths = [
'/login',
'/register',
'/api/auth/login',
'/api/auth/register',
'/api/auth/verify-otp',
'/api/auth/send'
];
// Static assets and Next.js internals
if (
pathname.startsWith('/_next') ||
pathname.startsWith('/static') ||
pathname.includes('.') // images, icons, etc
) {
return NextResponse.next();
}
const isPublic = publicPaths.some(path => pathname.startsWith(path));
// If user has session, try to verify it
let isValidSession = false;
if (session) {
try {
await jwtVerify(session, SECRET_KEY);
isValidSession = true;
} catch (e) {
isValidSession = false;
}
}
// Logic:
// 1. If public path and Logged In -> Redirect to Dashboard
if (isPublic && isValidSession && (pathname === '/login' || pathname === '/register')) {
return NextResponse.redirect(new URL('/', request.url));
}
// 2. If public path -> Allow
if (isPublic) {
return NextResponse.next();
}
// 3. If protected path and Not Logged In -> Redirect to Login
if (!isValidSession) {
const loginUrl = new URL('/login', request.url);
// Optional: Add ?from=pathname to redirect back after login
return NextResponse.redirect(loginUrl);
}
// 4. Protected path and Logged In -> Allow
return NextResponse.next();
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes) -> Wait, we WANT to protect API routes except auth ones
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
'/((?!_next/static|_next/image|favicon.ico).*)',
],
};