diff --git a/src/Api/Controllers/TwoFactorController.cs b/src/Api/Controllers/TwoFactorController.cs
index 3e7ee360d3..08cd3d512f 100644
--- a/src/Api/Controllers/TwoFactorController.cs
+++ b/src/Api/Controllers/TwoFactorController.cs
@@ -207,6 +207,24 @@ namespace Bit.Api.Controllers
             await _userService.SendTwoFactorEmailAsync(user);
         }
 
+        [AllowAnonymous]
+        [HttpPost("send-email-login")]
+        public async Task SendEmailLogin([FromBody]TwoFactorEmailRequestModel model)
+        {
+            var user = await _userManager.FindByEmailAsync(model.Email.ToLowerInvariant());
+            if(user != null)
+            {
+                if(await _userManager.CheckPasswordAsync(user, model.MasterPasswordHash))
+                {
+                    await _userService.SendTwoFactorEmailAsync(user);
+                    return;
+                }
+            }
+
+            await Task.Delay(2000);
+            throw new BadRequestException("Cannot send two-factor email.");
+        }
+
         [HttpPut("email")]
         [HttpPost("email")]
         public async Task<TwoFactorEmailResponseModel> PutEmail([FromBody]UpdateTwoFactorEmailRequestModel model)
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index 55aef19abc..8bcf8e8374 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -56,7 +56,7 @@
     <PackageReference Include="Serilog.Extensions.Logging" Version="1.4.0" />
     <PackageReference Include="Serilog.Sinks.AzureDocumentDB" Version="3.6.1" />
     <PackageReference Include="Stripe.net" Version="7.8.0" />
-    <PackageReference Include="u2flib" Version="1.0.5" />
+    <PackageReference Include="U2F.Core" Version="1.0.3" />
     <PackageReference Include="WindowsAzure.Storage" Version="8.1.1" />
     <PackageReference Include="Otp.NET" Version="1.0.1" />
     <PackageReference Include="YubicoDotNetClient" Version="1.0.0" />
diff --git a/src/Core/Identity/U2fTokenProvider.cs b/src/Core/Identity/U2fTokenProvider.cs
index 340a32041f..1e72edb3ad 100644
--- a/src/Core/Identity/U2fTokenProvider.cs
+++ b/src/Core/Identity/U2fTokenProvider.cs
@@ -7,10 +7,9 @@ using Bit.Core.Repositories;
 using Newtonsoft.Json;
 using System.Collections.Generic;
 using System.Linq;
