From fc79042212b689aef8bcfae0dc0f73fe77984b93 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Sun, 9 Jul 2023 08:27:02 +0200 Subject: [PATCH] Update send notifications to only sync sends --- .../PushNotificationListenerService.cs | 16 ++++- src/Core/Abstractions/ISyncService.cs | 2 + .../Models/Response/NotificationResponse.cs | 7 ++ src/Core/Services/SyncService.cs | 72 +++++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/App/Services/PushNotificationListenerService.cs b/src/App/Services/PushNotificationListenerService.cs index 08bcb5ac5..4b49130e4 100644 --- a/src/App/Services/PushNotificationListenerService.cs +++ b/src/App/Services/PushNotificationListenerService.cs @@ -133,10 +133,20 @@ namespace Bit.App.Services break; case NotificationType.SyncSendCreate: case NotificationType.SyncSendUpdate: - case NotificationType.SyncSendDelete: - if (isAuthenticated) + var sendCreateUpdateMessage = JsonConvert.DeserializeObject( + notification.Payload); + if (isAuthenticated && sendCreateUpdateMessage.UserId == myUserId) { - await _syncService.Value.FullSyncAsync(false); + await _syncService.Value.SyncUpsertSendAsync(sendCreateUpdateMessage, + notification.Type == NotificationType.SyncCipherUpdate); + } + break; + case NotificationType.SyncSendDelete: + var sendDeleteMessage = JsonConvert.DeserializeObject( + notification.Payload); + if (isAuthenticated && sendDeleteMessage.UserId == myUserId) + { + await _syncService.Value.SyncDeleteSendAsync(sendDeleteMessage); } break; case NotificationType.AuthRequest: diff --git a/src/Core/Abstractions/ISyncService.cs b/src/Core/Abstractions/ISyncService.cs index aeb0205b1..52c686aac 100644 --- a/src/Core/Abstractions/ISyncService.cs +++ b/src/Core/Abstractions/ISyncService.cs @@ -12,8 +12,10 @@ namespace Bit.Core.Abstractions Task SetLastSyncAsync(DateTime date); Task SyncDeleteCipherAsync(SyncCipherNotification notification); Task SyncDeleteFolderAsync(SyncFolderNotification notification); + Task SyncDeleteSendAsync(SyncSendNotification notification); Task SyncUpsertCipherAsync(SyncCipherNotification notification, bool isEdit); Task SyncUpsertFolderAsync(SyncFolderNotification notification, bool isEdit); + Task SyncUpsertSendAsync(SyncSendNotification notification, bool isEdit); // Passwordless code will be moved to an independent service in future techdept Task SyncPasswordlessLoginRequestsAsync(); } diff --git a/src/Core/Models/Response/NotificationResponse.cs b/src/Core/Models/Response/NotificationResponse.cs index ae5405d9b..6addf5e07 100644 --- a/src/Core/Models/Response/NotificationResponse.cs +++ b/src/Core/Models/Response/NotificationResponse.cs @@ -33,6 +33,13 @@ namespace Bit.Core.Models.Response public string UserId { get; set; } public DateTime Date { get; set; } } + + public class SyncSendNotification + { + public string Id { get; set; } + public string UserId { get; set; } + public DateTime RevisionDate { get; set; } + } public class PasswordlessRequestNotification { diff --git a/src/Core/Services/SyncService.cs b/src/Core/Services/SyncService.cs index 4351e0f08..eb5af45f9 100644 --- a/src/Core/Services/SyncService.cs +++ b/src/Core/Services/SyncService.cs @@ -274,6 +274,78 @@ namespace Bit.Core.Services return SyncCompleted(false); } + public async Task SyncUpsertSendAsync(SyncSendNotification notification, bool isEdit) + { + SyncStarted(); + if (await _stateService.IsAuthenticatedAsync()) + { + try + { + var shouldUpdate = true; + var localSend = await _sendService.GetAsync(notification.Id); + if (localSend != null && localSend.RevisionDate >= notification.RevisionDate) + { + shouldUpdate = false; + } + + if (shouldUpdate) + { + if (isEdit) + { + shouldUpdate = localSend != null; + } + else + { + shouldUpdate = localSend == null; + } + } + + if (shouldUpdate) + { + var remoteSend = await _apiService.GetSendAsync(notification.Id); + if (remoteSend != null) + { + var userId = await _stateService.GetActiveUserIdAsync(); + await _sendService.UpsertAsync(new SendData(remoteSend, userId)); + _messagingService.Send("syncedUpsertedSend", new Dictionary + { + ["sendId"] = notification.Id + }); + return SyncCompleted(true); + } + } + } + catch (ApiException e) + { + if (e.Error != null && e.Error.StatusCode == System.Net.HttpStatusCode.NotFound && isEdit) + { + await _sendService.DeleteAsync(notification.Id); + _messagingService.Send("syncedDeletedSend", new Dictionary + { + ["sendId"] = notification.Id + }); + return SyncCompleted(true); + } + } + } + return SyncCompleted(false); + } + + public async Task SyncDeleteSendAsync(SyncSendNotification notification) + { + SyncStarted(); + if (await _stateService.IsAuthenticatedAsync()) + { + await _sendService.DeleteAsync(notification.Id); + _messagingService.Send("syncedDeletedSend", new Dictionary + { + ["sendId"] = notification.Id + }); + return SyncCompleted(true); + } + return SyncCompleted(false); + } + // Helpers private void SyncStarted()