How would you change the User model to allow for a password to be updated?
Opened this issue · 4 comments
Your User
model is fine for a very simple case but in the real-world people will need to be able to change their passwords.
Given you can't access model methods from within the beforeCreate
and beforeSave
methods, and with a view to maintaining DRYness as much as possible, what changes would you make to your User
model such that when a user's password is updated it's properly hashed. Obviously just changing beforeCreate
to beforeSave
is not going to work as then the password will be rehashed every time it's saved.
There are a number of ways to do this but I'm wondering what the best-practice, DRY way would be.
@davesag I imagine using a beforeSave
hook would work if you just check if a password is provided in the body of the request. If the password is sent with it then we can assume an update is being attempted, otherwise do nothing.
@davesag Also, I'll apologize for having little activity on this project for awhile. I should be getting back to the article series soon as time permits.
Here's how I ended up doing it
var bcrypt = require('bcrypt');
function hashPassword(password, errCallback, successCallback) {
bcrypt.genSalt(10, function(err, salt) {
if (err) return errCallback(err);
bcrypt.hash(password, salt, function(err, hash) {
if (err) return errCallback(err);
return successCallback(hash);
});
});
}
module.exports = {
beforeCreate: function (attrs, next) {
// ensure the password is properly encrypted
hashPassword(attrs.password, function(err){
sails.log.error('Caught error while hashing password', err);
return next(err);
}, function(hash){
attrs.password = hash;
return next();
});
},
attributes: {
email: {
type: 'string',
unique: true,
required: true
},
password: {
type: 'string',
required: true,
minLength: 6
},
updatePassword: function(password, next) {
var attrs = this;
hashPassword(attrs.password, function(err){
sails.log.error('Caught error while hashing password', err);
return next(err);
}, function(hash){
attrs.password = hash;
return next();
});
},
// strip out password from JSON representation of the User
toJSON: function() {
var obj = this.toObject();
delete obj.password;
return obj;
}
}
};
Very nice. Thanks for sharing :)
On May 12, 2014 5:05 PM, "Dave Sag" notifications@github.com wrote:
Here's how I ended up doing it
var bcrypt = require('bcrypt');
function hashPassword(password, errCallback, successCallback) {
bcrypt.genSalt(10, function(err, salt) {
if (err) return errCallback(err);bcrypt.hash(password, salt, function(err, hash) { if (err) return errCallback(err); return successCallback(hash); });
});
}module.exports = {
beforeCreate: function (attrs, next) {
// ensure the password is properly encrypted
hashPassword(attrs.password, function(err){
sails.log.error('Caught error while hashing password', err);
return next(err);
}, function(hash){
attrs.password = hash;
return next();
});
},attributes: {
email: { type: 'string', unique: true, required: true }, password: { type: 'string', required: true, minLength: 6 }, updatePassword: function(password, next) { var attrs = this; hashPassword(attrs.password, function(err){ sails.log.error('Caught error while hashing password', err); return next(err); }, function(hash){ attrs.password = hash; return next(); }); }, // strip out password from JSON representation of the User toJSON: function() { var obj = this.toObject(); delete obj.password; return obj; }
}
};
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-42894569
.