Enhancing user management

master
Mark Moffat 2019-11-07 17:06:20 +10:30
parent 001c015c36
commit 22c4362dc4
6 changed files with 80 additions and 33 deletions

View File

@ -101,7 +101,8 @@
"usersName" : "test",
"userEmail" : "test@test.com",
"userPassword" : "$2a$10$7jQx/hQOWrRni531b/dHRuH8o1ZP8Yo8g..GpTOF4M7RrEH/pzTMy",
"isAdmin" : true
"isAdmin" : true,
"isOwner": true
}
],
"orders": [

View File

@ -107,7 +107,8 @@ router.post('/admin/setup_action', async (req, res) => {
usersName: req.body.usersName,
userEmail: req.body.userEmail,
userPassword: bcrypt.hashSync(req.body.userPassword, 10),
isAdmin: true
isAdmin: true,
isOwner: true
};
// check for users

View File

@ -41,6 +41,14 @@ router.get('/admin/user/edit/:id', restrict, (req, res) => {
return;
}
// Cannot edit the original user/owner
if(user._id !== req.session.userId && user.isOwner){
req.session.message = 'Access denied.';
req.session.messageType = 'danger';
res.redirect('/admin/users');
return;
}
// if the user we want to edit is not the current logged in user and the current user is not
// an admin we render an access denied message
if(user.userEmail !== req.session.user && req.session.isAdmin === false){
@ -77,31 +85,51 @@ router.get('/admin/user/new', restrict, (req, res) => {
});
// delete user
router.get('/admin/user/delete/:id', restrict, (req, res) => {
router.get('/admin/user/delete/:id', restrict, async (req, res) => {
const db = req.app.db;
// userId
if(req.session.isAdmin === true){
if(req.session.userId === req.params.id){
req.session.message = 'You can\'t delete your own user account.';
req.session.messageType = 'danger';
res.redirect('/admin/users');
return;
}
db.users.deleteOne({ _id: common.getId(req.params.id) }, {}, (err, numRemoved) => {
if(err){
console.info(err.stack);
}
req.session.message = 'User deleted.';
req.session.messageType = 'success';
res.redirect('/admin/users');
});
}else{
if(req.session.isAdmin !== true){
req.session.message = 'Access denied.';
req.session.messageType = 'danger';
res.redirect('/admin/users');
return;
}
// Cannot delete your own account
if(req.session.userId === req.params.id){
req.session.message = 'Unable to delete own user account.';
req.session.messageType = 'danger';
res.redirect('/admin/users');
return;
}
const user = await db.users.findOne({ _id: common.getId(req.params.id) });
// If user is not found
if(!user){
req.session.message = 'User not found.';
req.session.messageType = 'danger';
res.redirect('/admin/users');
return;
}
// Cannot delete the original user/owner
if(user.isOwner){
req.session.message = 'Access denied.';
req.session.messageType = 'danger';
res.redirect('/admin/users');
return;
}
db.users.deleteOne({ _id: common.getId(req.params.id) }, {}, (err, numRemoved) => {
if(err){
console.info(err.stack);
}
req.session.message = 'User deleted.';
req.session.messageType = 'success';
res.redirect('/admin/users');
});
});
// update a user

View File

@ -98,6 +98,17 @@ test.serial('[Success] User Login', async t => {
t.deepEqual(res.body.message, 'Login successful');
});
test.serial('[Fail] Incorrect user password', async t => {
const res = await request
.post('/admin/login_action')
.send({
email: users[0].userEmail,
password: 'test1'
})
.expect(400);
t.deepEqual(res.body.message, 'Access denied. Check password and try again.');
});
test.serial('[Success] Create API key', async t => {
const res = await request
.post('/admin/createApiKey')
@ -108,15 +119,18 @@ test.serial('[Success] Create API key', async t => {
t.deepEqual(res.body.apiKey.length, 24);
});
test.serial('[Fail] Incorrect user password', async t => {
test.serial('[Fail] Delete own user account', async t => {
const res = await request
.post('/admin/login_action')
.send({
email: users[0].userEmail,
password: 'test1'
})
.expect(400);
t.deepEqual(res.body.message, 'Access denied. Check password and try again.');
.get(`/admin/user/delete/${users[0]._id}`)
.expect(302);
t.deepEqual(res.header['location'], '/admin/users');
});
test.serial('[Fail] Delete invalid user ID', async t => {
const res = await request
.get('/admin/user/delete/invalid_user_id')
.expect(302);
t.deepEqual(res.header['location'], '/admin/users');
});
test.serial('[Fail] Customer login with incorrect email', async t => {

View File

@ -15,17 +15,17 @@
</div>
<div class="form-group">
<label>{{ @root.__ "User password" }} {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
<input type="password" class="form-control" name="userPassword" {{#ifCond session.user '==' user.userEmail}}required{{/ifCond}}>
<input autocomplete="off" type="password" class="form-control" name="userPassword" {{#ifCond session.user '==' user.userEmail}}required{{/ifCond}}>
</div>
<div class="form-group">
<label>{{ @root.__ "Password confirm" }} {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
<input type="password" data-validation-match-match="userPassword" data-validation-match-message="Password values to not match" class="form-control" name="frm_userPassword_confirm" {{#ifCond session.user '==' user.userEmail}}required{{/ifCond}}>
<input autocomplete="off" type="password" data-validation-match-match="userPassword" data-validation-match-message="Password values to not match" class="form-control" name="frm_userPassword_confirm" {{#ifCond session.user '==' user.userEmail}}required{{/ifCond}}>
</div>
{{#isAnAdmin session.isAdmin}}
{{#ifCond session.user '!=' user.userEmail}}
{{#isAnAdmin @root.session.isAdmin}}
{{#ifCond @root.session.user '!=' user.userEmail}}
<div class="checkbox">
<label>
<input name="user_admin" {{#checkedState user.isAdmin}}{{/checkedState}} type="checkbox"> {{ @root.__ "User is admin?" }}
<input name="user_admin" {{#checkedState @root.user.isAdmin}}{{/checkedState}} type="checkbox"> {{ @root.__ "User is admin?" }}
</label>
</div>
{{/ifCond}}

View File

@ -11,6 +11,9 @@
<strong>{{ @root.__ "Role" }}: </strong>
{{#isAnAdmin this.isAdmin}}
<span>Admin</span>
{{#if ../this.isOwner}}
(Owner)
{{/if}}
{{else}}
<span>{{ @root.__ "User" }}</span>
{{/isAnAdmin}}