Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
1c4fd6c
feat(auth-validator): [PM-22975] Client Version Validator - initial iโ€ฆ
Patrick-Pimentel-Bitwarden Nov 17, 2025
22e9e5b
mend
Patrick-Pimentel-Bitwarden Nov 17, 2025
1af2fba
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Nov 17, 2025
47a26bb
fix(auth-validator): [PM-22975] Client Version Validator - Minor toucโ€ฆ
Patrick-Pimentel-Bitwarden Nov 20, 2025
a82b31c
fix(auth-validator): [PM-22975] Client Version Validator - Fixing somโ€ฆ
Patrick-Pimentel-Bitwarden Nov 20, 2025
7d71ee2
fix(auth-validator): [PM-22975] Client Version Validator - Finished fโ€ฆ
Patrick-Pimentel-Bitwarden Nov 20, 2025
851f963
test(auth-validator): [PM-22975] Client Version Validator - Fixed tesโ€ฆ
Patrick-Pimentel-Bitwarden Nov 20, 2025
756ae5e
fix(auth-validator): [PM-22975] Client Version Validator - Fixed namiโ€ฆ
Patrick-Pimentel-Bitwarden Nov 20, 2025
7874ec7
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Nov 20, 2025
91af02b
test(auth-validator): [PM-22975] Client Version Validator - Fixed tests.
Patrick-Pimentel-Bitwarden Nov 20, 2025
59d9d7b
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Nov 21, 2025
7897485
fix(auth-validator): [PM-22975] Client Version Validator - Renamed vaโ€ฆ
Patrick-Pimentel-Bitwarden Nov 21, 2025
d0c5333
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Nov 24, 2025
e46425d
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Nov 24, 2025
d69842d
fix(auth-validator): [PM-22975] Client Version Validator - Added headโ€ฆ
Patrick-Pimentel-Bitwarden Nov 24, 2025
1681703
fix(auth-validator): [PM-22975] Client Version Validator - Trying to โ€ฆ
Patrick-Pimentel-Bitwarden Nov 24, 2025
cb146fc
fix(auth-validator): [PM-22975] Client Version Validator - Fixed tests
Patrick-Pimentel-Bitwarden Nov 24, 2025
e74682b
Merge remote-tracking branch 'origin' into auth/pm-22975/client-versiโ€ฆ
Patrick-Pimentel-Bitwarden Nov 26, 2025
53e6509
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 1, 2025
b3b1b9b
fix(auth-validator): [PM-22975] Client Version Validator - misc changโ€ฆ
Patrick-Pimentel-Bitwarden Dec 1, 2025
8f89694
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 2, 2025
8b8694e
test(auth-validator): [PM-22975] Client Version Validator - WIP changes.
Patrick-Pimentel-Bitwarden Dec 2, 2025
ed89cf8
fix(auth-validator): [PM-22975] Client Version Validator - Made enougโ€ฆ
Patrick-Pimentel-Bitwarden Dec 2, 2025
6696104
fix(auth-validator): [PM-22975] Client Version Validator - Fixed moreโ€ฆ
Patrick-Pimentel-Bitwarden Dec 2, 2025
aa4f8ab
test(auth-validator): [PM-22975] Client Version Validator - Fixed theโ€ฆ
Patrick-Pimentel-Bitwarden Dec 2, 2025
86bca81
fix(auth-validator): [PM-22975] Client Version Validator - Changed soโ€ฆ
Patrick-Pimentel-Bitwarden Dec 2, 2025
c1bc10b
fix(auth-validator): [PM-22975] Client Version Validator - Removed unโ€ฆ
Patrick-Pimentel-Bitwarden Dec 2, 2025
753670d
fix(auth-validator): [PM-22975] Client Version Validator - Took in feโ€ฆ
Patrick-Pimentel-Bitwarden Dec 3, 2025
544965e
test(auth-validator): [PM-22975] Client Version Validator - Fixed test
Patrick-Pimentel-Bitwarden Dec 3, 2025
f719763
fix(auth-validator): [PM-22975] Client Version Validator - Took in teโ€ฆ
Patrick-Pimentel-Bitwarden Dec 3, 2025
cff2f5d
fix(auth-validator): [PM-22975] Client Version Validator - Added moreโ€ฆ
Patrick-Pimentel-Bitwarden Dec 4, 2025
2ed458d
fix(auth-validator): [PM-22975] Client Version Validator - Removed onโ€ฆ
Patrick-Pimentel-Bitwarden Dec 4, 2025
d706796
fix(auth-validator): [PM-22975] Client Version Validator - Updated vaโ€ฆ
Patrick-Pimentel-Bitwarden Dec 4, 2025
2264056
fix(auth-validator): [PM-22975] Client Version Validator - Updated wiโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
55bfb71
test(auth-validator): [PM-22975] Client Version Validator - Added encโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
36e7b1c
test(auth-validator): [PM-22975] Client Version Validator - Added stuโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
1f8be3b
docs(auth-validator): [PM-22975] Client Version Validator - Updated cโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
998aeb1
fix(auth-validator): [PM-22975] Client Version Validator - Not havingโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
27c9e4d
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 8, 2025
fb83df3
fix(auth-validator): [PM-22975] Client Version Validator - Minor toucโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
10cbfd8
fix(auth-validator): [PM-22975] Client Version Validator - Minor funcโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
79256d7
fix(auth-validator): [PM-22975] Client Version Validator - Minor chanโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
865e76f
fix(auth-validator): [PM-22975] Client Version Validator - Reorder ofโ€ฆ
Patrick-Pimentel-Bitwarden Dec 8, 2025
50298fb
fix(auth-validator): [PM-22975] Client Version Validator - Fixed testโ€ฆ
Patrick-Pimentel-Bitwarden Dec 11, 2025
ad68312
fix(auth-validator): [PM-22975] Client Version Validator - Added tickโ€ฆ
Patrick-Pimentel-Bitwarden Dec 11, 2025
3f0d7d2
test(auth-validator): [PM-22975] Client Version Validator - added oneโ€ฆ
Patrick-Pimentel-Bitwarden Dec 11, 2025
fc6a513
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 12, 2025
06224d9
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 15, 2025
6a5518a
fix(auth-validator): [PM-22975] Client Version Validator - Rename funโ€ฆ
Patrick-Pimentel-Bitwarden Dec 15, 2025
fcd4b24
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 15, 2025
3736944
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 17, 2025
6ddd8c7
Merge branch 'main' into auth/pm-22975/client-version-validator
JaredSnider-Bitwarden Dec 22, 2025
c7ea4ea
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Dec 23, 2025
3bd54e5
test(auth-validator): [PM-22975] Client Version Validator - Fixed tests.
Patrick-Pimentel-Bitwarden Dec 23, 2025
f44cd58
Merge remote-tracking branch 'origin' into auth/pm-22975/client-versiโ€ฆ
Patrick-Pimentel-Bitwarden Jan 2, 2026
9a1f91f
fix(auth-validator): [PM-22975] Client Version Validator - Fixed tests.
Patrick-Pimentel-Bitwarden Jan 2, 2026
a3f5a32
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Jan 2, 2026
19d43e9
Merge branch 'main' into auth/pm-22975/client-version-validator
Patrick-Pimentel-Bitwarden Jan 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Core/KeyManagement/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
๏ปฟnamespace Bit.Core.KeyManagement;

