diff --git a/src/Api/Controllers/SendsController.cs b/src/Api/Controllers/SendsController.cs index c9cbe91fa6..6b3751d676 100644 --- a/src/Api/Controllers/SendsController.cs +++ b/src/Api/Controllers/SendsController.cs @@ -84,7 +84,6 @@ namespace Bit.Api.Controllers [HttpPost("")] public async Task Post([FromBody] SendRequestModel model) { - throw new NotFoundException(); model.ValidateCreation(); var userId = _userService.GetProperUserId(User).Value; var send = model.ToSend(userId, _sendService); @@ -97,7 +96,6 @@ namespace Bit.Api.Controllers [DisableFormValueModelBinding] public async Task PostFile() { - throw new NotFoundException(); if (!Request?.ContentType.Contains("multipart/") ?? true) { throw new BadRequestException("Invalid content."); diff --git a/src/Core/Enums/PushType.cs b/src/Core/Enums/PushType.cs index 67ada37fa7..7899656b5f 100644 --- a/src/Core/Enums/PushType.cs +++ b/src/Core/Enums/PushType.cs @@ -16,5 +16,9 @@ SyncSettings = 10, LogOut = 11, + + SyncSendCreate = 12, + SyncSendUpdate = 13, + SyncSendDelete = 14, } } diff --git a/src/Core/Models/PushNotification.cs b/src/Core/Models/PushNotification.cs index 0945da0db0..b5d4d37025 100644 --- a/src/Core/Models/PushNotification.cs +++ b/src/Core/Models/PushNotification.cs @@ -39,4 +39,11 @@ namespace Bit.Core.Models public Guid UserId { get; set; } public DateTime Date { get; set; } } + + public class SyncSendPushNotification + { + public Guid Id { get; set; } + public Guid UserId { get; set; } + public DateTime RevisionDate { get; set; } + } } diff --git a/src/Core/Services/IPushNotificationService.cs b/src/Core/Services/IPushNotificationService.cs index 6f55620bc2..799fd1a532 100644 --- a/src/Core/Services/IPushNotificationService.cs +++ b/src/Core/Services/IPushNotificationService.cs @@ -19,6 +19,9 @@ namespace Bit.Core.Services Task PushSyncOrgKeysAsync(Guid userId); Task PushSyncSettingsAsync(Guid userId); Task PushLogOutAsync(Guid userId); + Task PushSyncSendCreateAsync(Send send); + Task PushSyncSendUpdateAsync(Send send); + Task PushSyncSendDeleteAsync(Send send); Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier, string deviceId = null); Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier, string deviceId = null); diff --git a/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs b/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs index 0bfc860f2c..723bc0c7b3 100644 --- a/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs +++ b/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs @@ -135,6 +135,36 @@ namespace Bit.Core.Services await SendMessageAsync(type, message, false); } + public async Task PushSyncSendCreateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendCreate); + } + + public async Task PushSyncSendUpdateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendUpdate); + } + + public async Task PushSyncSendDeleteAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendDelete); + } + + private async Task PushSendAsync(Send send, PushType type) + { + if (send.UserId.HasValue) + { + var message = new SyncSendPushNotification + { + Id = send.Id, + UserId = send.UserId.Value, + RevisionDate = send.RevisionDate + }; + + await SendMessageAsync(type, message, true); + } + } + private async Task SendMessageAsync(PushType type, T payload, bool excludeCurrentContext) { var contextId = GetContextIdentifier(excludeCurrentContext); diff --git a/src/Core/Services/Implementations/MultiServicePushNotificationService.cs b/src/Core/Services/Implementations/MultiServicePushNotificationService.cs index 40ce4fbf3a..ffc46564c1 100644 --- a/src/Core/Services/Implementations/MultiServicePushNotificationService.cs +++ b/src/Core/Services/Implementations/MultiServicePushNotificationService.cs @@ -122,6 +122,24 @@ namespace Bit.Core.Services return Task.FromResult(0); } + public Task PushSyncSendCreateAsync(Send send) + { + PushToServices((s) => s.PushSyncSendCreateAsync(send)); + return Task.FromResult(0); + } + + public Task PushSyncSendUpdateAsync(Send send) + { + PushToServices((s) => s.PushSyncSendUpdateAsync(send)); + return Task.FromResult(0); + } + + public Task PushSyncSendDeleteAsync(Send send) + { + PushToServices((s) => s.PushSyncSendDeleteAsync(send)); + return Task.FromResult(0); + } + public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier, string deviceId = null) { diff --git a/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs b/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs index e12a55baa0..d7cf981127 100644 --- a/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs +++ b/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs @@ -136,6 +136,36 @@ namespace Bit.Core.Services await SendPayloadToUserAsync(userId, type, message, false); } + public async Task PushSyncSendCreateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendCreate); + } + + public async Task PushSyncSendUpdateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendUpdate); + } + + public async Task PushSyncSendDeleteAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendDelete); + } + + private async Task PushSendAsync(Send send, PushType type) + { + if (send.UserId.HasValue) + { + var message = new SyncSendPushNotification + { + Id = send.Id, + UserId = send.UserId.Value, + RevisionDate = send.RevisionDate + }; + + await SendPayloadToUserAsync(message.UserId, type, message, true); + } + } + private async Task SendPayloadToUserAsync(Guid userId, PushType type, object payload, bool excludeCurrentContext) { await SendPayloadToUserAsync(userId.ToString(), type, payload, GetContextIdentifier(excludeCurrentContext)); diff --git a/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs b/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs index 04f2240268..c4d8eed121 100644 --- a/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs +++ b/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs @@ -142,6 +142,36 @@ namespace Bit.Core.Services await SendMessageAsync(type, message, false); } + public async Task PushSyncSendCreateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendCreate); + } + + public async Task PushSyncSendUpdateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendUpdate); + } + + public async Task PushSyncSendDeleteAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendDelete); + } + + private async Task PushSendAsync(Send send, PushType type) + { + if (send.UserId.HasValue) + { + var message = new SyncSendPushNotification + { + Id = send.Id, + UserId = send.UserId.Value, + RevisionDate = send.RevisionDate + }; + + await SendMessageAsync(type, message, false); + } + } + private async Task SendMessageAsync(PushType type, T payload, bool excludeCurrentContext) { var contextId = GetContextIdentifier(excludeCurrentContext); diff --git a/src/Core/Services/Implementations/RelayPushNotificationService.cs b/src/Core/Services/Implementations/RelayPushNotificationService.cs index d17e71f21c..3611d5276c 100644 --- a/src/Core/Services/Implementations/RelayPushNotificationService.cs +++ b/src/Core/Services/Implementations/RelayPushNotificationService.cs @@ -139,6 +139,36 @@ namespace Bit.Core.Services await SendPayloadToUserAsync(userId, type, message, false); } + public async Task PushSyncSendCreateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendCreate); + } + + public async Task PushSyncSendUpdateAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendUpdate); + } + + public async Task PushSyncSendDeleteAsync(Send send) + { + await PushSendAsync(send, PushType.SyncSendDelete); + } + + private async Task PushSendAsync(Send send, PushType type) + { + if (send.UserId.HasValue) + { + var message = new SyncSendPushNotification + { + Id = send.Id, + UserId = send.UserId.Value, + RevisionDate = send.RevisionDate + }; + + await SendPayloadToUserAsync(message.UserId, type, message, true); + } + } + private async Task SendPayloadToUserAsync(Guid userId, PushType type, object payload, bool excludeCurrentContext) { var request = new PushSendRequestModel diff --git a/src/Core/Services/Implementations/SendService.cs b/src/Core/Services/Implementations/SendService.cs index 5888b6b2bb..73f3eb0872 100644 --- a/src/Core/Services/Implementations/SendService.cs +++ b/src/Core/Services/Implementations/SendService.cs @@ -18,6 +18,7 @@ namespace Bit.Core.Services private readonly IOrganizationRepository _organizationRepository; private readonly ISendFileStorageService _sendFileStorageService; private readonly IPasswordHasher _passwordHasher; + private readonly IPushNotificationService _pushService; private readonly GlobalSettings _globalSettings; public SendService( @@ -27,6 +28,7 @@ namespace Bit.Core.Services IOrganizationRepository organizationRepository, ISendFileStorageService sendFileStorageService, IPasswordHasher passwordHasher, + IPushNotificationService pushService, GlobalSettings globalSettings) { _sendRepository = sendRepository; @@ -35,6 +37,7 @@ namespace Bit.Core.Services _organizationRepository = organizationRepository; _sendFileStorageService = sendFileStorageService; _passwordHasher = passwordHasher; + _pushService = pushService; _globalSettings = globalSettings; } @@ -43,11 +46,13 @@ namespace Bit.Core.Services if (send.Id == default(Guid)) { await _sendRepository.CreateAsync(send); + await _pushService.PushSyncSendCreateAsync(send); } else { send.RevisionDate = DateTime.UtcNow; await _sendRepository.UpsertAsync(send); + await _pushService.PushSyncSendUpdateAsync(send); } } @@ -129,6 +134,7 @@ namespace Bit.Core.Services var data = JsonConvert.DeserializeObject(send.Data); await _sendFileStorageService.DeleteFileAsync(data.Id); } + await _pushService.PushSyncSendDeleteAsync(send); } // Response: Send, password required, password invalid diff --git a/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs b/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs index 7a85d3ac08..d49239d338 100644 --- a/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs +++ b/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs @@ -63,6 +63,21 @@ namespace Bit.Core.Services return Task.FromResult(0); } + public Task PushSyncSendCreateAsync(Send send) + { + return Task.FromResult(0); + } + + public Task PushSyncSendDeleteAsync(Send send) + { + return Task.FromResult(0); + } + + public Task PushSyncSendUpdateAsync(Send send) + { + return Task.FromResult(0); + } + public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier, string deviceId = null) { diff --git a/src/Notifications/HubHelpers.cs b/src/Notifications/HubHelpers.cs index 7f907fde1e..d71912ceb1 100644 --- a/src/Notifications/HubHelpers.cs +++ b/src/Notifications/HubHelpers.cs @@ -54,6 +54,15 @@ namespace Bit.Notifications await hubContext.Clients.User(userNotification.Payload.UserId.ToString()) .SendAsync("ReceiveMessage", userNotification, cancellationToken); break; + case PushType.SyncSendCreate: + case PushType.SyncSendUpdate: + case PushType.SyncSendDelete: + var sendNotification = + JsonConvert.DeserializeObject>( + notificationJson); + await hubContext.Clients.User(sendNotification.Payload.UserId.ToString()) + .SendAsync("ReceiveMessage", sendNotification, cancellationToken); + break; default: break; }