diff --git a/src/App/Abstractions/Services/IAppSettingsService.cs b/src/App/Abstractions/Services/IAppSettingsService.cs index f10fe8a5f..3780c5672 100644 --- a/src/App/Abstractions/Services/IAppSettingsService.cs +++ b/src/App/Abstractions/Services/IAppSettingsService.cs @@ -5,6 +5,8 @@ namespace Bit.App.Abstractions public interface IAppSettingsService { bool Locked { get; set; } + string LockTimerId { get; set; } + double LastActivityLockTime { get; set; } DateTime LastActivity { get; set; } DateTime LastCacheClear { get; set; } bool AutofillPersistNotification { get; set; } diff --git a/src/App/Abstractions/Services/ILockService.cs b/src/App/Abstractions/Services/ILockService.cs index 405b773aa..dd4066305 100644 --- a/src/App/Abstractions/Services/ILockService.cs +++ b/src/App/Abstractions/Services/ILockService.cs @@ -7,7 +7,7 @@ namespace Bit.App.Abstractions public interface ILockService { bool CheckForLockInBackground { get; set; } - void UpdateLastActivity(DateTime? activityDate = null); + void UpdateLastActivity(); Task GetLockTypeAsync(bool forceLock); Task CheckLockAsync(bool forceLock); bool TopPageIsLock(); diff --git a/src/App/App.cs b/src/App/App.cs index 9ad9b1421..551133b31 100644 --- a/src/App/App.cs +++ b/src/App/App.cs @@ -87,8 +87,7 @@ namespace Bit.App }); } - // TODO: Still testing. - //_lockService.StartLockTimer(); + _lockService.StartLockTimer(); } protected async override void OnStart() diff --git a/src/App/Constants.cs b/src/App/Constants.cs index 73d13fcf4..1555284a8 100644 --- a/src/App/Constants.cs +++ b/src/App/Constants.cs @@ -33,8 +33,10 @@ public const string SecurityStamp = "other:securityStamp"; public const string LastActivityDate = "other:lastActivityDate"; + public const string LastActivityLockTime = "other:lastActivityLockTime"; public const string LastCacheClearDate = "other:cacheClearDate"; public const string Locked = "other:locked"; + public const string LockTimerId = "other:lockTimerId"; public const string LastLoginEmail = "other:lastLoginEmail"; public const string LastSync = "other:lastSync"; public const string LastBuildKey = "LastBuild"; diff --git a/src/App/Services/AppSettingsService.cs b/src/App/Services/AppSettingsService.cs index be2bc2f01..a60d524bd 100644 --- a/src/App/Services/AppSettingsService.cs +++ b/src/App/Services/AppSettingsService.cs @@ -26,6 +26,30 @@ namespace Bit.App.Services } } + public string LockTimerId + { + get + { + return _settings.GetValueOrDefault(Constants.LockTimerId, null); + } + set + { + _settings.AddOrUpdateValue(Constants.LockTimerId, value); + } + } + + public double LastActivityLockTime + { + get + { + return _settings.GetValueOrDefault(Constants.LastActivityLockTime, Double.MinValue); + } + set + { + _settings.AddOrUpdateValue(Constants.LastActivityLockTime, value); + } + } + public DateTime LastActivity { get diff --git a/src/App/Services/LockService.cs b/src/App/Services/LockService.cs index 8668ba077..f2a0711de 100644 --- a/src/App/Services/LockService.cs +++ b/src/App/Services/LockService.cs @@ -17,8 +17,7 @@ namespace Bit.App.Services private readonly IAppSettingsService _appSettings; private readonly IAuthService _authService; private readonly IFingerprint _fingerprint; - private bool _timerCreated = false; - private bool _firstLockCheck = false; // TODO: true when we want to support this + private string _timerId = null; public LockService( ISettings settings, @@ -33,46 +32,52 @@ namespace Bit.App.Services } public bool CheckForLockInBackground { get; set; } = true; + public double CurrentLockTime { get; set; } - public void UpdateLastActivity(DateTime? activityDate = null) + public void UpdateLastActivity() { if(_appSettings.Locked) { return; } - _appSettings.LastActivity = activityDate.GetValueOrDefault(DateTime.UtcNow); + _appSettings.LastActivityLockTime = CurrentLockTime; } public async Task GetLockTypeAsync(bool forceLock) { + var returnNone = false; + // Only lock if they are logged in if(!_authService.IsAuthenticated) { - return LockType.None; + returnNone = true; } - - // Lock seconds tells if they want to lock the app or not - var lockSeconds = _settings.GetValueOrDefault(Constants.SettingLockSeconds, 60 * 15); - // Are we forcing a lock? (i.e. clicking a button to lock the app manually, immediately) - if(!_firstLockCheck && !forceLock && !_appSettings.Locked) + else if(!forceLock && !_appSettings.Locked) { + // Lock seconds tells if they want to lock the app or not + var lockSeconds = _settings.GetValueOrDefault(Constants.SettingLockSeconds, 60 * 15); if(lockSeconds == -1) { - return LockType.None; + returnNone = true; } - - // Has it been longer than lockSeconds since the last time the app was used? - var now = DateTime.UtcNow; - if(now > _appSettings.LastActivity && (now - _appSettings.LastActivity).TotalSeconds < lockSeconds) + // Validate timer instance + else if(_appSettings.LockTimerId != null && _timerId == _appSettings.LockTimerId) { - return LockType.None; + // Has it been longer than lockSeconds since the last time the app was used? + var now = CurrentLockTime; + var elapsedSeconds = (now - _appSettings.LastActivityLockTime) / 1000; + if(now >= _appSettings.LastActivityLockTime && elapsedSeconds < lockSeconds) + { + returnNone = true; + } } } - // Skip first lock check if not using locking - if(_firstLockCheck && lockSeconds == -1 && !forceLock && !_appSettings.Locked) + // Set the new lock timer id + _appSettings.LockTimerId = _timerId; + if(returnNone) { return LockType.None; } @@ -99,13 +104,10 @@ namespace Bit.App.Services { if(TopPageIsLock()) { - // already locked - _firstLockCheck = false; return; } var lockType = await GetLockTypeAsync(forceLock); - _firstLockCheck = false; if(lockType == LockType.None) { return; @@ -152,25 +154,16 @@ namespace Bit.App.Services public void StartLockTimer() { - if(_timerCreated) + if(_timerId != null) { return; } - _timerCreated = true; - Device.StartTimer(TimeSpan.FromMinutes(1), () => + _timerId = Guid.NewGuid().ToString(); + var interval = TimeSpan.FromSeconds(10); + Device.StartTimer(interval, () => { - if(CheckForLockInBackground && !_appSettings.Locked) - { - System.Diagnostics.Debug.WriteLine("Check lock from timer at " + DateTime.Now); - var lockType = GetLockTypeAsync(false).GetAwaiter().GetResult(); - if(lockType != LockType.None) - { - System.Diagnostics.Debug.WriteLine("Locked from timer at " + DateTime.Now); - _appSettings.Locked = true; - } - } - + CurrentLockTime += interval.TotalMilliseconds; return true; }); }