1
0
mirror of https://github.com/bitwarden/server synced 2026-01-06 02:23:51 +00:00

[PM-14406] Security Task Notifications (#5344)

* initial commit of `CipherOrganizationPermission_GetManyByUserId`

* create queries to get all of the security tasks that are actionable by a user

- A task is "actionable" when the user has manage permissions for that cipher

* rename query

* return the user's email from the query as well

* Add email notification for at-risk passwords

- Added email layouts for security tasks

* add push notification for security tasks

* update entity framework to match stored procedure plus testing

* update date of migration and remove orderby

* add push service to security task controller

* rename `SyncSecurityTasksCreated` to `SyncNotification`

* remove duplicate return

* remove unused directive

* remove unneeded new notification type

* use `createNotificationCommand` to alert all platforms

* return the cipher id that is associated with the security task and store the security task id on the notification entry

* Add `TaskId` to the output model of `GetUserSecurityTasksByCipherIdsAsync`

* move notification logic to command

* use TaskId from `_getSecurityTasksNotificationDetailsQuery`

* add service

* only push last notification for each user

* formatting

* refactor `CreateNotificationCommand` parameter to `sendPush`

* flip boolean in test

* update interface to match usage

* do not push any of the security related notifications to the user

* add `PendingSecurityTasks` push type

* add push notification for pending security tasks
This commit is contained in:
Nick Krantz
2025-02-27 08:34:42 -06:00
committed by GitHub
parent a2e665cb96
commit 1267332b5b
35 changed files with 893 additions and 8 deletions

View File

@@ -219,6 +219,11 @@ public class AzureQueuePushNotificationService : IPushNotificationService
await SendMessageAsync(PushType.NotificationStatus, message, true);
}
public async Task PushPendingSecurityTasksAsync(Guid userId)
{
await PushUserAsync(userId, PushType.PendingSecurityTasks);
}
private async Task PushSendAsync(Send send, PushType type)
{
if (send.UserId.HasValue)

View File

@@ -38,4 +38,5 @@ public interface IPushNotificationService
string? deviceId = null, ClientType? clientType = null);
Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string? identifier,
string? deviceId = null, ClientType? clientType = null);
Task PushPendingSecurityTasksAsync(Guid userId);
}

View File

@@ -179,6 +179,12 @@ public class MultiServicePushNotificationService : IPushNotificationService
return Task.FromResult(0);
}
public Task PushPendingSecurityTasksAsync(Guid userId)
{
PushToServices((s) => s.PushPendingSecurityTasksAsync(userId));
return Task.CompletedTask;
}
private void PushToServices(Func<IPushNotificationService, Task> pushFunc)
{
if (!_services.Any())

View File

@@ -121,4 +121,9 @@ public class NoopPushNotificationService : IPushNotificationService
{
return Task.FromResult(0);
}
public Task PushPendingSecurityTasksAsync(Guid userId)
{
return Task.FromResult(0);
}
}

View File

@@ -232,6 +232,11 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
await SendMessageAsync(PushType.NotificationStatus, message, true);
}
public async Task PushPendingSecurityTasksAsync(Guid userId)
{
await PushUserAsync(userId, PushType.PendingSecurityTasks);
}
private async Task PushSendAsync(Send send, PushType type)
{
if (send.UserId.HasValue)

View File

@@ -300,6 +300,11 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
false
);
public async Task PushPendingSecurityTasksAsync(Guid userId)
{
await PushUserAsync(userId, PushType.PendingSecurityTasks);
}
private async Task SendPayloadToInstallationAsync(PushType type, object payload, bool excludeCurrentContext,
ClientType? clientType = null)
{