public async Task <bool> IsChangePasswordCooldownInEffect(AuthenticationUser user) { if (user.LastPasswordChangeTimestamp.HasValue) { var lastPasswordChangeTimestamp = user.LastPasswordChangeTimestamp.Value; var hoursElapsedSinceLastPasswordChange = (DateTime.UtcNow - lastPasswordChangeTimestamp).TotalHours; var passwordChangeCooldownInHours = await _applicationSettingsRepository.GetValue(PasswordChangeCooldownInHoursKey, DefaultPasswordChangeCooldownInHours); if (hoursElapsedSinceLastPasswordChange < passwordChangeCooldownInHours) { return(true); } } return(false); }
public async Task <IHttpActionResult> PostRequestPasswordResetAsync([FromBody] string login) { try { var matchingSetting = await _applicationSettingsRepository.GetValue(IsPasswordRecoveryEnabledKey, false); if (!matchingSetting) { await _log.LogInformation(WebApiConfig.LogSourceUsersPasswordReset, "Password recovery is disabled"); return(Conflict()); } var instanceSettings = await _settingsRepository.GetInstanceSettingsAsync(); if (instanceSettings?.EmailSettingsDeserialized?.HostName == null) { await _log.LogInformation(WebApiConfig.LogSourceUsersPasswordReset, "Invalid instance email settings"); return(Conflict()); } var user = await _userRepository.GetUserByLoginAsync(login); if (user == null) { await _log.LogInformation(WebApiConfig.LogSourceUsersPasswordReset, "The user doesn't exist"); return(Conflict()); } bool passwordResetAllowed = await _userRepository.CanUserResetPasswordAsync(login); if (!passwordResetAllowed) { await _log.LogInformation(WebApiConfig.LogSourceUsersPasswordReset, "The user isn't allowed to reset the password"); return(Conflict()); } bool passwordRequestLimitExceeded = await _userRepository.HasUserExceededPasswordRequestLimitAsync(login); if (passwordRequestLimitExceeded) { await _log.LogInformation(WebApiConfig.LogSourceUsersPasswordReset, "Exceeded requests limit"); return(Conflict()); } bool passwordResetCooldownInEffect = await _authenticationRepository.IsChangePasswordCooldownInEffect(user); if (passwordResetCooldownInEffect) { await _log.LogInformation(WebApiConfig.LogSourceUsersPasswordReset, "Cooldown is in effect"); return(Conflict()); } var recoveryToken = SystemEncryptions.CreateCryptographicallySecureGuid(); var recoveryUrl = new Uri(Request.RequestUri, ServiceConstants.ForgotPasswordResetUrl + "/" + recoveryToken).AbsoluteUri; // decrypt the password to be set in mailBee instanceSettings.EmailSettingsDeserialized.DecryptPassword(); _emailHelper.Initialize(instanceSettings.EmailSettingsDeserialized); _emailHelper.SendEmail(user.Email, "Reset Password", $@" <html> <div>Hello {user.DisplayName}.</div> <br> <div>We have received a request to reset your password.</div> <br> <div>To confirm this password reset, visit the following link:</div> <a href='{recoveryUrl}'>Reset password</a> <br><br> <div>If you did not make this request, you can ignore this email, and no changes will be made.</div> <br> <div>If you have any questions, please contact your administrator. </div> </html>"); await _userRepository.UpdatePasswordRecoveryTokensAsync(login, recoveryToken); return(Ok()); } catch (EmailException ex) { await _log.LogError(WebApiConfig.LogSourceUsersPasswordReset, ex); return(Conflict()); } catch (Exception ex) { await _log.LogError(WebApiConfig.LogSourceUsersPasswordReset, ex); return(InternalServerError()); } }