Files
pagodera/app/api/users/me/route.ts
T
Evandro Fonseca Junior 55eebde0ba 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.
2025-11-04 02:33:29 -03:00

180 lines
5.0 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { secureLogger } from "@/lib/secure-logger";
import { requireAuth } from "@/lib/auth/middleware";
import { getUserById, updateUser } from "@/lib/db/queries/users";
import { getUserCharacters } from "@/lib/db/queries/characters";
import { updateUserSchema } from "@/lib/validation-schemas";
export async function GET(request: NextRequest) {
try {
// Middleware de autenticação
const authResult = await requireAuth(request);
if (authResult instanceof NextResponse) {
return authResult;
}
const auth = authResult;
// Buscar dados do usuário
const user = await getUserById(auth.userId);
if (!user) {
return NextResponse.json(
{
success: false,
error: "Usuário não encontrado",
},
{ status: 404 }
);
}
// Buscar personagens do usuário
const characters = await getUserCharacters(auth.userId);
return NextResponse.json(
{
success: true,
user: {
userId: user.user_id,
username: user.username,
email: user.email,
firstName: user.first_name,
lastName: user.last_name,
phone: user.phone,
cpf: user.cpf,
accountLevel: user.account_level,
hasDonated: user.has_donated,
whatsappNotifications: user.whatsapp_notifications,
createdAt: user.created_at,
updatedAt: user.updated_at,
lastLogin: user.last_login,
isActive: user.is_active,
isVerified: user.is_verified,
},
characters: characters.map((char) => ({
characterId: char.character_id,
characterName: char.character_name,
serverName: char.server_name,
isMain: char.is_main,
verified: char.verified,
createdAt: char.created_at,
})),
},
{ status: 200 }
);
} catch (error) {
// Se for NextResponse (erro de autenticação), re-lançar
if (error instanceof NextResponse) {
return error;
}
secureLogger.error("❌ Erro ao buscar perfil do usuário", {
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 }
);
}
}
export async function PUT(request: NextRequest) {
try {
// Middleware de autenticação
const authResult = await requireAuth(request);
if (authResult instanceof NextResponse) {
return authResult;
}
const auth = authResult;
const body = await request.json();
// Validação com Zod
const validationResult = updateUserSchema.safeParse(body);
if (!validationResult.success) {
const errors = validationResult.error.issues.map((err) => ({
field: err.path.join("."),
message: err.message,
}));
return NextResponse.json(
{
success: false,
error: "Dados de entrada inválidos",
details: errors,
},
{ status: 400 }
);
}
const validatedData = validationResult.data;
// Atualizar usuário
const updatedUser = await updateUser(auth.userId, {
first_name: validatedData.firstName,
last_name: validatedData.lastName,
phone: validatedData.phone,
whatsapp_notifications: validatedData.whatsappNotifications,
});
secureLogger.info("✅ Perfil atualizado com sucesso", {
userId: auth.userId,
timestamp: new Date().toISOString(),
});
return NextResponse.json(
{
success: true,
user: {
userId: updatedUser.user_id,
username: updatedUser.username,
email: updatedUser.email,
firstName: updatedUser.first_name,
lastName: updatedUser.last_name,
phone: updatedUser.phone,
cpf: updatedUser.cpf,
accountLevel: updatedUser.account_level,
hasDonated: updatedUser.has_donated,
whatsappNotifications: updatedUser.whatsapp_notifications,
createdAt: updatedUser.created_at,
updatedAt: updatedUser.updated_at,
lastLogin: updatedUser.last_login,
isActive: updatedUser.is_active,
isVerified: updatedUser.is_verified,
},
},
{ status: 200 }
);
} catch (error) {
// Se for NextResponse (erro de autenticação), re-lançar
if (error instanceof NextResponse) {
return error;
}
secureLogger.error("❌ Erro ao atualizar perfil", {
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 }
);
}
}