From 28e6783a00890de79f6ecff4f24922f8736abe13 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 16 Aug 2018 12:05:01 -0400 Subject: [PATCH] hub api notifications --- src/Admin/appsettings.Production.json | 2 + src/Admin/appsettings.json | 2 + src/Api/appsettings.Production.json | 2 + src/Api/appsettings.json | 2 + src/Billing/appsettings.Production.json | 6 +- src/Billing/appsettings.json | 2 + src/Core/GlobalSettings.cs | 2 + .../BaseIdentityClientService.cs | 31 +++- .../HubApiPushNotificationService.cs | 169 ++++++++++++++++++ .../RelayPushNotificationService.cs | 28 +-- .../RelayPushRegistrationService.cs | 86 +-------- src/Events/appsettings.Production.json | 2 + src/Events/appsettings.json | 2 + src/Hub/AzureQueueHostedService.cs | 44 +---- src/Hub/Controllers/EventsController.cs | 25 --- src/Hub/Controllers/NotificationController.cs | 27 +++ src/Hub/HubHelpers.cs | 56 ++++++ src/Hub/appsettings.Production.json | 2 + src/Hub/appsettings.json | 2 + src/Identity/appsettings.Production.json | 2 + src/Identity/appsettings.json | 2 + util/Setup/EnvironmentFileBuilder.cs | 3 + 22 files changed, 320 insertions(+), 179 deletions(-) create mode 100644 src/Core/Services/Implementations/HubApiPushNotificationService.cs delete mode 100644 src/Hub/Controllers/EventsController.cs create mode 100644 src/Hub/Controllers/NotificationController.cs create mode 100644 src/Hub/HubHelpers.cs diff --git a/src/Admin/appsettings.Production.json b/src/Admin/appsettings.Production.json index 9501db8ac..0b7bb7fae 100644 --- a/src/Admin/appsettings.Production.json +++ b/src/Admin/appsettings.Production.json @@ -5,6 +5,8 @@ "api": "https://api.bitwarden.com", "identity": "https://identity.bitwarden.com", "admin": "https://admin.bitwarden.com", + "hub": "https://hub.bitwarden.com", + "internalHub": "https://hub.bitwarden.com", "internalAdmin": "https://admin.bitwarden.com", "internalIdentity": "https://identity.bitwarden.com", "internalApi": "https://api.bitwarden.com", diff --git a/src/Admin/appsettings.json b/src/Admin/appsettings.json index f30714da0..931682f7f 100644 --- a/src/Admin/appsettings.json +++ b/src/Admin/appsettings.json @@ -9,6 +9,8 @@ "api": "http://localhost:4000", "identity": "http://localhost:33656", "admin": "http://localhost:62911", + "hub": "http://localhost:61840", + "internalHub": "http://localhost:61840", "internalAdmin": "http://localhost:62911", "internalIdentity": "http://localhost:33656", "internalApi": "http://localhost:4000", diff --git a/src/Api/appsettings.Production.json b/src/Api/appsettings.Production.json index 9501db8ac..0b7bb7fae 100644 --- a/src/Api/appsettings.Production.json +++ b/src/Api/appsettings.Production.json @@ -5,6 +5,8 @@ "api": "https://api.bitwarden.com", "identity": "https://identity.bitwarden.com", "admin": "https://admin.bitwarden.com", + "hub": "https://hub.bitwarden.com", + "internalHub": "https://hub.bitwarden.com", "internalAdmin": "https://admin.bitwarden.com", "internalIdentity": "https://identity.bitwarden.com", "internalApi": "https://api.bitwarden.com", diff --git a/src/Api/appsettings.json b/src/Api/appsettings.json index fb14c7a76..06a5d57ee 100644 --- a/src/Api/appsettings.json +++ b/src/Api/appsettings.json @@ -9,6 +9,8 @@ "api": "http://localhost:4000", "identity": "http://localhost:33656", "admin": "http://localhost:62911", + "hub": "http://localhost:61840", + "internalHub": "http://localhost:61840", "internalAdmin": "http://localhost:62911", "internalIdentity": "http://localhost:33656", "internalApi": "http://localhost:4000", diff --git a/src/Billing/appsettings.Production.json b/src/Billing/appsettings.Production.json index 24da86e99..0b7bb7fae 100644 --- a/src/Billing/appsettings.Production.json +++ b/src/Billing/appsettings.Production.json @@ -5,8 +5,12 @@ "api": "https://api.bitwarden.com", "identity": "https://identity.bitwarden.com", "admin": "https://admin.bitwarden.com", + "hub": "https://hub.bitwarden.com", + "internalHub": "https://hub.bitwarden.com", "internalAdmin": "https://admin.bitwarden.com", - "internalIdentity": "https://identity.bitwarden.com" + "internalIdentity": "https://identity.bitwarden.com", + "internalApi": "https://api.bitwarden.com", + "internalVault": "https://vault.bitwarden.com" }, "braintree": { "production": true diff --git a/src/Billing/appsettings.json b/src/Billing/appsettings.json index 787cec2ed..ac43dc17d 100644 --- a/src/Billing/appsettings.json +++ b/src/Billing/appsettings.json @@ -9,6 +9,8 @@ "api": "http://localhost:4000", "identity": "http://localhost:33656", "admin": "http://localhost:62911", + "hub": "http://localhost:61840", + "internalHub": "http://localhost:61840", "internalAdmin": "http://localhost:62911", "internalIdentity": "http://localhost:33656", "internalApi": "http://localhost:4000", diff --git a/src/Core/GlobalSettings.cs b/src/Core/GlobalSettings.cs index f7250793a..4db96e373 100644 --- a/src/Core/GlobalSettings.cs +++ b/src/Core/GlobalSettings.cs @@ -36,6 +36,8 @@ namespace Bit.Core public string Api { get; set; } public string Identity { get; set; } public string Admin { get; set; } + public string Hub { get; set; } + public string InternalHub { get; set; } public string InternalAdmin { get; set; } public string InternalIdentity { get; set; } public string InternalApi { get; set; } diff --git a/src/Core/Services/Implementations/BaseIdentityClientService.cs b/src/Core/Services/Implementations/BaseIdentityClientService.cs index f4ecb71aa..a92cb869f 100644 --- a/src/Core/Services/Implementations/BaseIdentityClientService.cs +++ b/src/Core/Services/Implementations/BaseIdentityClientService.cs @@ -52,6 +52,30 @@ namespace Bit.Core.Services protected HttpClient IdentityClient { get; private set; } protected string AccessToken { get; private set; } + protected async Task SendAsync(HttpMethod method, string path, object requestModel = null) + { + var tokenStateResponse = await HandleTokenStateAsync(); + if(!tokenStateResponse) + { + return; + } + + var message = new TokenHttpRequestMessage(requestModel, AccessToken) + { + Method = method, + RequestUri = new Uri(string.Concat(Client.BaseAddress, path)) + }; + + try + { + await Client.SendAsync(message); + } + catch(Exception e) + { + _logger.LogError(12334, e, "Failed to send to {0}.", message.RequestUri.ToString()); + } + } + protected async Task HandleTokenStateAsync() { if(_nextAuthAttempt.HasValue && DateTime.UtcNow > _nextAuthAttempt.Value) @@ -119,8 +143,11 @@ namespace Bit.Core.Services public TokenHttpRequestMessage(object requestObject, string token) : this(token) { - var stringContent = JsonConvert.SerializeObject(requestObject); - Content = new StringContent(stringContent, Encoding.UTF8, "application/json"); + if(requestObject != null) + { + var stringContent = JsonConvert.SerializeObject(requestObject); + Content = new StringContent(stringContent, Encoding.UTF8, "application/json"); + } } } diff --git a/src/Core/Services/Implementations/HubApiPushNotificationService.cs b/src/Core/Services/Implementations/HubApiPushNotificationService.cs new file mode 100644 index 000000000..610785d07 --- /dev/null +++ b/src/Core/Services/Implementations/HubApiPushNotificationService.cs @@ -0,0 +1,169 @@ +using System; +using System.Threading.Tasks; +using Bit.Core.Models.Table; +using Bit.Core.Enums; +using Newtonsoft.Json; +using Bit.Core.Models; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using System.Net.Http; + +namespace Bit.Core.Services +{ + public class HubApiPushNotificationService : BaseIdentityClientService, IPushNotificationService + { + private readonly GlobalSettings _globalSettings; + private readonly IHttpContextAccessor _httpContextAccessor; + + private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }; + + public HubApiPushNotificationService( + GlobalSettings globalSettings, + IHttpContextAccessor httpContextAccessor, + ILogger logger) + : base( + globalSettings.BaseServiceUri.InternalHub, + globalSettings.BaseServiceUri.InternalIdentity, + "internal", + $"internal.{globalSettings.ProjectName}", + globalSettings.InternalIdentityKey, + logger) + { + _globalSettings = globalSettings; + _httpContextAccessor = httpContextAccessor; + } + + public async Task PushSyncCipherCreateAsync(Cipher cipher) + { + await PushCipherAsync(cipher, PushType.SyncCipherCreate); + } + + public async Task PushSyncCipherUpdateAsync(Cipher cipher) + { + await PushCipherAsync(cipher, PushType.SyncCipherUpdate); + } + + public async Task PushSyncCipherDeleteAsync(Cipher cipher) + { + await PushCipherAsync(cipher, PushType.SyncLoginDelete); + } + + private async Task PushCipherAsync(Cipher cipher, PushType type) + { + if(cipher.OrganizationId.HasValue) + { + var message = new SyncCipherPushNotification + { + Id = cipher.Id, + OrganizationId = cipher.OrganizationId, + RevisionDate = cipher.RevisionDate, + }; + + await SendMessageAsync(type, message, true); + } + else if(cipher.UserId.HasValue) + { + var message = new SyncCipherPushNotification + { + Id = cipher.Id, + UserId = cipher.UserId, + RevisionDate = cipher.RevisionDate, + }; + + await SendMessageAsync(type, message, true); + } + } + + public async Task PushSyncFolderCreateAsync(Folder folder) + { + await PushFolderAsync(folder, PushType.SyncFolderCreate); + } + + public async Task PushSyncFolderUpdateAsync(Folder folder) + { + await PushFolderAsync(folder, PushType.SyncFolderUpdate); + } + + public async Task PushSyncFolderDeleteAsync(Folder folder) + { + await PushFolderAsync(folder, PushType.SyncFolderDelete); + } + + private async Task PushFolderAsync(Folder folder, PushType type) + { + var message = new SyncFolderPushNotification + { + Id = folder.Id, + UserId = folder.UserId, + RevisionDate = folder.RevisionDate + }; + + await SendMessageAsync(type, message, true); + } + + public async Task PushSyncCiphersAsync(Guid userId) + { + await PushSyncUserAsync(userId, PushType.SyncCiphers); + } + + public async Task PushSyncVaultAsync(Guid userId) + { + await PushSyncUserAsync(userId, PushType.SyncVault); + } + + public async Task PushSyncOrgKeysAsync(Guid userId) + { + await PushSyncUserAsync(userId, PushType.SyncOrgKeys); + } + + public async Task PushSyncSettingsAsync(Guid userId) + { + await PushSyncUserAsync(userId, PushType.SyncSettings); + } + + private async Task PushSyncUserAsync(Guid userId, PushType type) + { + var message = new SyncUserPushNotification + { + UserId = userId, + Date = DateTime.UtcNow + }; + + await SendMessageAsync(type, message, false); + } + + private async Task SendMessageAsync(PushType type, T payload, bool excludeCurrentContext) + { + var contextId = GetContextIdentifier(excludeCurrentContext); + var request = new PushNotificationData(type, payload, contextId); + await SendAsync(HttpMethod.Post, "/notification", request); + } + + private string GetContextIdentifier(bool excludeCurrentContext) + { + if(!excludeCurrentContext) + { + return null; + } + + var currentContext = _httpContextAccessor?.HttpContext?. + RequestServices.GetService(typeof(CurrentContext)) as CurrentContext; + return currentContext?.DeviceIdentifier; + } + + public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier) + { + // Noop + return Task.FromResult(0); + } + + public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier) + { + // Noop + return Task.FromResult(0); + } + } +} diff --git a/src/Core/Services/Implementations/RelayPushNotificationService.cs b/src/Core/Services/Implementations/RelayPushNotificationService.cs index cb9dcc1d1..34bffcaf6 100644 --- a/src/Core/Services/Implementations/RelayPushNotificationService.cs +++ b/src/Core/Services/Implementations/RelayPushNotificationService.cs @@ -143,7 +143,7 @@ namespace Bit.Core.Services ExcludeCurrentContext(request); } - await SendAsync(request); + await SendAsync(HttpMethod.Post, "/push/send", request); } private async Task SendPayloadToOrganizationAsync(Guid orgId, PushType type, object payload, bool excludeCurrentContext) @@ -160,31 +160,7 @@ namespace Bit.Core.Services ExcludeCurrentContext(request); } - await SendAsync(request); - } - - private async Task SendAsync(PushSendRequestModel requestModel) - { - var tokenStateResponse = await HandleTokenStateAsync(); - if(!tokenStateResponse) - { - return; - } - - var message = new TokenHttpRequestMessage(requestModel, AccessToken) - { - Method = HttpMethod.Post, - RequestUri = new Uri(string.Concat(Client.BaseAddress, "/push/send")) - }; - - try - { - await Client.SendAsync(message); - } - catch(Exception e) - { - _logger.LogError(12334, e, "Unable to send push notification."); - } + await SendAsync(HttpMethod.Post, "/push/send", request); } private void ExcludeCurrentContext(PushSendRequestModel request) diff --git a/src/Core/Services/Implementations/RelayPushRegistrationService.cs b/src/Core/Services/Implementations/RelayPushRegistrationService.cs index 8c17d8f96..d537e7f75 100644 --- a/src/Core/Services/Implementations/RelayPushRegistrationService.cs +++ b/src/Core/Services/Implementations/RelayPushRegistrationService.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Net.Http; -using System; using Bit.Core.Models.Api; using Bit.Core.Enums; using System.Linq; @@ -30,12 +29,6 @@ namespace Bit.Core.Services public async Task CreateOrUpdateRegistrationAsync(string pushToken, string deviceId, string userId, string identifier, DeviceType type) { - var tokenStateResponse = await HandleTokenStateAsync(); - if(!tokenStateResponse) - { - return; - } - var requestModel = new PushRegistrationRequestModel { DeviceId = deviceId, @@ -44,45 +37,12 @@ namespace Bit.Core.Services Type = type, UserId = userId }; - - var message = new TokenHttpRequestMessage(requestModel, AccessToken) - { - Method = HttpMethod.Post, - RequestUri = new Uri(string.Concat(Client.BaseAddress, "/push/register")) - }; - - try - { - await Client.SendAsync(message); - } - catch(Exception e) - { - _logger.LogError(12335, e, "Unable to create push registration."); - } + await SendAsync(HttpMethod.Post, "/push/register", requestModel); } public async Task DeleteRegistrationAsync(string deviceId) { - var tokenStateResponse = await HandleTokenStateAsync(); - if(!tokenStateResponse) - { - return; - } - - var message = new TokenHttpRequestMessage(AccessToken) - { - Method = HttpMethod.Delete, - RequestUri = new Uri(string.Concat(Client.BaseAddress, "/push/", deviceId)) - }; - - try - { - await Client.SendAsync(message); - } - catch(Exception e) - { - _logger.LogError(12336, e, "Unable to delete push registration."); - } + await SendAsync(HttpMethod.Delete, string.Concat("/push/", deviceId)); } public async Task AddUserRegistrationOrganizationAsync(IEnumerable deviceIds, string organizationId) @@ -92,27 +52,8 @@ namespace Bit.Core.Services return; } - var tokenStateResponse = await HandleTokenStateAsync(); - if(!tokenStateResponse) - { - return; - } - var requestModel = new PushUpdateRequestModel(deviceIds, organizationId); - var message = new TokenHttpRequestMessage(requestModel, AccessToken) - { - Method = HttpMethod.Put, - RequestUri = new Uri(string.Concat(Client.BaseAddress, "/push/add-organization")) - }; - - try - { - await Client.SendAsync(message); - } - catch(Exception e) - { - _logger.LogError(12337, e, "Unable to add user org push registration."); - } + await SendAsync(HttpMethod.Put, "/push/add-organization", requestModel); } public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable deviceIds, string organizationId) @@ -122,27 +63,8 @@ namespace Bit.Core.Services return; } - var tokenStateResponse = await HandleTokenStateAsync(); - if(!tokenStateResponse) - { - return; - } - var requestModel = new PushUpdateRequestModel(deviceIds, organizationId); - var message = new TokenHttpRequestMessage(requestModel, AccessToken) - { - Method = HttpMethod.Put, - RequestUri = new Uri(string.Concat(Client.BaseAddress, "/push/delete-organization")) - }; - - try - { - await Client.SendAsync(message); - } - catch(Exception e) - { - _logger.LogError(12338, e, "Unable to delete user org push registration."); - } + await SendAsync(HttpMethod.Put, "/push/delete-organization", requestModel); } } } diff --git a/src/Events/appsettings.Production.json b/src/Events/appsettings.Production.json index 8bca868fc..1a13dcf18 100644 --- a/src/Events/appsettings.Production.json +++ b/src/Events/appsettings.Production.json @@ -5,6 +5,8 @@ "api": "https://api.bitwarden.com", "identity": "https://identity.bitwarden.com", "admin": "https://admin.bitwarden.com", + "hub": "https://hub.bitwarden.com", + "internalHub": "https://hub.bitwarden.com", "internalAdmin": "https://admin.bitwarden.com", "internalIdentity": "https://identity.bitwarden.com", "internalApi": "https://api.bitwarden.com", diff --git a/src/Events/appsettings.json b/src/Events/appsettings.json index 1f7fc714a..3d94343d6 100644 --- a/src/Events/appsettings.json +++ b/src/Events/appsettings.json @@ -7,6 +7,8 @@ "api": "http://localhost:4000", "identity": "http://localhost:33656", "admin": "http://localhost:62911", + "hub": "http://localhost:61840", + "internalHub": "http://localhost:61840", "internalAdmin": "http://localhost:62911", "internalIdentity": "http://localhost:33656", "internalApi": "http://localhost:4000", diff --git a/src/Hub/AzureQueueHostedService.cs b/src/Hub/AzureQueueHostedService.cs index c1a989fa2..04d665923 100644 --- a/src/Hub/AzureQueueHostedService.cs +++ b/src/Hub/AzureQueueHostedService.cs @@ -70,49 +70,7 @@ namespace Bit.Hub { var notification = JsonConvert.DeserializeObject>( message.AsString); - switch(notification.Type) - { - case Core.Enums.PushType.SyncCipherUpdate: - case Core.Enums.PushType.SyncCipherCreate: - case Core.Enums.PushType.SyncCipherDelete: - case Core.Enums.PushType.SyncLoginDelete: - var cipherNotification = - JsonConvert.DeserializeObject>( - message.AsString); - if(cipherNotification.Payload.UserId.HasValue) - { - await _hubContext.Clients.User(cipherNotification.Payload.UserId.ToString()) - .SendAsync("ReceiveMessage", notification, cancellationToken); - } - else if(cipherNotification.Payload.OrganizationId.HasValue) - { - await _hubContext.Clients.Group( - $"Organization_{cipherNotification.Payload.OrganizationId}") - .SendAsync("ReceiveMessage", notification, cancellationToken); - } - break; - case Core.Enums.PushType.SyncFolderUpdate: - case Core.Enums.PushType.SyncFolderCreate: - case Core.Enums.PushType.SyncFolderDelete: - var folderNotification = - JsonConvert.DeserializeObject>( - message.AsString); - await _hubContext.Clients.User(folderNotification.Payload.UserId.ToString()) - .SendAsync("ReceiveMessage", notification, cancellationToken); - break; - case Core.Enums.PushType.SyncCiphers: - case Core.Enums.PushType.SyncVault: - case Core.Enums.PushType.SyncOrgKeys: - case Core.Enums.PushType.SyncSettings: - var userNotification = - JsonConvert.DeserializeObject>( - message.AsString); - await _hubContext.Clients.User(userNotification.Payload.UserId.ToString()) - .SendAsync("ReceiveMessage", notification, cancellationToken); - break; - default: - break; - } + await HubHelpers.SendNotificationToHubAsync(notification, _hubContext, cancellationToken); await _queue.DeleteMessageAsync(message); } } diff --git a/src/Hub/Controllers/EventsController.cs b/src/Hub/Controllers/EventsController.cs deleted file mode 100644 index 213e3b690..000000000 --- a/src/Hub/Controllers/EventsController.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.SignalR; - -namespace Bit.Hub -{ - [Authorize("Internal")] - public class EventsController : Controller - { - private readonly IHubContext _syncHubContext; - - public EventsController(IHubContext syncHubContext) - { - _syncHubContext = syncHubContext; - } - - [HttpGet("~/events")] - public async Task GetTest() - { - await _syncHubContext.Clients.All.SendAsync("ReceiveMessage", "From API."); - } - } -} diff --git a/src/Hub/Controllers/NotificationController.cs b/src/Hub/Controllers/NotificationController.cs new file mode 100644 index 000000000..b7b8627c8 --- /dev/null +++ b/src/Hub/Controllers/NotificationController.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using Bit.Core.Models; +using Bit.Core.Utilities; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.SignalR; + +namespace Bit.Hub +{ + [Authorize("Internal")] + [SelfHosted(SelfHostedOnly = true)] + public class NotificationController : Controller + { + private readonly IHubContext _syncHubContext; + + public NotificationController(IHubContext syncHubContext) + { + _syncHubContext = syncHubContext; + } + + [HttpPost("~/notification")] + public async Task PostNotification([FromBody]PushNotificationData model) + { + await HubHelpers.SendNotificationToHubAsync(model, _syncHubContext); + } + } +} diff --git a/src/Hub/HubHelpers.cs b/src/Hub/HubHelpers.cs new file mode 100644 index 000000000..89f5e7415 --- /dev/null +++ b/src/Hub/HubHelpers.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Bit.Core.Models; +using Microsoft.AspNetCore.SignalR; + +namespace Bit.Hub +{ + public static class HubHelpers + { + public static async Task SendNotificationToHubAsync(PushNotificationData notification, + IHubContext hubContext, CancellationToken cancellationToken = default(CancellationToken)) + { + switch(notification.Type) + { + case Core.Enums.PushType.SyncCipherUpdate: + case Core.Enums.PushType.SyncCipherCreate: + case Core.Enums.PushType.SyncCipherDelete: + case Core.Enums.PushType.SyncLoginDelete: + var cipherPayload = (SyncCipherPushNotification)Convert.ChangeType( + notification.Payload, typeof(SyncCipherPushNotification)); + if(cipherPayload.UserId.HasValue) + { + await hubContext.Clients.User(cipherPayload.UserId.ToString()) + .SendAsync("ReceiveMessage", notification, cancellationToken); + } + else if(cipherPayload.OrganizationId.HasValue) + { + await hubContext.Clients.Group( + $"Organization_{cipherPayload.OrganizationId}") + .SendAsync("ReceiveMessage", notification, cancellationToken); + } + break; + case Core.Enums.PushType.SyncFolderUpdate: + case Core.Enums.PushType.SyncFolderCreate: + case Core.Enums.PushType.SyncFolderDelete: + var folderPayload = (SyncFolderPushNotification)Convert.ChangeType( + notification.Payload, typeof(SyncFolderPushNotification)); + await hubContext.Clients.User(folderPayload.UserId.ToString()) + .SendAsync("ReceiveMessage", notification, cancellationToken); + break; + case Core.Enums.PushType.SyncCiphers: + case Core.Enums.PushType.SyncVault: + case Core.Enums.PushType.SyncOrgKeys: + case Core.Enums.PushType.SyncSettings: + var userPayload = (SyncUserPushNotification)Convert.ChangeType( + notification.Payload, typeof(SyncUserPushNotification)); + await hubContext.Clients.User(userPayload.UserId.ToString()) + .SendAsync("ReceiveMessage", notification, cancellationToken); + break; + default: + break; + } + } + } +} diff --git a/src/Hub/appsettings.Production.json b/src/Hub/appsettings.Production.json index 8bca868fc..1a13dcf18 100644 --- a/src/Hub/appsettings.Production.json +++ b/src/Hub/appsettings.Production.json @@ -5,6 +5,8 @@ "api": "https://api.bitwarden.com", "identity": "https://identity.bitwarden.com", "admin": "https://admin.bitwarden.com", + "hub": "https://hub.bitwarden.com", + "internalHub": "https://hub.bitwarden.com", "internalAdmin": "https://admin.bitwarden.com", "internalIdentity": "https://identity.bitwarden.com", "internalApi": "https://api.bitwarden.com", diff --git a/src/Hub/appsettings.json b/src/Hub/appsettings.json index b34ee5a24..507901b23 100644 --- a/src/Hub/appsettings.json +++ b/src/Hub/appsettings.json @@ -7,6 +7,8 @@ "api": "http://localhost:4000", "identity": "http://localhost:33656", "admin": "http://localhost:62911", + "hub": "http://localhost:61840", + "internalHub": "http://localhost:61840", "internalAdmin": "http://localhost:62911", "internalIdentity": "http://localhost:33656", "internalApi": "http://localhost:4000", diff --git a/src/Identity/appsettings.Production.json b/src/Identity/appsettings.Production.json index 9501db8ac..0b7bb7fae 100644 --- a/src/Identity/appsettings.Production.json +++ b/src/Identity/appsettings.Production.json @@ -5,6 +5,8 @@ "api": "https://api.bitwarden.com", "identity": "https://identity.bitwarden.com", "admin": "https://admin.bitwarden.com", + "hub": "https://hub.bitwarden.com", + "internalHub": "https://hub.bitwarden.com", "internalAdmin": "https://admin.bitwarden.com", "internalIdentity": "https://identity.bitwarden.com", "internalApi": "https://api.bitwarden.com", diff --git a/src/Identity/appsettings.json b/src/Identity/appsettings.json index 66a2cbbe4..07d1a939c 100644 --- a/src/Identity/appsettings.json +++ b/src/Identity/appsettings.json @@ -9,6 +9,8 @@ "api": "http://localhost:4000", "identity": "http://localhost:33656", "admin": "http://localhost:62911", + "hub": "http://localhost:61840", + "internalHub": "http://localhost:61840", "internalAdmin": "http://localhost:62911", "internalIdentity": "http://localhost:33656", "internalApi": "http://localhost:4000", diff --git a/util/Setup/EnvironmentFileBuilder.cs b/util/Setup/EnvironmentFileBuilder.cs index 7381eaf64..3f7350023 100644 --- a/util/Setup/EnvironmentFileBuilder.cs +++ b/util/Setup/EnvironmentFileBuilder.cs @@ -42,6 +42,7 @@ namespace Bit.Setup ["globalSettings__baseServiceUri__api"] = $"{Url}/api", ["globalSettings__baseServiceUri__identity"] = $"{Url}/identity", ["globalSettings__baseServiceUri__admin"] = $"{Url}/admin", + ["globalSettings__baseServiceUri__hub"] = $"{Url}/hub", ["globalSettings__sqlServer__connectionString"] = $"\"{ dbConnectionString }\"", ["globalSettings__identityServer__certificatePassword"] = IdentityCertPassword, ["globalSettings__attachment__baseDirectory"] = $"{OutputDirectory}/core/attachments", @@ -129,6 +130,8 @@ globalSettings__baseServiceUri__vault=http://localhost globalSettings__baseServiceUri__api=http://localhost/api globalSettings__baseServiceUri__identity=http://localhost/identity globalSettings__baseServiceUri__admin=http://localhost/admin +globalSettings__baseServiceUri__hub=http://localhost/hub +globalSettings__baseServiceUri__internalHub=http://hub:5000 globalSettings__baseServiceUri__internalAdmin=http://admin:5000 globalSettings__baseServiceUri__internalIdentity=http://identity:5000 globalSettings__baseServiceUri__internalApi=http://api:5000