From 051b5e002d3717918af42575442b221219270fec Mon Sep 17 00:00:00 2001 From: Tim Howitz Date: Tue, 3 Jun 2025 15:43:56 +0100 Subject: [PATCH] Added delete user route --- src/app/api/update-user/route.ts | 14 +++++++- src/app/api/user/delete/route.ts | 59 ++++++++++++++++++++++++++++++++ src/app/profile/page.tsx | 3 +- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 src/app/api/user/delete/route.ts diff --git a/src/app/api/update-user/route.ts b/src/app/api/update-user/route.ts index 51b11fd..1cc7721 100644 --- a/src/app/api/update-user/route.ts +++ b/src/app/api/update-user/route.ts @@ -13,7 +13,19 @@ export async function POST(req: Request) { if ("user" in authResult === false) return authResult; const { user } = authResult; - const { userId, email, name, password, requestedRole } = await req.json(); + 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 diff --git a/src/app/api/user/delete/route.ts b/src/app/api/user/delete/route.ts new file mode 100644 index 0000000..ee1af29 --- /dev/null +++ b/src/app/api/user/delete/route.ts @@ -0,0 +1,59 @@ +import { NextResponse } from "next/server"; +import { env } from "@utils/env"; +import { prisma } from "@utils/prisma"; +import { apiAuthMiddleware } from "@utils/apiAuthMiddleware"; + +export async function POST(req: Request) { + try { + const authResult = await apiAuthMiddleware(); + if ("user" in authResult === false) return authResult; + + const { user } = authResult; + const { userId }: { userId: number } = await req.json(); + + if (!userId) { + return NextResponse.json({ message: "User id required to delete" }, { status: 401 }); + } + + if (userId !== user.id && user.role !== "ADMIN") { + return NextResponse.json({ message: "Not authorised" }, { status: 401 }); + } + + await prisma.$transaction(async (tx) => { + // Handle Scientist and its subordinates + const scientist = await tx.scientist.findUnique({ where: { userId: userId } }); + if (scientist) { + // Unlink subordinates + await tx.scientist.updateMany({ + where: { superiorId: scientist.id }, + data: { superiorId: null }, + }); + // Delete Scientist + await tx.scientist.delete({ where: { userId: userId } }); + } + + // Delete Requests + await tx.request.deleteMany({ where: { requestingUserId: userId } }); + + // Unlink Observatories (set creatorId to null) + await tx.observatory.updateMany({ + where: { creatorId: userId }, + data: { creatorId: null }, + }); + + // Unlink Artefacts (set creatorId to null) + await tx.artefact.updateMany({ + where: { creatorId: userId }, + data: { creatorId: null }, + }); + + // Delete User (Orders and Earthquakes are handled automatically) + await tx.user.delete({ where: { id: userId } }); + }); + + return NextResponse.json({ message: "User deleted successfully" }, { status: 200 }); + } catch (error) { + console.error("Error in delete-user endpoint:", error); + return NextResponse.json({ message: "Internal Server Error" }, { status: 500 }); + } +} diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx index a7a60e1..4238810 100644 --- a/src/app/profile/page.tsx +++ b/src/app/profile/page.tsx @@ -229,9 +229,8 @@ export default function Profile() { } setIsDeleting(true); try { - // todo add delete user route const res = await axios.post( - "/api/delete-user", + "/api/user/delete", { userId: user!.id }, { headers: { "Content-Type": "application/json" } } );