1
0
mirror of https://github.com/bitwarden/server synced 2025-12-15 15:53:59 +00:00

Update Push README's

This commit is contained in:
Justin Baur
2025-11-19 16:44:58 -05:00
parent c073fc2ae2
commit 00845895e0
2 changed files with 88 additions and 20 deletions

View File

@@ -12,7 +12,7 @@ The general usage will be to call `Bit.Core.Platform.Push.IPushNotificationServi
method takes a `PushNotification<T>`.
```c#
// This would send a notification to all the devices of the given `userId`.
// This would send a notification to all the devices of the given `userId`.
await pushNotificationService.PushAsync(new PushNotification<MyPayload>
{
Type = PushType.MyNotificationType,
@@ -29,7 +29,7 @@ await pushNotificationService.PushAsync(new PushNotification<MyPayload>
## Extending
If you want to extend this framework for sending your own notification type you do so by adding a
new enum member to the [`PushType`](./PushType.cs) enum. Assign a number to it that is 1 above the
new enum member to the [`PushType`](./PushType.cs) enum. Assign a number to it that is 1 above the
next highest value. You must then annotate that enum member with a
[`[NotificationInfo]`](./NotificationInfoAttribute.cs) attribute to inform others who the owning
team and expected payload type are. Then you may inject
@@ -44,7 +44,7 @@ implementations. They do currently have tests for many of the notification types
eventually be deleted and no new ones need to be added.
Since notifications are relayed through our cloud instance for self hosted users (if they opt in)
it's important to try and keep the information in the notification payload minimal. It's generally
it's important to try and keep the information in the notification payload minimal. It's generally
best to send a notification with IDs for any entities involved, which mean nothing to our cloud but
can then be used to get more detailed information once the notification is received on the device.
@@ -58,16 +58,16 @@ before its returned task completes.
### Azure Notification Hub
Used when the application is hosted by Bitwarden in the cloud. This sends the notification to the
configured Azure Notification Hub, which we currently rely on for sending notifications to:
- Our mobile clients, through the Notification Hub federation with mobile app notification systems,
and
configured Azure Notification Hub (ANH), which we currently rely on for sending notifications to:
- Our mobile clients, through the Notification Hub federation with mobile app notification systems
- Our clients configured to use Web Push (currently the Chrome Extension).
This implementation is always assumed to have available configuration when running in the cloud.
### Azure Queue
Used when the application is hosted by Bitwarden in the cloud, to send the notification over web
Used when the application is hosted by Bitwarden in the cloud, to send the notification over web
sockets (SignalR). This sends the notification to a Azure Queue. That queue is then consumed in our
Notifications service, where the notification is sent to a SignalR hub so that our clients connected
through a persistent web socket to our notifications service get the notification.
@@ -101,7 +101,7 @@ set automatically in supported Bitwarden setups.
[`NotificationTarget`](./NotificationTarget.cs) is an enum that defines the possible targets for a
notification, `IPushEngine` implementations may or may not need to be aware and have special
considerations for each notification target type. For that reason adding a new target is NOT as easy
as adding a new enum member. The ANH implementation uses it to build it's tag query. A new target
as adding a new enum member. The ANH implementation uses it to build its tag query. A new target
also needs to be something that is targettable through the tag query. For example, say a team wants
a notification target for users in an org with a verified email. Today this target would not be
expressable through a target because when we register a device with ANH we do not include whether
@@ -112,3 +112,32 @@ be for the team that wants such a target to instead do a query to find users who
and send a notification for each user individually using `NotificationTarget.User`. If there are
enough requests like that though we may want to consider adding a `BulkPushAsync` method to
`IPushNotificationService`.
### Self host diagram
```mermaid
flowchart TD
BitwardenClient[Bitwarden Client] -->|Some action| ApiContainer(API Container)
ApiContainer --> |HTTP Call|NotificationsContainer{Notifications Container}
ApiContainer -.-> |"HTTP Call (Can be disabled)"|PushRelay{Cloud Push Relay}
PushRelay --> |ANH Library|ANH{Azure Notifications Hub}
NotificationsContainer --> |SignalR/Web Sockets|WebClients[Web, Desktop, Browser]
ANH --> Firebase{Firebase}
ANH --> APNS{Apple Push Notifications Service}
APNS --> iOS[iOS Clients]
Firebase --> Android[Android Clients]
```
### Cloud Diagram
```mermaid
flowchart TD
BitwardenClient[Bitwarden Client] -->|Some action| ApiContainer(API Container)
ApiContainer --> |Enqueue|AzureQueue{Azure Queue}
ApiContainer --> |ANH Library|ANH{Azure Notification Hub}
ANH --> |*Simplified*|Mobile
ANH --> WebPush[Web Push]
AzureQueue --> |Deque|NotificationsContainer{Notifications Container}
NotificationsContainer --> SignalR
SignalR --> WebClients[Web, Desktop, Browser]
```

View File

@@ -10,7 +10,7 @@ entrypoint for this feature is `IPushRegistrationService`.
This feature is largely used internally to Platform owned endpoints or in concert with another team.
If your feature changes the status of any of the following pieces of data please contact Platform
so that we can keep push registration working correctly.
so that we can keep push registration working correctly:
- The creation/deletion of a new `Device`.
- The addition of removal of an organization a `User` is a part of.
@@ -24,26 +24,65 @@ associated metadata with Azure Notification Hub (ANH). This is necessary so that
is sent ANH will be able to get the notification to that device.
Since Azure Notification Hub has a limit on the amount of devices per hub we have begun to shard
devices across multiple hubs. Multiple hubs can be configured through configuration and each one can
devices across multiple hubs. Multiple hubs can be setup through configuration and each one can
have a `RegistrationStartDate` and `RegistrationEndDate`. If the start date is `null` no devices
will be registered against that given hub. A `null` end date is treated as no known expiry. The
creation date for a device is retrieved by the device's ID, and that date is used to find a hub that
spans uring it's creation date.
was actively accepting registrations on that device's creation date. When a new notification hub
pool entry is a `RegistrationEndDate` should be added for the previous pool entry. The end date
added to the previous entry should be equal to the start date of the new entry. Both of these dates
should be in the future relative to the release date of the release they are going to be added as a
part of. This way the release can happen and any current in flight devices will continue to be
registered with the previous entry and once the release has completed and had a little time to
settle we can start registering devices on the new notification hub. An overlap of one entries end
date and another entries start date would be preferable to not having them be equal or no overlap.
When we register a device with Azure Notification Hub we include tags, which are data that can later
be used to specifically target that device with a notification. We send the ID of the user this
device belongs to, the type of the client (Web, Desktop, Mobile, etc), all the organization IDs of
organizations of which the user is a confirmed member, the ID of the self-hosted installation if
this device was relayed to us, and the device identifier, which is a random GUID generated on the
device. Most of this data is considered immutable after the creation of a device, except for the
organization memberships of a user. If a user is added/removed from an organization, it is important
that `CreateOrUpdateRegistrationAsync` is called with the new memberships.
Notification hub pool example settings:
```json
{
"GlobalSettings": {
"NotificationHubPool": {
"NotificationHubs": [
{
"HubName": "first",
"ConnectionString": "anh-connection-string-1",
"EnableSendTracing": true,
"RegistrationStartDate": "1900-01-01T00:00:00.0000000Z",
"RegistrationEndDate": "2025-01-01T00:00:00.0000000Z"
},
{
"HubName": "second",
"ConnectionString": "anh-connection-string-2",
"EnableSendTracing": false,
"RegistrationStartDate": "2025-01-01T00:00:00.0000000Z",
"RegistrationEndDate": null
}
]
}
}
}
```
When we register a device with Azure Notification Hub we include the following tags:
- User ID
- Client Type (Web, Desktop, Mobile, etc)
- Organization ID's of the which the user is a confirmed member
- ID of the self-hosted installation if this device was relayed to us
- Device identifier
These tags are used to specifically target a device based on those tags with a notification. Most of
this data is considered immutable after the creation of a device, except for the organization
memberships of a user. If a user is added/removed from an organization, it is important that
`CreateOrUpdateRegistrationAsync` is called with the new memberships.
### Relay
Used when the application is self-hosted. This sends a API request to the configured cloud instance
and which will then use [Azure Notification Hub](#azure-notification-hub) but will associate the
installation as the self-hosted installation id instead of using the cloud one.
installation as the self-hosted installation id instead of using the cloud one. The endpoints are
in the [`PushController`](../../../Api/Platform/Push/Controllers/PushController.cs)
### SignalR