Add login and register dialogs, user dropdown menu with profile link and logout option, and integrate with session management hook. Prevent hydration mismatches by conditionally rendering auth elements after mount. Update package-lock.json with new @esbuild dependencies for build tooling.
82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import {
|
|
checkRateLimit,
|
|
getClientIP,
|
|
createRateLimitResponse,
|
|
} from "@/lib/rate-limiter";
|
|
import { secureLogger } from "@/lib/secure-logger";
|
|
import { verifyRefreshToken, generateAccessToken } from "@/lib/auth/jwt";
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
// Rate limiting
|
|
const ip = getClientIP(request);
|
|
const rateLimit = checkRateLimit(ip, "/api/auth/refresh");
|
|
|
|
if (!rateLimit.allowed) {
|
|
return createRateLimitResponse(rateLimit.resetAt);
|
|
}
|
|
|
|
// Extrair refresh token do cookie
|
|
const refreshToken = request.cookies.get("refreshToken")?.value;
|
|
|
|
if (!refreshToken) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: "Refresh token não fornecido",
|
|
},
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
// Validar refresh token
|
|
const payload = verifyRefreshToken(refreshToken);
|
|
|
|
if (!payload) {
|
|
// Token inválido - limpar cookie
|
|
const response = NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: "Refresh token inválido ou expirado",
|
|
},
|
|
{ status: 401 }
|
|
);
|
|
|
|
response.cookies.delete("refreshToken");
|
|
return response;
|
|
}
|
|
|
|
// Gerar novo access token
|
|
const accessToken = generateAccessToken(payload.userId, payload.username);
|
|
|
|
secureLogger.info("✅ Token renovado com sucesso", {
|
|
userId: payload.userId,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
|
|
return NextResponse.json(
|
|
{
|
|
success: true,
|
|
accessToken,
|
|
},
|
|
{ status: 200 }
|
|
);
|
|
} catch (error) {
|
|
secureLogger.error("❌ Erro ao renovar token", {
|
|
error: error instanceof Error ? error.message : "Erro desconhecido",
|
|
stack: error instanceof Error ? error.stack : undefined,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Erro interno",
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|