j-app icon indicating copy to clipboard operation
j-app copied to clipboard

How would you change the User model to allow for a password to be updated?

Open davesag opened this issue 11 years ago • 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 avatar May 12 '14 02:05 davesag

@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.

sethetter avatar May 12 '14 16:05 sethetter

@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.

sethetter avatar May 12 '14 16:05 sethetter

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;
    }    
  }

};

davesag avatar May 12 '14 22:05 davesag

Very nice. Thanks for sharing :) On May 12, 2014 5:05 PM, "Dave Sag" [email protected] 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/sethetter/j-app/issues/3#issuecomment-42894569 .

sethetter avatar May 13 '14 16:05 sethetter