import { FastifyInstance } from 'fastify'; import prisma from '../../config/database'; import { requireAuth } from '../../middleware/auth'; import { success, error } from '../../utils/response'; import bcrypt from 'bcryptjs'; import { config } from '../../config/env'; import { logAudit } from '../../services/audit'; import { parseBody } from '../../schemas/common'; import { UpdateProfileSchema } from '../../schemas/profile.schema'; export default async function profileRoutes(fastify: FastifyInstance): Promise { fastify.get('/', { preHandler: requireAuth }, async (request, reply) => { const user = await prisma.users.findUnique({ where: { id: request.authData!.userId }, select: { id: true, username: true, email: true, first_name: true, last_name: true, totp_enabled: true, last_login: true, password_changed_at: true, roles: { select: { id: true, name: true, display_name: true } }, }, }); if (!user) return error(reply, 'Uživatel nenalezen', 404); return success(reply, user); }); fastify.put('/', { preHandler: requireAuth }, async (request, reply) => { const parsed = parseBody(UpdateProfileSchema, request.body); if ('error' in parsed) return error(reply, parsed.error, 400); const body = parsed.data; const userId = request.authData!.userId; const data: Record = {}; if (body.email) { const newEmail = String(body.email).trim(); const existing = await prisma.users.findFirst({ where: { email: newEmail, id: { not: userId } } }); if (existing) return error(reply, 'E-mail již existuje', 409); data.email = newEmail; } if (body.first_name) data.first_name = String(body.first_name); if (body.last_name) data.last_name = String(body.last_name); if (body.current_password && body.new_password) { const user = await prisma.users.findUnique({ where: { id: userId } }); if (!user) return error(reply, 'Uživatel nenalezen', 404); const valid = await bcrypt.compare(String(body.current_password), user.password_hash); if (!valid) return error(reply, 'Nesprávné aktuální heslo', 400); data.password_hash = await bcrypt.hash(String(body.new_password), config.security.bcryptCost); data.password_changed_at = new Date(); await logAudit({ request, authData: request.authData, action: 'password_change', entityType: 'user', entityId: userId, description: 'Změna hesla' }); } await prisma.users.update({ where: { id: userId }, data }); return success(reply, null, 200, 'Profil aktualizován'); }); }