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?
source to share
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.
source to share
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();
}
},
source to share
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();
}
}
source to share