mirror of
https://github.com/bitwarden/server.git
synced 2025-04-24 14:26:38 -05:00
Removed logic to enforce failed login attempts
This commit is contained in:
parent
be4e782370
commit
7027cc8bb6
@ -1,31 +0,0 @@
|
|||||||
{{#>FullHtmlLayout}}
|
|
||||||
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
Additional security has been placed on your Bitwarden account.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
We've detected several failed attempts to log into your Bitwarden account. Future login attempts for your account will be protected by a captcha.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
<b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">Account:</b> {{AffectedEmail}}<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
|
|
||||||
<b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">Date:</b> {{TheDate}} at {{TheTime}} {{TimeZone}}<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
|
|
||||||
<b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">IP Address:</b> {{IpAddress}}<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
If this was you, you can remove the captcha requirement by successfully logging in.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block last" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
If this was not you, don't worry. The login attempt was not successful and your account has been given additional protection.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
{{/FullHtmlLayout}}
|
|
@ -1,13 +0,0 @@
|
|||||||
{{#>BasicTextLayout}}
|
|
||||||
Additional security has been placed on your Bitwarden account.
|
|
||||||
|
|
||||||
We've detected several failed attempts to log into your Bitwarden account. Future login attempts for your account will be protected by a captcha.
|
|
||||||
|
|
||||||
Account: {{AffectedEmail}}
|
|
||||||
Date: {{TheDate}} at {{TheTime}} {{TimeZone}}
|
|
||||||
IP Address: {{IpAddress}}
|
|
||||||
|
|
||||||
If this was you, you can remove the captcha requirement by successfully logging in.
|
|
||||||
|
|
||||||
If this was not you, don't worry. The login attempt was not successful and your account has been given additional protection.
|
|
||||||
{{/BasicTextLayout}}
|
|
@ -1,31 +0,0 @@
|
|||||||
{{#>FullHtmlLayout}}
|
|
||||||
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
Additional security has been placed on your Bitwarden account.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
We've detected several failed attempts to log into your Bitwarden account. Future login attempts for your account will be protected by a captcha.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
<b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">Account:</b> {{AffectedEmail}}<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
|
|
||||||
<b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">Date:</b> {{TheDate}} at {{TheTime}} {{TimeZone}}<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
|
|
||||||
<b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">IP Address:</b> {{IpAddress}}<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
If this was you, you can remove the captcha requirement by successfully logging in. If you're having trouble with two step login, you can login using a <a target="_blank" clicktracking=off href="https://bitwarden.com/help/two-step-recovery-code/" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #175DDC; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; text-decoration: underline;">recovery code</a>.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
|
||||||
<td class="content-block last" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
|
|
||||||
If this was not you, you should <a target="_blank" clicktracking=off href="https://bitwarden.com/help/master-password/#change-master-password" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #175DDC; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; text-decoration: underline;">change your master password</a> immediately. You can view our tips for selecting a secure master password <a target="_blank" clicktracking=off href="https://bitwarden.com/blog/picking-the-right-password-for-your-password-manager/" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #175DDC; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; text-decoration: underline;">here</a>.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
{{/FullHtmlLayout}}
|
|
@ -1,13 +0,0 @@
|
|||||||
{{#>BasicTextLayout}}
|
|
||||||
Additional security has been placed on your Bitwarden account.
|
|
||||||
|
|
||||||
We've detected several failed attempts to log into your Bitwarden account. Future login attempts for your account will be protected by a captcha.
|
|
||||||
|
|
||||||
Account: {{AffectedEmail}}
|
|
||||||
Date: {{TheDate}} at {{TheTime}} {{TimeZone}}
|
|
||||||
IP Address: {{IpAddress}}
|
|
||||||
|
|
||||||
If this was you, you can remove the captcha requirement by successfully logging in. If you're having trouble with two step login, you can login using a recovery code (https://bitwarden.com/help/two-step-recovery-code/).
|
|
||||||
|
|
||||||
If this was not you, you should change your master password (https://bitwarden.com/help/master-password/#change-master-password) immediately. You can view our tips for selecting a secure master password here (https://bitwarden.com/blog/picking-the-right-password-for-your-password-manager/).
|
|
||||||
{{/BasicTextLayout}}
|
|
@ -87,8 +87,6 @@ public interface IMailService
|
|||||||
Task SendFamiliesForEnterpriseRedeemedEmailsAsync(string familyUserEmail, string sponsorEmail);
|
Task SendFamiliesForEnterpriseRedeemedEmailsAsync(string familyUserEmail, string sponsorEmail);
|
||||||
Task SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync(string email, DateTime expirationDate);
|
Task SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync(string email, DateTime expirationDate);
|
||||||
Task SendOTPEmailAsync(string email, string token);
|
Task SendOTPEmailAsync(string email, string token);
|
||||||
Task SendFailedLoginAttemptsEmailAsync(string email, DateTime utcNow, string ip);
|
|
||||||
Task SendFailedTwoFactorAttemptsEmailAsync(string email, DateTime utcNow, string ip);
|
|
||||||
Task SendUnverifiedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName);
|
Task SendUnverifiedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName);
|
||||||
Task SendUnclaimedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName);
|
Task SendUnclaimedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName);
|
||||||
Task SendSecretsManagerMaxSeatLimitReachedEmailAsync(Organization organization, int maxSeatCount, IEnumerable<string> ownerEmails);
|
Task SendSecretsManagerMaxSeatLimitReachedEmailAsync(Organization organization, int maxSeatCount, IEnumerable<string> ownerEmails);
|
||||||
|
@ -1135,40 +1135,6 @@ public class HandlebarsMailService : IMailService
|
|||||||
await _mailDeliveryService.SendEmailAsync(message);
|
await _mailDeliveryService.SendEmailAsync(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendFailedLoginAttemptsEmailAsync(string email, DateTime utcNow, string ip)
|
|
||||||
{
|
|
||||||
var message = CreateDefaultMessage("Failed login attempts detected", email);
|
|
||||||
var model = new FailedAuthAttemptsModel()
|
|
||||||
{
|
|
||||||
TheDate = utcNow.ToLongDateString(),
|
|
||||||
TheTime = utcNow.ToShortTimeString(),
|
|
||||||
TimeZone = _utcTimeZoneDisplay,
|
|
||||||
IpAddress = ip,
|
|
||||||
AffectedEmail = email
|
|
||||||
|
|
||||||
};
|
|
||||||
await AddMessageContentAsync(message, "Auth.FailedLoginAttempts", model);
|
|
||||||
message.Category = "FailedLoginAttempts";
|
|
||||||
await _mailDeliveryService.SendEmailAsync(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SendFailedTwoFactorAttemptsEmailAsync(string email, DateTime utcNow, string ip)
|
|
||||||
{
|
|
||||||
var message = CreateDefaultMessage("Failed login attempts detected", email);
|
|
||||||
var model = new FailedAuthAttemptsModel()
|
|
||||||
{
|
|
||||||
TheDate = utcNow.ToLongDateString(),
|
|
||||||
TheTime = utcNow.ToShortTimeString(),
|
|
||||||
TimeZone = _utcTimeZoneDisplay,
|
|
||||||
IpAddress = ip,
|
|
||||||
AffectedEmail = email
|
|
||||||
|
|
||||||
};
|
|
||||||
await AddMessageContentAsync(message, "Auth.FailedTwoFactorAttempts", model);
|
|
||||||
message.Category = "FailedTwoFactorAttempts";
|
|
||||||
await _mailDeliveryService.SendEmailAsync(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SendUnverifiedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName)
|
public async Task SendUnverifiedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName)
|
||||||
{
|
{
|
||||||
var message = CreateDefaultMessage("Domain not verified", adminEmails);
|
var message = CreateDefaultMessage("Domain not verified", adminEmails);
|
||||||
|
@ -267,16 +267,6 @@ public class NoopMailService : IMailService
|
|||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendFailedLoginAttemptsEmailAsync(string email, DateTime utcNow, string ip)
|
|
||||||
{
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task SendFailedTwoFactorAttemptsEmailAsync(string email, DateTime utcNow, string ip)
|
|
||||||
{
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task SendUnverifiedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName)
|
public Task SendUnverifiedOrganizationDomainEmailAsync(IEnumerable<string> adminEmails, string organizationId, string domainName)
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
|
@ -372,32 +372,6 @@ public abstract class BaseRequestValidator<T> where T : class
|
|||||||
user.FailedLoginCount = ++user.FailedLoginCount;
|
user.FailedLoginCount = ++user.FailedLoginCount;
|
||||||
user.LastFailedLoginDate = user.RevisionDate = utcNow;
|
user.LastFailedLoginDate = user.RevisionDate = utcNow;
|
||||||
await _userRepository.ReplaceAsync(user);
|
await _userRepository.ReplaceAsync(user);
|
||||||
|
|
||||||
if (ValidateFailedAuthEmailConditions(unknownDevice, user))
|
|
||||||
{
|
|
||||||
if (twoFactorInvalid)
|
|
||||||
{
|
|
||||||
await _mailService.SendFailedTwoFactorAttemptsEmailAsync(user.Email, utcNow, CurrentContext.IpAddress);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await _mailService.SendFailedLoginAttemptsEmailAsync(user.Email, utcNow, CurrentContext.IpAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// checks to see if a user is trying to log into a new device
|
|
||||||
/// and has reached the maximum number of failed login attempts.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="unknownDevice">boolean</param>
|
|
||||||
/// <param name="user">current user</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool ValidateFailedAuthEmailConditions(bool unknownDevice, User user)
|
|
||||||
{
|
|
||||||
var failedLoginCeiling = _globalSettings.Captcha.MaximumFailedLoginAttempts;
|
|
||||||
var failedLoginCount = user?.FailedLoginCount ?? 0;
|
|
||||||
return unknownDevice && failedLoginCeiling > 0 && failedLoginCount == failedLoginCeiling;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<MasterPasswordPolicyResponseModel> GetMasterPasswordPolicyAsync(User user)
|
private async Task<MasterPasswordPolicyResponseModel> GetMasterPasswordPolicyAsync(User user)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Amazon.Runtime.Credentials.Internal;
|
using AutoFixture.Xunit2;
|
||||||
using AutoFixture.Xunit2;
|
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Tokens;
|
using Bit.Core.Tokens;
|
||||||
|
@ -106,43 +106,6 @@ public class BaseRequestValidatorTests
|
|||||||
Assert.Equal("Username or password is incorrect. Try again.", errorResponse.Message);
|
Assert.Equal("Username or password is incorrect. Try again.", errorResponse.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Logic path
|
|
||||||
* ValidateAsync -> UpdateFailedAuthDetailsAsync -> _mailService.SendFailedLoginAttemptsEmailAsync
|
|
||||||
* |-> BuildErrorResultAsync -> _eventService.LogUserEventAsync
|
|
||||||
* |-> SetErrorResult
|
|
||||||
*/
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task ValidateAsync_ContextNotValid_MaxAttemptLogin_ShouldSendEmail(
|
|
||||||
[AuthFixtures.ValidatedTokenRequest] ValidatedTokenRequest tokenRequest,
|
|
||||||
CustomValidatorRequestContext requestContext,
|
|
||||||
GrantValidationResult grantResult)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
|
||||||
|
|
||||||
// This needs to be n-1 of the max failed login attempts
|
|
||||||
context.CustomValidatorRequestContext.User.FailedLoginCount = 2;
|
|
||||||
context.CustomValidatorRequestContext.KnownDevice = false;
|
|
||||||
|
|
||||||
_globalSettings.Captcha.Returns(
|
|
||||||
new GlobalSettings.CaptchaSettings
|
|
||||||
{
|
|
||||||
MaximumFailedLoginAttempts = 3
|
|
||||||
});
|
|
||||||
_sut.isValid = false;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await _sut.ValidateAsync(context);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
await _mailService.Received(1)
|
|
||||||
.SendFailedLoginAttemptsEmailAsync(
|
|
||||||
Arg.Any<string>(), Arg.Any<DateTime>(), Arg.Any<string>());
|
|
||||||
Assert.True(context.GrantResult.IsError);
|
|
||||||
var errorResponse = (ErrorResponseModel)context.GrantResult.CustomResponse["ErrorModel"];
|
|
||||||
Assert.Equal("Username or password is incorrect. Try again.", errorResponse.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task ValidateAsync_DeviceNotValidated_ShouldLogError(
|
public async Task ValidateAsync_DeviceNotValidated_ShouldLogError(
|
||||||
[AuthFixtures.ValidatedTokenRequest] ValidatedTokenRequest tokenRequest,
|
[AuthFixtures.ValidatedTokenRequest] ValidatedTokenRequest tokenRequest,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using AspNetCoreRateLimit;
|
using AspNetCoreRateLimit;
|
||||||
using Bit.Core.Auth.Services;
|
|
||||||
using Bit.Core.Billing.Services;
|
using Bit.Core.Billing.Services;
|
||||||
using Bit.Core.Platform.Push;
|
using Bit.Core.Platform.Push;
|
||||||
using Bit.Core.Platform.Push.Internal;
|
using Bit.Core.Platform.Push.Internal;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user