1
0
mirror of https://github.com/bitwarden/server synced 2025-12-21 18:53:41 +00:00

feat(2FA): [PM-17129] Login with 2FA Recovery Code

* feat(2FA): [PM-17129] Login with 2FA Recovery Code - Login with Recovery Code working.

* feat(2FA): [PM-17129] Login with 2FA Recovery Code - Feature flagged implementation.

* style(2FA): [PM-17129] Login with 2FA Recovery Code - Code cleanup.

* test(2FA): [PM-17129] Login with 2FA Recovery Code - Tests.
This commit is contained in:
Patrick-Pimentel-Bitwarden
2025-02-13 15:51:36 -05:00
committed by GitHub
parent 465549b812
commit ac6bc40d85
10 changed files with 220 additions and 76 deletions

View File

@@ -22,7 +22,6 @@ public interface IUserService
Task<IdentityResult> CreateUserAsync(User user, string masterPasswordHash);
Task SendMasterPasswordHintAsync(string email);
Task SendTwoFactorEmailAsync(User user);
Task<bool> VerifyTwoFactorEmailAsync(User user, string token);
Task<CredentialCreateOptions> StartWebAuthnRegistrationAsync(User user);
Task<bool> DeleteWebAuthnKeyAsync(User user, int id);
Task<bool> CompleteWebAuthRegistrationAsync(User user, int value, string name, AuthenticatorAttestationRawResponse attestationResponse);
@@ -41,8 +40,6 @@ public interface IUserService
Task<IdentityResult> RefreshSecurityStampAsync(User user, string masterPasswordHash);
Task UpdateTwoFactorProviderAsync(User user, TwoFactorProviderType type, bool setEnabled = true, bool logEvent = true);
Task DisableTwoFactorProviderAsync(User user, TwoFactorProviderType type);
Task<bool> RecoverTwoFactorAsync(string email, string masterPassword, string recoveryCode);
Task<string> GenerateUserTokenAsync(User user, string tokenProvider, string purpose);
Task<IdentityResult> DeleteAsync(User user);
Task<IdentityResult> DeleteAsync(User user, string token);
Task SendDeleteConfirmationAsync(string email);
@@ -55,9 +52,7 @@ public interface IUserService
Task CancelPremiumAsync(User user, bool? endOfPeriod = null);
Task ReinstatePremiumAsync(User user);
Task EnablePremiumAsync(Guid userId, DateTime? expirationDate);
Task EnablePremiumAsync(User user, DateTime? expirationDate);
Task DisablePremiumAsync(Guid userId, DateTime? expirationDate);
Task DisablePremiumAsync(User user, DateTime? expirationDate);
Task UpdatePremiumExpirationAsync(Guid userId, DateTime? expirationDate);
Task<UserLicense> GenerateLicenseAsync(User user, SubscriptionInfo subscriptionInfo = null,
int? version = null);
@@ -91,9 +86,26 @@ public interface IUserService
void SetTwoFactorProvider(User user, TwoFactorProviderType type, bool setEnabled = true);
[Obsolete("To be removed when the feature flag pm-17128-recovery-code-login is removed PM-18175.")]
Task<bool> RecoverTwoFactorAsync(string email, string masterPassword, string recoveryCode);
/// <summary>
/// Returns true if the user is a legacy user. Legacy users use their master key as their encryption key.
/// We force these users to the web to migrate their encryption scheme.
/// This method is used by the TwoFactorAuthenticationValidator to recover two
/// factor for a user. This allows users to be logged in after a successful recovery
/// attempt.
///
/// This method logs the event, sends an email to the user, and removes two factor
/// providers on the user account. This means that a user will have to accomplish
/// new device verification on their account on new logins, if it is enabled for their user.
/// </summary>
/// <param name="recoveryCode">recovery code associated with the user logging in</param>
/// <param name="user">The user to refresh the 2FA and Recovery Code on.</param>
/// <returns>true if the recovery code is valid; false otherwise</returns>
Task<bool> RecoverTwoFactorAsync(User user, string recoveryCode);
/// <summary>
/// Returns true if the user is a legacy user. Legacy users use their master key as their
/// encryption key. We force these users to the web to migrate their encryption scheme.
/// </summary>
Task<bool> IsLegacyUser(string userId);
@@ -101,7 +113,8 @@ public interface IUserService
/// Indicates if the user is managed by any organization.
/// </summary>
/// <remarks>
/// A user is considered managed by an organization if their email domain matches one of the verified domains of that organization, and the user is a member of it.
/// A user is considered managed by an organization if their email domain matches one of the
/// verified domains of that organization, and the user is a member of it.
/// The organization must be enabled and able to have verified domains.
/// </remarks>
/// <returns>