stormpath / express-stormpath

Build simple, secure web applications with Stormpath and Express!
http://docs.stormpath.com/nodejs/express/
Apache License 2.0
325 stars 111 forks source link

Changing a user's password doesn't work #623

Open passatgt opened 7 years ago

passatgt commented 7 years ago

Previously with Stormpath i changed a user's password(after validating the current password) like this:

req.user.password = req.body.password;
req.user.save(function (err,res) {
    ...
});

This doesn't seem to work with Okta. I don't see any error in the response, its just the user object as usual.

robertjd commented 7 years ago

Hi @passatgt , unfortunately that functionality has not been patched. There is an endpoint in the Okta API to achieve this:

https://developer.okta.com/docs/api/resources/users.html#change-password

You may be able to make this call through the new Okta Node SDK (alpha preview):

https://developer.okta.com/okta-sdk-nodejs/jsdocs/GeneratedApiClient.html#changePassword__anchor

If you have troubles please let us know, and fallback to manual HTTP calls for now.

Hope this helps!

passatgt commented 7 years ago

Thanks, i'll do a simple http call for now(i already do that to check for the validation of the current password), but would be nice to fix this so its even easier to use. I guess on the long run, this repo will be renamed / moved to okta?

isaacdre commented 7 years ago

Points for the Modest Mouse reference in the Okta Change-Password documents.

I'm fixing this for my migrated Express-Stormpath app. Will post before and after code when done.

isaacdre commented 7 years ago

Express-Stormpath change password example Before Okta

app.patch('/passwords', stormpath.authenticationRequired, function(req, res) {
      req.user.password = req.get('custom-password');
      req.user.save(function (err) {
        if (err) {
          return res.status(400).json({success: false, error: err});
        } else {
          return res.status(200).json({success: true, message: 'Account password changed'});
        }
      });
    });

Express-Stormpath change password example with Okta

    app.patch('/passwords', stormpath.authenticationRequired, function(req, res) {

      // var request = require('request'); imported above

      var oldPass = req.get('custom-old_password');
      var newPass = req.get('custom-new_password');
      var userOktaID = req.user.id;

      var requestOptions = {
        method: "POST",
        url: oktaOrgURL + "/api/v1/users/" + userOktaID + "/credentials/change_password",
        headers: {
          "Accept": "application/json",
          "Content-Type": "application/json",
          "Authorization": "SSWS " + oktaAPIToken
        },
        json: true,
        body: {
          oldPassword: oldPass,
          newPassword: newPass
        }
      };

      request(requestOptions, function(error, response, body){
        if (error){  // If sending the request failed
          console.log(error);
          res.status(500).json({success:false, error: error});
        } else {
          if (!body.errorCode){ // If resetting the password failed
            return res.status(200).json({success: true, message: 'Account password changed'});
          } else {
            return res.status(400).json({success: false, error: body.errorSummary});
          }
        }
      });
    });
passatgt commented 6 years ago

@isaacdre theres a simpler way to do this:

const okta = require('@okta/okta-sdk-nodejs');
const oktaClient = new okta.Client({
  orgUrl: config.okta_url,
  token: config.okta_token
});

 var changePasswordCredentials = {
    oldPassword: { value: req.body.old_password },
    newPassword: { value: req.body.password }
  };

  oktaClient.getUser(req.user.id).then(user => {

    user.changePassword(changePasswordCredentials).then(user => {
      return res.status(200).send({status: 'success', code: 'password_changed', message: 'Password changed successfully.'});

    }).catch((error) => {
      return res.status(400).send({status: 'fail', code: 'wrong_password', message: 'Wrong password.'});
    });

  }).catch((error) => {
    return res.status(400).send({status: 'fail', code: 'wrong_password', message: 'Wrong password.'});
  });