diff --git a/src/Core/IdentityServer/BaseRequestValidator.cs b/src/Core/IdentityServer/BaseRequestValidator.cs index 83d0b6baee..9b6da5e4ec 100644 --- a/src/Core/IdentityServer/BaseRequestValidator.cs +++ b/src/Core/IdentityServer/BaseRequestValidator.cs @@ -471,12 +471,18 @@ namespace Bit.Core.IdentityServer } } + protected async Task KnownDeviceAsync(User user, ValidatedTokenRequest request) => + (await GetKnownDeviceAsync(user, request)) != default; + + protected async Task GetKnownDeviceAsync(User user, ValidatedTokenRequest request) => + await _deviceRepository.GetByIdentifierAsync(GetDeviceFromRequest(request).Identifier, user.Id); + private async Task SaveDeviceAsync(User user, ValidatedTokenRequest request) { var device = GetDeviceFromRequest(request); if (device != null) { - var existingDevice = await _deviceRepository.GetByIdentifierAsync(device.Identifier, user.Id); + var existingDevice = await GetKnownDeviceAsync(user, request); if (existingDevice == null) { device.UserId = user.Id; diff --git a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs index 518f0848f4..57eb5bd7fd 100644 --- a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs +++ b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs @@ -58,9 +58,10 @@ namespace Bit.Core.IdentityServer } string bypassToken = null; - if (_captchaValidationService.RequireCaptchaValidation(_currentContext)) + var user = await _userManager.FindByEmailAsync(context.UserName.ToLowerInvariant()); + var unknownDevice = !await KnownDeviceAsync(user, context.Request); + if (!unknownDevice && _captchaValidationService.RequireCaptchaValidation(_currentContext)) { - var user = await _userManager.FindByEmailAsync(context.UserName.ToLowerInvariant()); var captchaResponse = context.Request.Raw["captchaResponse"]?.ToString(); if (string.IsNullOrWhiteSpace(captchaResponse))