diff --git a/src/Core/Models/PushNotification.cs b/src/Core/Models/PushNotification.cs new file mode 100644 index 0000000000..335daeca6b --- /dev/null +++ b/src/Core/Models/PushNotification.cs @@ -0,0 +1,63 @@ +using Bit.Core.Enums; +using Newtonsoft.Json; +using System; + +namespace Bit.Core.Models +{ + public class PayloadPushNotification + { + [JsonProperty(PropertyName = "data")] + public DataObj Data { get; set; } + + public class DataObj + { + public DataObj(PushType type, string payload) + { + Type = type; + Payload = payload; + } + + [JsonProperty(PropertyName = "type")] + public PushType Type { get; set; } + [JsonProperty(PropertyName = "payload")] + public string Payload { get; set; } + } + } + + public class ApplePayloadPushNotification : PayloadPushNotification + { + [JsonProperty(PropertyName = "aps")] + public AppleData Aps { get; set; } = new AppleData { ContentAvailable = 1 }; + + public class AppleData + { + [JsonProperty(PropertyName = "badge")] + public dynamic Badge { get; set; } = null; + [JsonProperty(PropertyName = "alert")] + public string Alert { get; set; } + [JsonProperty(PropertyName = "content-available")] + public int ContentAvailable { get; set; } + } + } + + public class SyncCipherPushNotification + { + public Guid Id { get; set; } + public Guid? UserId { get; set; } + public Guid? OrganizationId { get; set; } + public DateTime RevisionDate { get; set; } + } + + public class SyncFolderPushNotification + { + public Guid Id { get; set; } + public Guid UserId { get; set; } + public DateTime RevisionDate { get; set; } + } + + public class SyncUserPushNotification + { + public Guid UserId { get; set; } + public DateTime Date { get; set; } + } +} diff --git a/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs b/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs index c509259705..83abc916b1 100644 --- a/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs +++ b/src/Core/Services/Implementations/NotificationHubPushNotificationService.cs @@ -6,6 +6,7 @@ using Bit.Core.Enums; using Newtonsoft.Json; using System.Collections.Generic; using Microsoft.AspNetCore.Http; +using Bit.Core.Models; namespace Bit.Core.Services { @@ -158,26 +159,5 @@ namespace Bit.Core.Services { "payload", JsonConvert.SerializeObject(payload) } }, tag); } - - private class SyncCipherPushNotification - { - public Guid Id { get; set; } - public Guid? UserId { get; set; } - public Guid? OrganizationId { get; set; } - public DateTime RevisionDate { get; set; } - } - - private class SyncFolderPushNotification - { - public Guid Id { get; set; } - public Guid UserId { get; set; } - public DateTime RevisionDate { get; set; } - } - - private class SyncUserPushNotification - { - public Guid UserId { get; set; } - public DateTime Date { get; set; } - } } } diff --git a/src/Core/Services/Implementations/PushSharpPushNotificationService.cs b/src/Core/Services/Implementations/PushSharpPushNotificationService.cs index c502b36162..1357725238 100644 --- a/src/Core/Services/Implementations/PushSharpPushNotificationService.cs +++ b/src/Core/Services/Implementations/PushSharpPushNotificationService.cs @@ -15,6 +15,7 @@ using Microsoft.Extensions.Logging; using System.Diagnostics; using Bit.Core.Utilities; using Microsoft.AspNetCore.Http; +using Bit.Core.Models; namespace Bit.Core.Services { @@ -89,12 +90,10 @@ namespace Bit.Core.Services var message = new SyncCipherPushNotification { - Type = type, Id = cipher.Id, UserId = cipher.UserId, OrganizationId = cipher.OrganizationId, - RevisionDate = cipher.RevisionDate, - Aps = new PushNotification.AppleData { ContentAvailable = 1 } + RevisionDate = cipher.RevisionDate }; var excludedTokens = new List(); @@ -105,18 +104,16 @@ namespace Bit.Core.Services excludedTokens.Add(currentContext.DeviceIdentifier); } - await PushToAllUserDevicesAsync(cipher.UserId.Value, JObject.FromObject(message), excludedTokens); + await PushToAllUserDevicesAsync(cipher.UserId.Value, type, message, excludedTokens); } private async Task PushFolderAsync(Folder folder, PushType type) { var message = new SyncFolderPushNotification { - Type = type, Id = folder.Id, UserId = folder.UserId, - RevisionDate = folder.RevisionDate, - Aps = new PushNotification.AppleData { ContentAvailable = 1 } + RevisionDate = folder.RevisionDate }; var excludedTokens = new List(); @@ -127,7 +124,7 @@ namespace Bit.Core.Services excludedTokens.Add(currentContext.DeviceIdentifier); } - await PushToAllUserDevicesAsync(folder.UserId, JObject.FromObject(message), excludedTokens); + await PushToAllUserDevicesAsync(folder.UserId, type, message, excludedTokens); } public async Task PushSyncCiphersAsync(Guid userId) @@ -154,13 +151,11 @@ namespace Bit.Core.Services { var message = new SyncUserPushNotification { - Type = type, UserId = userId, - Date = DateTime.UtcNow, - Aps = new PushNotification.AppleData { ContentAvailable = 1 } + Date = DateTime.UtcNow }; - await PushToAllUserDevicesAsync(userId, JObject.FromObject(message), null); + await PushToAllUserDevicesAsync(userId, type, message, null); } private void InitGcmBroker(GlobalSettings globalSettings) @@ -310,7 +305,7 @@ namespace Bit.Core.Services // timestamp is the time the token was reported as expired } - private async Task PushToAllUserDevicesAsync(Guid userId, JObject message, IEnumerable tokensToSkip) + private async Task PushToAllUserDevicesAsync(Guid userId, PushType type, object message, IEnumerable tokensToSkip) { var devices = (await _deviceRepository.GetManyByUserIdAsync(userId)) .Where(d => !string.IsNullOrWhiteSpace(d.PushToken) && (!tokensToSkip?.Contains(d.PushToken) ?? true)); @@ -321,13 +316,20 @@ namespace Bit.Core.Services if(_apnsBroker != null) { + var appleNotification = new ApplePayloadPushNotification + { + Data = new PayloadPushNotification.DataObj(type, JsonConvert.SerializeObject(message)) + }; + + var obj = JObject.FromObject(appleNotification); + // Send to each iOS device foreach(var device in devices.Where(d => d.Type == DeviceType.iOS)) { _apnsBroker.QueueNotification(new ApnsNotification { DeviceToken = device.PushToken, - Payload = message + Payload = obj }); } } @@ -336,50 +338,15 @@ namespace Bit.Core.Services var androidDevices = devices.Where(d => d.Type == DeviceType.Android); if(_gcmBroker != null && androidDevices.Count() > 0) { + var gcmData = new PayloadPushNotification.DataObj(type, JsonConvert.SerializeObject(message)); + var obj = JObject.FromObject(gcmData); + _gcmBroker.QueueNotification(new GcmNotification { RegistrationIds = androidDevices.Select(d => d.PushToken).ToList(), - Data = message + Data = obj }); } } - - private class PushNotification - { - public PushType Type { get; set; } - [JsonProperty(PropertyName = "aps")] - public AppleData Aps { get; set; } - - public class AppleData - { - [JsonProperty(PropertyName = "badge")] - public dynamic Badge { get; set; } = null; - [JsonProperty(PropertyName = "alert")] - public string Alert { get; set; } - [JsonProperty(PropertyName = "content-available")] - public int ContentAvailable { get; set; } - } - } - - private class SyncCipherPushNotification : PushNotification - { - public Guid Id { get; set; } - public Guid? UserId { get; set; } - public Guid? OrganizationId { get; set; } - public DateTime RevisionDate { get; set; } - } - - private class SyncFolderPushNotification : PushNotification - { - public Guid Id { get; set; } - public Guid UserId { get; set; } - public DateTime RevisionDate { get; set; } - } - - private class SyncUserPushNotification : PushNotification - { - public Guid UserId { get; set; } - public DateTime Date { get; set; } - } } }