server/src/controllers/user.js
import bcrypt from 'bcrypt';
import models from '../models';
import generateToken from '../controllers/middleware/authenticate';
import pagination from '../controllers/helpers/pagination';
const { User, Userlevel } = models;
const userController = {
/**
* Route: POST: /auth/users/signin
*
* @description Create a new user
*
* @param {Object} req request object
*
* @param {Object} res response object
*
* @returns {void|object} response object
*/
createUser(req, res) {
if (req.body.password !== req.body.passwordConfirmation) {
return res.status(422).send({
message: 'Password and Password confirmation do not match'
});
}
User.findOne({ where: { username: req.body.username } })
.then((usernameExists) => {
if (usernameExists) {
res.status(409).json({
success: false, message: 'This username is already in use'
});
} else {
User.findOne({
where: { email: req.body.email }
})
.then((userExists) => {
if (userExists) {
res.status(409).json({
success: false, message: 'This email is already in use'
});
} else {
User.create({
firstname: req.body.firstname.trim(),
lastname: req.body.lastname.trim(),
username: req.body.username.trim(),
password: req.body.password.trim(),
userImage: req.body.userImage || process.env.PROFILE_PIC,
passwordConfirmation: req.body.passwordConfirmation.trim(),
email: req.body.email.trim(),
googleId: req.body.googleId || null,
isAdmin: req.body.isAdmin
}).then((user) => {
if (user.googleId) {
return userController.signIn(req, res);
} else {
res.status(201).send({
message: `${user.username} has been added to the ` +
'library, Please Login, you will be only ' +
'required to Sign up once'
});
}
});
}
})
.catch((error) => {
res.status(400).send({
success: false, message: ` ${error.message}`
});
});
}
});
},
/**
*
* Route: POST: /auth/users/sigin
*
* @description User sign in
*
* @param {Object} req request object
*
* @param {Object} res response object
*
* @returns {void|Response} status, send
*
*/
signIn(req, res) {
const googleId = req.body.googleId || null;
return User.findOne({
where: {
username: req.body.username
}
})
.then((user) => {
if (!user) {
if (googleId) {
return userController.createUser(req, res);
}
return res.status(404).send({
success: false,
message: `${req.body.username} ` +
'does not exist, Make sure you are signed up'
});
} else if (bcrypt.compareSync(req.body.password, user.password)) {
const Userjwt = {
id: user.id,
isAdmin: user.isAdmin
};
generateToken
.getJWT(Userjwt)
.then((token) => {
res.status(200).send({
success: true,
message: ` You are now logged in as ${req.body.username}`,
token: token.token,
username: user.username,
email: user.email,
profilePic: `${user.userImage}`,
firstname: user.firstname,
isAdmin: user.isAdmin
});
});
} else {
res.status(403).send({
success: false, message: 'Wrong Credentials'
});
}
})
.catch(error => res.status(500).send(error.message));
},
/**
* @description Get user details
*
* @method getUser
*
* @param {object} req HTTP request object
*
* @param {object} res HTTP response object
*
* @returns {object} response
*/
getUser(req, res) {
const id = req.params.userId;
User
.findOne({
where: id ? { id } : null,
attributes: [
'userLevel',
'username',
'id'],
})
.then(user => res
.status(200)
.send({
user
}));
},
/** @description changes user password
*
* @param {object} req HTTP request object
*
* @param {object} res HTTP response object
*
* @returns {string} Message
*/
changePassword(req, res) {
const userId = req.userId;
User
.findOne({
where: {
id: userId
}
}).then((user) => {
if (!user) {
return res.status(404).send({ message: 'User not logged In' });
}
const compareOldPasswords =
bcrypt.compareSync(req.body.oldPassword, user.password);
if (!compareOldPasswords) {
return res.status(409)
.send({
message:
'Your current password does not match our records, ' +
'Please Re-enter'
});
}
const compareNewPasswords =
bcrypt.compareSync(req.body.newPassword, user.password);
if (compareNewPasswords) {
return res.status(409)
.send({ message: 'You cannot use a previous password' });
}
const encryptedPassword = bcrypt.hashSync(req.body.newPassword, 10);
user.update({
password: encryptedPassword
});
return res.status(200)
.send({
message: `${user.username}, your password has been updated`
});
})
.catch(error => res.status(500).send(error.message));
},
/** @description Changes a users level
*
* @param {object} req HTTP request object
*
* @param {object} res HTTP response object
*
* @returns {object} response object
*/
changeLevel(req, res) {
const newLevelId = req.body.newLevelId;
const userId = req.body.userId;
if (isNaN(newLevelId)) {
return res.status(400).send({
message: 'Please enter new Level'
});
}
User
.findById(userId).then((user) => {
if (!user) {
return res.status(404).send({ message: 'User not found' });
}
if (parseInt(newLevelId, 10) === user.userLevel) {
return res.status(409)
.send({ message: 'This user is already on this level' });
}
Userlevel.findById(newLevelId)
.then((level) => {
if (!level) {
return res.status(404).send({ message: 'Level does not exist' });
}
user.update({
userLevel: newLevelId
});
user.getLevel()
.then((newLevel) => {
const userDetails = {
username: user.username,
levelName: newLevel.levelName,
level: newLevel.level
};
res.status(200).send({
message:
'Level changed Successfully,' +
`New Level "${userDetails.levelName}"`,
userDetails
});
});
});
})
.catch(error => res.status(500).send(error.message));
},
/**
* Gets a list of users in tha library
*
* @method getUserList
*
* @param {object} req HTTP request object
*
* @param {object} res HTTP response object
*
* @return {object} response
*
* @return {string} response
*/
getUserList(req, res) {
const offset = req.query.offset || 0;
const limit = req.query.limit || 3;
return User
.findAndCountAll({
limit,
offset,
attributes: [
'id',
'firstname',
'lastname',
'email',
'username',
'userImage',
'userLevel',
'createdAt',
'updatedAt'],
order: [
['createdAt', 'DESC']
]
})
.then((users) => {
if (users.count === 0) {
res.json({
error: 'Empty',
message: 'There are no books present in the database'
});
} else {
res
.status(200)
.send({
users: users.rows,
pagination: pagination(offset, limit, users)
});
}
})
.catch(error => res.status(501).send(error.message));
},
/**
*
* @description UserLevelList fetches the list of the user levels
*
* @param {object} req - request object
*
* @param {object} res - response object
*
* @returns {object} response
*/
getUserLevelList(req, res) {
return Userlevel
.all({
attributes: ['maxBooks',
'maxDays',
'level',
'levelName'],
order: [['level', 'ASC']]
})
.then((userLevels) => {
if (Object.keys(userLevels).length < 1) {
return res.status(200)
.send({ message: 'Sorry there are no user levels available' });
}
const allUserLevels = { userLevels };
res.status(200).send(allUserLevels);
})
.catch(error => res.status(500).send(error.message));
}
};
export default userController;