Search code examples
javascriptangularjsnode.jsloopbackjsstrongloop

Reset Loopback Password with Access Token


I'm working on a project that uses Loopback as a framework, and includes users and authentication. I added a password reset route generated and sent in an email, and everything seemed to be working correctly. Recently, I discovered that the password reset does not appear to be working. The process for resetting the password here is:

  • Call password reset method for user
  • Send email from reset event, including user ID and access token
  • From reset link, set $http.defaults.headers.common.authorization to the passed token
  • Call user.prototype$updateAttributes (generated by lb-ng) to update password attribute based on a form

The expected behavior is that the password would be updated on the password reset form. Instead, I get an authorization error as either a 401 or a 500 (seems to go back and forth). I notice that in the actual headers sent to the API, the authorization token does not match what I'm passing from the route. Trying to set it using LoopBackAUth.setUser doesn't work, and neither doesn't updating the authorization property before actually sending the request.

I definitely spent time testing this when it was first added, and I can't figure out what would have changed to break this. I've been following the example from loopback-faq-user-management, but we have an Angular front-end instead of the server side views in that example.

Edit:

I tried opening up the ACLs completely to see if I could update the password (or any properties) of my user object (which inherits from User, but is its own type). I'm still getting a 401 when trying to do this.

Edit #2:

Here are my ACLs and sample code for how I'm calling this.

ACLs from model definition

...
{
    "accessType": "*",
    "principalType": "ROLE",
    "principalId": "$owner",
    "permission": "ALLOW"
},
{
    "accessType": "EXECUTE",
    "principalType": "ROLE",
    "principalId": "$owner",
    "permission": "ALLOW",
    "property": "updateAttributes"
}
...

auth.js

...
resetPassword: function(user) {
    return MyUser.prototype$updateAttributes(user, user).$promise;
}
...

Solution

  • Figured out what the issue was. In our app's server, we were not using Loopback's token middleware. Adding app.use(loopback.token()); before starting the server causes the access token provided in the reset link to work as expected!