Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-14406] Security Task Notifications #5344

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
99e51e8
initial commit of `CipherOrganizationPermission_GetManyByUserId`
nick-livefront Jan 21, 2025
2d8bf91
create queries to get all of the security tasks that are actionable b…
nick-livefront Jan 24, 2025
55a1f30
rename query
nick-livefront Jan 24, 2025
3bd9545
return the user's email from the query as well
nick-livefront Jan 24, 2025
aa9153f
Add email notification for at-risk passwords
nick-livefront Jan 27, 2025
36c1b53
add push notification for security tasks
nick-livefront Jan 27, 2025
635b3d6
update entity framework to match stored procedure plus testing
nick-livefront Jan 29, 2025
014b7e0
update date of migration and remove orderby
nick-livefront Jan 29, 2025
15fc6ae
add push service to security task controller
nick-livefront Jan 29, 2025
64e8181
rename `SyncSecurityTasksCreated` to `SyncNotification`
nick-livefront Jan 29, 2025
8d14898
remove duplicate return
nick-livefront Jan 29, 2025
76328f3
remove unused directive
nick-livefront Jan 29, 2025
60403c9
remove unneeded new notification type
nick-livefront Jan 30, 2025
7c18edf
use `createNotificationCommand` to alert all platforms
nick-livefront Jan 30, 2025
a2da2c0
return the cipher id that is associated with the security task and st…
nick-livefront Feb 11, 2025
40d43d3
Merge branch 'main' of https://github.com/bitwarden/server into vault…
nick-livefront Feb 14, 2025
c304667
Add `TaskId` to the output model of `GetUserSecurityTasksByCipherIdsA…
nick-livefront Feb 14, 2025
cd9a2c5
move notification logic to command
nick-livefront Feb 14, 2025
906fb54
use TaskId from `_getSecurityTasksNotificationDetailsQuery`
nick-livefront Feb 14, 2025
ae8d47a
add service
nick-livefront Feb 14, 2025
31d05e4
only push last notification for each user
nick-livefront Feb 14, 2025
2b9bc05
formatting
nick-livefront Feb 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion src/Api/Vault/Controllers/SecurityTaskController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
using Bit.Api.Vault.Models.Request;
using Bit.Api.Vault.Models.Response;
using Bit.Core;
using Bit.Core.Enums;
using Bit.Core.NotificationCenter.Commands.Interfaces;
using Bit.Core.NotificationCenter.Entities;
using Bit.Core.NotificationCenter.Enums;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Bit.Core.Vault.Commands.Interfaces;
using Bit.Core.Vault.Enums;
using Bit.Core.Vault.Models.Data;
using Bit.Core.Vault.Queries;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -22,19 +28,31 @@
private readonly IMarkTaskAsCompleteCommand _markTaskAsCompleteCommand;
private readonly IGetTasksForOrganizationQuery _getTasksForOrganizationQuery;
private readonly ICreateManyTasksCommand _createManyTasksCommand;
private readonly IGetSecurityTasksNotificationDetailsQuery _getSecurityTasksNotificationDetailsQuery;
private readonly IOrganizationRepository _organizationRepository;
private readonly IMailService _mailService;
private readonly ICreateNotificationCommand _createNotificationCommand;

public SecurityTaskController(
IUserService userService,
IGetTaskDetailsForUserQuery getTaskDetailsForUserQuery,
IMarkTaskAsCompleteCommand markTaskAsCompleteCommand,
IGetTasksForOrganizationQuery getTasksForOrganizationQuery,
ICreateManyTasksCommand createManyTasksCommand)
ICreateManyTasksCommand createManyTasksCommand,
IGetSecurityTasksNotificationDetailsQuery getSecurityTasksNotificationDetailsQuery,
IOrganizationRepository organizationRepository,
IMailService mailService,
ICreateNotificationCommand createNotificationCommand)

Check warning on line 45 in src/Api/Vault/Controllers/SecurityTaskController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/Vault/Controllers/SecurityTaskController.cs#L41-L45

Added lines #L41 - L45 were not covered by tests
{
_userService = userService;
_getTaskDetailsForUserQuery = getTaskDetailsForUserQuery;
_markTaskAsCompleteCommand = markTaskAsCompleteCommand;
_getTasksForOrganizationQuery = getTasksForOrganizationQuery;
_createManyTasksCommand = createManyTasksCommand;
_getSecurityTasksNotificationDetailsQuery = getSecurityTasksNotificationDetailsQuery;
_organizationRepository = organizationRepository;
_mailService = mailService;
_createNotificationCommand = createNotificationCommand;

Check warning on line 55 in src/Api/Vault/Controllers/SecurityTaskController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/Vault/Controllers/SecurityTaskController.cs#L52-L55

Added lines #L52 - L55 were not covered by tests
}

/// <summary>
Expand Down Expand Up @@ -87,6 +105,37 @@
[FromBody] BulkCreateSecurityTasksRequestModel model)
{
var securityTasks = await _createManyTasksCommand.CreateAsync(orgId, model.Tasks);

var securityTaskCiphers = await _getSecurityTasksNotificationDetailsQuery.GetNotificationDetailsByManyIds(orgId, securityTasks);

Check warning on line 109 in src/Api/Vault/Controllers/SecurityTaskController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/Vault/Controllers/SecurityTaskController.cs#L109

Added line #L109 was not covered by tests

// Get the number of tasks for each user
var userTaskCount = securityTaskCiphers.GroupBy(x => x.UserId).Select(x => new
UserSecurityTasksCount
{
UserId = x.Key,
Email = x.First().Email,
TaskCount = x.Count()
}).ToList();

Check warning on line 118 in src/Api/Vault/Controllers/SecurityTaskController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/Vault/Controllers/SecurityTaskController.cs#L112-L118

Added lines #L112 - L118 were not covered by tests

var organization = await _organizationRepository.GetByIdAsync(orgId);
await _mailService.SendBulkSecurityTaskNotificationsAsync(organization.Name, userTaskCount);

Check warning on line 121 in src/Api/Vault/Controllers/SecurityTaskController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/Vault/Controllers/SecurityTaskController.cs#L120-L121

Added lines #L120 - L121 were not covered by tests

foreach (var userSecurityTaskCipher in securityTaskCiphers)
{

Check warning on line 124 in src/Api/Vault/Controllers/SecurityTaskController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/Vault/Controllers/SecurityTaskController.cs#L124

Added line #L124 was not covered by tests
// Get the associated security task for the cipher
var securityTask = securityTasks.First(x => x.CipherId == userSecurityTaskCipher.CipherId);
// Create a notification for the user with the associated task
var notification = new Notification
{
UserId = userSecurityTaskCipher.UserId,
OrganizationId = orgId,
Priority = Priority.Informational,
ClientType = ClientType.Browser,
TaskId = securityTask.Id
};
await _createNotificationCommand.CreateAsync(notification);
}

Check warning on line 137 in src/Api/Vault/Controllers/SecurityTaskController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/Vault/Controllers/SecurityTaskController.cs#L128-L137

Added lines #L128 - L137 were not covered by tests

var response = securityTasks.Select(x => new SecurityTasksResponseModel(x)).ToList();
return new ListResponseModel<SecurityTasksResponseModel>(response);
}
Expand Down
61 changes: 61 additions & 0 deletions src/Core/MailTemplates/Handlebars/Layouts/SecurityTasks.html.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{{#>FullUpdatedHtmlLayout}}
<table border="0" cellpadding="0" cellspacing="0" width="100%"
style="background-color: #175DDC;padding-top:25px;padding-bottom:15px;">
<tr>
<td align="center" valign="top" width="70%" class="templateColumnContainer">
<table border="0" cellpadding="0" cellspacing="0" width="100%"
style="padding-left:30px; padding-right: 5px; padding-top: 20px;">
<tr>
<td
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 24px; color: #ffffff; line-height: 32px; font-weight: 500; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
{{OrgName}} has identified {{TaskCount}} critical login{{#if TaskCountPlural}}s{{/if}} that require{{#unless
TaskCountPlural}}s{{/unless}} a
password change
</td>
</tr>
</table>
</td>
<td align="right" valign="bottom" class="templateColumnContainer" style="padding-right: 15px;">
<img width="140" height="140" align="right" valign="bottom"
style="width: 140px; height:140px; font-size: 0; vertical-align: bottom; text-align: right;" alt=''
src='https://assets.bitwarden.com/email/v1/business-warning.png' />
</td>
</tr>
</table>

{{>@partial-block}}

<table width="100%" style="display:table; background-color: #FBFBFB; vertical-align: middle; padding:30px" border="0"
cellpadding="0" cellspacing="0" valign="middle">
<tr>
<td width="70%" class="footer-text" style="padding-right: 20px;">
<table align="left" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-style: normal; font-weight: 400; font-size: 16px; line-height: 24px;">
<p
style="margin: 0; padding: 0; margin-bottom: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-style: normal; font-weight: 600; font-size: 20px; line-height: 28px;">
We’re here for you!</p>
If you have any questions, search the Bitwarden <a
style="text-decoration: none; color: #175DDC; font-weight: 600;"
href="https://bitwarden.com/help/">Help</a> site or <a
style="text-decoration: none; color: #175DDC; font-weight: 600;"
href="https://bitwarden.com/contact/">contact us</a>.
</td>
</tr>
</table>
</td>
<td width="30%">
<table align="right" valign="bottom" class="footer-image" border="0" cellpadding="0" cellspacing="0"
style="padding-left: 40px;">
<tr>
<td>
<img width="94" height="77" src="https://assets.bitwarden.com/email/v1/chat.png"
style="width: 94px; height: 77px;" alt="" />
</td>
</tr>
</table>
</td>
</tr>
</table>
{{/FullUpdatedHtmlLayout}}
12 changes: 12 additions & 0 deletions src/Core/MailTemplates/Handlebars/Layouts/SecurityTasks.text.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{{#>FullTextLayout}}
{{OrgName}} has identified {{TaskCount}} critical login{{#if TaskCountPlural}}s{{/if}} that require{{#unless
TaskCountPlural}}s{{/unless}} a
password change

{{>@partial-block}}

We’re here for you!
If you have any questions, search the Bitwarden Help site or contact us.
- https://bitwarden.com/help/
- https://bitwarden.com/contact/
{{/FullTextLayout}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{#>SecurityTasksHtmlLayout}}
<table width="100%" border="0" style="display: block; padding: 30px;" align="center" cellpadding="0" cellspacing="0">
<tr>
<td
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-style: normal; font-weight: 400; font-size: 16px; line-height: 24px;">
Keep you and your organization's data safe by changing passwords that are weak, reused, or have been exposed in a
data breach.
</td>
</tr>
<tr>
<td
style="padding-top: 24px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-style: normal; font-weight: 400; font-size: 16px; line-height: 24px;">
Launch the Bitwarden extension to review your at-risk passwords.
</td>
</tr>
</table>
<table width="100%" border="0" cellpadding="0" cellspacing="0"
style="display: table; width:100%; padding-bottom: 35px; text-align: center;" align="center">
<tr>
<td display="display: table-cell">
<a href="{{ReviewPasswordsUrl}}" clicktracking=off target="_blank"
style="display: inline-block; color: #ffffff; text-decoration: none; text-align: center; cursor: pointer; border-radius: 999px; background-color: #175DDC; border-color: #175DDC; border-style: solid; border-width: 10px 20px; margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
Review at-risk passwords
</a>
</td>
</tr>
</table>
{{/SecurityTasksHtmlLayout}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{#>SecurityTasksHtmlLayout}}
Keep you and your organization's data safe by changing passwords that are weak, reused, or have been exposed in a data
breach.

Launch the Bitwarden extension to review your at-risk passwords.

Review at-risk passwords ({{{ReviewPasswordsUrl}}})
{{/SecurityTasksHtmlLayout}}
12 changes: 12 additions & 0 deletions src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Bit.Core.Models.Mail;

public class SecurityTaskNotificationViewModel : BaseMailModel
{
public string OrgName { get; set; }

Check warning on line 5 in src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs#L5

Added line #L5 was not covered by tests

public int TaskCount { get; set; }

Check warning on line 7 in src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs#L7

Added line #L7 was not covered by tests

public bool TaskCountPlural => TaskCount != 1;

Check warning on line 9 in src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs#L9

Added line #L9 was not covered by tests

public string ReviewPasswordsUrl => $"{WebVaultUrl}/browser-extension-prompt";

Check warning on line 11 in src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Models/Mail/SecurityTaskNotificationViewModel.cs#L11

Added line #L11 was not covered by tests
}
3 changes: 2 additions & 1 deletion src/Core/Services/IMailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Bit.Core.Entities;
using Bit.Core.Models.Data.Organizations;
using Bit.Core.Models.Mail;
using Bit.Core.Vault.Models.Data;

namespace Bit.Core.Services;

Expand Down Expand Up @@ -97,5 +98,5 @@ Task SendFamiliesForEnterpriseRemoveSponsorshipsEmailAsync(string email, string
string organizationName);
Task SendClaimedDomainUserEmailAsync(ManagedUserDomainClaimedEmails emailList);
Task SendDeviceApprovalRequestedNotificationEmailAsync(IEnumerable<string> adminEmails, Guid organizationId, string email, string userName);
Task SendBulkSecurityTaskNotificationsAsync(string orgName, IEnumerable<UserSecurityTasksCount> securityTaskNotificaitons);
}

24 changes: 23 additions & 1 deletion src/Core/Services/Implementations/HandlebarsMailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Bit.Core.SecretsManager.Models.Mail;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Bit.Core.Vault.Models.Data;
using HandlebarsDotNet;

namespace Bit.Core.Services;
Expand Down Expand Up @@ -644,6 +645,10 @@
Handlebars.RegisterTemplate("TitleContactUsHtmlLayout", titleContactUsHtmlLayoutSource);
var titleContactUsTextLayoutSource = await ReadSourceAsync("Layouts.TitleContactUs.text");
Handlebars.RegisterTemplate("TitleContactUsTextLayout", titleContactUsTextLayoutSource);
var securityTasksHtmlLayoutSource = await ReadSourceAsync("Layouts.SecurityTasks.html");
Handlebars.RegisterTemplate("SecurityTasksHtmlLayout", securityTasksHtmlLayoutSource);
var securityTasksTextLayoutSource = await ReadSourceAsync("Layouts.SecurityTasks.text");
Handlebars.RegisterTemplate("SecurityTasksTextLayout", securityTasksTextLayoutSource);

Handlebars.RegisterHelper("date", (writer, context, parameters) =>
{
Expand Down Expand Up @@ -1186,9 +1191,26 @@
await _mailDeliveryService.SendEmailAsync(message);
}

public async Task SendBulkSecurityTaskNotificationsAsync(string orgName, IEnumerable<UserSecurityTasksCount> securityTaskNotificaitons)
{

Check warning on line 1195 in src/Core/Services/Implementations/HandlebarsMailService.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Services/Implementations/HandlebarsMailService.cs#L1195

Added line #L1195 was not covered by tests
MailQueueMessage CreateMessage(UserSecurityTasksCount notification)
{

Check warning on line 1197 in src/Core/Services/Implementations/HandlebarsMailService.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Services/Implementations/HandlebarsMailService.cs#L1197

Added line #L1197 was not covered by tests
var message = CreateDefaultMessage($"{orgName} has identified {notification.TaskCount} at-risk password{(notification.TaskCount.Equals(1) ? "" : "s")}", notification.Email);
var model = new SecurityTaskNotificationViewModel
{
OrgName = orgName,
TaskCount = notification.TaskCount,
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
};
message.Category = "SecurityTasksNotification";
return new MailQueueMessage(message, "SecurityTasksNotification", model);
}
var messageModels = securityTaskNotificaitons.Select(CreateMessage);
await EnqueueMailAsync(messageModels.ToList());
}

Check warning on line 1210 in src/Core/Services/Implementations/HandlebarsMailService.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Services/Implementations/HandlebarsMailService.cs#L1199-L1210

Added lines #L1199 - L1210 were not covered by tests

private static string GetUserIdentifier(string email, string userName)
{
return string.IsNullOrEmpty(userName) ? email : CoreHelpers.SanitizeForEmail(userName, false);
}
}

7 changes: 6 additions & 1 deletion src/Core/Services/NoopImplementations/NoopMailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Bit.Core.Entities;
using Bit.Core.Models.Data.Organizations;
using Bit.Core.Models.Mail;
using Bit.Core.Vault.Models.Data;

namespace Bit.Core.Services;

Expand Down Expand Up @@ -321,5 +322,9 @@
{
return Task.FromResult(0);
}
}

public Task SendBulkSecurityTaskNotificationsAsync(string orgName, IEnumerable<UserSecurityTasksCount> securityTaskNotificaitons)
{
return Task.FromResult(0);
}

Check warning on line 329 in src/Core/Services/NoopImplementations/NoopMailService.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Services/NoopImplementations/NoopMailService.cs#L327-L329

Added lines #L327 - L329 were not covered by tests
}
22 changes: 22 additions & 0 deletions src/Core/Vault/Models/Data/UserSecurityTaskCipher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Bit.Core.Vault.Models.Data;

/// <summary>
/// Data model that represents a User and the associated cipher for a security task.
/// </summary>
public class UserSecurityTaskCipher
{
/// <summary>
/// The user's Id.
/// </summary>
public Guid UserId { get; set; }

Check warning on line 11 in src/Core/Vault/Models/Data/UserSecurityTaskCipher.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Models/Data/UserSecurityTaskCipher.cs#L11

Added line #L11 was not covered by tests

/// <summary>
/// The user's email.
/// </summary>
public string Email { get; set; }

Check warning on line 16 in src/Core/Vault/Models/Data/UserSecurityTaskCipher.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Models/Data/UserSecurityTaskCipher.cs#L16

Added line #L16 was not covered by tests

/// <summary>
/// The cipher Id of the security task.
/// </summary>
public Guid CipherId { get; set; }

Check warning on line 21 in src/Core/Vault/Models/Data/UserSecurityTaskCipher.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Models/Data/UserSecurityTaskCipher.cs#L21

Added line #L21 was not covered by tests
}
22 changes: 22 additions & 0 deletions src/Core/Vault/Models/Data/UserSecurityTasksCount.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Bit.Core.Vault.Models.Data;

/// <summary>
/// Data model that represents a User and the amount of actionable security tasks.
/// </summary>
public class UserSecurityTasksCount
{
/// <summary>
/// The user's Id.
/// </summary>
public Guid UserId { get; set; }

Check warning on line 11 in src/Core/Vault/Models/Data/UserSecurityTasksCount.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Models/Data/UserSecurityTasksCount.cs#L11

Added line #L11 was not covered by tests

/// <summary>
/// The user's email.
/// </summary>
public string Email { get; set; }

Check warning on line 16 in src/Core/Vault/Models/Data/UserSecurityTasksCount.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Models/Data/UserSecurityTasksCount.cs#L16

Added line #L16 was not covered by tests

/// <summary>
/// The number of actionable security tasks for the respective users.
/// </summary>
public int TaskCount { get; set; }

Check warning on line 21 in src/Core/Vault/Models/Data/UserSecurityTasksCount.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Models/Data/UserSecurityTasksCount.cs#L21

Added line #L21 was not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Bit.Core.Context;
using Bit.Core.Exceptions;
using Bit.Core.Vault.Entities;
using Bit.Core.Vault.Models.Data;
using Bit.Core.Vault.Repositories;

namespace Bit.Core.Vault.Queries;

public class GetSecurityTasksNotificationDetailsQuery : IGetSecurityTasksNotificationDetailsQuery
{
private readonly ICurrentContext _currentContext;
private readonly ICipherRepository _cipherRepository;

public GetSecurityTasksNotificationDetailsQuery(ICurrentContext currentContext, ICipherRepository cipherRepository)
{
_currentContext = currentContext;
_cipherRepository = cipherRepository;
}

Check warning on line 18 in src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs#L14-L18

Added lines #L14 - L18 were not covered by tests

public async Task<ICollection<UserSecurityTaskCipher>> GetNotificationDetailsByManyIds(Guid organizationId, IEnumerable<SecurityTask> tasks)
{
var org = _currentContext.GetOrganization(organizationId);
var cipherIds = tasks
.Where(task => task.CipherId.HasValue)
.Select(task => task.CipherId.Value)
.ToList();

Check warning on line 26 in src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs#L21-L26

Added lines #L21 - L26 were not covered by tests

if (org == null)
{
throw new NotFoundException();

Check warning on line 30 in src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs#L29-L30

Added lines #L29 - L30 were not covered by tests
}

var userSecurityTaskCiphers = await _cipherRepository.GetUserSecurityTasksByCipherIdsAsync(organizationId, cipherIds);

Check warning on line 33 in src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs#L33

Added line #L33 was not covered by tests

return userSecurityTaskCiphers;
}

Check warning on line 36 in src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/Vault/Queries/GetSecurityTasksNotificationDetailsQuery.cs#L35-L36

Added lines #L35 - L36 were not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Bit.Core.Vault.Entities;
using Bit.Core.Vault.Models.Data;

namespace Bit.Core.Vault.Queries;

public interface IGetSecurityTasksNotificationDetailsQuery
{
/// <summary>
/// Retrieves all users within the given organization that are applicable to the given security tasks.
///
/// <param name="organizationId"></param>
/// <param name="tasks"></param>
/// <returns>A dictionary of UserIds and the corresponding amount of security tasks applicable to them.</returns>
/// </summary>
public Task<ICollection<UserSecurityTaskCipher>> GetNotificationDetailsByManyIds(Guid organizationId, IEnumerable<SecurityTask> tasks);
}
Loading
Loading