-using u2flib.Data;
-using u2flib;
-using u2flib.Data.Messages;
-using u2flib.Exceptions;
+using U2fLib = U2F.Core.Crypto.U2F;
+using U2F.Core.Models;
+using U2F.Core.Exceptions;
 
 namespace Bit.Core.Identity
 {
@@ -62,7 +61,7 @@ namespace Bit.Core.Identity
             {
                 var registration = new DeviceRegistration(key.KeyHandleBytes, key.PublicKeyBytes,
                     key.CertificateBytes, key.Counter);
-                var auth = U2F.StartAuthentication(Utilities.CoreHelpers.U2fAppIdUrl(_globalSettings), registration);
+                var auth = U2fLib.StartAuthentication(Utilities.CoreHelpers.U2fAppIdUrl(_globalSettings), registration);
 
                 // Maybe move this to a bulk create when we support more than 1 key?
                 await _u2fRepository.CreateAsync(new U2f
@@ -113,7 +112,7 @@ namespace Bit.Core.Identity
                 return false;
             }
 
-            var authenticateResponse = DataObject.FromJson<AuthenticateResponse>(token);
+            var authenticateResponse = BaseModel.FromJson<AuthenticateResponse>(token);
             var key = keys.FirstOrDefault(f => f.KeyHandle == authenticateResponse.KeyHandle);
 
             if(key == null)
@@ -141,7 +140,7 @@ namespace Bit.Core.Identity
             try
             {
                 var auth = new StartedAuthentication(challenge.Challenge, challenge.AppId, challenge.KeyHandle);
-                U2F.FinishAuthentication(auth, authenticateResponse, registration);
+                U2fLib.FinishAuthentication(auth, authenticateResponse, registration);
             }
             catch(U2fException)
             {
diff --git a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs
index 836f1c7c9c..1ccc043557 100644
--- a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs
+++ b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs
@@ -120,7 +120,14 @@ namespace Bit.Core.IdentityServer
         {
             var providerKeys = new List<byte>();
             var providers = new Dictionary<byte, Dictionary<string, object>>();
-            foreach(var provider in user.GetTwoFactorProviders().Where(p => p.Value.Enabled))
+            var enabledProviders = user.GetTwoFactorProviders()?.Where(p => p.Value.Enabled);
+            if(enabledProviders == null)
+            {
+                BuildErrorResult(false, context);
+                return;
+            }
+
+            foreach(var provider in enabledProviders)
             {
                 providerKeys.Add((byte)provider.Key);
                 var infoDict = await BuildTwoFactorParams(user, provider.Key, provider.Value);
@@ -133,6 +140,12 @@ namespace Bit.Core.IdentityServer
                     { "TwoFactorProviders", providers.Keys },
                     { "TwoFactorProviders2", providers }
                 });
+
+            if(enabledProviders.Count() == 1 && enabledProviders.First().Key == TwoFactorProviderType.Email)
+            {
+                // Send email now if this is their only 2FA method
+                await _userService.SendTwoFactorEmailAsync(user);
+            }
         }
 
         private void BuildErrorResult(bool twoFactorRequest, ResourceOwnerPasswordValidationContext context)
diff --git a/src/Core/Models/TwoFactorProvider.cs b/src/Core/Models/TwoFactorProvider.cs
index 1f8e809674..1b74bc2a5c 100644
--- a/src/Core/Models/TwoFactorProvider.cs
+++ b/src/Core/Models/TwoFactorProvider.cs
@@ -1,7 +1,7 @@
 using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
-using u2flib.Util;
+using U2F.Core.Utils;
 
 namespace Bit.Core.Models
 {
diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs
index 58a1e7fe5b..27b4c17484 100644
--- a/src/Core/Services/Implementations/UserService.cs
+++ b/src/Core/Services/Implementations/UserService.cs
@@ -12,10 +12,9 @@ using Bit.Core.Enums;
 using System.Security.Claims;
 using Bit.Core.Models;
 using Bit.Core.Models.Business;
-using u2flib.Data.Messages;
-using u2flib.Util;
-using u2flib;
-using u2flib.Data;
+using U2fLib = U2F.Core.Crypto.U2F;
+using U2F.Core.Models;
+using U2F.Core.Utils;
 
 namespace Bit.Core.Services
 {
@@ -220,7 +219,7 @@ namespace Bit.Core.Services
         public async Task<U2fRegistration> StartU2fRegistrationAsync(User user)
         {
             await _u2fRepository.DeleteManyByUserIdAsync(user.Id);
-            var reg = U2F.StartRegistration(Utilities.CoreHelpers.U2fAppIdUrl(_globalSettings));
+            var reg = U2fLib.StartRegistration(Utilities.CoreHelpers.U2fAppIdUrl(_globalSettings));
             await _u2fRepository.CreateAsync(new U2f
             {
                 AppId = reg.AppId,
@@ -250,11 +249,11 @@ namespace Bit.Core.Services
                 return false;
             }
 
-            var registerResponse = DataObject.FromJson<RegisterResponse>(deviceResponse);
+            var registerResponse = BaseModel.FromJson<RegisterResponse>(deviceResponse);
 
             var challenge = challenges.OrderBy(i => i.Id).Last(i => i.KeyHandle == null);
             var statedReg = new StartedRegistration(challenge.Challenge, challenge.AppId);
-            var reg = U2F.FinishRegistration(statedReg, registerResponse);
+            var reg = U2fLib.FinishRegistration(statedReg, registerResponse);
 
             await _u2fRepository.DeleteManyByUserIdAsync(user.Id);