/// <summary>
        /// reseting password step
        /// </summary>
        /// <param name="appUser"></param>
        /// <param name="newPassword"></param>
        /// <param name="confirmNewPassword"></param>
        /// <returns></returns>
        public async Task <ForgotPasswordModel> ResetPasswordAsync(UserApplicationSession appUser, string newPassword, string confirmNewPassword)
        {
            var model = new ForgotPasswordModel {
                ForgotPasswordStep = ForgotPasswordStep.ResetPassword
            };

            if (newPassword != confirmNewPassword)
            {
                throw new PasswordRecoverException(model.ForgotPasswordStep, "New password must match with New confirm password.");
            }

            var user = await _userService.GetUserAsync(appUser.UserId);

            var identity = await _userService.ResetPassword(user.Id, user.PasswordRecoveryToken, newPassword);

            if (!identity.Errors.Any())
            {
                user.PasswordRecoveryToken = string.Empty;
                await _userService.UpdateUserAsync(user.Id, user);

                return(model);
            }

            ThrowPasswordRecoverException(identity.Errors, ForgotPasswordStep.ResetPassword);

            return(model);
        }
        /// <summary>
        /// validate security code before moving to next step
        /// </summary>
        /// <param name="appUser"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public async Task <ForgotPasswordModel> VerifyCodeAsync(UserApplicationSession appUser, string code)
        {
            var model = new ForgotPasswordModel {
                ForgotPasswordStep = ForgotPasswordStep.VerifySecurityCode
            };

            // check for empty security code
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new PasswordRecoverException(model.ForgotPasswordStep, "Security code is a required field.");
            }

            if (await _phoneService.IsValidSecurityCodeAsync(appUser.UserId, code))
            {
                await _phoneService.ClearUserPhoneSecurityCodeAsync(appUser.UserId);

                // set next step to verify answers
                // TODO bypass security questions/answers for now
                // model.ForgotPasswordStep = ForgotPasswordStep.VerifySecurityAnswers;
                model.ForgotPasswordStep = ForgotPasswordStep.ResetPassword;
            }
            else
            {
                throw new PasswordRecoverException(model.ForgotPasswordStep, "Provided code is invalid.");
            }

            return(model);
        }
Esempio n. 3
0
        public void ValifyCode_must_valify_invalid_code_and_add_error_once_empty_check_is_passed()
        {
            CreateNewMockServices();
            var userId       = "UserId";
            var securityCode = "SecurityCode";
            var appUser      = new UserApplicationSession
            {
                UserId = userId,
                PasswordRecoveryToken = "RecoveryToken"
            };

            _phoneServiceMock.Setup(c => c.IsValidSecurityCodeAsync(userId, securityCode)).ReturnsAsync(false);

            var exceptionObj = Assert.ThrowsAsync <PasswordRecoverException>(async() => await GetPasswordRecoverService().VerifyCodeAsync(appUser, "NotValidCode"));

            Assert.NotNull(exceptionObj.Result);
            Assert.NotEmpty(exceptionObj.Result.Message);
            Assert.Equal(exceptionObj.Result.ForgotPasswordStep, ForgotPasswordStep.VerifySecurityCode);
        }
Esempio n. 4
0
        public async Task ValifyCode_must__move_to_next_step__checks_are_passed()
        {
            CreateNewMockServices();
            var userId       = "UserId";
            var securityCode = "SecurityCode";
            var appUser      = new UserApplicationSession
            {
                UserId = userId,
                PasswordRecoveryToken = "RecoveryToken"
            };

            _phoneServiceMock.Setup(c => c.IsValidSecurityCodeAsync(userId, securityCode)).ReturnsAsync(true);
            _phoneServiceMock.Setup(c => c.ClearUserPhoneSecurityCodeAsync(It.IsAny <string>())).Returns(Task.Delay(0));

            var model = await GetPasswordRecoverService().VerifyCodeAsync(appUser, securityCode);

            Assert.False(model.HasError);
            Assert.Null(model.ErrorMessage);
            Assert.Equal(model.ForgotPasswordStep, ForgotPasswordStep.ResetPassword);
        }
        public async Task <ActionResult> Index(ForgotPasswordModel model)
        {
            if (Request.HttpMethod != "POST")
            {
                return(View(model));
            }

            try
            {
                var context = HttpContext.GetOwinContext().GetAutofacLifetimeScope();
                var passwordRecoverService = context.Resolve <IPasswordRecoverService>();

                if (!string.IsNullOrEmpty(Request.Form.Get("submit.VerifyUser")))
                {
                    // validate user and phone number
                    model = await passwordRecoverService.ValidateUserInfoAsync(Request.Form.Get("username"), Request.Form.Get("phonenumber"));

                    // save user id and password recovery token to session for next step to identify if it is the same session
                    Session["appUser"] = new UserApplicationSession
                    {
                        UserId = model.UserId
                    };

                    // set this password recovery session for 10 minutes after the security code is sent
                    Session.Timeout = 10;
                }
                else if (!string.IsNullOrEmpty(Request.Form.Get("submit.VerifySecurityCode")))
                {
                    // session must not be new
                    if (!IsNewSession(model) && Session["appUser"] != null)
                    {
                        // verify code
                        var appUser = Session["appUser"] as UserApplicationSession;
                        model = await passwordRecoverService.VerifyCodeAsync(appUser, Request.Form.Get("code"));

                        appUser.PasswordRecoveryToken = model.PasswordRecoveryToken;
                        Session["appUser"]            = appUser;
                    }
                }
                else if (!string.IsNullOrEmpty(Request.Form.Get("submit.VerifySecurityAnswers")))
                {
                    // session must not be new
                    if (!IsNewSession(model))
                    {
                        var appUser = Session["appUser"] as UserApplicationSession;
                        model = passwordRecoverService.VerifySecurityAnswers(appUser?.UserId, new List <string>());
                    }
                }
                else if (!string.IsNullOrEmpty(Request.Form.Get("submit.ResetPassword")))
                {
                    // session must not be new
                    if (!IsNewSession(model))
                    {
                        // reset user password
                        var appUser = Session["appUser"] as UserApplicationSession;
                        model = await passwordRecoverService.ResetPasswordAsync(appUser, Request.Form.Get("newpassword"), Request.Form.Get("confirmnewpassword"));

                        Session.Clear();
                        return(RedirectPermanent(Request.QueryString["ReturnUrl"]));
                    }
                }
            }
            catch (PasswordRecoverException ex)
            {
                // log error to database
                model.HasError           = true;
                model.ErrorMessage       = ex.Message;
                model.ForgotPasswordStep = ex.ForgotPasswordStep;
            }

            return(View(model));
        }