diff --git a/src/Core/Auth/Models/Business/Tokenables/SsoEmail2faSessionTokenable.cs b/src/Core/Auth/Models/Business/Tokenables/SsoEmail2faSessionTokenable.cs
index 24a74bde07..30687a6a4a 100644
--- a/src/Core/Auth/Models/Business/Tokenables/SsoEmail2faSessionTokenable.cs
+++ b/src/Core/Auth/Models/Business/Tokenables/SsoEmail2faSessionTokenable.cs
@@ -4,9 +4,10 @@ using Bit.Core.Tokens;
namespace Bit.Core.Auth.Models.Business.Tokenables;
-// This token just provides a verifiable authN mechanism for the API service
-// TwoFactorController.cs SendEmailLogin anonymous endpoint so it cannot be
-// used maliciously.
+///
+/// This token provides a verifiable authN mechanism for the TwoFactorController.SendEmailLoginAsync
+/// anonymous endpoint so it cannot used maliciously.
+///
public class SsoEmail2faSessionTokenable : ExpiringTokenable
{
// Just over 2 min expiration (client expires session after 2 min)
diff --git a/src/Identity/IdentityServer/RequestValidators/TwoFactorAuthenticationValidator.cs b/src/Identity/IdentityServer/RequestValidators/TwoFactorAuthenticationValidator.cs
index 80b3b6e1f4..000f98c006 100644
--- a/src/Identity/IdentityServer/RequestValidators/TwoFactorAuthenticationValidator.cs
+++ b/src/Identity/IdentityServer/RequestValidators/TwoFactorAuthenticationValidator.cs
@@ -91,7 +91,10 @@ public class TwoFactorAuthenticationValidator(
{ "TwoFactorProviders2", providers },
};
- // If we have email as a 2FA provider, we might need an SsoEmail2fa Session Token
+ // If we have an Email 2FA provider we need this session token so SSO users
+ // can re-request an email TOTP. The TwoFactorController.SendEmailLoginAsync
+ // endpoint requires a way to authenticate the user before sending another email with
+ // a TOTP, this token acts as the authentication mechanism.
if (enabledProviders.Any(p => p.Key == TwoFactorProviderType.Email))
{
twoFactorResultDict.Add("SsoEmail2faSessionToken",
@@ -100,12 +103,6 @@ public class TwoFactorAuthenticationValidator(
twoFactorResultDict.Add("Email", user.Email);
}
- if (enabledProviders.Count == 1 && enabledProviders.First().Key == TwoFactorProviderType.Email)
- {
- // Send email now if this is their only 2FA method
- await _userService.SendTwoFactorEmailAsync(user);
- }
-
return twoFactorResultDict;
}
diff --git a/test/Identity.Test/IdentityServer/TwoFactorAuthenticationValidatorTests.cs b/test/Identity.Test/IdentityServer/TwoFactorAuthenticationValidatorTests.cs
index 1f075a0147..53e9a00c9f 100644
--- a/test/Identity.Test/IdentityServer/TwoFactorAuthenticationValidatorTests.cs
+++ b/test/Identity.Test/IdentityServer/TwoFactorAuthenticationValidatorTests.cs
@@ -252,9 +252,9 @@ public class TwoFactorAuthenticationValidatorTests
[Theory]
[BitAutoData(TwoFactorProviderType.Email)]
- public async void BuildTwoFactorResultAsync_IndividualEmailProvider_SendsEmail_SetsSsoToken_ReturnsNotNull(
- TwoFactorProviderType providerType,
- User user)
+ public async void BuildTwoFactorResultAsync_SetsSsoToken_ReturnsNotNull(
+ TwoFactorProviderType providerType,
+ User user)
{
// Arrange
var providerTypeInt = (int)providerType;
@@ -276,8 +276,6 @@ public class TwoFactorAuthenticationValidatorTests
Assert.True(providers.ContainsKey(providerTypeInt.ToString()));
Assert.True(result.ContainsKey("SsoEmail2faSessionToken"));
Assert.True(result.ContainsKey("Email"));
-
- await _userService.Received(1).SendTwoFactorEmailAsync(Arg.Any());
}
[Theory]