1
0
mirror of https://github.com/bitwarden/server synced 2025-12-24 04:03:25 +00:00

feat(2fa): [PM-24425] Add email on failed 2FA attempt

* Added email on failed 2FA attempt.

* Added tests.

* Adjusted email verbiage.

* Added feature flag.

* Undid accidental change.

* Undid unintentional change to clean up PR.

* Linting

* Added attempted method to email.

* Changes to email templates.

* Linting.

* Email format changes.

* Email formatting changes.
This commit is contained in:
Todd Martin
2025-08-11 16:39:43 -04:00
committed by GitHub
parent 5b67abba31
commit 3c5de319d1
13 changed files with 212 additions and 19 deletions

View File

@@ -36,6 +36,7 @@ public abstract class BaseRequestValidator<T> where T : class
private readonly GlobalSettings _globalSettings;
private readonly IUserRepository _userRepository;
private readonly IAuthRequestRepository _authRequestRepository;
private readonly IMailService _mailService;
protected ICurrentContext CurrentContext { get; }
protected IPolicyService PolicyService { get; }
@@ -61,7 +62,8 @@ public abstract class BaseRequestValidator<T> where T : class
ISsoConfigRepository ssoConfigRepository,
IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder,
IPolicyRequirementQuery policyRequirementQuery,
IAuthRequestRepository authRequestRepository
IAuthRequestRepository authRequestRepository,
IMailService mailService
)
{
_userManager = userManager;
@@ -80,6 +82,7 @@ public abstract class BaseRequestValidator<T> where T : class
UserDecryptionOptionsBuilder = userDecryptionOptionsBuilder;
PolicyRequirementQuery = policyRequirementQuery;
_authRequestRepository = authRequestRepository;
_mailService = mailService;
}
protected async Task ValidateAsync(T context, ValidatedTokenRequest request,
@@ -160,6 +163,7 @@ public abstract class BaseRequestValidator<T> where T : class
}
else
{
await SendFailedTwoFactorEmail(user, twoFactorProviderType);
await UpdateFailedAuthDetailsAsync(user);
await BuildErrorResultAsync("Two-step token is invalid. Try again.", true, context, user);
}
@@ -373,6 +377,14 @@ public abstract class BaseRequestValidator<T> where T : class
await _userRepository.ReplaceAsync(user);
}
private async Task SendFailedTwoFactorEmail(User user, TwoFactorProviderType failedAttemptType)
{
if (FeatureService.IsEnabled(FeatureFlagKeys.FailedTwoFactorEmail))
{
await _mailService.SendFailedTwoFactorAttemptEmailAsync(user.Email, failedAttemptType, DateTime.UtcNow, CurrentContext.IpAddress);
}
}
private async Task<MasterPasswordPolicyResponseModel> GetMasterPasswordPolicyAsync(User user)
{
// Check current context/cache to see if user is in any organizations, avoids extra DB call if not