Fix login bug.

This commit is contained in:
Ritchie Martori 2013-07-15 18:22:33 -07:00
parent aa8d1bb853
commit 49da6f4249
2 changed files with 45 additions and 21 deletions

View File

@ -16,13 +16,9 @@ var Model = require('../asteroid').Model
*/
var properties = {
id: {type: String, required: true},
realm: {type: String, },
username: {type: String, required: true},
password: {type: String, transient: true}, // Transient property
hash: {type: String}, // Hash code calculated from sha256(realm, username, password, salt, macKey)
salt: {type: String},
macKey: {type: String}, // HMAC to calculate the hash code
email: String,
emailVerified: Boolean,
verificationToken: String,
@ -62,8 +58,17 @@ var User = module.exports = Model.extend('user', properties);
User.login = function (credentials, fn) {
var UserCtor = this;
var query = {};
this.findOne({username: credentials.username}, function(err, user) {
if(credentials.email) {
query.email = credentials.email;
} else if(credentials.username) {
query.username = credentials.username;
} else {
return fn(new Error('must provide username or email'));
}
this.findOne(query, function(err, user) {
var defaultError = new Error('login failed');
if(err) {
@ -240,12 +245,6 @@ User.confirm = function (uid, token, redirect, fn) {
}
});
}
User.setter.password = function (plain) {
var salt = bcrypt.genSaltSync(this.constructor.settings.saltWorkFactor || SALT_WORK_FACTOR);
this._password = bcrypt.hashSync(plain, salt);
}
/**
* Setup an extended user model.
*/
@ -253,6 +252,11 @@ User.setter.password = function (plain) {
User.setup = function () {
var UserModel = this;
UserModel.setter.password = function (plain) {
var salt = bcrypt.genSaltSync(this.constructor.settings.saltWorkFactor || SALT_WORK_FACTOR);
this._password = bcrypt.hashSync(plain, salt);
}
asteroid.remoteMethod(
UserModel.login,
{

View File

@ -1,4 +1,4 @@
var User = asteroid.User;
var User = asteroid.User.extend('user');
var Session = asteroid.Session;
var passport = require('passport');
@ -6,26 +6,28 @@ var userMemory = asteroid.createDataSource({
connector: asteroid.Memory
});
asteroid.User.attachTo(userMemory);
asteroid.User.session.attachTo(userMemory);
asteroid.User.email.setup({transports: [{type: 'STUB'}]});
describe('User', function(){
User.attachTo(userMemory);
User.session.attachTo(userMemory);
User.email.setup({transports: [{type: 'STUB'}]});
// allow many User.afterRemote's to be called
User.setMaxListeners(22);
beforeEach(function (done) {
app.use(asteroid.cookieParser());
app.use(asteroid.auth());
app.use(asteroid.rest());
app.model(asteroid.User);
app.model(User);
asteroid.User.create({email: 'foo@bar.com', password: 'bar'}, done);
User.create({email: 'foo@bar.com', password: 'bar'}, done);
});
afterEach(function (done) {
asteroid.User.destroyAll(function (err) {
Session.destroyAll(done);
User.destroyAll(function (err) {
User.session.destroyAll(done);
});
});
@ -67,6 +69,11 @@ describe('User', function(){
});
});
});
it('Hashes the given password.', function() {
var u = new User({username: 'foo', password: 'bar'});
assert(u.password !== 'bar');
});
});
describe('User.login', function() {
@ -168,6 +175,19 @@ describe('User', function(){
});
});
it('should match a password when saved', function(done) {
var u = new User({username: 'a', password: 'b', email: 'z@z.net'});
u.save(function (err, user) {
User.findById(user.id, function (err, uu) {
uu.hasPassword('b', function (err, isMatch) {
assert(isMatch);
done();
});
});
});
});
it('should match a password after it is changed', function(done) {
User.create({email: 'foo@baz.net', username: 'bat', password: 'baz'}, function (err, user) {
User.findById(user.id, function (err, foundUser) {