From 085745c5e49aadff13edc4a88aa8c0887bdc787a Mon Sep 17 00:00:00 2001 From: Timothy Carambat Date: Tue, 14 Nov 2023 14:43:40 -0800 Subject: [PATCH] Prevent lone-admin from locking themselves out the system (#376) resolves #367 --- server/endpoints/admin.js | 22 ++++++++++++++++++++++ server/endpoints/api/admin/index.js | 22 ++++++++++++++++++++++ server/models/user.js | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/server/endpoints/admin.js b/server/endpoints/admin.js index 26444f5a..32fc35f9 100644 --- a/server/endpoints/admin.js +++ b/server/endpoints/admin.js @@ -55,6 +55,28 @@ function adminEndpoints(app) { try { const { id } = request.params; const updates = reqBody(request); + const user = await User.get({ id: Number(id) }); + + // Check to make sure with this update that includes a role change to + // something other than admin that we still have at least one admin left. + if ( + updates.hasOwnProperty("role") && // has admin prop to change + updates.role !== "admin" && // and we are changing to non-admin + user.role === "admin" // and they currently are an admin + ) { + const adminCount = await User.count({ role: "admin" }); + if (adminCount - 1 <= 0) { + response + .status(200) + .json({ + success: false, + error: + "No system admins will remain if you do this. Update failed.", + }); + return; + } + } + const { success, error } = await User.update(id, updates); response.status(200).json({ success, error }); } catch (e) { diff --git a/server/endpoints/api/admin/index.js b/server/endpoints/api/admin/index.js index ee147c30..0cba0ad6 100644 --- a/server/endpoints/api/admin/index.js +++ b/server/endpoints/api/admin/index.js @@ -197,6 +197,28 @@ function apiAdminEndpoints(app) { const { id } = request.params; const updates = reqBody(request); + const user = await User.get({ id: Number(id) }); + + // Check to make sure with this update that includes a role change to + // something other than admin that we still have at least one admin left. + if ( + updates.hasOwnProperty("role") && // has admin prop to change + updates.role !== "admin" && // and we are changing to non-admin + user.role === "admin" // and they currently are an admin + ) { + const adminCount = await User.count({ role: "admin" }); + if (adminCount - 1 <= 0) { + response + .status(200) + .json({ + success: false, + error: + "No system admins will remain if you do this. Update failed.", + }); + return; + } + } + const { success, error } = await User.update(id, updates); response.status(200).json({ success, error }); } catch (e) { diff --git a/server/models/user.js b/server/models/user.js index 613aa95e..c6d6771b 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -21,7 +21,7 @@ const User = { update: async function (userId, updates = {}) { try { - const updatedUser = await prisma.users.update({ + await prisma.users.update({ where: { id: parseInt(userId) }, data: updates, });