3
votes

On my MVC and web API projects I'm using ASP.NET Identity for the Login.

This is my Forgot Password function on the AccountController:

    [HttpPost]
    [AllowAnonymous]
    [Route("ForgotPassword")]
    public async Task<IHttpActionResult> ForgotPassword(ForgotPasswordViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindByNameAsync(model.Email);

            if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
            {
                return Ok();
            }

            try
            {
                var code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
                var callbackUrl = new Uri(@"http://MyProject/ResetPassword?userid=" + user.Id + "&code=" + code);

                string subject = "Reset Password";
                string body = "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>";
                SendEmail(user.Email, callbackUrl, subject, body);
            }

            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }

            return Ok();
        }

        // If we got this far, something failed, redisplay form
        return BadRequest(ModelState);
    }

I'm getting the confirmation email, I am successfully redirected to the Reset Password View but then I'm not sure how to proceed.

How do I reset a password with the following parameters: NewPssword, ConfirmPassword and Code?

Sorry if it's a stupid question but i'm a little bit confused.

I tried to call the SetPassword method but got a 401 error.

    self.resetPassword = function () {
    var data = {
        Email: self.loginUserName(),
        NewPassword: self.registerPassword(),
        ConfirmPassword: self.registerPassword2()
    }
    $.ajax({
        type: 'POST',
        url: '../API/Account/SetPassword',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(data),
        complete: showError
    });
}

And the setPassword function:

// POST api/Account/SetPassword
    [Route("SetPassword")]
    public async Task<IHttpActionResult> SetPassword(SetPasswordBindingModel model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);

        if (!result.Succeeded)
        {
            return GetErrorResult(result);
        }

        return Ok();
    }

Currently the process is a s follow:

  1. user clicks on "Forgot Password" link.
  2. He is redirected to the Forgot Password View that has one field: Email.
  3. The user provides his email address and submit the form.
  4. the request is being sent to the Forgot Password function.
  5. An email with a unique code is being sent to the client.

Till here I wrote the code and got it to work but I'm not sure how to implement the next steps:

  1. The user is redirected the the Reset Password View that has 3 fields: Email, New Password and Confirm Password.
  2. The user submits the form, a request is being sent to the SetPassword function (?) with the unique code and the user's password is being reset successfully.

Thanks in advance.

1

1 Answers

4
votes

Sounds like your SetPassword api should call

var user = await UserManager.FindByNameAsync(model.Email);
if (user != null)
{
    var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.NewPassword);
    if (result.Succeeded)
    {
          //handle success
    }
}
//handle invalid