Fixed user create and update API endpoints
parent
38ccb1fd9f
commit
1f84f77089
|
@ -112,6 +112,50 @@ $(document).ready(function (){
|
|||
});
|
||||
});
|
||||
|
||||
$('#userNewForm').validator().on('submit', function(e){
|
||||
if(!e.isDefaultPrevented()){
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '/admin/user/insert',
|
||||
data: {
|
||||
usersName: $('#usersName').val(),
|
||||
userEmail: $('#userEmail').val(),
|
||||
userPassword: $('#userPassword').val()
|
||||
}
|
||||
})
|
||||
.done(function(msg){
|
||||
showNotification(msg.message, 'success', false, '/admin/user/edit/' + msg.userId);
|
||||
})
|
||||
.fail(function(msg){
|
||||
showNotification(msg.responseJSON.message, 'danger');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#userEditForm').validator().on('submit', function(e){
|
||||
if(!e.isDefaultPrevented()){
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '/admin/user/update',
|
||||
data: {
|
||||
userId: $('#userId').val(),
|
||||
usersName: $('#usersName').val(),
|
||||
userEmail: $('#userEmail').val(),
|
||||
userPassword: $('#userPassword').val(),
|
||||
userAdmin: $('#userPassword').is(':checked')
|
||||
}
|
||||
})
|
||||
.done(function(msg){
|
||||
showNotification(msg.message, 'success');
|
||||
})
|
||||
.fail(function(msg){
|
||||
showNotification(msg.responseJSON.message, 'danger');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#productNewForm').validator().on('submit', function(e){
|
||||
if(!e.isDefaultPrevented()){
|
||||
e.preventDefault();
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -24,6 +24,27 @@ $(document).ready(function (){
|
|||
$('#offcanvasClose').hide();
|
||||
}
|
||||
|
||||
$('#userSetupForm').validator().on('submit', function(e){
|
||||
if(!e.isDefaultPrevented()){
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '/admin/setup_action',
|
||||
data: {
|
||||
usersName: $('#usersName').val(),
|
||||
userEmail: $('#userEmail').val(),
|
||||
userPassword: $('#userPassword').val()
|
||||
}
|
||||
})
|
||||
.done(function(msg){
|
||||
showNotification(msg.message, 'success', false, '/admin/login');
|
||||
})
|
||||
.fail(function(msg){
|
||||
showNotification(msg.responseJSON.message, 'danger');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.shipping-form input').each(function(e){
|
||||
$(this).wrap('<fieldset></fieldset>');
|
||||
var tag = $(this).attr('placeholder');
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -116,19 +116,15 @@ router.post('/admin/setup_action', async (req, res) => {
|
|||
// email is ok to be used.
|
||||
try{
|
||||
await db.users.insertOne(doc);
|
||||
req.session.message = 'User account inserted';
|
||||
req.session.messageType = 'success';
|
||||
res.redirect('/admin/login');
|
||||
res.status(200).json({ message: 'User account inserted' });
|
||||
return;
|
||||
}catch(ex){
|
||||
console.error(colors.red('Failed to insert user: ' + ex));
|
||||
req.session.message = 'Setup failed';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/setup');
|
||||
res.status(200).json({ message: 'Setup failed' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.redirect('/admin/login');
|
||||
res.status(200).json({ message: 'Already setup.' });
|
||||
});
|
||||
|
||||
// settings
|
||||
|
|
105
routes/user.js
105
routes/user.js
|
@ -168,21 +168,14 @@ router.get('/admin/user/delete/:id', restrict, async (req, res) => {
|
|||
router.post('/admin/user/update', restrict, async (req, res) => {
|
||||
const db = req.app.db;
|
||||
|
||||
let isAdmin = req.body.user_admin === 'on';
|
||||
let isAdmin = req.body.userAdmin === 'on';
|
||||
|
||||
// get the user we want to update
|
||||
const user = await db.users.findOne({ _id: common.getId(req.body.userId) });
|
||||
|
||||
// If user not found
|
||||
if(!user){
|
||||
if(req.apiAuthenticated){
|
||||
res.status(400).json({ message: 'User not found' });
|
||||
return;
|
||||
}
|
||||
|
||||
req.session.message = 'User not found';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/users');
|
||||
res.status(400).json({ message: 'User not found' });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -194,14 +187,7 @@ router.post('/admin/user/update', restrict, async (req, res) => {
|
|||
// 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){
|
||||
if(req.apiAuthenticated){
|
||||
res.status(400).json({ message: 'Access denied' });
|
||||
return;
|
||||
}
|
||||
|
||||
req.session.message = 'Access denied';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/users');
|
||||
res.status(400).json({ message: 'Access denied' });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -221,13 +207,10 @@ router.post('/admin/user/update', restrict, async (req, res) => {
|
|||
// Validate update user
|
||||
const schemaResult = validateJson('editUser', updateDoc);
|
||||
if(!schemaResult.result){
|
||||
if(req.apiAuthenticated){
|
||||
res.status(400).json(schemaResult.errors);
|
||||
return;
|
||||
}
|
||||
req.session.message = 'Please check your inputs.';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/user/edit/' + req.body.userId);
|
||||
res.status(400).json({
|
||||
message: 'Failed to create user. Check inputs.',
|
||||
error: schemaResult.errors
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -238,26 +221,15 @@ router.post('/admin/user/update', restrict, async (req, res) => {
|
|||
$set: updateDoc
|
||||
}, { multi: false, returnOriginal: false }
|
||||
);
|
||||
if(req.apiAuthenticated){
|
||||
const returnUser = updatedUser.value;
|
||||
delete returnUser.userPassword;
|
||||
delete returnUser.apiKey;
|
||||
res.status(200).json({ message: 'User account updated', user: updatedUser.value });
|
||||
return;
|
||||
}
|
||||
// show the view
|
||||
req.session.message = 'User account updated';
|
||||
req.session.messageType = 'success';
|
||||
res.redirect('/admin/user/edit/' + req.body.userId);
|
||||
|
||||
const returnUser = updatedUser.value;
|
||||
delete returnUser.userPassword;
|
||||
delete returnUser.apiKey;
|
||||
res.status(200).json({ message: 'User account updated', user: updatedUser.value });
|
||||
return;
|
||||
}catch(ex){
|
||||
console.error(colors.red('Failed updating user: ' + ex));
|
||||
if(req.apiAuthenticated){
|
||||
res.status(400).json({ message: 'Failed to update user' });
|
||||
return;
|
||||
}
|
||||
req.session.message = 'Failed to update user';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/user/edit/' + req.body.userId);
|
||||
res.status(400).json({ message: 'Failed to update user' });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -265,9 +237,6 @@ router.post('/admin/user/update', restrict, async (req, res) => {
|
|||
router.post('/admin/user/insert', restrict, async (req, res) => {
|
||||
const db = req.app.db;
|
||||
|
||||
// set the account to admin if using the setup form. Eg: First user account
|
||||
const urlParts = req.get('Referrer');
|
||||
|
||||
// Check number of users
|
||||
const userCount = await db.users.countDocuments({});
|
||||
let isAdmin = false;
|
||||
|
@ -287,57 +256,27 @@ router.post('/admin/user/insert', restrict, async (req, res) => {
|
|||
// Validate new user
|
||||
const schemaResult = validateJson('newUser', userObj);
|
||||
if(!schemaResult.result){
|
||||
if(req.apiAuthenticated){
|
||||
res.status(400).json(schemaResult.errors);
|
||||
return;
|
||||
}
|
||||
req.session.message = 'Invalid new user. Please check your inputs.';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/user/new');
|
||||
res.status(400).json({ message: 'Failed to create user. Check inputs.', error: schemaResult.errors });
|
||||
return;
|
||||
}
|
||||
|
||||
// check for existing user
|
||||
const user = await db.users.findOne({ userEmail: req.body.userEmail });
|
||||
if(user){
|
||||
if(req.apiAuthenticated){
|
||||
res.status(400).json({ message: 'A user with that email address already exists' });
|
||||
return;
|
||||
}
|
||||
// user already exists with that email address
|
||||
console.error(colors.red('Failed to insert user, possibly already exists'));
|
||||
req.session.message = 'A user with that email address already exists';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/user/new');
|
||||
res.status(400).json({ message: 'A user with that email address already exists' });
|
||||
return;
|
||||
}
|
||||
// email is ok to be used.
|
||||
try{
|
||||
await db.users.insertOne(userObj);
|
||||
// if from setup we add user to session and redirect to login.
|
||||
// Otherwise we show users screen
|
||||
if(urlParts && urlParts.path === '/admin/setup'){
|
||||
req.session.user = req.body.userEmail;
|
||||
res.redirect('/admin/login');
|
||||
return;
|
||||
}
|
||||
if(req.apiAuthenticated){
|
||||
res.status(200).json({ message: 'User account inserted' });
|
||||
return;
|
||||
}
|
||||
|
||||
req.session.message = 'User account inserted';
|
||||
req.session.messageType = 'success';
|
||||
res.redirect('/admin/users');
|
||||
const newUser = await db.users.insertOne(userObj);
|
||||
res.status(200).json({
|
||||
message: 'User account inserted',
|
||||
userId: newUser.insertedId
|
||||
});
|
||||
}catch(ex){
|
||||
console.error(colors.red('Failed to insert user: ' + ex));
|
||||
if(req.apiAuthenticated){
|
||||
res.status(400).json({ message: 'New user creation failed' });
|
||||
return;
|
||||
}
|
||||
req.session.message = 'New user creation failed';
|
||||
req.session.messageType = 'danger';
|
||||
res.redirect('/admin/user/new');
|
||||
res.status(400).json({ message: 'New user creation failed' });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -88,7 +88,8 @@ test('[Fail] Create new user with invalid email', async t => {
|
|||
.send(user)
|
||||
.set('apiKey', g.users[0].apiKey)
|
||||
.expect(400);
|
||||
t.deepEqual(res.body[0].message, 'should match format "emailAddress"');
|
||||
t.deepEqual(res.body.message, 'Failed to create user. Check inputs.');
|
||||
t.deepEqual(res.body.error[0].message, 'should match format "emailAddress"');
|
||||
});
|
||||
|
||||
test('[Success] Update user', async t => {
|
||||
|
@ -123,7 +124,8 @@ test('[Fail] Update user invalid email', async t => {
|
|||
.send(user)
|
||||
.set('apiKey', g.users[0].apiKey)
|
||||
.expect(400);
|
||||
t.deepEqual(res.body[0].message, 'should match format "emailAddress"');
|
||||
t.deepEqual(res.body.message, 'Failed to create user. Check inputs.');
|
||||
t.deepEqual(res.body.error[0].message, 'should match format "emailAddress"');
|
||||
});
|
||||
|
||||
test('[Fail] Update user invalid userId', async t => {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<div class="col-md-offset-4 col-md-4 col-lg-offset-4 col-lg-4" style="padding-top: 50px">
|
||||
<form class="form-signin" action="/admin/setup_action" method="post" role="form" data-toggle="validator">
|
||||
<form class="form-signin" id="userSetupForm" role="form" data-toggle="validator">
|
||||
<h2 class="form-signin-heading text-center">expressCart Setup</h2>
|
||||
<div class="form-group">
|
||||
<label for="usersName">{{ @root.__ "Users name" }} *</label>
|
||||
<input type="text" class="form-control" id="usersName" name="usersName" placeholder="{{ @root.__ "Users name" }}" required>
|
||||
<input type="text" class="form-control" id="usersName" placeholder="{{ @root.__ "Users name" }}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="userEmail">{{ @root.__ "User email" }} *</label>
|
||||
<input type="email" class="form-control" id="userEmail" name="userEmail" placeholder="{{ @root.__ "Email address" }}" required>
|
||||
<input type="email" class="form-control" id="userEmail" placeholder="{{ @root.__ "Email address" }}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="userPassword">{{ @root.__ "User password" }} *</label>
|
||||
<input type="password" class="form-control" id="userPassword" name="userPassword" placeholder="Password" required>
|
||||
<input type="password" class="form-control" id="userPassword" placeholder="Password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="frm_userPassword_confirm">{{ @root.__ "Password confirm" }} *</label>
|
||||
|
|
|
@ -3,47 +3,48 @@
|
|||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h2>User edit</h2>
|
||||
<form method="post" id="edit_form" action="/admin/user/update" data-toggle="validator">
|
||||
<input type="hidden" name="userId" value="{{user._id}}" />
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "Users name" }}</label>
|
||||
<input type="text" class="form-control" name="usersName" value="{{user.usersName}}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User email" }}</label>
|
||||
<input type="text" class="form-control" name="userEmail" value="{{user.userEmail}}" readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User password" }} {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
|
||||
<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 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 @root.session.isAdmin}}
|
||||
{{#ifCond @root.session.user '!=' user.userEmail}}
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input name="user_admin" {{#checkedState @root.user.isAdmin}}{{/checkedState}} type="checkbox"> {{ @root.__ "User is admin?" }}
|
||||
</label>
|
||||
</div>
|
||||
{{/ifCond}}
|
||||
{{/isAnAdmin}}
|
||||
<div class="form-group">
|
||||
<label>API Key</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="apiKey" value="{{user.apiKey}}" aria-label="..." readonly>
|
||||
<div class="input-group-btn">
|
||||
<button id="btnGenerateAPIkey" class="btn btn-success">{{ @root.__ "Generate" }}</button>
|
||||
<form id="userEditForm" data-toggle="validator">
|
||||
<input type="hidden" id="userId" value="{{user._id}}" />
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "Users name" }}</label>
|
||||
<input type="text" class="form-control" id="usersName" value="{{user.usersName}}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User email" }}</label>
|
||||
<input type="text" class="form-control" id="userEmail" value="{{user.userEmail}}" readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User password" }} {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
|
||||
<input autocomplete="off" type="password" class="form-control" id="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 autocomplete="off" type="password" data-validation-match-match="userPassword" data-validation-match-message="Password values to not match" class="form-control" {{#ifCond session.user '==' user.userEmail}}required{{/ifCond}}>
|
||||
</div>
|
||||
{{#isAnAdmin @root.session.isAdmin}}
|
||||
{{#ifCond @root.session.user '!=' user.userEmail}}
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input id="userAdmin" {{#checkedState @root.user.isAdmin}}{{/checkedState}} type="checkbox"> {{ @root.__ "User is admin?" }}
|
||||
</label>
|
||||
</div>
|
||||
{{/ifCond}}
|
||||
{{/isAnAdmin}}
|
||||
<div class="form-group">
|
||||
<label>API Key</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="apiKey" value="{{user.apiKey}}" aria-label="..." readonly>
|
||||
<div class="input-group-btn">
|
||||
<button id="btnGenerateAPIkey" class="btn btn-success">{{ @root.__ "Generate" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div><br/>
|
||||
<div class="form-group">
|
||||
<div class="pull-right">
|
||||
<button type="submit" class="btn btn-success">{{ @root.__ "Update" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div><br/>
|
||||
<div class="form-group">
|
||||
<div class="pull-right">
|
||||
<button type="submit" class="btn btn-success">{{ @root.__ "Update" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -3,28 +3,29 @@
|
|||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h2>{{ @root.__ "New User" }}</h2>
|
||||
<form method="post" id="edit_form" action="/admin/user/insert" data-toggle="validator">
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "Users name" }} *</label>
|
||||
<input type="text" class="form-control" name="usersName" value="{{user.usersName}}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User email" }} *</label>
|
||||
<input type="email" class="form-control" name="userEmail" value="{{user.userEmail}}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User password" }} *</label>
|
||||
<input type="password" class="form-control" id="userPassword" name="userPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "Password confirm" }} *</label>
|
||||
<input type="password" data-match="#userPassword" class="form-control" name="frm_userPassword_confirm" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="pull-right">
|
||||
<button type="submit" class="btn btn-success">{{ @root.__ "Create" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<form id="userNewForm" data-toggle="validator" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "Users name" }} *</label>
|
||||
<input type="text" class="form-control" id="usersName" value="{{user.usersName}}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User email" }} *</label>
|
||||
<input type="email" class="form-control" id="userEmail" value="{{user.userEmail}}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "User password" }} *</label>
|
||||
<input type="password" class="form-control" id="userPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ @root.__ "Password confirm" }} *</label>
|
||||
<input type="password" data-match="#userPassword" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="pull-right">
|
||||
<button type="submit" class="btn btn-success">{{ @root.__ "Create" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue