mirror of
https://github.com/bitwarden/server
synced 2025-12-25 20:53:16 +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:
@@ -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
|
||||
|
||||
@@ -46,7 +46,8 @@ public class CustomTokenRequestValidator : BaseRequestValidator<CustomTokenReque
|
||||
IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder,
|
||||
IUpdateInstallationCommand updateInstallationCommand,
|
||||
IPolicyRequirementQuery policyRequirementQuery,
|
||||
IAuthRequestRepository authRequestRepository)
|
||||
IAuthRequestRepository authRequestRepository,
|
||||
IMailService mailService)
|
||||
: base(
|
||||
userManager,
|
||||
userService,
|
||||
@@ -63,7 +64,8 @@ public class CustomTokenRequestValidator : BaseRequestValidator<CustomTokenReque
|
||||
ssoConfigRepository,
|
||||
userDecryptionOptionsBuilder,
|
||||
policyRequirementQuery,
|
||||
authRequestRepository)
|
||||
authRequestRepository,
|
||||
mailService)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_updateInstallationCommand = updateInstallationCommand;
|
||||
|
||||
@@ -40,7 +40,8 @@ public class ResourceOwnerPasswordValidator : BaseRequestValidator<ResourceOwner
|
||||
IFeatureService featureService,
|
||||
ISsoConfigRepository ssoConfigRepository,
|
||||
IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder,
|
||||
IPolicyRequirementQuery policyRequirementQuery)
|
||||
IPolicyRequirementQuery policyRequirementQuery,
|
||||
IMailService mailService)
|
||||
: base(
|
||||
userManager,
|
||||
userService,
|
||||
@@ -57,7 +58,8 @@ public class ResourceOwnerPasswordValidator : BaseRequestValidator<ResourceOwner
|
||||
ssoConfigRepository,
|
||||
userDecryptionOptionsBuilder,
|
||||
policyRequirementQuery,
|
||||
authRequestRepository)
|
||||
authRequestRepository,
|
||||
mailService)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_currentContext = currentContext;
|
||||
|
||||
@@ -49,7 +49,8 @@ public class WebAuthnGrantValidator : BaseRequestValidator<ExtensionGrantValidat
|
||||
IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder,
|
||||
IAssertWebAuthnLoginCredentialCommand assertWebAuthnLoginCredentialCommand,
|
||||
IPolicyRequirementQuery policyRequirementQuery,
|
||||
IAuthRequestRepository authRequestRepository)
|
||||
IAuthRequestRepository authRequestRepository,
|
||||
IMailService mailService)
|
||||
: base(
|
||||
userManager,
|
||||
userService,
|
||||
@@ -66,7 +67,8 @@ public class WebAuthnGrantValidator : BaseRequestValidator<ExtensionGrantValidat
|
||||
ssoConfigRepository,
|
||||
userDecryptionOptionsBuilder,
|
||||
policyRequirementQuery,
|
||||
authRequestRepository)
|
||||
authRequestRepository,
|
||||
mailService)
|
||||
{
|
||||
_assertionOptionsDataProtector = assertionOptionsDataProtector;
|
||||
_assertWebAuthnLoginCredentialCommand = assertWebAuthnLoginCredentialCommand;
|
||||
|
||||
Reference in New Issue
Block a user