/** * Middleware de autenticação * Extrai e valida tokens JWT das requisições */ import { NextRequest, NextResponse } from "next/server"; import { cookies } from "next/headers"; import { verifyAccessToken } from "./jwt"; import { getSession } from "@/lib/redis/session"; /** * Extrai token do header Authorization * @param request - Request do Next.js * @returns Token ou null */ function extractToken(request: NextRequest): string | null { const authHeader = request.headers.get("authorization"); if (!authHeader || !authHeader.startsWith("Bearer ")) { return null; } return authHeader.substring(7); // Remove "Bearer " } /** * Middleware que requer autenticação * Retorna dados do usuário ou NextResponse com erro * Suporta tanto Bearer token quanto cookie sessionId * @param request - Request do Next.js * @returns Dados do usuário autenticado ou NextResponse com erro */ export async function requireAuth( request: NextRequest ): Promise< | { userId: number; username: string } | NextResponse<{ success: false; error: string }> > { // Tentar primeiro com Bearer token const token = extractToken(request); if (token) { const payload = verifyAccessToken(token); if (payload) { return payload; } } // Se não tiver token no header, tentar com cookie try { const cookieStore = await cookies(); const sessionId = cookieStore.get("sessionId")?.value; if (sessionId) { const session = await getSession(sessionId); if (session) { const tokenPayload = verifyAccessToken(session.accessToken); if (tokenPayload) { return tokenPayload; } } } } catch (error) { // Se der erro ao acessar cookies, continuar com o erro de token } return NextResponse.json( { success: false, error: "Token de autenticação não fornecido ou inválido", }, { status: 401 } ); } /** * Middleware opcional de autenticação * Retorna dados do usuário se autenticado, null caso contrário * Não lança erro se não autenticado * @param request - Request do Next.js * @returns Dados do usuário ou null */ export async function optionalAuth( request: NextRequest ): Promise<{ userId: number; username: string } | null> { // Tentar primeiro com Bearer token const token = extractToken(request); if (token) { const payload = verifyAccessToken(token); if (payload) { return payload; } } // Tentar com cookie try { const cookieStore = await cookies(); const sessionId = cookieStore.get("sessionId")?.value; if (sessionId) { const session = await getSession(sessionId); if (session) { const tokenPayload = verifyAccessToken(session.accessToken); return tokenPayload; } } } catch (error) { // Ignorar erros de cookie } return null; }