diff --git a/src/Admin/Views/Users/Index.cshtml b/src/Admin/Views/Users/Index.cshtml
index e55f5c8107..98847d5096 100644
--- a/src/Admin/Views/Users/Index.cshtml
+++ b/src/Admin/Views/Users/Index.cshtml
@@ -69,7 +69,7 @@
{
}
- @if(await user.TwoFactorIsEnabledAsync(userService))
+ @if(await userService.TwoFactorIsEnabledAsync(user))
{
}
diff --git a/src/Admin/Views/Users/_ViewInformation.cshtml b/src/Admin/Views/Users/_ViewInformation.cshtml
index 7244dd6829..67cb8eba98 100644
--- a/src/Admin/Views/Users/_ViewInformation.cshtml
+++ b/src/Admin/Views/Users/_ViewInformation.cshtml
@@ -14,7 +14,7 @@
@(Model.User.EmailVerified ? "Yes" : "No")
Using 2FA
- @(await Model.User.TwoFactorIsEnabledAsync(userService) ? "Yes" : "No")
+ @(await userService.TwoFactorIsEnabledAsync(Model.User) ? "Yes" : "No")
Items
@Model.CipherCount
diff --git a/src/Api/Controllers/AccountsController.cs b/src/Api/Controllers/AccountsController.cs
index a475918e3b..7400197952 100644
--- a/src/Api/Controllers/AccountsController.cs
+++ b/src/Api/Controllers/AccountsController.cs
@@ -307,7 +307,7 @@ namespace Bit.Api.Controllers
var organizationUserDetails = await _organizationUserRepository.GetManyDetailsByUserAsync(user.Id,
OrganizationUserStatusType.Confirmed);
var response = new ProfileResponseModel(user, organizationUserDetails,
- await user.TwoFactorIsEnabledAsync(_userService));
+ await _userService.TwoFactorIsEnabledAsync(user));
return response;
}
@@ -332,7 +332,7 @@ namespace Bit.Api.Controllers
}
await _userService.SaveUserAsync(model.ToUser(user));
- var response = new ProfileResponseModel(user, null, await user.TwoFactorIsEnabledAsync(_userService));
+ var response = new ProfileResponseModel(user, null, await _userService.TwoFactorIsEnabledAsync(user));
return response;
}
@@ -462,7 +462,7 @@ namespace Bit.Api.Controllers
await _userService.SignUpPremiumAsync(user, model.PaymentToken,
model.AdditionalStorageGb.GetValueOrDefault(0), license);
- return new ProfileResponseModel(user, null, await user.TwoFactorIsEnabledAsync(_userService));
+ return new ProfileResponseModel(user, null, await _userService.TwoFactorIsEnabledAsync(user));
}
[HttpGet("billing")]
diff --git a/src/Api/Controllers/SyncController.cs b/src/Api/Controllers/SyncController.cs
index b272ec340d..ad961da52c 100644
--- a/src/Api/Controllers/SyncController.cs
+++ b/src/Api/Controllers/SyncController.cs
@@ -69,7 +69,7 @@ namespace Bit.Api.Controllers
collectionCiphersGroupDict = collectionCiphers.GroupBy(c => c.CipherId).ToDictionary(s => s.Key);
}
- var userTwoFactorEnabled = await user.TwoFactorIsEnabledAsync(_userService);
+ var userTwoFactorEnabled = await _userService.TwoFactorIsEnabledAsync(user);
var response = new SyncResponseModel(_globalSettings, user, userTwoFactorEnabled, organizationUserDetails,
folders, collections, ciphers, collectionCiphersGroupDict, excludeDomains);
return response;
diff --git a/src/Api/web.config b/src/Api/web.config
index ac273d18b2..4dcf28ca24 100644
--- a/src/Api/web.config
+++ b/src/Api/web.config
@@ -4,7 +4,9 @@
-
+
+
+
diff --git a/src/Core/Identity/AuthenticatorTokenProvider.cs b/src/Core/Identity/AuthenticatorTokenProvider.cs
index e7bcd789ec..bccfc9f713 100644
--- a/src/Core/Identity/AuthenticatorTokenProvider.cs
+++ b/src/Core/Identity/AuthenticatorTokenProvider.cs
@@ -25,8 +25,8 @@ namespace Bit.Core.Identity
{
return false;
}
- return await user.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Authenticator,
- _serviceProvider.GetRequiredService());
+ return await _serviceProvider.GetRequiredService()
+ .TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Authenticator, user);
}
public Task GenerateAsync(string purpose, UserManager manager, User user)
diff --git a/src/Core/Identity/DuoWebTokenProvider.cs b/src/Core/Identity/DuoWebTokenProvider.cs
index a651bed5e7..aff9cff938 100644
--- a/src/Core/Identity/DuoWebTokenProvider.cs
+++ b/src/Core/Identity/DuoWebTokenProvider.cs
@@ -37,7 +37,7 @@ namespace Bit.Core.Identity
return false;
}
- return await user.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Duo, userService);
+ return await userService.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Duo, user);
}
public async Task GenerateAsync(string purpose, UserManager manager, User user)
diff --git a/src/Core/Identity/ReadOnlyDatabaseIdentityUserStore.cs b/src/Core/Identity/ReadOnlyDatabaseIdentityUserStore.cs
index adacc3a86e..751477e23a 100644
--- a/src/Core/Identity/ReadOnlyDatabaseIdentityUserStore.cs
+++ b/src/Core/Identity/ReadOnlyDatabaseIdentityUserStore.cs
@@ -24,7 +24,7 @@ namespace Bit.Core.Identity
CancellationToken cancellationToken = default(CancellationToken))
{
var user = await _userRepository.GetByEmailAsync(normalizedEmail);
- return user?.ToIdentityUser(await user.TwoFactorIsEnabledAsync(_userService));
+ return user?.ToIdentityUser(await _userService.TwoFactorIsEnabledAsync(user));
}
public override async Task FindByIdAsync(string userId,
@@ -36,7 +36,7 @@ namespace Bit.Core.Identity
}
var user = await _userRepository.GetByIdAsync(userIdGuid);
- return user?.ToIdentityUser(await user.TwoFactorIsEnabledAsync(_userService));
+ return user?.ToIdentityUser(await _userService.TwoFactorIsEnabledAsync(user));
}
}
}
diff --git a/src/Core/Identity/U2fTokenProvider.cs b/src/Core/Identity/U2fTokenProvider.cs
index 2822d1c017..70d6872a1f 100644
--- a/src/Core/Identity/U2fTokenProvider.cs
+++ b/src/Core/Identity/U2fTokenProvider.cs
@@ -47,7 +47,7 @@ namespace Bit.Core.Identity
return false;
}
- return await user.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.U2f, userService);
+ return await userService.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.U2f, user);
}
public async Task GenerateAsync(string purpose, UserManager manager, User user)
diff --git a/src/Core/Identity/UserStore.cs b/src/Core/Identity/UserStore.cs
index 33096fa0b2..be0dab2002 100644
--- a/src/Core/Identity/UserStore.cs
+++ b/src/Core/Identity/UserStore.cs
@@ -169,7 +169,7 @@ namespace Bit.Core.Identity
public async Task GetTwoFactorEnabledAsync(User user, CancellationToken cancellationToken)
{
- return await user.TwoFactorIsEnabledAsync(_serviceProvider.GetRequiredService());
+ return await _serviceProvider.GetRequiredService().TwoFactorIsEnabledAsync(user);
}
public Task SetSecurityStampAsync(User user, string stamp, CancellationToken cancellationToken)
diff --git a/src/Core/Identity/YubicoOtpTokenProvider.cs b/src/Core/Identity/YubicoOtpTokenProvider.cs
index 1bd19487ef..fdcbff77b3 100644
--- a/src/Core/Identity/YubicoOtpTokenProvider.cs
+++ b/src/Core/Identity/YubicoOtpTokenProvider.cs
@@ -37,7 +37,7 @@ namespace Bit.Core.Identity
return false;
}
- return await user.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.YubiKey, userService);
+ return await userService.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.YubiKey, user);
}
public Task GenerateAsync(string purpose, UserManager manager, User user)
diff --git a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs
index f1a29ca39f..6c02fc2ec8 100644
--- a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs
+++ b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs
@@ -164,7 +164,7 @@ namespace Bit.Core.IdentityServer
{
foreach(var p in user.GetTwoFactorProviders())
{
- if(await user.TwoFactorProviderIsEnabledAsync(p.Key, _userService))
+ if(await _userService.TwoFactorProviderIsEnabledAsync(p.Key, user))
{
enabledProviders.Add(p);
}
@@ -279,13 +279,13 @@ namespace Bit.Core.IdentityServer
case TwoFactorProviderType.U2f:
case TwoFactorProviderType.Remember:
if(type != TwoFactorProviderType.Remember &&
- !(await user.TwoFactorProviderIsEnabledAsync(type, _userService)))
+ !(await _userService.TwoFactorProviderIsEnabledAsync(type, user)))
{
return false;
}
return await _userManager.VerifyTwoFactorTokenAsync(user, type.ToString(), token);
case TwoFactorProviderType.Email:
- if(!(await user.TwoFactorProviderIsEnabledAsync(type, _userService)))
+ if(!(await _userService.TwoFactorProviderIsEnabledAsync(type, user)))
{
return false;
}
@@ -311,7 +311,7 @@ namespace Bit.Core.IdentityServer
case TwoFactorProviderType.U2f:
case TwoFactorProviderType.Email:
case TwoFactorProviderType.YubiKey:
- if(!(await user.TwoFactorProviderIsEnabledAsync(type, _userService)))
+ if(!(await _userService.TwoFactorProviderIsEnabledAsync(type, user)))
{
return null;
}
diff --git a/src/Core/Models/Table/User.cs b/src/Core/Models/Table/User.cs
index b156108e7a..cffa45add3 100644
--- a/src/Core/Models/Table/User.cs
+++ b/src/Core/Models/Table/User.cs
@@ -92,48 +92,6 @@ namespace Bit.Core.Models.Table
_twoFactorProviders = providers;
}
- public async Task TwoFactorProviderIsEnabledAsync(TwoFactorProviderType provider,
- IUserService userService)
- {
- var providers = GetTwoFactorProviders();
- if(providers == null || !providers.ContainsKey(provider) || !providers[provider].Enabled)
- {
- return false;
- }
-
- if(!TwoFactorProvider.RequiresPremium(provider))
- {
- return true;
- }
-
- return await userService.CanAccessPremium(this);
- }
-
- public async Task TwoFactorIsEnabledAsync(IUserService userService)
- {
- var providers = GetTwoFactorProviders();
- if(providers == null)
- {
- return false;
- }
-
- foreach(var p in providers)
- {
- if(p.Value?.Enabled ?? false)
- {
- if(!TwoFactorProvider.RequiresPremium(p.Key))
- {
- return true;
- }
- if(await userService.CanAccessPremium(this))
- {
- return true;
- }
- }
- }
- return false;
- }
-
public TwoFactorProvider GetTwoFactorProvider(TwoFactorProviderType provider)
{
var providers = GetTwoFactorProviders();
diff --git a/src/Core/Services/IUserService.cs b/src/Core/Services/IUserService.cs
index a69fd10ca1..a64d24d895 100644
--- a/src/Core/Services/IUserService.cs
+++ b/src/Core/Services/IUserService.cs
@@ -55,5 +55,7 @@ namespace Bit.Core.Services
Task GenerateLicenseAsync(User user, BillingInfo billingInfo = null);
Task CheckPasswordAsync(User user, string password);
Task CanAccessPremium(User user);
+ Task TwoFactorIsEnabledAsync(User user);
+ Task TwoFactorProviderIsEnabledAsync(TwoFactorProviderType provider, User user);
}
}
diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs
index 0748743317..0ebf0daf65 100644
--- a/src/Core/Services/Implementations/UserService.cs
+++ b/src/Core/Services/Implementations/UserService.cs
@@ -916,6 +916,47 @@ namespace Bit.Core.Services
orgAbilities[o.Id].UsersGetPremium && orgAbilities[o.Id].Enabled);
}
+ public async Task TwoFactorIsEnabledAsync(User user)
+ {
+ var providers = user.GetTwoFactorProviders();
+ if(providers == null)
+ {
+ return false;
+ }
+
+ foreach(var p in providers)
+ {
+ if(p.Value?.Enabled ?? false)
+ {
+ if(!TwoFactorProvider.RequiresPremium(p.Key))
+ {
+ return true;
+ }
+ if(await CanAccessPremium(user))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public async Task TwoFactorProviderIsEnabledAsync(TwoFactorProviderType provider, User user)
+ {
+ var providers = user.GetTwoFactorProviders();
+ if(providers == null || !providers.ContainsKey(provider) || !providers[provider].Enabled)
+ {
+ return false;
+ }
+
+ if(!TwoFactorProvider.RequiresPremium(provider))
+ {
+ return true;
+ }
+
+ return await CanAccessPremium(user);
+ }
+
private async Task UpdatePasswordHash(User user, string newPassword,
bool validatePassword = true, bool refreshStamp = true)
{