///<inheritdoc/> public async Task <IdentityResult> ValidateAsync( UserManager <TUser> manager, TUser user, string password) { var(pwned, count) = await _passwordService.IsPasswordPwnedAsync(password); if (pwned) { return(await Task.FromResult(IdentityResult.Failed(new IdentityError { Code = "PwnedPassword", Description = $"The password you chose has appeared in a data breach {count} times. It is recommended that you change your password immediately" })).ConfigureAwait(false)); } return(await Task.FromResult(IdentityResult.Success).ConfigureAwait(false)); }
public async Task <IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { var(pwned, count) = await _passwordService.IsPasswordPwnedAsync(Input.Password); // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, set lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure : true); if (result.Succeeded) { _logger.LogInformation("User logged in."); if (pwned) { _logger.LogInformation("User's password has been pwned"); return(RedirectToPage("./PwnedPassword", new { ReturnUrl = returnUrl, Count = count })); } return(LocalRedirect(returnUrl)); } if (result.RequiresTwoFactor) { return(RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, Input.RememberMe })); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return(RedirectToPage("./Lockout")); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return(Page()); } } // If we got this far, something failed, redisplay form return(Page()); }
public async Task <IActionResult> Register([BindRequired, FromBody, FromForm] RegisterModel model) { var(pwned, count) = await pwnedPasswordService.IsPasswordPwnedAsync(model.Password).ConfigureAwait(false); if (pwned) { return(Ok(new RegisterResults { IsPwned = true, ErrorMessage = string.Format(PwnedPasswordMessage, count), })); } // See if we're already registered. var emailLower = model.Email.ToLowerInvariant(); var existingUser = await userManager.FindByEmailAsync(emailLower).ConfigureAwait(false); if (existingUser != null) { return(Ok(new RegisterResults { ErrorMessage = "You're already registered.", IsAlreadyRegistered = true, NeedsConfirmation = !existingUser.EmailConfirmed })); } // Reject throwaway emails. We need to do this because this helps prevent upvote/downvote fraud. var throwawayDomainsDoc = await DbSession.LoadOptionalAsync <ThrowawayEmailDomains>("ThrowawayEmailDomains/1"); var attemptedDomain = emailLower.Substring(emailLower.LastIndexOf('@') + 1); var isThrowawayEmail = throwawayDomainsDoc?.Domains.Contains(attemptedDomain, StringComparison.InvariantCultureIgnoreCase); if (isThrowawayEmail == true) { logger.LogInformation("Rejected attempt to register with a throwaway email address {email}", emailLower); return(Ok(new RegisterResults { ErrorMessage = "Throwaway email accounts are unable to register with Chavah. Please use a valid email address. We'll never send spam nor share your email with anyone." })); } // The user doesn't exist yet. Try and register him. var user = new AppUser { Id = $"AppUsers/{emailLower}", UserName = model.Email, Email = model.Email, LastSeen = DateTime.UtcNow, RegistrationDate = DateTime.UtcNow }; var createUserResult = await userManager.CreateAsync(user, model.Password).ConfigureAwait(false); if (createUserResult.Succeeded) { // Send confirmation email. var confirmToken = new AccountToken //await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); { Id = $"AccountTokens/Confirm/{emailLower}", ApplicationUserId = user.Id, Token = Guid.NewGuid().ToString() }; await DbSession.StoreAsync(confirmToken); DbSession.SetRavenExpiration(confirmToken, DateTime.UtcNow.AddDays(14)); emailSender.QueueConfirmEmail(model.Email, confirmToken.Token, appOptions); logger.LogInformation("Sending new user confirmation email to {email} with confirm token {token}", model.Email, confirmToken.Token); return(Ok(new RegisterResults { Success = true })); } else { // Registration failed. logger.LogWarning("Register new user failed with {result}", createUserResult); return(Ok(new RegisterResults { ErrorMessage = string.Join(", ", createUserResult.Errors.Select(s => s.Description)) })); } }