From 37428c01dd38881bf0718e966063e603d6877107 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 27 Jun 2017 16:35:29 -0400 Subject: [PATCH] remeber two factor token --- .../Abstractions/Services/ITokenService.cs | 1 + src/App/Models/Api/Response/TokenResponse.cs | 1 + src/App/Pages/LoginPage.cs | 2 ++ src/App/Repositories/ConnectApiRepository.cs | 3 ++- src/App/Services/AuthService.cs | 13 +++++++++ src/App/Services/TokenService.cs | 27 +++++++++++++++++++ 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/App/Abstractions/Services/ITokenService.cs b/src/App/Abstractions/Services/ITokenService.cs index c7819dc32..ecc5b14cd 100644 --- a/src/App/Abstractions/Services/ITokenService.cs +++ b/src/App/Abstractions/Services/ITokenService.cs @@ -8,6 +8,7 @@ namespace Bit.App.Abstractions string RefreshToken { get; set; } [Obsolete("Old auth scheme")] string AuthBearer { get; set; } + string TwoFactorToken { get; set; } DateTime TokenExpiration { get; } string TokenIssuer { get; } bool TokenExpired { get; } diff --git a/src/App/Models/Api/Response/TokenResponse.cs b/src/App/Models/Api/Response/TokenResponse.cs index 84e7b01e9..84d553a9d 100644 --- a/src/App/Models/Api/Response/TokenResponse.cs +++ b/src/App/Models/Api/Response/TokenResponse.cs @@ -16,6 +16,7 @@ namespace Bit.App.Models.Api public string TokenType { get; set; } public Dictionary> TwoFactorProviders2 { get; set; } public string PrivateKey { get; set; } + public string TwoFactorToken { get; set; } public string Key { get; set; } } } diff --git a/src/App/Pages/LoginPage.cs b/src/App/Pages/LoginPage.cs index 3a17e7680..d49c51b1d 100644 --- a/src/App/Pages/LoginPage.cs +++ b/src/App/Pages/LoginPage.cs @@ -189,6 +189,8 @@ namespace Bit.App.Pages return; } + PasswordCell.Entry.Text = string.Empty; + if(result.TwoFactorRequired) { _googleAnalyticsService.TrackAppEvent("LoggedIn To Two-step"); diff --git a/src/App/Repositories/ConnectApiRepository.cs b/src/App/Repositories/ConnectApiRepository.cs index cc60c1cf3..822a10335 100644 --- a/src/App/Repositories/ConnectApiRepository.cs +++ b/src/App/Repositories/ConnectApiRepository.cs @@ -5,7 +5,6 @@ using Bit.App.Abstractions; using Bit.App.Models.Api; using Newtonsoft.Json; using Plugin.Connectivity.Abstractions; -using System.Net; using Newtonsoft.Json.Linq; using System.Collections.Generic; using Bit.App.Enums; @@ -49,6 +48,8 @@ namespace Bit.App.Repositories var errorResponse = JObject.Parse(responseContent); if(errorResponse["TwoFactorProviders2"] != null) { + TokenService.TwoFactorToken = null; + return ApiResult.Success(new TokenResponse { TwoFactorProviders2 = diff --git a/src/App/Services/AuthService.cs b/src/App/Services/AuthService.cs index c38d3c4b2..dec07eb11 100644 --- a/src/App/Services/AuthService.cs +++ b/src/App/Services/AuthService.cs @@ -222,6 +222,14 @@ namespace Bit.App.Services Device = new DeviceRequest(_appIdService, _deviceInfoService) }; + var twoFactorToken = _tokenService.TwoFactorToken; + if(!string.IsNullOrWhiteSpace(twoFactorToken)) + { + request.Token = twoFactorToken; + request.Provider = TwoFactorProviderType.Remember; + request.Remember = false; + } + var response = await _connectApiRepository.PostTokenAsync(request); if(!response.Succeeded) { @@ -273,6 +281,11 @@ namespace Bit.App.Services private async Task ProcessLoginSuccessAsync(SymmetricCryptoKey key, TokenResponse response) { + if(!string.IsNullOrWhiteSpace(response.TwoFactorToken)) + { + _tokenService.TwoFactorToken = response.TwoFactorToken; + } + if(response.Key != null) { _cryptoService.SetEncKey(new CipherString(response.Key)); diff --git a/src/App/Services/TokenService.cs b/src/App/Services/TokenService.cs index 526a9fac1..d115b6880 100644 --- a/src/App/Services/TokenService.cs +++ b/src/App/Services/TokenService.cs @@ -9,6 +9,7 @@ namespace Bit.App.Services { private const string TokenKey = "accessToken"; private const string RefreshTokenKey = "refreshToken"; + private const string TwoFactorTokenKey = "twoFactorToken"; private const string AuthBearerKey = "token"; private readonly ISecureStorageService _secureStorage; @@ -165,6 +166,32 @@ namespace Bit.App.Services } } + public string TwoFactorToken + { + get + { + var tokenBytes = _secureStorage.Retrieve(TwoFactorTokenKey); + if(tokenBytes == null) + { + return null; + } + + return Encoding.UTF8.GetString(tokenBytes, 0, tokenBytes.Length); + } + set + { + if(value != null) + { + var tokenBytes = Encoding.UTF8.GetBytes(value); + _secureStorage.Store(TwoFactorTokenKey, tokenBytes); + } + else + { + _secureStorage.Delete(TwoFactorTokenKey); + } + } + } + public JObject DecodeToken() { if(_decodedToken != null)