Conditional beforeUpdate in sails

I only need to encrypt the password if some criteria are filled.

beforeUpdate: function (value, cb) {
User.findOne(value.id)
  .exec(function (err, originalUser) {
    if (err || !originalUser) {
      return cb();
    }
    //encrypt the password only if the password is not previously encrypted
    if (value.password != originalUser.password) {
       //encrypt the Pwd
    } else {
      cb();
    }
  });

      

} The problem is that the value object only contains the update parameters, how can I get the entire user object in the value object?

+3


source to share


6 answers


After updating async, this method no longer works.



You cannot get the whole object inside beforeUpdate

. You can try this to get the id. var id= this.update.arguments[0]

+5


source


To expand on what user3036010 suggested, I created a new policy like this:

In api/policies/propagateId.js

:

module.exports = function(req, res, next) {
    var id = req.param('id');
    if (id && req.body) {
        req.body.id = id;
    }

    next();
};

      

Then configure the file api/config/policies.js

to apply the default policy to all controllers and actions:



module.exports.policies = {
    '*': 'propagateId'
};

      

What this means is, it forces the property to id

be set in the body of the document, which triggers the update action, assuming the parameter id

was manually specified. For some reason, there is a block of code in the update action that checks this, and if id

not manually specified, it will remove it from the values.

It's kind of a policy abuse, but it seems to work great for me. If you don't want to do that, it looks like manually specifying id

in your request body every time you make an update API request should also work.

+2


source


I'm not sure why this is needed in the value object here, but you can create a custom policy that will receive the entire user object and send a 'next ()' callback to update;

+1


source


Just use lodash to increment the value with originalUser. Or for this use case, you can always just check if the password has already been hashed if you are using node bcrypt or something

+1


source


Now, only if you submit password: password in the Update method, it will update the password (hash and store), otherwise it will only update the provided user fields.

Controller (UserController.js):

updateDisplayName: function(req, res) {

var userid = req.token;
var newDisplayName = req.param('newdisplayname');

User.update({id: userid},{displayname: newDisplayName}).exec(function afterwards(err,updated){

if (err) {
res.json(err);
} else {
res.json("Success");
}
});

},

      

Model (user.js):

beforeUpdate: function(values, next) {
if(values.password) {
hashPassword(values, next);
} else {
next();
}
},

      

+1


source


I also tried to do something similar: save the password in the corresponding passport entry. I am using the sails-auth and sails-permissions modules which include passport.

Finally, I was able to do this using the lifecycle afterValidate callback instead of the beforeUpdate callback. In the afterValidate callback, you can access the custom model with this.user

.

Here's the code I entered into my callback after I validated when I save the password passed using the Passport model:

afterValidate: function(updates, next) {
  // Update the passport password if it was passed in
  if(updates.password) {
    Passport.update({user: this.user.id}, {password: updates.password}).exec(function(err, passport) {
      next(err);
    });
  }
  else {
    next();
  }
}

      

+1


source







All Articles