Skip to content

Commit

Permalink
Merge pull request #128 from Gentlee/change-password
Browse files Browse the repository at this point in the history
Implement changePassword method #127
  • Loading branch information
saintedlama authored Aug 8, 2017
2 parents 3985bbc + 4537324 commit a88d36e
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 1 deletion.
45 changes: 44 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,50 @@ module.exports = function(schema, options) {
});
});
};

function changePassword(user, oldPassword, newPassword, cb) {
if (!oldPassword || !newPassword) {
return cb(new errors.MissingPasswordError(options.errorMessages.MissingPasswordError));
}

if (!user.get(options.saltField)) {
return cb(new errors.NoSaltValueStoredError(options.errorMessages.NoSaltValueStoredError));
}

pbkdf2(oldPassword, user.get(options.saltField), function(err, hashRaw) {
if (err) {
return cb(err);
}

var hash = new Buffer(hashRaw, 'binary').toString(options.encoding);

if (scmp(hash, user.get(options.hashField))) {
if (oldPassword === newPassword) {
return cb(null, user);
}
user.setPassword(newPassword, cb);
} else {
return cb(new errors.IncorrectPasswordError(options.errorMessages.IncorrectPasswordError));
}
});
}

schema.methods.changePassword = function(oldPassword, newPassword, cb) {
var self = this;

if (!self.get(options.saltField)) {
self.constructor.findByUsername(self.get(options.usernameField), true, function(err, user) {
if (err) return cb(err);
if (user) {
return changePassword(user, oldPassword, newPassword, cb);
} else {
return cb(new errors.IncorrectUsernameError(options.errorMessages.IncorrectUsernameError));
}
});
} else {
return changePassword(self, oldPassword, newPassword, cb);
}
};

function authenticate(user, password, cb) {
if (options.limitAttempts) {
Expand Down Expand Up @@ -157,7 +201,6 @@ module.exports = function(schema, options) {
}
}
});

}

schema.methods.authenticate = function(password, cb) {
Expand Down
76 changes: 76 additions & 0 deletions test/passport-local-mongoose.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,82 @@ describe('passportLocalMongoose', function() {
});
});
});

describe('#changePassword()', function() {
it('should change password', function(done) {
this.timeout(5000); // Five seconds - heavy crypto in background

var user = new DefaultUser();

user.setPassword('password1', function(err) {
assert.ifError(err);

user.changePassword('password1', 'password2', function(err, user) {
assert.ifError(err);
assert.ok(user);

user.authenticate('password2', function(err, result, data) {
assert.ifError(err);
assert.ok(result);

done();
});
});
});
});

it('should fail on wrong password', function(done) {
this.timeout(5000); // Five seconds - heavy crypto in background

var user = new DefaultUser();

user.setPassword('password1', function(err) {
assert.ifError(err);

user.changePassword('password2', 'password2', function(err, user) {
assert.ok(err);
done();
})
});
});

it('should not fail when passwords are the same', function(done) {
this.timeout(5000); // Five seconds - heavy crypto in background

var user = new DefaultUser();

user.setPassword('password1', function(err) {
assert.ifError(err);

user.changePassword('password1', 'password1', function(err, user) {
assert.ifError(err);
assert.ok(user);

done();
});
});
});

it('should change password when user model doesnt include salt/hash fields', function(done) {
this.timeout(5000); // Five seconds - heavy crypto in background

var user = new DefaultUser();

user.setPassword('password1', function(err) {
assert.ifError(err);

delete user.salt;
delete user.hash;

user.changePassword('password1', 'password2', function(err, user) {
assert.ifError(err);
assert.ok(user);

done();
});
});
});
});

describe('#authenticate()', function() {
it('should yield false in case user cannot be authenticated', function(done) {
Expand Down

0 comments on commit a88d36e

Please sign in to comment.