Reputation: 2847
I need to encrypt the password only if some criteria is fullfilled.
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 params, how can I get the whole user object in the value object?
Upvotes: 3
Views: 3450
Reputation: 195
After the update of async, this method does not work anymore.
You can not get the whole object inside beforeUpdate
. You can try this to get the id.
var id= this.update.arguments[0]
Upvotes: 5
Reputation: 478
I was also trying to do something similar: save the password to the associated passport record. I'm using the sails-auth and sails-permissions modules, which includes passport.
I was finally able to do it by using the afterValidate lifecycle callback instead of beforeUpdate callback. In the afterValidate callback, you can access the user model using this.user
.
Here's the code I put into my afterValidate callback where I save the password passed in 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();
}
}
Upvotes: 1
Reputation: 1604
To expand on what user3036010 suggested, I ended up creating 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 set up your api/config/policies.js
file to apply the policy by default to all controllers and actions:
module.exports.policies = {
'*': 'propagateId'
};
What this does is it forces the id
property to be set on the document body, which tricks the update action into thinking that the id
was manually specified. For whatever reason, there is a block of code in the update action that checks for this, and if the id
is not manually specified it will remove it from the values.
This is sort of an abuse of policies, but it seems to work fine for me. If you don't want to do it this way, it looks like manually specifying id
in your request body every time you make an update API request should work too.
Upvotes: 2
Reputation: 613
Now, only if you send password: password in the Update method, it will update the password (hash and store) else 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();
}
},
Upvotes: 1
Reputation: 5979
Just use lodash to extend value with originalUser. Or for this use case you can always just check if the pasword is already hashed if you using node bcrypt or something
Upvotes: 1
Reputation: 49
I'm not sure why you need this in the value object here, but you may create a custom policy that will get the whole user object and send in 'next()' callback to update;
Upvotes: 1