feat: add user authentication UI to header component
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.
This commit is contained in:
1 parent
e641138887
commit
55eebde0ba
55 files changed
+7353
-7
No files matched your search
@@ -0,0 +1,136 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { cookies } from "next/headers";
|
||||
import { secureLogger } from "@/lib/secure-logger";
|
||||
import { getSession, refreshSession, deleteSession } from "@/lib/redis/session";
|
||||
import { verifyAccessToken } from "@/lib/auth/jwt";
|
||||
|
||||
/**
|
||||
* GET /api/auth/session
|
||||
* Verifica e retorna dados da sessão atual
|
||||
*/
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
// Buscar sessionId do cookie
|
||||
const cookieStore = await cookies();
|
||||
const sessionId = cookieStore.get("sessionId")?.value;
|
||||
|
||||
if (!sessionId) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
authenticated: false,
|
||||
error: "Nenhuma sessão encontrada",
|
||||
},
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
// Buscar sessão no Redis
|
||||
const session = await getSession(sessionId);
|
||||
|
||||
if (!session) {
|
||||
// Limpar cookie se sessão não existe
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
authenticated: false,
|
||||
error: "Sessão expirada ou inválida",
|
||||
},
|
||||
{ status: 401 }
|
||||
);
|
||||
|
||||
response.cookies.delete("sessionId");
|
||||
return response;
|
||||
}
|
||||
|
||||
// Verificar se o access token ainda é válido
|
||||
const tokenPayload = verifyAccessToken(session.accessToken);
|
||||
|
||||
if (!tokenPayload) {
|
||||
// Token expirado - remover sessão
|
||||
await deleteSession(sessionId);
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
authenticated: false,
|
||||
error: "Token expirado",
|
||||
},
|
||||
{ status: 401 }
|
||||
);
|
||||
|
||||
response.cookies.delete("sessionId");
|
||||
return response;
|
||||
}
|
||||
|
||||
// Atualizar TTL da sessão
|
||||
await refreshSession(sessionId);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
authenticated: true,
|
||||
user: {
|
||||
userId: session.userId,
|
||||
username: session.username,
|
||||
email: session.email,
|
||||
},
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
secureLogger.error("❌ Erro ao verificar sessão", {
|
||||
error: error instanceof Error ? error.message : "Erro desconhecido",
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
authenticated: false,
|
||||
error: error instanceof Error ? error.message : "Erro interno",
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /api/auth/session
|
||||
* Encerra a sessão atual
|
||||
*/
|
||||
export async function DELETE(request: NextRequest) {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
const sessionId = cookieStore.get("sessionId")?.value;
|
||||
|
||||
if (sessionId) {
|
||||
await deleteSession(sessionId);
|
||||
}
|
||||
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Sessão encerrada",
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
|
||||
response.cookies.delete("sessionId");
|
||||
return response;
|
||||
} catch (error) {
|
||||
secureLogger.error("❌ Erro ao encerrar sessão", {
|
||||
error: error instanceof Error ? error.message : "Erro desconhecido",
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : "Erro interno",
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user