Here is my “complete” solution for implementing a specific method of remote remote data transfer in the LoopBack / StrongLoop - IBM project. Ensure that the loopback-datasource-juggler has a higher or equal version than 2.45.1 ( npm list loopback-datasource-juggler ). My user model is called MyUserModel and inherits from the built-in User model:
"my user is model.js"
module.exports = function (MyUserModel) { ... MyUserModel.updatePassword = function (ctx, emailVerify, oldPassword, newPassword, cb) { var newErrMsg, newErr; try { this.findOne({where: {id: ctx.req.accessToken.userId, email: emailVerify}}, function (err, user) { if (err) { cb(err); } else if (!user) { newErrMsg = "No match between provided current logged user and email"; newErr = new Error(newErrMsg); newErr.statusCode = 401; newErr.code = 'LOGIN_FAILED_EMAIL'; cb(newErr); } else { user.hasPassword(oldPassword, function (err, isMatch) { if (isMatch) { // TODO ...further verifications should be done here (eg non-empty new password, complex enough password etc.)... user.updateAttributes({'password': newPassword}, function (err, instance) { if (err) { cb(err); } else { cb(null, true); } }); } else { newErrMsg = 'User specified wrong current password !'; newErr = new Error(newErrMsg); newErr.statusCode = 401; newErr.code = 'LOGIN_FAILED_PWD'; return cb(newErr); } }); } }); } catch (err) { logger.error(err); cb(err); } }; MyUserModel.remoteMethod( 'updatePassword', { description: "Allows a logged user to change his/her password.", http: {verb: 'put'}, accepts: [ {arg: 'ctx', type: 'object', http: {source: 'context'}}, {arg: 'emailVerify', type: 'string', required: true, description: "The user email, just for verification"}, {arg: 'oldPassword', type: 'string', required: true, description: "The user old password"}, {arg: 'newPassword', type: 'string', required: true, description: "The user NEW password"} ], returns: {arg: 'passwordChange', type: 'boolean'} } ); ... };
"my user model.json"
{ "name": "MyUserModel", "base": "User", ... "acls": [ ... { "comment":"allow authenticated users to change their password", "accessType": "EXECUTE", "property":"updatePassword", "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW" } ... ], ... }
Note. The same functionality can be performed using the PUT request on MyUserModel and simply specify {body]: "... newpassword ..."} in the body. But it is probably more convenient to have a specific remote method than this trick to enforce the security policy of the new password.