1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-19 00:21:35 -05:00

[PM-15637] Add Email Notification Templates and Logic for Device Approval Requests (#5270)

* Add device approval notification email templates

* Add DeviceApprovalRequestedViewModel for device approval notifications

* Add method to send device approval requested notification email

* Send email notification to Organization Admins when adding a new admin approval auth request

* Add tests for device approval notification email sending in AuthRequestServiceTests

* fix(email-templates): Remove unnecessary triple braces from user name variable in device approval notification emails

* Add feature flag for admin notifications on device approval requests

* Add logging for skipped admin notifications on device approval requests
This commit is contained in:
Rui Tomé
2025-01-27 10:59:46 +00:00
committed by GitHub
parent 3908edd08f
commit 9e718d7336
11 changed files with 249 additions and 1 deletions

View File

@ -12,6 +12,7 @@ using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Microsoft.Extensions.Logging;
#nullable enable
@ -27,6 +28,9 @@ public class AuthRequestService : IAuthRequestService
private readonly IPushNotificationService _pushNotificationService;
private readonly IEventService _eventService;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IMailService _mailService;
private readonly IFeatureService _featureService;
private readonly ILogger<AuthRequestService> _logger;
public AuthRequestService(
IAuthRequestRepository authRequestRepository,
@ -36,7 +40,10 @@ public class AuthRequestService : IAuthRequestService
ICurrentContext currentContext,
IPushNotificationService pushNotificationService,
IEventService eventService,
IOrganizationUserRepository organizationRepository)
IOrganizationUserRepository organizationRepository,
IMailService mailService,
IFeatureService featureService,
ILogger<AuthRequestService> logger)
{
_authRequestRepository = authRequestRepository;
_userRepository = userRepository;
@ -46,6 +53,9 @@ public class AuthRequestService : IAuthRequestService
_pushNotificationService = pushNotificationService;
_eventService = eventService;
_organizationUserRepository = organizationRepository;
_mailService = mailService;
_featureService = featureService;
_logger = logger;
}
public async Task<AuthRequest?> GetAuthRequestAsync(Guid id, Guid userId)
@ -132,6 +142,8 @@ public class AuthRequestService : IAuthRequestService
{
var createdAuthRequest = await CreateAuthRequestAsync(model, user, organizationUser.OrganizationId);
firstAuthRequest ??= createdAuthRequest;
await NotifyAdminsOfDeviceApprovalRequestAsync(organizationUser, user);
}
// I know this won't be null because I have already validated that at least one organization exists
@ -276,4 +288,19 @@ public class AuthRequestService : IAuthRequestService
{
return DateTime.UtcNow > savedDate.Add(allowedLifetime);
}
private async Task NotifyAdminsOfDeviceApprovalRequestAsync(OrganizationUser organizationUser, User user)
{
if (!_featureService.IsEnabled(FeatureFlagKeys.DeviceApprovalRequestAdminNotifications))
{
_logger.LogWarning("Skipped sending device approval notification to admins - feature flag disabled");
return;
}
var admins = await _organizationUserRepository.GetManyByMinimumRoleAsync(
organizationUser.OrganizationId,
OrganizationUserType.Admin);
var adminEmails = admins.Select(a => a.Email).Distinct().ToList();
await _mailService.SendDeviceApprovalRequestedNotificationEmailAsync(adminEmails, organizationUser.OrganizationId, user.Email, user.Name);
}
}