diff --git a/src/Core/Auth/UserFeatures/WebAuthnLogin/Implementations/CreateWebAuthnLoginCredentialCommand.cs b/src/Core/Auth/UserFeatures/WebAuthnLogin/Implementations/CreateWebAuthnLoginCredentialCommand.cs index 795fa95b9d..406621271a 100644 --- a/src/Core/Auth/UserFeatures/WebAuthnLogin/Implementations/CreateWebAuthnLoginCredentialCommand.cs +++ b/src/Core/Auth/UserFeatures/WebAuthnLogin/Implementations/CreateWebAuthnLoginCredentialCommand.cs @@ -1,9 +1,12 @@ // FIXME: Update this file to be null safe and then delete the line below + #nullable disable using Bit.Core.Auth.Entities; using Bit.Core.Auth.Repositories; using Bit.Core.Entities; +using Bit.Core.Services; +using Bit.Core.Settings; using Bit.Core.Utilities; using Fido2NetLib; @@ -11,27 +14,35 @@ namespace Bit.Core.Auth.UserFeatures.WebAuthnLogin.Implementations; internal class CreateWebAuthnLoginCredentialCommand : ICreateWebAuthnLoginCredentialCommand { - public const int MaxCredentialsPerUser = 5; - private readonly IFido2 _fido2; private readonly IWebAuthnCredentialRepository _webAuthnCredentialRepository; + private readonly GlobalSettings _globalSettings; + private readonly IUserService _userService; - public CreateWebAuthnLoginCredentialCommand(IFido2 fido2, IWebAuthnCredentialRepository webAuthnCredentialRepository) + public CreateWebAuthnLoginCredentialCommand(IFido2 fido2, + IWebAuthnCredentialRepository webAuthnCredentialRepository, GlobalSettings globalSettings, IUserService userService) { _fido2 = fido2; _webAuthnCredentialRepository = webAuthnCredentialRepository; + _globalSettings = globalSettings; + _userService = userService; } - public async Task CreateWebAuthnLoginCredentialAsync(User user, string name, CredentialCreateOptions options, AuthenticatorAttestationRawResponse attestationResponse, bool supportsPrf, string encryptedUserKey = null, string encryptedPublicKey = null, string encryptedPrivateKey = null) + public async Task CreateWebAuthnLoginCredentialAsync(User user, string name, CredentialCreateOptions options, + AuthenticatorAttestationRawResponse attestationResponse, bool supportsPrf, string encryptedUserKey = null, + string encryptedPublicKey = null, string encryptedPrivateKey = null) { var existingCredentials = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id); - if (existingCredentials.Count >= MaxCredentialsPerUser) + var maximumAllowedCredentialCount = (await _userService.CanAccessPremium(user)) ? + _globalSettings.WebAuthN.PremiumMaximumAllowedCredentials : _globalSettings.WebAuthN.NonPremiumMaximumAllowedCredentials; + if (existingCredentials.Count >= maximumAllowedCredentialCount) { return false; } var existingCredentialIds = existingCredentials.Select(c => c.CredentialId); - IsCredentialIdUniqueToUserAsyncDelegate callback = (args, cancellationToken) => Task.FromResult(!existingCredentialIds.Contains(CoreHelpers.Base64UrlEncode(args.CredentialId))); + IsCredentialIdUniqueToUserAsyncDelegate callback = (args, cancellationToken) => + Task.FromResult(!existingCredentialIds.Contains(CoreHelpers.Base64UrlEncode(args.CredentialId))); var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback);