From f21fae7feafeef09d9af9c64ba74c85842a1a260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bispo?= Date: Wed, 6 Sep 2023 10:26:11 +0100 Subject: [PATCH] [PM-3382] User cannot select Email as a secondary 2FA option following SSO (#2719) * [PM-3382] Update mobile client to receive and use SsoEmail2faSessionToken * [PM-3382] Fix null 2fa email with local email on MP login. --- src/App/Pages/Accounts/TwoFactorPageViewModel.cs | 3 ++- src/Core/Abstractions/IAuthService.cs | 1 + src/Core/Models/Request/TwoFactorEmailRequest.cs | 1 + src/Core/Models/Response/IdentityTwoFactorResponse.cs | 2 ++ src/Core/Services/AuthService.cs | 6 ++++-- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/App/Pages/Accounts/TwoFactorPageViewModel.cs b/src/App/Pages/Accounts/TwoFactorPageViewModel.cs index a49b9fa02..74fcec583 100644 --- a/src/App/Pages/Accounts/TwoFactorPageViewModel.cs +++ b/src/App/Pages/Accounts/TwoFactorPageViewModel.cs @@ -466,7 +466,8 @@ namespace Bit.App.Pages { Email = _authService.Email, MasterPasswordHash = _authService.MasterPasswordHash, - DeviceIdentifier = await _appIdService.GetAppIdAsync() + DeviceIdentifier = await _appIdService.GetAppIdAsync(), + SsoEmail2FaSessionToken = _authService.SsoEmail2FaSessionToken }; await _apiService.PostTwoFactorEmailAsync(request); if (showLoading) diff --git a/src/Core/Abstractions/IAuthService.cs b/src/Core/Abstractions/IAuthService.cs index 88c537f4d..64de565ee 100644 --- a/src/Core/Abstractions/IAuthService.cs +++ b/src/Core/Abstractions/IAuthService.cs @@ -15,6 +15,7 @@ namespace Bit.Core.Abstractions string Code { get; set; } string CodeVerifier { get; set; } string SsoRedirectUrl { get; set; } + string SsoEmail2FaSessionToken { get; set; } TwoFactorProviderType? SelectedTwoFactorProviderType { get; set; } Dictionary TwoFactorProviders { get; set; } Dictionary> TwoFactorProvidersData { get; set; } diff --git a/src/Core/Models/Request/TwoFactorEmailRequest.cs b/src/Core/Models/Request/TwoFactorEmailRequest.cs index 2b5784099..d1a65884a 100644 --- a/src/Core/Models/Request/TwoFactorEmailRequest.cs +++ b/src/Core/Models/Request/TwoFactorEmailRequest.cs @@ -5,5 +5,6 @@ public string Email { get; set; } public string MasterPasswordHash { get; set; } public string DeviceIdentifier { get; set; } + public string SsoEmail2FaSessionToken { get; set; } } } diff --git a/src/Core/Models/Response/IdentityTwoFactorResponse.cs b/src/Core/Models/Response/IdentityTwoFactorResponse.cs index 3607a3230..89ff9d92e 100644 --- a/src/Core/Models/Response/IdentityTwoFactorResponse.cs +++ b/src/Core/Models/Response/IdentityTwoFactorResponse.cs @@ -12,5 +12,7 @@ namespace Bit.Core.Models.Response public MasterPasswordPolicyOptions MasterPasswordPolicy { get; set; } [JsonProperty("CaptchaBypassToken")] public string CaptchaToken { get; set; } + public string SsoEmail2faSessionToken { get; set; } + public string Email { get; set; } } } diff --git a/src/Core/Services/AuthService.cs b/src/Core/Services/AuthService.cs index d1d38382a..f89d25ed6 100644 --- a/src/Core/Services/AuthService.cs +++ b/src/Core/Services/AuthService.cs @@ -124,6 +124,7 @@ namespace Bit.Core.Services public string Code { get; set; } public string CodeVerifier { get; set; } public string SsoRedirectUrl { get; set; } + public string SsoEmail2FaSessionToken { get; set; } public Dictionary TwoFactorProviders { get; set; } public Dictionary> TwoFactorProvidersData { get; set; } public TwoFactorProviderType? SelectedTwoFactorProviderType { get; set; } @@ -457,20 +458,21 @@ namespace Bit.Core.Services if (result.TwoFactor) { // Two factor required. - Email = email; + Email = response.TwoFactorResponse.Email ?? email; MasterPasswordHash = hashedPassword; LocalMasterPasswordHash = localHashedPassword; AuthRequestId = authRequestId; Code = code; CodeVerifier = codeVerifier; SsoRedirectUrl = redirectUrl; + SsoEmail2FaSessionToken = response.TwoFactorResponse.SsoEmail2faSessionToken; _masterKey = _setCryptoKeys ? masterKey : null; _userKey = userKey2FA; TwoFactorProvidersData = response.TwoFactorResponse.TwoFactorProviders2; result.TwoFactorProviders = response.TwoFactorResponse.TwoFactorProviders2; CaptchaToken = response.TwoFactorResponse.CaptchaToken; _masterPasswordPolicy = response.TwoFactorResponse.MasterPasswordPolicy; - await _tokenService.ClearTwoFactorTokenAsync(email); + await _tokenService.ClearTwoFactorTokenAsync(Email); return result; }