import { NextResponse } from "next/server"; import bcryptjs from "bcryptjs"; import { env } from "@utils/env"; import { prisma } from "@utils/prisma"; import { apiAuthMiddleware } from "@utils/apiAuthMiddleware"; import { validatePassword } from "@utils/validation"; export async function POST(req: Request) { try { const authResult = await apiAuthMiddleware(); if ("user" in authResult === false) return authResult; const { user } = authResult; const { userId, email, name, password, requestedRole, }: { userId?: number; email?: string; name?: string; password?: string; requestedRole?: string; } = await req.json(); // Trying to update a different user than themselves // Only available to admins if (userId && userId !== user.id) { if (user.role !== "ADMIN") { return NextResponse.json({ message: "Not authorised" }, { status: 401 }); } } // Check if email is already in use by another user if (email && email !== user.email) { const foundUser = await prisma.user.findUnique({ where: { email }, }); if (foundUser) { return NextResponse.json({ message: "This email is already in use" }, { status: 409 }); } } // Validate password strength if provided let passwordHash = user.passwordHash; if (password) { const passwordCheckResult = validatePassword(password); if ("message" in passwordCheckResult) { return NextResponse.json({ message: passwordCheckResult.message }, { status: passwordCheckResult.status }); } passwordHash = await bcryptjs.hash(password, 10); } if (requestedRole && ["GUEST", "SCIENTIST", "ADMIN"].includes(requestedRole) && requestedRole !== user.role) { await prisma.request.create({ data: { requestType: requestedRole, requestingUserId: userId || user.id }, }); } const updatedUser = await prisma.user.update({ where: { id: userId || user.id }, data: { name: name || user.name, email: email || user.email, passwordHash, }, }); // Link non-account orders with matching email to the updated user if (email && email !== user.email) { await prisma.order.updateMany({ where: { email, userId: null, }, data: { userId: updatedUser.id, }, }); } const fullUser = await prisma.user.findUnique({ where: { id: updatedUser.id }, include: { earthquakes: true, observatories: true, artefacts: true, purchasedOrders: true, requests: true, scientist: { include: { superior: true, subordinates: true, }, }, }, }); const { passwordHash: _, ...userSansHash } = fullUser!; return NextResponse.json({ message: "User updated successfully", user: userSansHash }, { status: 200 }); } catch (error) { console.error("Error in update-user endpoint:", error); return NextResponse.json({ message: "Internal Server Error" }, { status: 500 }); } }