diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js index e06c58eb9..184158e55 100644 --- a/Server/controllers/authController.js +++ b/Server/controllers/authController.js @@ -31,6 +31,17 @@ const issueToken = (payload) => { return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: tokenTTL }); }; +const getTokenFromHeaders = (headers) => { + const authorizationHeader = headers.authorization; + if (!authorizationHeader) throw new Error("No auth headers"); + + const parts = authorizationHeader.split(" "); + if (parts.length !== 2 || parts[0] !== "Bearer") + throw new Error("Invalid auth headers"); + + return parts[1]; +}; + /** * @function * @param {express.Request} req @@ -149,6 +160,32 @@ const userEditController = async (req, res, next) => { } try { + // Change Password check + if (req.body.password && req.body.newPassword) { + const newPassword = req.body.newPassword; + const password = req.body.password; + + // Compare password + // Get token from headers + const token = getTokenFromHeaders(req.headers); + // Get email from token + const { email } = jwt.verify(token, process.env.JWT_SECRET); + // Add user email to body for DB operation + req.body.email = email; + // Get user + const user = await req.db.getUserByEmail(req, res); + // Compare passwords + const match = await user.comparePassword(req.body.password); + // If not a match, throw a 403 + if (!match) { + const error = new Error(errorMessages.AUTH_INCORRECT_PASSWORD); + error.status = 403; + throw error; + } + // If a match, update the password + req.body.password = req.body.newPassword; + } + const updatedUser = await req.db.updateUser(req, res); return res.status(200).json({ success: true, @@ -280,7 +317,7 @@ const resetPasswordController = async (req, res, next) => { */ const deleteUserController = async (req, res, next) => { try { - const token = req.headers.authorization.split(" ")[1]; + const token = getTokenFromHeaders(req.headers); const decodedToken = jwt.decode(token); const { _id, email } = decodedToken; diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js index 4c9e19095..3c8984563 100644 --- a/Server/db/MongoDB.js +++ b/Server/db/MongoDB.js @@ -130,6 +130,7 @@ const updateUser = async (req, res) => { ) .select("-password") .select("-profileImage"); + console.log(updatedUser); return updatedUser; } catch (error) { throw error; diff --git a/Server/models/user.js b/Server/models/user.js index 1a8135e33..a1fe2aaf8 100644 --- a/Server/models/user.js +++ b/Server/models/user.js @@ -55,6 +55,16 @@ UserSchema.pre("save", async function (next) { next(); }); +UserSchema.pre("findOneAndUpdate", async function (next) { + const update = this.getUpdate(); + if ("password" in update) { + const salt = await bcrypt.genSalt(10); //genSalt is asynchronous, need to wait + update.password = await bcrypt.hash(update.password, salt); // hash is also async, need to eitehr await or use hashSync + } + + next(); +}); + UserSchema.methods.comparePassword = async function (submittedPassword) { res = await bcrypt.compare(submittedPassword, this.password); return res; diff --git a/Server/validation/joi.js b/Server/validation/joi.js index 28973f2cf..8144a7fb4 100644 --- a/Server/validation/joi.js +++ b/Server/validation/joi.js @@ -26,6 +26,8 @@ const editUserBodyValidation = joi.object({ firstname: joi.string(), lastname: joi.string(), profileImage: joi.any(), + newPassword: joi.string().min(8), + password: joi.string().min(8), deleteProfileImage: joi.boolean(), role: joi.string(), });