Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion modules/auth/controllers/auth.password.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ const updatePassword = async (req, res) => {
if (!(await AuthService.comparePassword(req.body.currentPassword, user.password)))
return responses.error(res, 422, 'Unprocessable Entity', 'Current password is incorrect')();
if (req.body.newPassword !== req.body.verifyPassword) return responses.error(res, 422, 'Unprocessable Entity', 'Passwords do not match')();
password = AuthService.checkPassword(req.body.newPassword);
const checkedPassword = AuthService.checkPassword(req.body.newPassword);
password = await AuthService.hashPassword(checkedPassword);
user = await UserService.update(user, { password }, 'recover');
return res
.status(200)
Expand Down
24 changes: 22 additions & 2 deletions modules/users/tests/user.account.integration.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,39 @@ describe('User integration tests:', () => {
});

test('should be able to change user own password successfully', async () => {
const newPassword = 'Waos.azs@^:SA3$&2';
try {
const result = await agent
.post('/api/users/password')
.send({
newPassword: 'Waos.azs@^:SA3$&2',
verifyPassword: 'Waos.azs@^:SA3$&2',
newPassword,
verifyPassword: newPassword,
currentPassword: credentials[0].password,
})
.expect(200);
expect(result.body.message).toBe('Password changed successfully');
} catch (err) {
expect(err).toBeFalsy();
}

// Regression guard (#3925): the STORED password must be a bcrypt hash,
// never the raw plaintext. updatePassword previously persisted the
// plaintext verbatim (the model has no pre-save hash hook), which both
// stored credentials in the clear and locked the user out on next signin.
// This shipped undetected precisely because no test read the persisted
// value — assert the hash format at rest, then confirm via signin oracle.
try {
const stored = await UserService.getBrut({ id: user.id });
expect(stored.password).toMatch(/^\$2[aby]\$/);
expect(stored.password).not.toBe(newPassword);

// Runtime oracle: the NEW password authenticates, the OLD one does not.
await request(app).post('/api/auth/signin').send({ email: credentials[0].email, password: newPassword }).expect(200);
await request(app).post('/api/auth/signin').send({ email: credentials[0].email, password: credentials[0].password }).expect(401);
} catch (err) {
console.log(err);
expect(err).toBeFalsy();
}
});

test('should not be able to change user own password if wrong verifyPassword is given', async () => {
Expand Down
Loading