From 5fb1f08df836c349ce58858b386299572828d45e Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Thu, 29 Sep 2022 15:15:11 -0700 Subject: [PATCH] Split up account update logic. --- components/forms/AccountEditForm.js | 3 +- pages/api/account/[id].js | 59 +++++++++++++++++++++++----- pages/api/account/index.js | 60 ++++++++--------------------- 3 files changed, 66 insertions(+), 56 deletions(-) diff --git a/components/forms/AccountEditForm.js b/components/forms/AccountEditForm.js index 97317aff..86825629 100644 --- a/components/forms/AccountEditForm.js +++ b/components/forms/AccountEditForm.js @@ -33,7 +33,8 @@ export default function AccountEditForm({ values, onSave, onClose }) { const [message, setMessage] = useState(); const handleSubmit = async values => { - const { ok, data } = await post('/account', values); + const { user_id } = values; + const { ok, data } = await post(user_id ? `/account/${user_id}` : '/account', values); if (ok) { onSave(); diff --git a/pages/api/account/[id].js b/pages/api/account/[id].js index 31c4b2dc..e5020f1f 100644 --- a/pages/api/account/[id].js +++ b/pages/api/account/[id].js @@ -1,26 +1,65 @@ -import { getAccountById, deleteAccount } from 'queries'; +import { badRequest, hashPassword, methodNotAllowed, ok, unauthorized } from 'next-basics'; +import { getAccountById, deleteAccount, getAccountByUsername, updateAccount } from 'queries'; import { useAuth } from 'lib/middleware'; -import { methodNotAllowed, ok, unauthorized } from 'next-basics'; export default async (req, res) => { await useAuth(req, res); - const { is_admin } = req.auth; + const { is_admin: currentUserIsAdmin, user_id: currentUserId } = req.auth; const { id } = req.query; - const user_id = +id; - - if (!is_admin) { - return unauthorized(res); - } + const userId = +id; if (req.method === 'GET') { - const account = await getAccountById(user_id); + if (userId !== currentUserId && !currentUserIsAdmin) { + return unauthorized(res); + } + + const account = await getAccountById(userId); return ok(res, account); } + if (req.method === 'POST') { + const { username, password, is_admin } = req.body; + + if (userId !== currentUserId && !currentUserIsAdmin) { + return unauthorized(res); + } + + const account = await getAccountById(userId); + + const data = {}; + + if (password) { + data.password = hashPassword(password); + } + + // Only admin can change these fields + if (currentUserIsAdmin) { + data.username = username; + data.is_admin = is_admin; + } + + // Check when username changes + if (data.username && account.username !== data.username) { + const accountByUsername = await getAccountByUsername(username); + + if (accountByUsername) { + return badRequest(res, 'Account already exists'); + } + } + + const updated = await updateAccount(userId, data); + + return ok(res, updated); + } + if (req.method === 'DELETE') { - await deleteAccount(user_id); + if (!currentUserIsAdmin) { + return unauthorized(res); + } + + await deleteAccount(userId); return ok(res); } diff --git a/pages/api/account/index.js b/pages/api/account/index.js index fe9cafe1..236538bc 100644 --- a/pages/api/account/index.js +++ b/pages/api/account/index.js @@ -1,56 +1,26 @@ import { ok, unauthorized, methodNotAllowed, badRequest, hashPassword } from 'next-basics'; -import { getAccountById, getAccountByUsername, updateAccount, createAccount } from 'queries'; +import { getAccountByUsername, createAccount } from 'queries'; import { useAuth } from 'lib/middleware'; export default async (req, res) => { - await useAuth(req, res); - - const { user_id: current_user_id, is_admin: current_user_is_admin } = req.auth; - if (req.method === 'POST') { - const { user_id, username, password, is_admin } = req.body; - - if (user_id) { - const account = await getAccountById(user_id); - - if (account.user_id === current_user_id || current_user_is_admin) { - const data = {}; - - if (password) { - data.password = hashPassword(password); - } - - // Only admin can change these fields - if (current_user_is_admin) { - data.username = username; - data.is_admin = is_admin; - } - - if (data.username && account.username !== data.username) { - const accountByUsername = await getAccountByUsername(username); - - if (accountByUsername) { - return badRequest(res, 'Account already exists'); - } - } - - const updated = await updateAccount(user_id, data); - - return ok(res, updated); - } + await useAuth(req, res); + if (!req.auth.is_admin) { return unauthorized(res); - } else { - const accountByUsername = await getAccountByUsername(username); - - if (accountByUsername) { - return badRequest(res, 'Account already exists'); - } - - const created = await createAccount({ username, password: hashPassword(password) }); - - return ok(res, created); } + + const { username, password } = req.body; + + const accountByUsername = await getAccountByUsername(username); + + if (accountByUsername) { + return badRequest(res, 'Account already exists'); + } + + const created = await createAccount({ username, password: hashPassword(password) }); + + return ok(res, created); } return methodNotAllowed(res);