mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 16:12:49 -05:00
PM-10600: Notification push notification
This commit is contained in:
@ -25,4 +25,6 @@ public enum PushType : byte
|
|||||||
AuthRequestResponse = 16,
|
AuthRequestResponse = 16,
|
||||||
|
|
||||||
SyncOrganizations = 17,
|
SyncOrganizations = 17,
|
||||||
|
|
||||||
|
SyncNotification = 18,
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,15 @@ public class SyncSendPushNotification
|
|||||||
public DateTime RevisionDate { get; set; }
|
public DateTime RevisionDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public bool Global { get; set; }
|
||||||
|
public Guid? UserId { get; set; }
|
||||||
|
public Guid? OrganizationId { get; set; }
|
||||||
|
public DateTime RevisionDate { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class AuthRequestPushNotification
|
public class AuthRequestPushNotification
|
||||||
{
|
{
|
||||||
public Guid UserId { get; set; }
|
public Guid UserId { get; set; }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
using Bit.Core.Vault.Entities;
|
using Bit.Core.Vault.Entities;
|
||||||
|
|
||||||
@ -22,9 +23,16 @@ public interface IPushNotificationService
|
|||||||
Task PushSyncSendCreateAsync(Send send);
|
Task PushSyncSendCreateAsync(Send send);
|
||||||
Task PushSyncSendUpdateAsync(Send send);
|
Task PushSyncSendUpdateAsync(Send send);
|
||||||
Task PushSyncSendDeleteAsync(Send send);
|
Task PushSyncSendDeleteAsync(Send send);
|
||||||
|
Task PushSyncNotificationAsync(Notification notification);
|
||||||
Task PushAuthRequestAsync(AuthRequest authRequest);
|
Task PushAuthRequestAsync(AuthRequest authRequest);
|
||||||
Task PushAuthRequestResponseAsync(AuthRequest authRequest);
|
Task PushAuthRequestResponseAsync(AuthRequest authRequest);
|
||||||
Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier, string deviceId = null);
|
|
||||||
|
Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
|
string deviceId = null, ClientType? clientType = null);
|
||||||
|
|
||||||
Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null);
|
string deviceId = null, ClientType? clientType = null);
|
||||||
|
|
||||||
|
Task SendPayloadToEveryoneAsync(PushType type, object payload, string identifier, string deviceId = null,
|
||||||
|
ClientType? clientType = null);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using Bit.Core.Auth.Entities;
|
|||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
@ -128,11 +129,7 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
|
|
||||||
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
||||||
{
|
{
|
||||||
var message = new UserPushNotification
|
var message = new UserPushNotification { UserId = userId, Date = DateTime.UtcNow };
|
||||||
{
|
|
||||||
UserId = userId,
|
|
||||||
Date = DateTime.UtcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendMessageAsync(type, message, excludeCurrentContext);
|
await SendMessageAsync(type, message, excludeCurrentContext);
|
||||||
}
|
}
|
||||||
@ -149,11 +146,7 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
|
|
||||||
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
||||||
{
|
{
|
||||||
var message = new AuthRequestPushNotification
|
var message = new AuthRequestPushNotification { Id = authRequest.Id, UserId = authRequest.UserId };
|
||||||
{
|
|
||||||
Id = authRequest.Id,
|
|
||||||
UserId = authRequest.UserId
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendMessageAsync(type, message, true);
|
await SendMessageAsync(type, message, true);
|
||||||
}
|
}
|
||||||
@ -173,6 +166,20 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
await PushSendAsync(send, PushType.SyncSendDelete);
|
await PushSendAsync(send, PushType.SyncSendDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationAsync(Notification notification)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
Global = notification.Global,
|
||||||
|
UserId = notification.Id,
|
||||||
|
OrganizationId = notification.Id,
|
||||||
|
RevisionDate = notification.RevisionDate
|
||||||
|
};
|
||||||
|
|
||||||
|
await SendMessageAsync(PushType.SyncNotification, message, true);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task PushSendAsync(Send send, PushType type)
|
private async Task PushSendAsync(Send send, PushType type)
|
||||||
{
|
{
|
||||||
if (send.UserId.HasValue)
|
if (send.UserId.HasValue)
|
||||||
@ -203,22 +210,25 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
var currentContext =
|
||||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
_httpContextAccessor?.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||||
return currentContext?.DeviceIdentifier;
|
return currentContext?.DeviceIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task SendPayloadToEveryoneAsync(PushType type, object payload, string identifier, string deviceId = null,
|
||||||
|
ClientType? clientType = null) => Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
@ -34,6 +35,7 @@ public class MultiServicePushNotificationService : IPushNotificationService
|
|||||||
_services.Add(new RelayPushNotificationService(httpFactory, deviceRepository, globalSettings,
|
_services.Add(new RelayPushNotificationService(httpFactory, deviceRepository, globalSettings,
|
||||||
httpContextAccessor, relayLogger));
|
httpContextAccessor, relayLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
|
if (CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
|
||||||
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
|
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
|
||||||
{
|
{
|
||||||
@ -43,12 +45,14 @@ public class MultiServicePushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var generalHub = globalSettings.NotificationHubs?.FirstOrDefault(h => h.HubType == NotificationHubType.General);
|
var generalHub =
|
||||||
|
globalSettings.NotificationHubs?.FirstOrDefault(h => h.HubType == NotificationHubType.General);
|
||||||
if (CoreHelpers.SettingHasValue(generalHub?.ConnectionString))
|
if (CoreHelpers.SettingHasValue(generalHub?.ConnectionString))
|
||||||
{
|
{
|
||||||
_services.Add(new NotificationHubPushNotificationService(installationDeviceRepository,
|
_services.Add(new NotificationHubPushNotificationService(installationDeviceRepository,
|
||||||
globalSettings, httpContextAccessor, hubLogger));
|
globalSettings, httpContextAccessor, hubLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
|
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
|
||||||
{
|
{
|
||||||
_services.Add(new AzureQueuePushNotificationService(globalSettings, httpContextAccessor));
|
_services.Add(new AzureQueuePushNotificationService(globalSettings, httpContextAccessor));
|
||||||
@ -161,19 +165,32 @@ public class MultiServicePushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
PushToServices((s) => s.SendPayloadToUserAsync(userId, type, payload, identifier, deviceId));
|
PushToServices((s) => s.SendPayloadToUserAsync(userId, type, payload, identifier, deviceId, clientType));
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
PushToServices((s) => s.SendPayloadToOrganizationAsync(orgId, type, payload, identifier, deviceId));
|
PushToServices((s) => s.SendPayloadToOrganizationAsync(orgId, type, payload, identifier, deviceId, clientType));
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task PushSyncNotificationAsync(Notification notification)
|
||||||
|
{
|
||||||
|
PushToServices((s) => s.PushSyncNotificationAsync(notification));
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SendPayloadToEveryoneAsync(PushType type, object payload, string identifier, string deviceId = null,
|
||||||
|
ClientType? clientType = null)
|
||||||
|
{
|
||||||
|
PushToServices((s) => s.SendPayloadToEveryoneAsync(type, payload, identifier, deviceId, clientType));
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
private void PushToServices(Func<IPushNotificationService, Task> pushFunc)
|
private void PushToServices(Func<IPushNotificationService, Task> pushFunc)
|
||||||
{
|
{
|
||||||
if (_services != null)
|
if (_services != null)
|
||||||
|
@ -12,6 +12,7 @@ using Bit.Core.Vault.Entities;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Azure.NotificationHubs;
|
using Microsoft.Azure.NotificationHubs;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Notification = Bit.Core.NotificationCenter.Entities.Notification;
|
||||||
|
|
||||||
namespace Bit.Core.Services;
|
namespace Bit.Core.Services;
|
||||||
|
|
||||||
@ -148,11 +149,7 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
|
|
||||||
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
||||||
{
|
{
|
||||||
var message = new UserPushNotification
|
var message = new UserPushNotification { UserId = userId, Date = DateTime.UtcNow };
|
||||||
{
|
|
||||||
UserId = userId,
|
|
||||||
Date = DateTime.UtcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendPayloadToUserAsync(userId, type, message, excludeCurrentContext);
|
await SendPayloadToUserAsync(userId, type, message, excludeCurrentContext);
|
||||||
}
|
}
|
||||||
@ -197,31 +194,65 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
await PushAuthRequestAsync(authRequest, PushType.AuthRequestResponse);
|
await PushAuthRequestAsync(authRequest, PushType.AuthRequestResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationAsync(Notification notification)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
Global = notification.Global,
|
||||||
|
UserId = notification.Id,
|
||||||
|
OrganizationId = notification.Id,
|
||||||
|
RevisionDate = notification.RevisionDate
|
||||||
|
};
|
||||||
|
|
||||||
|
if (notification.Global)
|
||||||
|
{
|
||||||
|
await SendPayloadToEveryoneAsync(PushType.SyncNotification, message, true, notification.ClientType);
|
||||||
|
}
|
||||||
|
else if (notification.UserId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotification, message, true,
|
||||||
|
notification.ClientType);
|
||||||
|
}
|
||||||
|
else if (notification.OrganizationId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotification, message,
|
||||||
|
true, notification.ClientType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
||||||
{
|
{
|
||||||
var message = new AuthRequestPushNotification
|
var message = new AuthRequestPushNotification { Id = authRequest.Id, UserId = authRequest.UserId };
|
||||||
{
|
|
||||||
Id = authRequest.Id,
|
|
||||||
UserId = authRequest.UserId
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendPayloadToUserAsync(authRequest.UserId, type, message, true);
|
await SendPayloadToUserAsync(authRequest.UserId, type, message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendPayloadToUserAsync(Guid userId, PushType type, object payload, bool excludeCurrentContext)
|
private async Task SendPayloadToUserAsync(Guid userId, PushType type, object payload, bool excludeCurrentContext,
|
||||||
|
ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
await SendPayloadToUserAsync(userId.ToString(), type, payload, GetContextIdentifier(excludeCurrentContext));
|
await SendPayloadToUserAsync(userId.ToString(), type, payload, GetContextIdentifier(excludeCurrentContext),
|
||||||
|
clientType: clientType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendPayloadToOrganizationAsync(Guid orgId, PushType type, object payload, bool excludeCurrentContext)
|
private async Task SendPayloadToOrganizationAsync(Guid orgId, PushType type, object payload,
|
||||||
|
bool excludeCurrentContext, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
await SendPayloadToUserAsync(orgId.ToString(), type, payload, GetContextIdentifier(excludeCurrentContext));
|
await SendPayloadToUserAsync(orgId.ToString(), type, payload, GetContextIdentifier(excludeCurrentContext),
|
||||||
|
clientType: clientType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SendPayloadToEveryoneAsync(PushType type, object payload, bool excludeCurrentContext,
|
||||||
|
ClientType? clientType = null)
|
||||||
|
{
|
||||||
|
await SendPayloadToEveryoneAsync(type, payload, GetContextIdentifier(excludeCurrentContext),
|
||||||
|
clientType: clientType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public async Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
var tag = BuildTag($"template:payload_userId:{SanitizeTagInput(userId)}", identifier);
|
var tag = BuildTag($"template:payload_userId:{SanitizeTagInput(userId)}", identifier, clientType);
|
||||||
await SendPayloadAsync(tag, type, payload);
|
await SendPayloadAsync(tag, type, payload);
|
||||||
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||||
{
|
{
|
||||||
@ -230,9 +261,20 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public async Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
var tag = BuildTag($"template:payload && organizationId:{SanitizeTagInput(orgId)}", identifier);
|
var tag = BuildTag($"template:payload && organizationId:{SanitizeTagInput(orgId)}", identifier, clientType);
|
||||||
|
await SendPayloadAsync(tag, type, payload);
|
||||||
|
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||||
|
{
|
||||||
|
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SendPayloadToEveryoneAsync(PushType type, object payload, string identifier,
|
||||||
|
string deviceId = null, ClientType? clientType = null)
|
||||||
|
{
|
||||||
|
var tag = BuildTag($"template:payload", identifier, clientType);
|
||||||
await SendPayloadAsync(tag, type, payload);
|
await SendPayloadAsync(tag, type, payload);
|
||||||
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||||
{
|
{
|
||||||
@ -247,18 +289,23 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
var currentContext =
|
||||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
_httpContextAccessor?.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||||
return currentContext?.DeviceIdentifier;
|
return currentContext?.DeviceIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string BuildTag(string tag, string identifier)
|
private string BuildTag(string tag, string identifier, ClientType? clientType)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(identifier))
|
if (!string.IsNullOrWhiteSpace(identifier))
|
||||||
{
|
{
|
||||||
tag += $" && !deviceIdentifier:{SanitizeTagInput(identifier)}";
|
tag += $" && !deviceIdentifier:{SanitizeTagInput(identifier)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientType.HasValue && clientType.Value != ClientType.All)
|
||||||
|
{
|
||||||
|
tag += $" && clientType:{clientType}";
|
||||||
|
}
|
||||||
|
|
||||||
return $"({tag})";
|
return $"({tag})";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,8 +317,7 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
var task = client.SendTemplateNotificationAsync(
|
var task = client.SendTemplateNotificationAsync(
|
||||||
new Dictionary<string, string>
|
new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ "type", ((byte)type).ToString() },
|
{ "type", ((byte)type).ToString() }, { "payload", JsonSerializer.Serialize(payload) }
|
||||||
{ "payload", JsonSerializer.Serialize(payload) }
|
|
||||||
}, tag);
|
}, tag);
|
||||||
tasks.Add(task);
|
tasks.Add(task);
|
||||||
}
|
}
|
||||||
@ -285,7 +331,8 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
if (_clients[i].EnableTestSend)
|
if (_clients[i].EnableTestSend)
|
||||||
{
|
{
|
||||||
var outcome = await tasks[i];
|
var outcome = await tasks[i];
|
||||||
_logger.LogInformation("Azure Notification Hub Tracking ID: {id} | {type} push notification with {success} successes and {failure} failures with a payload of {@payload} and result of {@results}",
|
_logger.LogInformation(
|
||||||
|
"Azure Notification Hub Tracking ID: {id} | {type} push notification with {success} successes and {failure} failures with a payload of {@payload} and result of {@results}",
|
||||||
outcome.TrackingId, type, outcome.Success, outcome.Failure, payload, outcome.Results);
|
outcome.TrackingId, type, outcome.Success, outcome.Failure, payload, outcome.Results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Azure.NotificationHubs;
|
using Microsoft.Azure.NotificationHubs;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@ -62,10 +63,9 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
Templates = new Dictionary<string, InstallationTemplate>()
|
Templates = new Dictionary<string, InstallationTemplate>()
|
||||||
};
|
};
|
||||||
|
|
||||||
installation.Tags = new List<string>
|
var clientType = DeviceTypes.ToClientType(type);
|
||||||
{
|
|
||||||
$"userId:{userId}"
|
installation.Tags = new List<string> { $"userId:{userId}", $"clientType:{clientType}" };
|
||||||
};
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(identifier))
|
if (!string.IsNullOrWhiteSpace(identifier))
|
||||||
{
|
{
|
||||||
@ -81,24 +81,25 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
{
|
{
|
||||||
payloadTemplate = "{\"message\":{\"data\":{\"type\":\"$(type)\",\"payload\":\"$(payload)\"}}}";
|
payloadTemplate = "{\"message\":{\"data\":{\"type\":\"$(type)\",\"payload\":\"$(payload)\"}}}";
|
||||||
messageTemplate = "{\"message\":{\"data\":{\"type\":\"$(type)\"}," +
|
messageTemplate = "{\"message\":{\"data\":{\"type\":\"$(type)\"}," +
|
||||||
"\"notification\":{\"title\":\"$(title)\",\"body\":\"$(message)\"}}}";
|
"\"notification\":{\"title\":\"$(title)\",\"body\":\"$(message)\"}}}";
|
||||||
installation.Platform = NotificationPlatform.FcmV1;
|
installation.Platform = NotificationPlatform.FcmV1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
payloadTemplate = "{\"data\":{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}}}";
|
payloadTemplate = "{\"data\":{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}}}";
|
||||||
messageTemplate = "{\"data\":{\"data\":{\"type\":\"#(type)\"}," +
|
messageTemplate = "{\"data\":{\"data\":{\"type\":\"#(type)\"}," +
|
||||||
"\"notification\":{\"title\":\"$(title)\",\"body\":\"$(message)\"}}}";
|
"\"notification\":{\"title\":\"$(title)\",\"body\":\"$(message)\"}}}";
|
||||||
installation.Platform = NotificationPlatform.Fcm;
|
installation.Platform = NotificationPlatform.Fcm;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DeviceType.iOS:
|
case DeviceType.iOS:
|
||||||
payloadTemplate = "{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}," +
|
payloadTemplate = "{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}," +
|
||||||
"\"aps\":{\"content-available\":1}}";
|
"\"aps\":{\"content-available\":1}}";
|
||||||
messageTemplate = "{\"data\":{\"type\":\"#(type)\"}," +
|
messageTemplate = "{\"data\":{\"type\":\"#(type)\"}," +
|
||||||
"\"aps\":{\"alert\":\"$(message)\",\"badge\":null,\"content-available\":1}}";
|
"\"aps\":{\"alert\":\"$(message)\",\"badge\":null,\"content-available\":1}}";
|
||||||
badgeMessageTemplate = "{\"data\":{\"type\":\"#(type)\"}," +
|
badgeMessageTemplate = "{\"data\":{\"type\":\"#(type)\"}," +
|
||||||
"\"aps\":{\"alert\":\"$(message)\",\"badge\":\"#(badge)\",\"content-available\":1}}";
|
"\"aps\":{\"alert\":\"$(message)\",\"badge\":\"#(badge)\",\"content-available\":1}}";
|
||||||
|
|
||||||
installation.Platform = NotificationPlatform.Apns;
|
installation.Platform = NotificationPlatform.Apns;
|
||||||
break;
|
break;
|
||||||
@ -112,10 +113,10 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildInstallationTemplate(installation, "payload", payloadTemplate, userId, identifier);
|
BuildInstallationTemplate(installation, "payload", payloadTemplate, userId, identifier, clientType);
|
||||||
BuildInstallationTemplate(installation, "message", messageTemplate, userId, identifier);
|
BuildInstallationTemplate(installation, "message", messageTemplate, userId, identifier, clientType);
|
||||||
BuildInstallationTemplate(installation, "badgeMessage", badgeMessageTemplate ?? messageTemplate,
|
BuildInstallationTemplate(installation, "badgeMessage", badgeMessageTemplate ?? messageTemplate,
|
||||||
userId, identifier);
|
userId, identifier, clientType);
|
||||||
|
|
||||||
await GetClient(type).CreateOrUpdateInstallationAsync(installation);
|
await GetClient(type).CreateOrUpdateInstallationAsync(installation);
|
||||||
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||||
@ -125,7 +126,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void BuildInstallationTemplate(Installation installation, string templateId, string templateBody,
|
private void BuildInstallationTemplate(Installation installation, string templateId, string templateBody,
|
||||||
string userId, string identifier)
|
string userId, string identifier, ClientType clientType)
|
||||||
{
|
{
|
||||||
if (templateBody == null)
|
if (templateBody == null)
|
||||||
{
|
{
|
||||||
@ -139,8 +140,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
Body = templateBody,
|
Body = templateBody,
|
||||||
Tags = new List<string>
|
Tags = new List<string>
|
||||||
{
|
{
|
||||||
fullTemplateId,
|
fullTemplateId, $"{fullTemplateId}_userId:{userId}", $"clientType:{clientType}"
|
||||||
$"{fullTemplateId}_userId:{userId}"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -168,7 +168,8 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<KeyValuePair<string, DeviceType>> devices, string organizationId)
|
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<KeyValuePair<string, DeviceType>> devices,
|
||||||
|
string organizationId)
|
||||||
{
|
{
|
||||||
await PatchTagsForUserDevicesAsync(devices, UpdateOperationType.Add, $"organizationId:{organizationId}");
|
await PatchTagsForUserDevicesAsync(devices, UpdateOperationType.Add, $"organizationId:{organizationId}");
|
||||||
if (devices.Any() && InstallationDeviceEntity.IsInstallationDeviceId(devices.First().Key))
|
if (devices.Any() && InstallationDeviceEntity.IsInstallationDeviceId(devices.First().Key))
|
||||||
@ -178,7 +179,8 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable<KeyValuePair<string, DeviceType>> devices, string organizationId)
|
public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable<KeyValuePair<string, DeviceType>> devices,
|
||||||
|
string organizationId)
|
||||||
{
|
{
|
||||||
await PatchTagsForUserDevicesAsync(devices, UpdateOperationType.Remove,
|
await PatchTagsForUserDevicesAsync(devices, UpdateOperationType.Remove,
|
||||||
$"organizationId:{organizationId}");
|
$"organizationId:{organizationId}");
|
||||||
@ -189,7 +191,8 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PatchTagsForUserDevicesAsync(IEnumerable<KeyValuePair<string, DeviceType>> devices, UpdateOperationType op,
|
private async Task PatchTagsForUserDevicesAsync(IEnumerable<KeyValuePair<string, DeviceType>> devices,
|
||||||
|
UpdateOperationType op,
|
||||||
string tag)
|
string tag)
|
||||||
{
|
{
|
||||||
if (!devices.Any())
|
if (!devices.Any())
|
||||||
@ -197,11 +200,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var operation = new PartialUpdateOperation
|
var operation = new PartialUpdateOperation { Operation = op, Path = "/tags" };
|
||||||
{
|
|
||||||
Operation = op,
|
|
||||||
Path = "/tags"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (op == UpdateOperationType.Add)
|
if (op == UpdateOperationType.Add)
|
||||||
{
|
{
|
||||||
@ -216,7 +215,8 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await GetClient(device.Value).PatchInstallationAsync(device.Key, new List<PartialUpdateOperation> { operation });
|
await GetClient(device.Value)
|
||||||
|
.PatchInstallationAsync(device.Key, new List<PartialUpdateOperation> { operation });
|
||||||
}
|
}
|
||||||
catch (Exception e) when (e.InnerException == null || !e.InnerException.Message.Contains("(404) Not Found"))
|
catch (Exception e) when (e.InnerException == null || !e.InnerException.Message.Contains("(404) Not Found"))
|
||||||
{
|
{
|
||||||
@ -227,41 +227,21 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
|
|
||||||
private NotificationHubClient GetClient(DeviceType deviceType)
|
private NotificationHubClient GetClient(DeviceType deviceType)
|
||||||
{
|
{
|
||||||
var hubType = NotificationHubType.General;
|
var clientType = DeviceTypes.ToClientType(deviceType);
|
||||||
switch (deviceType)
|
|
||||||
|
var hubType = clientType switch
|
||||||
{
|
{
|
||||||
case DeviceType.Android:
|
ClientType.Web => NotificationHubType.GeneralWeb,
|
||||||
hubType = NotificationHubType.Android;
|
ClientType.Browser => NotificationHubType.GeneralBrowserExtension,
|
||||||
break;
|
ClientType.Desktop => NotificationHubType.GeneralDesktop,
|
||||||
case DeviceType.iOS:
|
ClientType.Mobile => deviceType switch
|
||||||
hubType = NotificationHubType.iOS;
|
{
|
||||||
break;
|
DeviceType.Android => NotificationHubType.Android,
|
||||||
case DeviceType.ChromeExtension:
|
DeviceType.iOS => NotificationHubType.iOS,
|
||||||
case DeviceType.FirefoxExtension:
|
_ => NotificationHubType.General
|
||||||
case DeviceType.OperaExtension:
|
},
|
||||||
case DeviceType.EdgeExtension:
|
_ => NotificationHubType.General
|
||||||
case DeviceType.VivaldiExtension:
|
};
|
||||||
case DeviceType.SafariExtension:
|
|
||||||
hubType = NotificationHubType.GeneralBrowserExtension;
|
|
||||||
break;
|
|
||||||
case DeviceType.WindowsDesktop:
|
|
||||||
case DeviceType.MacOsDesktop:
|
|
||||||
case DeviceType.LinuxDesktop:
|
|
||||||
hubType = NotificationHubType.GeneralDesktop;
|
|
||||||
break;
|
|
||||||
case DeviceType.ChromeBrowser:
|
|
||||||
case DeviceType.FirefoxBrowser:
|
|
||||||
case DeviceType.OperaBrowser:
|
|
||||||
case DeviceType.EdgeBrowser:
|
|
||||||
case DeviceType.IEBrowser:
|
|
||||||
case DeviceType.UnknownBrowser:
|
|
||||||
case DeviceType.SafariBrowser:
|
|
||||||
case DeviceType.VivaldiBrowser:
|
|
||||||
hubType = NotificationHubType.GeneralWeb;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_clients.ContainsKey(hubType))
|
if (!_clients.ContainsKey(hubType))
|
||||||
{
|
{
|
||||||
@ -272,6 +252,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
|
|||||||
throw new Exception("No general hub client found.");
|
throw new Exception("No general hub client found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _clients[hubType];
|
return _clients[hubType];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
using Bit.Core.Vault.Entities;
|
using Bit.Core.Vault.Entities;
|
||||||
@ -135,11 +136,7 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
|
|
||||||
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
||||||
{
|
{
|
||||||
var message = new UserPushNotification
|
var message = new UserPushNotification { UserId = userId, Date = DateTime.UtcNow };
|
||||||
{
|
|
||||||
UserId = userId,
|
|
||||||
Date = DateTime.UtcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendMessageAsync(type, message, excludeCurrentContext);
|
await SendMessageAsync(type, message, excludeCurrentContext);
|
||||||
}
|
}
|
||||||
@ -156,11 +153,7 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
|
|
||||||
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
||||||
{
|
{
|
||||||
var message = new AuthRequestPushNotification
|
var message = new AuthRequestPushNotification { Id = authRequest.Id, UserId = authRequest.UserId };
|
||||||
{
|
|
||||||
Id = authRequest.Id,
|
|
||||||
UserId = authRequest.UserId
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendMessageAsync(type, message, true);
|
await SendMessageAsync(type, message, true);
|
||||||
}
|
}
|
||||||
@ -180,6 +173,20 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
await PushSendAsync(send, PushType.SyncSendDelete);
|
await PushSendAsync(send, PushType.SyncSendDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationAsync(Notification notification)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
Global = notification.Global,
|
||||||
|
UserId = notification.Id,
|
||||||
|
OrganizationId = notification.Id,
|
||||||
|
RevisionDate = notification.RevisionDate
|
||||||
|
};
|
||||||
|
|
||||||
|
await SendMessageAsync(PushType.SyncNotification, message, true);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task PushSendAsync(Send send, PushType type)
|
private async Task PushSendAsync(Send send, PushType type)
|
||||||
{
|
{
|
||||||
if (send.UserId.HasValue)
|
if (send.UserId.HasValue)
|
||||||
@ -209,22 +216,25 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
var currentContext =
|
||||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
_httpContextAccessor?.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||||
return currentContext?.DeviceIdentifier;
|
return currentContext?.DeviceIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task SendPayloadToEveryoneAsync(PushType type, object payload, string identifier, string deviceId = null,
|
||||||
|
ClientType? clientType = null) => Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using Bit.Core.Enums;
|
|||||||
using Bit.Core.IdentityServer;
|
using Bit.Core.IdentityServer;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
@ -136,11 +137,7 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
|
|
||||||
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
|
||||||
{
|
{
|
||||||
var message = new UserPushNotification
|
var message = new UserPushNotification { UserId = userId, Date = DateTime.UtcNow };
|
||||||
{
|
|
||||||
UserId = userId,
|
|
||||||
Date = DateTime.UtcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendPayloadToUserAsync(userId, type, message, excludeCurrentContext);
|
await SendPayloadToUserAsync(userId, type, message, excludeCurrentContext);
|
||||||
}
|
}
|
||||||
@ -187,36 +184,58 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
|
|
||||||
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
|
||||||
{
|
{
|
||||||
var message = new AuthRequestPushNotification
|
var message = new AuthRequestPushNotification { Id = authRequest.Id, UserId = authRequest.UserId };
|
||||||
{
|
|
||||||
Id = authRequest.Id,
|
|
||||||
UserId = authRequest.UserId
|
|
||||||
};
|
|
||||||
|
|
||||||
await SendPayloadToUserAsync(authRequest.UserId, type, message, true);
|
await SendPayloadToUserAsync(authRequest.UserId, type, message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationAsync(Notification notification)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
Global = notification.Global,
|
||||||
|
UserId = notification.Id,
|
||||||
|
OrganizationId = notification.Id,
|
||||||
|
RevisionDate = notification.RevisionDate
|
||||||
|
};
|
||||||
|
|
||||||
|
if (notification.Global)
|
||||||
|
{
|
||||||
|
await SendPayloadToEveryoneAsync(PushType.SyncNotification, message, true);
|
||||||
|
}
|
||||||
|
else if (notification.UserId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotification, message, true);
|
||||||
|
}
|
||||||
|
else if (notification.OrganizationId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotification, message,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SendPayloadToUserAsync(Guid userId, PushType type, object payload, bool excludeCurrentContext)
|
private async Task SendPayloadToUserAsync(Guid userId, PushType type, object payload, bool excludeCurrentContext)
|
||||||
{
|
{
|
||||||
var request = new PushSendRequestModel
|
var request = new PushSendRequestModel { UserId = userId.ToString(), Type = type, Payload = payload };
|
||||||
{
|
|
||||||
UserId = userId.ToString(),
|
|
||||||
Type = type,
|
|
||||||
Payload = payload
|
|
||||||
};
|
|
||||||
|
|
||||||
await AddCurrentContextAsync(request, excludeCurrentContext);
|
await AddCurrentContextAsync(request, excludeCurrentContext);
|
||||||
await SendAsync(HttpMethod.Post, "push/send", request);
|
await SendAsync(HttpMethod.Post, "push/send", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendPayloadToOrganizationAsync(Guid orgId, PushType type, object payload, bool excludeCurrentContext)
|
private async Task SendPayloadToOrganizationAsync(Guid orgId, PushType type, object payload,
|
||||||
|
bool excludeCurrentContext)
|
||||||
{
|
{
|
||||||
var request = new PushSendRequestModel
|
var request = new PushSendRequestModel { OrganizationId = orgId.ToString(), Type = type, Payload = payload };
|
||||||
{
|
|
||||||
OrganizationId = orgId.ToString(),
|
await AddCurrentContextAsync(request, excludeCurrentContext);
|
||||||
Type = type,
|
await SendAsync(HttpMethod.Post, "push/send", request);
|
||||||
Payload = payload
|
}
|
||||||
};
|
|
||||||
|
private async Task SendPayloadToEveryoneAsync(PushType type, object payload, bool excludeCurrentContext)
|
||||||
|
{
|
||||||
|
// TODO global flag prop to be explicit ?
|
||||||
|
var request = new PushSendRequestModel { Type = type, Payload = payload };
|
||||||
|
|
||||||
await AddCurrentContextAsync(request, excludeCurrentContext);
|
await AddCurrentContextAsync(request, excludeCurrentContext);
|
||||||
await SendAsync(HttpMethod.Post, "push/send", request);
|
await SendAsync(HttpMethod.Post, "push/send", request);
|
||||||
@ -224,8 +243,8 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
|
|
||||||
private async Task AddCurrentContextAsync(PushSendRequestModel request, bool addIdentifier)
|
private async Task AddCurrentContextAsync(PushSendRequestModel request, bool addIdentifier)
|
||||||
{
|
{
|
||||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
var currentContext =
|
||||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
_httpContextAccessor?.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||||
if (!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
if (!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
||||||
{
|
{
|
||||||
var device = await _deviceRepository.GetByIdentifierAsync(currentContext.DeviceIdentifier);
|
var device = await _deviceRepository.GetByIdentifierAsync(currentContext.DeviceIdentifier);
|
||||||
@ -233,6 +252,7 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
{
|
{
|
||||||
request.DeviceId = device.Id.ToString();
|
request.DeviceId = device.Id.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addIdentifier)
|
if (addIdentifier)
|
||||||
{
|
{
|
||||||
request.Identifier = currentContext.DeviceIdentifier;
|
request.Identifier = currentContext.DeviceIdentifier;
|
||||||
@ -241,13 +261,19 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SendPayloadToEveryoneAsync(PushType type, object payload, string identifier, string deviceId = null,
|
||||||
|
ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
using Bit.Core.Vault.Entities;
|
using Bit.Core.Vault.Entities;
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ public class NoopPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
@ -99,8 +100,13 @@ public class NoopPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null)
|
string deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task PushSyncNotificationAsync(Notification notification) => Task.CompletedTask;
|
||||||
|
|
||||||
|
public Task SendPayloadToEveryoneAsync(PushType type, object payload, string identifier, string deviceId = null,
|
||||||
|
ClientType? clientType = null) => Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ public static class HubHelpers
|
|||||||
CancellationToken cancellationToken = default(CancellationToken)
|
CancellationToken cancellationToken = default(CancellationToken)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var notification = JsonSerializer.Deserialize<PushNotificationData<object>>(notificationJson, _deserializerOptions);
|
var notification =
|
||||||
|
JsonSerializer.Deserialize<PushNotificationData<object>>(notificationJson, _deserializerOptions);
|
||||||
logger.LogInformation("Sending notification: {NotificationType}", notification.Type);
|
logger.LogInformation("Sending notification: {NotificationType}", notification.Type);
|
||||||
switch (notification.Type)
|
switch (notification.Type)
|
||||||
{
|
{
|
||||||
@ -37,9 +38,10 @@ public static class HubHelpers
|
|||||||
else if (cipherNotification.Payload.OrganizationId.HasValue)
|
else if (cipherNotification.Payload.OrganizationId.HasValue)
|
||||||
{
|
{
|
||||||
await hubContext.Clients.Group(
|
await hubContext.Clients.Group(
|
||||||
$"Organization_{cipherNotification.Payload.OrganizationId}")
|
$"Organization_{cipherNotification.Payload.OrganizationId}")
|
||||||
.SendAsync("ReceiveMessage", cipherNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", cipherNotification, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PushType.SyncFolderUpdate:
|
case PushType.SyncFolderUpdate:
|
||||||
case PushType.SyncFolderCreate:
|
case PushType.SyncFolderCreate:
|
||||||
@ -48,7 +50,7 @@ public static class HubHelpers
|
|||||||
JsonSerializer.Deserialize<PushNotificationData<SyncFolderPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<SyncFolderPushNotification>>(
|
||||||
notificationJson, _deserializerOptions);
|
notificationJson, _deserializerOptions);
|
||||||
await hubContext.Clients.User(folderNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(folderNotification.Payload.UserId.ToString())
|
||||||
.SendAsync("ReceiveMessage", folderNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", folderNotification, cancellationToken);
|
||||||
break;
|
break;
|
||||||
case PushType.SyncCiphers:
|
case PushType.SyncCiphers:
|
||||||
case PushType.SyncVault:
|
case PushType.SyncVault:
|
||||||
@ -60,31 +62,51 @@ public static class HubHelpers
|
|||||||
JsonSerializer.Deserialize<PushNotificationData<UserPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<UserPushNotification>>(
|
||||||
notificationJson, _deserializerOptions);
|
notificationJson, _deserializerOptions);
|
||||||
await hubContext.Clients.User(userNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(userNotification.Payload.UserId.ToString())
|
||||||
.SendAsync("ReceiveMessage", userNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", userNotification, cancellationToken);
|
||||||
break;
|
break;
|
||||||
case PushType.SyncSendCreate:
|
case PushType.SyncSendCreate:
|
||||||
case PushType.SyncSendUpdate:
|
case PushType.SyncSendUpdate:
|
||||||
case PushType.SyncSendDelete:
|
case PushType.SyncSendDelete:
|
||||||
var sendNotification =
|
var sendNotification =
|
||||||
JsonSerializer.Deserialize<PushNotificationData<SyncSendPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<SyncSendPushNotification>>(
|
||||||
notificationJson, _deserializerOptions);
|
notificationJson, _deserializerOptions);
|
||||||
await hubContext.Clients.User(sendNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(sendNotification.Payload.UserId.ToString())
|
||||||
.SendAsync("ReceiveMessage", sendNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", sendNotification, cancellationToken);
|
||||||
break;
|
break;
|
||||||
case PushType.AuthRequestResponse:
|
case PushType.AuthRequestResponse:
|
||||||
var authRequestResponseNotification =
|
var authRequestResponseNotification =
|
||||||
JsonSerializer.Deserialize<PushNotificationData<AuthRequestPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<AuthRequestPushNotification>>(
|
||||||
notificationJson, _deserializerOptions);
|
notificationJson, _deserializerOptions);
|
||||||
await anonymousHubContext.Clients.Group(authRequestResponseNotification.Payload.Id.ToString())
|
await anonymousHubContext.Clients.Group(authRequestResponseNotification.Payload.Id.ToString())
|
||||||
.SendAsync("AuthRequestResponseRecieved", authRequestResponseNotification, cancellationToken);
|
.SendAsync("AuthRequestResponseRecieved", authRequestResponseNotification, cancellationToken);
|
||||||
break;
|
break;
|
||||||
case PushType.AuthRequest:
|
case PushType.AuthRequest:
|
||||||
var authRequestNotification =
|
var authRequestNotification =
|
||||||
JsonSerializer.Deserialize<PushNotificationData<AuthRequestPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<AuthRequestPushNotification>>(
|
||||||
notificationJson, _deserializerOptions);
|
notificationJson, _deserializerOptions);
|
||||||
await hubContext.Clients.User(authRequestNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(authRequestNotification.Payload.UserId.ToString())
|
||||||
.SendAsync("ReceiveMessage", authRequestNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", authRequestNotification, cancellationToken);
|
||||||
break;
|
break;
|
||||||
|
case PushType.SyncNotification:
|
||||||
|
var syncNotification =
|
||||||
|
JsonSerializer.Deserialize<PushNotificationData<SyncNotificationPushNotification>>(
|
||||||
|
notificationJson, _deserializerOptions);
|
||||||
|
if (syncNotification.Payload.Global)
|
||||||
|
{
|
||||||
|
await hubContext.Clients.All.SendAsync("ReceiveMessage", syncNotification, cancellationToken);
|
||||||
|
}
|
||||||
|
else if (syncNotification.Payload.UserId.HasValue)
|
||||||
|
{
|
||||||
|
await hubContext.Clients.User(syncNotification.Payload.UserId.ToString())
|
||||||
|
.SendAsync("ReceiveMessage", syncNotification, cancellationToken);
|
||||||
|
}
|
||||||
|
else if (syncNotification.Payload.OrganizationId.HasValue)
|
||||||
|
{
|
||||||
|
await hubContext.Clients.Group(
|
||||||
|
$"Organization_{syncNotification.Payload.OrganizationId}")
|
||||||
|
.SendAsync("ReceiveMessage", syncNotification, cancellationToken);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user