public async Task SendForgetMails() { // create a user : var user = RandomObjects.RandomUser(new string[] { }).Generate(); var username = user.UserName; var password = "******"; var httpClient = factory.CreateSecureClient(); var token = await this._CreateUserAndGetToken(httpClient, user, password); var bindings = new ForgotPasswordBindings { UserName = user.UserName }; var authrequest = await httpClient.PostAsync($"{TestStartup.PATH}/account/forgot", new JsonContent(bindings)); var authcontent = await authrequest.Content.ReadAsStringAsync(); var authresult = JsonConvert.DeserializeObject <ApiModel <AccountDto> >(authcontent); var authuser = authresult.Value; Assert.Null(authuser); // we expect no informations; Assert.True(authrequest.IsSuccessStatusCode, authrequest.ReasonPhrase ?? ""); // emails : var recievedEmails = this.factory.EmailSender.Flush(); // we expect to have recieved a message : Assert.NotEmpty(recievedEmails); var message = recievedEmails.First().message; // find the link in the email = var regex = new Regex("href=[\"'].*action=(.+)(&[^\"'])?[\"']", RegexOptions.IgnoreCase); Assert.Matches(regex, message); var encodedlink = regex.Match(message).Groups[1].Value; var actionLink = WebUtility.UrlDecode(encodedlink); // we expect the message to have a link to the reset page: var resetroute = "account/reset"; Assert.Matches(new Regex(resetroute, RegexOptions.IgnoreCase), actionLink); }
// [ValidateAntiForgeryToken] public async Task <IActionResult> ForgotPassword([FromBody] ForgotPasswordBindings bindings, [FromQuery] string resetFormURL = "") { // TODO: validate model here or with a filter ? // TODO: do we really need the email confirmation ? var user = await _userManager.FindByNameAsync(bindings.UserName); if (user == null) // || !(await _userManager.IsEmailConfirmedAsync(user)) { _logger.LogWarning("Invalid forgot password attempt."); // Don't reveal that the user does not exist or is not confirmed return(Ok(ApiModel.AsSuccess <UserDto>(null))); } // For more information on how to enable account confirmation and password reset please // visit https://go.microsoft.com/fwlink/?LinkID=532713 var code = await _userManager.GeneratePasswordResetTokenAsync(user); var callbackUrl = Url.Action( action: nameof(AccountController.ResetPassword), controller: nameof(AccountController).ToLowerInvariant().Replace("controller", ""), values: new { id = user.Id, code = code }, protocol: Request.Scheme, host: Request.Host.Value); var encodedCallback = WebUtility.UrlEncode(callbackUrl); var sendResult = await _emailSender.SendEmailAsync(user.Email, "Reset Password", $"Please reset your password by clicking here: <a href='{resetFormURL}?action={encodedCallback}'>link</a>"); if (sendResult) { return(Ok(ApiModel.AsSuccess <UserDto>(null))); } else { return(Ok(ApiModel.AsError <UserDto>(null, "impossible to send reset password link by email"))); } }
public async Task ResetsPassword() { // create a user : var user = RandomObjects.RandomUser(new string[] { }).Generate(); var username = user.UserName; var oldpassword = $"username-Pa$$w0rd-old"; var httpClient = factory.CreateSecureClient(); var token = await this._CreateUserAndGetToken(httpClient, user, oldpassword); // forgot his email var bindings = new ForgotPasswordBindings { UserName = username }; var forgotrequest = await httpClient.PostAsync($"{TestStartup.PATH}/account/forgot", new JsonContent(bindings)); var forgotcontent = await forgotrequest.Content.ReadAsStringAsync(); var forgotresult = JsonConvert.DeserializeObject <ApiModel <AccountDto> >(forgotcontent); // emails : var recievedEmails = this.factory.EmailSender.Flush(); var message = recievedEmails.First().message; // find the link in the email = var regex = new Regex("href=[\"'].*action=(.+)(&[^\"'])?[\"']", RegexOptions.IgnoreCase); var encodedlink = regex.Match(message).Groups[1].Value; var actionLink = WebUtility.UrlDecode(encodedlink); // // finds the action = // var uri = new Uri(actionLink); // var action = HttpUtility.ParseQueryString(uri.Query).Get("action"); var newpassword = $"username-Pa$$w0rd-reset"; var encodedPassword = WebUtility.UrlEncode(newpassword); // request rest var resetrequest = await httpClient.GetAsync($"{actionLink}&password={encodedPassword}"); var resetcontent = await resetrequest.Content.ReadAsStringAsync(); var resetresult = JsonConvert.DeserializeObject <ApiModel <AccountDto> >(resetcontent); Assert.True(resetrequest.IsSuccessStatusCode, resetrequest.ReasonPhrase ?? ""); Assert.True(resetresult.Result.Success, resetresult.Result.Errors?.FirstOrDefault().Value?.FirstOrDefault() ?? ""); Assert.Empty(resetresult.Result.Errors); var verifyNewbindings = new AuthenticateBindings { UserName = user.UserName, Password = newpassword }; var verifyNewresponse = await httpClient.PostAsync($"{TestStartup.PATH}/account/authenticate", new JsonContent(verifyNewbindings)); var verifyNewcontent = await verifyNewresponse.Content.ReadAsStringAsync(); Assert.True(verifyNewresponse.IsSuccessStatusCode, verifyNewresponse.ReasonPhrase ?? ""); var verifyNewResult = JsonConvert.DeserializeObject <ApiModel <AccountDto> >(verifyNewcontent); Assert.True(verifyNewResult.Result.Success, verifyNewResult.Result.Errors?.FirstOrDefault().Value?.FirstOrDefault() ?? ""); Assert.Empty(verifyNewResult.Result.Errors); var resultUser = verifyNewResult.Value; Assert.NotNull(resultUser); Assert.True(resultUser.IsAuthenticated); Assert.NotNull(resultUser.Token); Assert.Equal(user.UserName, resultUser.UserName); Assert.NotEqual("", resultUser.Token); var verifyOldbindings = new AuthenticateBindings { UserName = user.UserName, Password = oldpassword }; var verifyOldresponse = await httpClient.PostAsync($"{TestStartup.PATH}/account/authenticate", new JsonContent(verifyOldbindings)); var verifyOldcontent = await verifyOldresponse.Content.ReadAsStringAsync(); Assert.True(verifyOldresponse.IsSuccessStatusCode, verifyOldresponse.ReasonPhrase ?? ""); var verifyOldResult = JsonConvert.DeserializeObject <ApiModel <AccountDto> >(verifyOldcontent); Assert.False(verifyOldResult.Result.Success); Assert.NotEmpty(verifyOldResult.Result.Errors); // var resultOldUser = verifyOldResult.Value; // Assert.Null(resultOldUser); // Assert.False(resultOldUser.IsAuthenticated); // Assert.Null(resultOldUser.Token); }