From 5a138fee517aa059086593dfb88e36ad53d428b2 Mon Sep 17 00:00:00 2001 From: SuJiaKuan Date: Fri, 8 Jun 2018 14:33:04 +0800 Subject: [PATCH 1/3] Add old password in changing user password API --- services/api/users.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/services/api/users.js b/services/api/users.js index c0bd252..4b5d62e 100644 --- a/services/api/users.js +++ b/services/api/users.js @@ -41,9 +41,9 @@ const createUserValidator = checkSchema({ }) const changePasswordValidator = checkSchema({ - password: { + newPassword: { exists: true, - errorMessage: 'Password is required', + errorMessage: 'New password is required', }, }) @@ -144,22 +144,34 @@ async function deleteUser(req, res, next) { } async function changePassword(req, res, next) { - const { id } = req.params + const { id: targetId } = req.params + const { _id: requesterId } = req.user + const { oldPassword, newPassword } = req.body - if (!isValidId(id)) { + if (!isValidId(targetId)) { return next(createError(400, 'Invalid ID')) } try { + const targetUser = await models.users.findById(targetId) + + // If the user changes its own password and it is not the first time + // to be changed, then the request also needs old password. + if (requesterId.toString() === targetId && targetUser.passwordLastUpdated) { + if (oldPassword !== targetUser.password) { + return next(createError(400, 'Incorrect old password')) + } + } + const updated = { - password: req.body.password, + password: newPassword, passwordLastUpdated: new Date(), } const options = { new: true, runValidators: true, } - const result = await models.users.findByIdAndUpdate(id, updated, options) + const result = await models.users.findByIdAndUpdate(targetId, updated, options) if (!result) { return next(createError(404, 'User not existed')) From 107494a5ed8baf22517b598ca08de534929aa050 Mon Sep 17 00:00:00 2001 From: SuJiaKuan Date: Fri, 8 Jun 2018 15:15:59 +0800 Subject: [PATCH 2/3] Add API to update user's role --- services/api/users.js | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/services/api/users.js b/services/api/users.js index 4b5d62e..ce352d1 100644 --- a/services/api/users.js +++ b/services/api/users.js @@ -31,7 +31,7 @@ const userValidator = checkSchema({ }, }) -const createUserValidator = checkSchema({ +const roleValidator = checkSchema({ role: { matches: { errorMessage: `Role should be "${ROLES.WRITER}" or "${ROLES.READER}"`, @@ -183,6 +183,39 @@ async function changePassword(req, res, next) { } } +async function updateRole(req, res, next) { + const { id: targetId } = req.params + const { role } = req.body + const { _id: requesterId } = req.user + + try { + const targetUser = await models.users.findById(targetId) + + if (!targetUser) { + return next(createError(404, 'User not existed')) + } + + if (targetUser.role === ROLES.ADMIN) { + return next(createError(400, 'Updating admin role is not allowed')) + } + + const updated = { role } + const options = { + new: true, + runValidators: true, + } + const result = await models.users.findByIdAndUpdate(targetId, updated, options) + + if (!result) { + return next(createError(404, 'User not existed')) + } + + return res.status(204).send() + } catch (err) { + return next(createError(500, null, err)) + } +} + async function login(req, res, next) { const { username, password } = req.body @@ -235,13 +268,14 @@ async function createAdminUser() { routesWithAuth( router, ['get', '/users', getAllUsers], - ['post', '/users', userValidator, createUserValidator, validate, createUser], + ['post', '/users', userValidator, roleValidator, validate, createUser], ) routesWithAuth( router, ['get', '/user/:id', isSelfOrAdmin, getUser], ['delete', '/user/:id', isSelfOrAdmin, deleteUser], ['patch', '/user/:id/password', isSelfOrAdmin, changePasswordValidator, validate, changePassword], + ['patch', '/user/:id/role', roleValidator, validate, updateRole], ) router.post('/login', userValidator, validate, login) From 09a11437038923b7f5f29fe907ade143f3598408 Mon Sep 17 00:00:00 2001 From: SuJiaKuan Date: Fri, 8 Jun 2018 15:18:04 +0800 Subject: [PATCH 3/3] Fix bugs of password changing API --- services/api/users.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/api/users.js b/services/api/users.js index ce352d1..6c9fd41 100644 --- a/services/api/users.js +++ b/services/api/users.js @@ -155,6 +155,10 @@ async function changePassword(req, res, next) { try { const targetUser = await models.users.findById(targetId) + if (!targetUser) { + return next(createError(404, 'User not existed')) + } + // If the user changes its own password and it is not the first time // to be changed, then the request also needs old password. if (requesterId.toString() === targetId && targetUser.passwordLastUpdated) {