public static class Constants
{
public static readonly Version MinimumClientVersion = new Version("2025.11.0");
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ private static void AddKeyManagementCommands(this IServiceCollection services)
private static void AddKeyManagementQueries(this IServiceCollection services)
{
services.AddScoped<IUserAccountKeysQuery, UserAccountKeysQuery>();
services.AddScoped<IIsV2EncryptionUserQuery, IsV2EncryptionUserQuery>();
services.AddScoped<IGetMinimumClientVersionForUserQuery, GetMinimumClientVersionForUserQuery>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
๏ปฟusing Bit.Core.Entities;
using Bit.Core.KeyManagement.Queries.Interfaces;

namespace Bit.Core.KeyManagement.Queries;

public class GetMinimumClientVersionForUserQuery(IIsV2EncryptionUserQuery isV2EncryptionUserQuery)
: IGetMinimumClientVersionForUserQuery
{
public async Task<Version?> Run(User? user)
{
if (user == null)
{
return null;
}

if (await isV2EncryptionUserQuery.Run(user))
{
return Constants.MinimumClientVersion;
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
๏ปฟusing Bit.Core.Entities;

namespace Bit.Core.KeyManagement.Queries.Interfaces;

public interface IGetMinimumClientVersionForUserQuery
{
Task<Version?> Run(User? user);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
๏ปฟusing Bit.Core.Entities;

namespace Bit.Core.KeyManagement.Queries.Interfaces;

public interface IIsV2EncryptionUserQuery
{
Task<bool> Run(User user);
}
31 changes: 31 additions & 0 deletions src/Core/KeyManagement/Queries/IsV2EncryptionUserQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
๏ปฟusing Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.KeyManagement.Queries.Interfaces;
using Bit.Core.KeyManagement.Repositories;
using Bit.Core.KeyManagement.Utilities;

namespace Bit.Core.KeyManagement.Queries;

public class IsV2EncryptionUserQuery(IUserSignatureKeyPairRepository userSignatureKeyPairRepository)
: IIsV2EncryptionUserQuery
{
public async Task<bool> Run(User user)
{
ArgumentNullException.ThrowIfNull(user);

var hasSignatureKeyPair = await userSignatureKeyPairRepository.GetByUserIdAsync(user.Id) != null;
var isPrivateKeyEncryptionV2 =
!string.IsNullOrWhiteSpace(user.PrivateKey) &&
EncryptionParsing.GetEncryptionType(user.PrivateKey) == EncryptionType.XChaCha20Poly1305_B64;

return hasSignatureKeyPair switch
{
// Valid v2 user
true when isPrivateKeyEncryptionV2 => true,
// Valid v1 user
false when !isPrivateKeyEncryptionV2 => false,
_ => throw new InvalidOperationException(
"User is in an invalid state for key rotation. User has a signature key pair, but the private key is not in v2 format, or vice versa.")
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Bit.Core.Enums;
using Bit.Core.KeyManagement.Models.Data;
using Bit.Core.KeyManagement.Repositories;
using Bit.Core.KeyManagement.Utilities;
using Bit.Core.Platform.Push;
using Bit.Core.Repositories;
using Bit.Core.Services;
Expand Down Expand Up @@ -137,7 +138,7 @@ public async Task UpdateAccountKeysAsync(RotateUserAccountKeysData model, User u
}
else
{
if (GetEncryptionType(model.AccountKeys.PublicKeyEncryptionKeyPairData.WrappedPrivateKey) != EncryptionType.AesCbc256_HmacSha256_B64)
if (EncryptionParsing.GetEncryptionType(model.AccountKeys.PublicKeyEncryptionKeyPairData.WrappedPrivateKey) != EncryptionType.AesCbc256_HmacSha256_B64)
{
throw new InvalidOperationException("The provided account private key was not wrapped with AES-256-CBC-HMAC");
}
Expand Down Expand Up @@ -209,7 +210,7 @@ private bool IsV2EncryptionUserAsync(User user)
{
// Returns whether the user is a V2 user based on the private key's encryption type.
ArgumentNullException.ThrowIfNull(user);
var isPrivateKeyEncryptionV2 = GetEncryptionType(user.PrivateKey) == EncryptionType.XChaCha20Poly1305_B64;
var isPrivateKeyEncryptionV2 = EncryptionParsing.GetEncryptionType(user.PrivateKey) == EncryptionType.XChaCha20Poly1305_B64;
return isPrivateKeyEncryptionV2;
}

Expand Down Expand Up @@ -237,7 +238,7 @@ private static void ValidateV2Encryption(RotateUserAccountKeysData model)
{
throw new InvalidOperationException("Signature key pair data is required for V2 encryption.");
}
if (GetEncryptionType(model.AccountKeys.SignatureKeyPairData.WrappedSigningKey) != EncryptionType.XChaCha20Poly1305_B64)
if (EncryptionParsing.GetEncryptionType(model.AccountKeys.SignatureKeyPairData.WrappedSigningKey) != EncryptionType.XChaCha20Poly1305_B64)
{
throw new InvalidOperationException("The provided signing key data is not wrapped with XChaCha20-Poly1305.");
}
Expand All @@ -246,7 +247,7 @@ private static void ValidateV2Encryption(RotateUserAccountKeysData model)
throw new InvalidOperationException("The provided signature key pair data does not contain a valid verifying key.");
}

if (GetEncryptionType(model.AccountKeys.PublicKeyEncryptionKeyPairData.WrappedPrivateKey) != EncryptionType.XChaCha20Poly1305_B64)
if (EncryptionParsing.GetEncryptionType(model.AccountKeys.PublicKeyEncryptionKeyPairData.WrappedPrivateKey) != EncryptionType.XChaCha20Poly1305_B64)
{
throw new InvalidOperationException("The provided private key encryption key is not wrapped with XChaCha20-Poly1305.");
}
Expand All @@ -260,23 +261,5 @@ private static void ValidateV2Encryption(RotateUserAccountKeysData model)
}
}

/// <summary>
/// Helper method to convert an encryption type string to an enum value.
/// </summary>
private static EncryptionType GetEncryptionType(string encString)
{
var parts = encString.Split('.');
if (parts.Length == 1)
{
throw new ArgumentException("Invalid encryption type string.");
}
if (byte.TryParse(parts[0], out var encryptionTypeNumber))
{
if (Enum.IsDefined(typeof(EncryptionType), encryptionTypeNumber))
{
return (EncryptionType)encryptionTypeNumber;
}
}
throw new ArgumentException("Invalid encryption type string.");
}
// Parsing moved to Bit.Core.KeyManagement.Utilities.EncryptionParsing
}
26 changes: 26 additions & 0 deletions src/Core/KeyManagement/Utilities/EncryptionParsing.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
๏ปฟusing Bit.Core.Enums;

namespace Bit.Core.KeyManagement.Utilities;

public static class EncryptionParsing
{
/// <summary>
/// Helper method to convert an encryption type string to an enum value.
/// </summary>
public static EncryptionType GetEncryptionType(string encString)
{
var parts = encString.Split('.');
if (parts.Length == 1)
{
throw new ArgumentException("Invalid encryption type string.");
}
if (byte.TryParse(parts[0], out var encryptionTypeNumber))
{
if (Enum.IsDefined(typeof(EncryptionType), encryptionTypeNumber))
{
return (EncryptionType)encryptionTypeNumber;
}
}
throw new ArgumentException("Invalid encryption type string.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public abstract class BaseRequestValidator<T> where T : class
private readonly IUserRepository _userRepository;
private readonly IAuthRequestRepository _authRequestRepository;
private readonly IMailService _mailService;
private readonly IClientVersionValidator _clientVersionValidator;

protected ICurrentContext CurrentContext { get; }
protected IPolicyService PolicyService { get; }
Expand Down Expand Up @@ -68,7 +69,8 @@ public BaseRequestValidator(
IPolicyRequirementQuery policyRequirementQuery,
IAuthRequestRepository authRequestRepository,
IMailService mailService,
IUserAccountKeysQuery userAccountKeysQuery
IUserAccountKeysQuery userAccountKeysQuery,
IClientVersionValidator clientVersionValidator
)
{
_userManager = userManager;
Expand All @@ -89,6 +91,7 @@ IUserAccountKeysQuery userAccountKeysQuery
_authRequestRepository = authRequestRepository;
_mailService = mailService;
_accountKeysQuery = userAccountKeysQuery;
_clientVersionValidator = clientVersionValidator;
}

protected async Task ValidateAsync(T context, ValidatedTokenRequest request,
Expand All @@ -108,7 +111,8 @@ await BuildSuccessResultAsync(validatorContext.User, context, validatorContext.D
}
else
{
// 1. We need to check if the user's master password hash is correct.
// 1. We need to check if the user is legitimate via the contextually appropriate mechanism
// (webauthn, password, custom token, etc.).
var valid = await ValidateContextAsync(context, validatorContext);
var user = validatorContext.User;
if (!valid)
Expand All @@ -119,6 +123,13 @@ await BuildSuccessResultAsync(validatorContext.User, context, validatorContext.D
return;
}

// 1.5 Now check the version number of the client. Do this after ValidateContextAsync so that
// we prevent account enumeration. If we were to do this before ValidateContextAsync, then attackers
// could use a known invalid client version and make a request for a user (before we know if they have
// demonstrated ownership of the account via correct credentials) and identify if they exist by getting
// an error response back from the validator saying the user is not compatible with the client.
await ValidateClientVersionAsync(context, validatorContext);

// 2. Decide if this user belongs to an organization that requires SSO.
validatorContext.SsoRequired = await RequireSsoLoginAsync(user, request.GrantType);
if (validatorContext.SsoRequired)
Expand Down Expand Up @@ -259,6 +270,7 @@ private Func<Task<bool>>[] DetermineValidationOrder(T context, ValidatedTokenReq
return
[
() => ValidateMasterPasswordAsync(context, validatorContext),
() => ValidateClientVersionAsync(context, validatorContext),
() => ValidateTwoFactorAsync(context, request, validatorContext),
() => ValidateSsoAsync(context, request, validatorContext),
() => ValidateNewDeviceAsync(context, request, validatorContext),
Expand All @@ -272,6 +284,7 @@ private Func<Task<bool>>[] DetermineValidationOrder(T context, ValidatedTokenReq
return
[
() => ValidateMasterPasswordAsync(context, validatorContext),
() => ValidateClientVersionAsync(context, validatorContext),
() => ValidateSsoAsync(context, request, validatorContext),
() => ValidateTwoFactorAsync(context, request, validatorContext),
() => ValidateNewDeviceAsync(context, request, validatorContext),
Expand Down Expand Up @@ -323,6 +336,24 @@ private static async Task<bool> ProcessValidatorsAsync(params Func<Task<bool>>[]
return true;
}

/// <summary>
/// Validates whether the client version is compatible for the user attempting to authenticate.
/// New authentications only; refresh/device grants are handled elsewhere.
/// </summary>
/// <returns>true if the scheme successfully passed validation, otherwise false.</returns>
private async Task<bool> ValidateClientVersionAsync(T context, CustomValidatorRequestContext validatorContext)
{
var ok = await _clientVersionValidator.ValidateAsync(validatorContext.User, validatorContext);
if (ok)
{
return true;
}

SetValidationErrorResult(context, validatorContext);
await LogFailedLoginEvent(validatorContext.User, EventType.User_FailedLogIn);
return false;
}

/// <summary>
/// Validates the user's Master Password hash.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
๏ปฟusing Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.KeyManagement.Queries.Interfaces;
using Bit.Core.Models.Api;
using Duende.IdentityServer.Validation;

namespace Bit.Identity.IdentityServer.RequestValidators;

public interface IClientVersionValidator
{
Task<bool> ValidateAsync(User user, CustomValidatorRequestContext requestContext);
}

public class ClientVersionValidator(
ICurrentContext currentContext,
IGetMinimumClientVersionForUserQuery getMinimumClientVersionForUserQuery)
: IClientVersionValidator
{
private static readonly string UpgradeMessage = "Please update your app to continue using Bitwarden";

public async Task<bool> ValidateAsync(User? user, CustomValidatorRequestContext requestContext)
{
if (user == null)
{
return true;
}

var clientVersion = currentContext.ClientVersion;
var minVersion = await getMinimumClientVersionForUserQuery.Run(user);

// Fail-open if headers are missing or no restriction
if (minVersion == null)
{
return true;
}

if (clientVersion < minVersion)
{
requestContext.ValidationErrorResult = new ValidationResult
{
Error = "invalid_client_version",
ErrorDescription = UpgradeMessage,
IsError = true
};
requestContext.CustomResponse = new Dictionary<string, object>
{
{ "ErrorModel", new ErrorResponseModel(UpgradeMessage) }
};
return false;
}

return true;
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@
using Duende.IdentityModel;
using Duende.IdentityServer.Extensions;
using Duende.IdentityServer.Validation;
using HandlebarsDotNet;
using Microsoft.AspNetCore.Identity;

#nullable enable

namespace Bit.Identity.IdentityServer.RequestValidators;

public class CustomTokenRequestValidator : BaseRequestValidator<CustomTokenRequestValidationContext>,
Expand Down Expand Up @@ -49,7 +46,8 @@ public CustomTokenRequestValidator(
IPolicyRequirementQuery policyRequirementQuery,
IAuthRequestRepository authRequestRepository,
IMailService mailService,
IUserAccountKeysQuery userAccountKeysQuery)
IUserAccountKeysQuery userAccountKeysQuery,
IClientVersionValidator clientVersionValidator)
: base(
userManager,
userService,
Expand All @@ -68,7 +66,8 @@ public CustomTokenRequestValidator(
policyRequirementQuery,
authRequestRepository,
mailService,
userAccountKeysQuery)
userAccountKeysQuery,
clientVersionValidator)
{
_userManager = userManager;
_updateInstallationCommand = updateInstallationCommand;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public ResourceOwnerPasswordValidator(
IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder,
IPolicyRequirementQuery policyRequirementQuery,
IMailService mailService,
IUserAccountKeysQuery userAccountKeysQuery)
IUserAccountKeysQuery userAccountKeysQuery,
IClientVersionValidator clientVersionValidator)
: base(
userManager,
userService,
Expand All @@ -62,7 +63,8 @@ public ResourceOwnerPasswordValidator(
policyRequirementQuery,
authRequestRepository,
mailService,
userAccountKeysQuery)
userAccountKeysQuery,
clientVersionValidator)
{
_userManager = userManager;
_currentContext = currentContext;
Expand Down
Loading
Loading