Skip to content
This repository has been archived by the owner on Aug 30, 2021. It is now read-only.

Commit

Permalink
feat(user): Add email support to forgot password (#1834)
Browse files Browse the repository at this point in the history
Adds support for recovering users account using email and username.

Previously only username worked.
  • Loading branch information
simison authored Aug 7, 2017
1 parent 27f5065 commit f65d4b9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<section class="row">
<h3 class="col-md-12 text-center">Restore your password</h3>
<p class="small text-center">Enter your account username.</p>
<div class="col-xs-offset-2 col-xs-8 col-md-offset-5 col-md-2">
<form name="vm.forgotPasswordForm" ng-submit="vm.askForPasswordReset(vm.forgotPasswordForm.$valid)" class="form-horizontal" novalidate autocomplete="off">
<fieldset>
<div class="form-group" show-errors>
<input type="text" id="username" name="username" class="form-control" ng-model="vm.credentials.username" placeholder="Username" lowercase required autofocus>
<div ng-messages="vm.forgotPasswordForm.username.$error" role="alert">
<p class="help-block error-text" ng-message="required">Enter a username.</p>
<label for="usernameOrEmail" class="text-center">Enter your account username or email.</label>
<input type="text" id="usernameOrEmail" name="usernameOrEmail" class="form-control" ng-model="vm.credentials.usernameOrEmail" lowercase required autofocus>
<div ng-messages="vm.forgotPasswordForm.usernameOrEmail.$error" role="alert">
<p class="help-block error-text" ng-message="required">Enter a username or email.</p>
</div>
</div>
<div class="text-center form-group">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="submit" class="btn btn-primary">Restore</button>
</div>
</fieldset>
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,23 @@ exports.forgot = function (req, res, next) {
},
// Lookup user by username
function (token, done) {
if (req.body.username) {
if (req.body.usernameOrEmail) {

var usernameOrEmail = String(req.body.usernameOrEmail).toLowerCase();

User.findOne({
username: req.body.username.toLowerCase()
$or: [
{ username: usernameOrEmail },
{ email: usernameOrEmail }
]
}, '-salt -password', function (err, user) {
if (err || !user) {
return res.status(400).send({
message: 'No account with that username has been found'
message: 'No account with that username or email has been found'
});
} else if (user.provider !== 'local') {
return res.status(400).send({
message: 'It seems like you signed up using your ' + user.provider + ' account'
message: 'It seems like you signed up using your ' + user.provider + ' account, please sign in using that provider.'
});
} else {
user.resetPasswordToken = token;
Expand All @@ -51,7 +57,7 @@ exports.forgot = function (req, res, next) {
});
} else {
return res.status(422).send({
message: 'Username field must not be blank'
message: 'Username/email field must not be blank'
});
}
},
Expand Down
70 changes: 59 additions & 11 deletions modules/users/tests/server/user.server.routes.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ describe('User CRUD tests', function () {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({
username: 'some_username_that_doesnt_exist'
usernameOrEmail: 'some_username_that_doesnt_exist'
})
.expect(400)
.end(function (err, res) {
Expand All @@ -334,13 +334,13 @@ describe('User CRUD tests', function () {
return done(err);
}

res.body.message.should.equal('No account with that username has been found');
res.body.message.should.equal('No account with that username or email has been found');
return done();
});
});
});

it('forgot password should return 400 for no username provided', function (done) {
it('forgot password should return 400 for empty username/email', function (done) {
var provider = 'facebook';
user.provider = provider;
user.roles = ['user'];
Expand All @@ -349,7 +349,7 @@ describe('User CRUD tests', function () {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({
username: ''
usernameOrEmail: ''
})
.expect(422)
.end(function (err, res) {
Expand All @@ -358,7 +358,29 @@ describe('User CRUD tests', function () {
return done(err);
}

res.body.message.should.equal('Username field must not be blank');
res.body.message.should.equal('Username/email field must not be blank');
return done();
});
});
});

it('forgot password should return 400 for no username or email provided', function (done) {
var provider = 'facebook';
user.provider = provider;
user.roles = ['user'];

user.save(function (err) {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({})
.expect(422)
.end(function (err, res) {
// Handle error
if (err) {
return done(err);
}

res.body.message.should.equal('Username/email field must not be blank');
return done();
});
});
Expand All @@ -373,7 +395,7 @@ describe('User CRUD tests', function () {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({
username: user.username
usernameOrEmail: user.username
})
.expect(400)
.end(function (err, res) {
Expand All @@ -382,20 +404,46 @@ describe('User CRUD tests', function () {
return done(err);
}

res.body.message.should.equal('It seems like you signed up using your ' + user.provider + ' account');
res.body.message.should.equal('It seems like you signed up using your ' + user.provider + ' account, please sign in using that provider.');
return done();
});
});
});

it('forgot password should be able to reset password for user password reset request', function (done) {
it('forgot password should be able to reset password for user password reset request using username', function (done) {
user.roles = ['user'];

user.save(function (err) {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({
usernameOrEmail: user.username
})
.expect(400)
.end(function (err, res) {
// Handle error
if (err) {
return done(err);
}

User.findOne({ username: user.username.toLowerCase() }, function(err, userRes) {
userRes.resetPasswordToken.should.not.be.empty();
should.exist(userRes.resetPasswordExpires);
res.body.message.should.be.equal('Failure sending email');
return done();
});
});
});
});

it('forgot password should be able to reset password for user password reset request using email', function (done) {
user.roles = ['user'];

user.save(function (err) {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({
username: user.username
usernameOrEmail: user.email
})
.expect(400)
.end(function (err, res) {
Expand All @@ -421,7 +469,7 @@ describe('User CRUD tests', function () {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({
username: user.username
usernameOrEmail: user.username
})
.expect(400)
.end(function (err, res) {
Expand Down Expand Up @@ -458,7 +506,7 @@ describe('User CRUD tests', function () {
should.not.exist(err);
agent.post('/api/auth/forgot')
.send({
username: user.username
usernameOrEmail: user.username
})
.expect(400)
.end(function (err, res) {
Expand Down

0 comments on commit f65d4b9

Please sign in to comment.