diff --git a/src/Core/Services/SettingsService.cs b/src/Core/Services/SettingsService.cs index e7be16eb..8a58adf0 100644 --- a/src/Core/Services/SettingsService.cs +++ b/src/Core/Services/SettingsService.cs @@ -216,6 +216,19 @@ namespace Bit.Core.Services } } + public string LastSyncHash + { + get + { + return Settings.LastSyncHash; + } + set + { + Settings.LastSyncHash = value; + SaveSettings(); + } + } + public class SettingsModel { public string ApiBaseUrl { get; set; } = "https://api.bitwarden.com"; @@ -229,6 +242,7 @@ namespace Bit.Core.Services public DateTime? LastUserSyncDate { get; set; } public string GroupDeltaToken { get; set; } public string UserDeltaToken { get; set; } + public string LastSyncHash { get; set; } } } } diff --git a/src/Core/Utilities/Sync.cs b/src/Core/Utilities/Sync.cs index dd1d027c..7d318000 100644 --- a/src/Core/Utilities/Sync.cs +++ b/src/Core/Utilities/Sync.cs @@ -1,8 +1,11 @@ using Bit.Core.Models; using Bit.Core.Services; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; +using System.Text; using System.Threading.Tasks; namespace Bit.Core.Utilities @@ -23,9 +26,13 @@ namespace Bit.Core.Utilities FlattenUsersToGroups(groups, null, groups); - if(!sendToServer || (groups.Count == 0 && users.Count == 0)) + if(!sendToServer) { RestoreDeltas(startingGroupDelta, startingUserDelta); + } + + if(!sendToServer || (groups.Count == 0 && users.Count == 0)) + { return new SyncResult { Success = true, @@ -35,9 +42,24 @@ namespace Bit.Core.Utilities } var request = new ImportRequest(groups, users); + var json = JsonConvert.SerializeObject(request); + var hash = ComputeHash(json); + + if(hash == SettingsService.Instance.LastSyncHash) + { + return new SyncResult + { + Success = true, + Groups = groups, + Users = users + }; + } + var response = await ApiService.Instance.PostImportAsync(request); if(response.Succeeded) { + SettingsService.Instance.LastSyncHash = hash; + if(SettingsService.Instance.Sync.SyncGroups) { SettingsService.Instance.LastGroupSyncDate = now; @@ -122,8 +144,31 @@ namespace Bit.Core.Utilities private static void RestoreDeltas(string groupDelta, string userDelta) { + if(SettingsService.Instance.Server.Type != Enums.DirectoryType.AzureActiveDirectory) + { + return; + } + SettingsService.Instance.GroupDeltaToken = groupDelta; SettingsService.Instance.UserDeltaToken = userDelta; } + + private static string ComputeHash(string value) + { + if(value == null) + { + return null; + } + + string result = null; + using(var hash = SHA256.Create()) + { + var bytes = Encoding.UTF8.GetBytes(value); + var hashBytes = hash.ComputeHash(bytes); + result = Convert.ToBase64String(hashBytes); + } + + return result; + } } }