Skip to content

Commit

Permalink
Merge pull request #233 from 4umfreak/master
Browse files Browse the repository at this point in the history
Issue #79 and Bug #58, handle save() asynchronously
  • Loading branch information
saintedlama committed Oct 25, 2017
2 parents b1e3e2e + 0f4db8b commit a2bd7bf
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 8 deletions.
27 changes: 19 additions & 8 deletions lib/authenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ module.exports = function authenticate(user, password, options, cb) {

if (Date.now() - user.get(options.lastLoginField) < calculatedInterval) {
user.set(options.lastLoginField, Date.now());
user.save();
return cb(null, false, new errors.AttemptTooSoonError(options.errorMessages.AttemptTooSoonError));
user.save(function(saveErr) {
if (saveErr) {
return cb(saveErr);
}
return cb(null, false, new errors.AttemptTooSoonError(options.errorMessages.AttemptTooSoonError));
});
return;
}

if (user.get(options.attemptsField) >= options.maxAttempts) {
Expand All @@ -30,12 +35,18 @@ module.exports = function authenticate(user, password, options, cb) {
}

if (scmp(hashBuffer, new Buffer(user.get(options.hashField), options.encoding))) {
if (options.limitAttempts) {
user.set(options.lastLoginField, Date.now());
user.set(options.attemptsField, 0);
user.save();
}
return cb(null, user);
if (options.limitAttempts) {
user.set(options.lastLoginField, Date.now());
user.set(options.attemptsField, 0);
user.save(function(saveErr, user) {
if (saveErr) {
return cb(saveErr);
}
return cb(null, user);
});
} else {
return cb(null, user);
}
} else {
if (options.limitAttempts) {
user.set(options.lastLoginField, Date.now());
Expand Down
157 changes: 157 additions & 0 deletions test/passport-local-mongoose.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ describe('passportLocalMongoose', function() {
});

describe('#authenticate()', function() {

beforeEach(mongotest.prepareDb('mongodb://localhost/passportlocalmongoosetests'));
afterEach(mongotest.disconnect());

this.timeout(5000); // Five seconds - heavy crypto in background

it('should yield false in case user cannot be authenticated', function(done) {
Expand All @@ -264,6 +268,159 @@ describe('passportLocalMongoose', function() {
done();
});
});

it('should supply message when limiting attempts and authenticating too soon', function(done) {
this.timeout(5000); // Five seconds - mongo db access needed

var UserSchema = new Schema({});
UserSchema.plugin(passportLocalMongoose, {
limitAttempts: true,
interval: 20000
});
var User = mongoose.model('LimitAttemptsTooSoonUser', UserSchema);

var user = new User({
username: 'mark',
attempts: 1,
last: Date.now()
});
user.setPassword('password', function(err) {
expect(err).to.not.exist;

user.save(function(err) {
expect(err).to.not.exist;

user.authenticate('password', function(err, user, message) {
expect(err).to.not.exist;
expect(user).to.be.false;
expect(message).to.be.instanceof(errors.AttemptTooSoonError);
done();
});
});
});
});

it('should get an error updating when limiting attempts and authenticating too soon', function(done) {
this.timeout(5000); // Five seconds - mongo db access needed

var UserSchema = new Schema({}, {saveErrorIfNotFound: true});
UserSchema.plugin(passportLocalMongoose, {
limitAttempts: true,
interval: 20000
});
var User = mongoose.model('LimitAttemptsTooSoonUpdateWithError', UserSchema);

var user = new User({
username: 'jimmy',
attempts: 1,
last: Date.now()
});
user.setPassword('password', function(err) {
expect(err).to.not.exist;

user.save(function(err) {
expect(err).to.not.exist;

user._id = id = mongoose.Types.ObjectId();
user.authenticate('password', function(err, user, message) {
expect(err).to.exist;
expect(user).to.not.exist;
expect(message).to.not.exist;
done();
});
});
});
});

it('should get an error updating the user on password match when limiting attempts', function(done) {
this.timeout(5000); // Five seconds - mongo db access needed

var UserSchema = new Schema({}, {saveErrorIfNotFound: true});
UserSchema.plugin(passportLocalMongoose, {
limitAttempts: true
});
var User = mongoose.model('LimitAttemptsUpdateWithError', UserSchema);

var user = new User({
username: 'jane'
});
user.setPassword('password', function(err) {
expect(err).to.not.exist;

user.save(function(err) {
expect(err).to.not.exist;

user._id = id = mongoose.Types.ObjectId();
user.authenticate('password', function(err, user, message) {
expect(err).to.exist;
expect(user).to.not.exist;
expect(message).to.not.exist;
done();
});
});
});
});

it('should update the user on password match while limiting attempts', function(done) {
this.timeout(5000); // Five seconds - mongo db access needed

var UserSchema = new Schema({});
UserSchema.plugin(passportLocalMongoose, {
limitAttempts: true
});
var User = mongoose.model('LimitAttemptsUpdateWithoutError', UserSchema);

var user = new User({
username: 'walter'
});
user.setPassword('password', function(err) {
expect(err).to.not.exist;

user.save(function(err) {
expect(err).to.not.exist;

user.authenticate('password', function(err, result, message) {
expect(err).to.not.exist;
expect(result).to.exist;
expect(result.username).to.equal(user.username);
expect(message).to.not.exist;
done();
});
});
});
});

it('should fail to update the user on password mismatch while limiting attempts', function(done) {
this.timeout(5000); // Five seconds - mongo db access needed

var UserSchema = new Schema({}, {saveErrorIfNotFound: true});
UserSchema.plugin(passportLocalMongoose, {
limitAttempts: true,
interval: 20000
});
var User = mongoose.model('LimitAttemptsMismatchWithAnError', UserSchema);

var user = new User({
username: 'wendy'
});
user.setPassword('password', function(err) {
expect(err).to.not.exist;

user.save(function(err) {
expect(err).to.not.exist;

user.hash = 'deadbeef'; // force an error on scmp with different length hex.
user._id = id = mongoose.Types.ObjectId(); // force the save to fail
user.authenticate('password', function(err, user, message) {
expect(err).to.exist;
expect(user).to.not.exist;
expect(message).to.not.exist;
done();
});
});
});
});

});

describe('static #authenticate()', function() {
Expand Down

0 comments on commit a2bd7bf

Please sign in to comment.