mirror of
https://github.com/bitwarden/server.git
synced 2026-02-04 02:05:30 -06:00
Adding email for sending to owners, admins, and managers to notify that auto confirm feature has been enabled from admin portal
This commit is contained in:
parent
d3aed59fcb
commit
a9e0fd909e
@ -9,6 +9,7 @@ using Bit.Admin.Utilities;
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Enums.Provider;
|
using Bit.Core.AdminConsole.Enums.Provider;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
||||||
using Bit.Core.AdminConsole.Providers.Interfaces;
|
using Bit.Core.AdminConsole.Providers.Interfaces;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
@ -59,6 +60,7 @@ public class OrganizationsController : Controller
|
|||||||
private readonly IPricingClient _pricingClient;
|
private readonly IPricingClient _pricingClient;
|
||||||
private readonly IResendOrganizationInviteCommand _resendOrganizationInviteCommand;
|
private readonly IResendOrganizationInviteCommand _resendOrganizationInviteCommand;
|
||||||
private readonly IOrganizationBillingService _organizationBillingService;
|
private readonly IOrganizationBillingService _organizationBillingService;
|
||||||
|
private readonly IOrganizationAutoConfirmEnabledNotificationCommand _organizationAutoConfirmEnabledNotificationCommand;
|
||||||
|
|
||||||
public OrganizationsController(
|
public OrganizationsController(
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
@ -84,7 +86,8 @@ public class OrganizationsController : Controller
|
|||||||
IOrganizationInitiateDeleteCommand organizationInitiateDeleteCommand,
|
IOrganizationInitiateDeleteCommand organizationInitiateDeleteCommand,
|
||||||
IPricingClient pricingClient,
|
IPricingClient pricingClient,
|
||||||
IResendOrganizationInviteCommand resendOrganizationInviteCommand,
|
IResendOrganizationInviteCommand resendOrganizationInviteCommand,
|
||||||
IOrganizationBillingService organizationBillingService)
|
IOrganizationBillingService organizationBillingService,
|
||||||
|
IOrganizationAutoConfirmEnabledNotificationCommand organizationAutoConfirmEnabledNotificationCommand)
|
||||||
{
|
{
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
@ -110,6 +113,7 @@ public class OrganizationsController : Controller
|
|||||||
_pricingClient = pricingClient;
|
_pricingClient = pricingClient;
|
||||||
_resendOrganizationInviteCommand = resendOrganizationInviteCommand;
|
_resendOrganizationInviteCommand = resendOrganizationInviteCommand;
|
||||||
_organizationBillingService = organizationBillingService;
|
_organizationBillingService = organizationBillingService;
|
||||||
|
_organizationAutoConfirmEnabledNotificationCommand = organizationAutoConfirmEnabledNotificationCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RequirePermission(Permission.Org_List_View)]
|
[RequirePermission(Permission.Org_List_View)]
|
||||||
@ -293,6 +297,18 @@ public class OrganizationsController : Controller
|
|||||||
|
|
||||||
await _applicationCacheService.UpsertOrganizationAbilityAsync(organization);
|
await _applicationCacheService.UpsertOrganizationAbilityAsync(organization);
|
||||||
|
|
||||||
|
if (!existingOrganizationData.UseAutomaticUserConfirmation && organization.UseAutomaticUserConfirmation)
|
||||||
|
{
|
||||||
|
var emailsToNotify =
|
||||||
|
(await _organizationUserRepository.GetManyDetailsByOrganizationAsync_vNext(organization.Id))
|
||||||
|
.Where(x => x.Type == OrganizationUserType.Admin || x.Type == OrganizationUserType.Owner ||
|
||||||
|
x.GetPermissions().ManageUsers)
|
||||||
|
.Select(x => x.Email);
|
||||||
|
|
||||||
|
await _organizationAutoConfirmEnabledNotificationCommand.SendEmailAsync(
|
||||||
|
new OrganizationAutoConfirmEnabledNotificationRequest(organization, [.. emailsToNotify]));
|
||||||
|
}
|
||||||
|
|
||||||
// Sync name/email changes to Stripe
|
// Sync name/email changes to Stripe
|
||||||
if (existingOrganizationData.Name != organization.Name || existingOrganizationData.BillingEmail != organization.BillingEmail)
|
if (existingOrganizationData.Name != organization.Name || existingOrganizationData.BillingEmail != organization.BillingEmail)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
using Bit.Core.Platform.Mail.Mailer;
|
||||||
|
|
||||||
|
namespace Bit.Core.AdminConsole.Models.Mail.Mailer.OrganizationUserAutoConfirmation;
|
||||||
|
|
||||||
|
public class OrganizationAutoConfirmationEnabledView : BaseMailView
|
||||||
|
{
|
||||||
|
public required string WebVaultUrl { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OrganizationAutoConfirmationEnabled : BaseMail<OrganizationAutoConfirmationEnabledView>
|
||||||
|
{
|
||||||
|
public override required string Subject { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,497 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="und" dir="auto" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<!--[if !mso]><!-->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<!--<![endif]-->
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style type="text/css">
|
||||||
|
#outlook a { padding:0; }
|
||||||
|
body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; }
|
||||||
|
table, td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; }
|
||||||
|
img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; }
|
||||||
|
p { display:block;margin:13px 0; }
|
||||||
|
</style>
|
||||||
|
<!--[if mso]>
|
||||||
|
<noscript>
|
||||||
|
<xml>
|
||||||
|
<o:OfficeDocumentSettings>
|
||||||
|
<o:AllowPNG/>
|
||||||
|
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||||
|
</o:OfficeDocumentSettings>
|
||||||
|
</xml>
|
||||||
|
</noscript>
|
||||||
|
<![endif]-->
|
||||||
|
<!--[if lte mso 11]>
|
||||||
|
<style type="text/css">
|
||||||
|
.mj-outlook-group-fix { width:100% !important; }
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<!--[if !mso]><!-->
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet" type="text/css">
|
||||||
|
<style type="text/css">
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Roboto:300,400,500,700);
|
||||||
|
</style>
|
||||||
|
<!--<![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
@media only screen and (min-width:480px) {
|
||||||
|
.mj-column-per-100 { width:100% !important; max-width: 100%; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style media="screen and (min-width:480px)">
|
||||||
|
.moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
@media only screen and (max-width:479px) {
|
||||||
|
table.mj-full-width-mobile { width: 100% !important; }
|
||||||
|
td.mj-full-width-mobile { width: auto !important; }
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.border-fix > table {
|
||||||
|
border-collapse: separate !important;
|
||||||
|
}
|
||||||
|
.border-fix > table > tbody > tr > td {
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body style="word-spacing:normal;background-color:#e6e9ef;">
|
||||||
|
|
||||||
|
|
||||||
|
<div style="background-color:#e6e9ef;" lang="und" dir="auto">
|
||||||
|
<!-- Blue Header Section -->
|
||||||
|
|
||||||
|
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="border-fix-outlook" role="presentation" style="width:660px;" width="660" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="border-fix" style="margin:0px auto;max-width:660px;">
|
||||||
|
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="direction:ltr;font-size:0px;padding:20px 20px 0px 20px;text-align:center;">
|
||||||
|
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" width="660px" ><![endif]-->
|
||||||
|
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#175ddc;background-color:#175ddc;width:100%;border-radius:4px 4px 0px 0px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:620px;" width="620" bgcolor="#175ddc" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
<div style="margin:0px auto;border-radius:4px 4px 0px 0px;max-width:620px;">
|
||||||
|
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;border-radius:4px 4px 0px 0px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="direction:ltr;font-size:0px;padding:20px 20px;text-align:center;">
|
||||||
|
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:580px;" ><![endif]-->
|
||||||
|
|
||||||
|
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||||
|
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td align="left" style="font-size:0px;padding:10px 5px;word-break:break-word;">
|
||||||
|
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="width:150px;">
|
||||||
|
|
||||||
|
<img alt src="https://bitwarden.com/images/logo-horizontal-white.png" style="border:0;display:block;outline:none;text-decoration:none;height:30px;width:100%;font-size:16px;" width="150" height="30">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
|
||||||
|
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:660px;" width="660" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
<div style="margin:0px auto;max-width:660px;">
|
||||||
|
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="direction:ltr;font-size:0px;padding:0px 20px 10px 20px;text-align:center;">
|
||||||
|
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" width="660px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:620px;" width="620" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:620px;">
|
||||||
|
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="direction:ltr;font-size:0px;padding:15px 10px 10px 10px;text-align:center;">
|
||||||
|
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
|
||||||
|
|
||||||
|
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||||
|
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="vertical-align:top;padding:15px 10px;">
|
||||||
|
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style width="100%">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||||
|
|
||||||
|
<div style="font-family:roboto;font-size:16px;font-weight:700;line-height:24px;text-align:left;color:#1B2029;">Automatic user confirmation is now available!</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||||
|
|
||||||
|
<div style="font-family:roboto;font-size:16px;font-weight:400;line-height:24px;text-align:left;color:#1B2029;">A new global policy is available for your organization. It allows
|
||||||
|
new users to be automatically confirmed while an admin’s device is
|
||||||
|
unlocked. Log in to the web app to turn on the policy.</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||||
|
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:separate;line-height:100%;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="center" bgcolor="#175ddc" role="presentation" style="border:none;border-radius:20px;cursor:auto;mso-padding-alt:10px 25px;background:#175ddc;" valign="middle">
|
||||||
|
<a href="{{WebVaultUrl}}" style="display:inline-block;background:#175ddc;color:#ffffff;font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;font-weight:normal;line-height:120%;margin:0;text-decoration:none;text-transform:none;padding:10px 25px;mso-padding-alt:0px;border-radius:20px;" target="_blank">
|
||||||
|
Log in
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||||
|
|
||||||
|
<div style="font-family:roboto;font-size:13px;font-weight:700;line-height:16px;text-align:left;color:#1B2029;"><a class="link" href="https://bitwarden.com/help/automatic-confirmation/" style="text-decoration: none; color: #175ddc; font-weight: 600;">Learn more about this policy</a></div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table></td></tr></table><![endif]-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
|
||||||
|
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:660px;" width="660" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
<div style="margin:0px auto;max-width:660px;">
|
||||||
|
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="direction:ltr;font-size:0px;padding:5px 20px 10px 20px;text-align:center;">
|
||||||
|
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:620px;" ><![endif]-->
|
||||||
|
|
||||||
|
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||||
|
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td align="center" style="font-size:0px;padding:0;word-break:break-word;">
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" ><tr><td><![endif]-->
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px;vertical-align:middle;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:24px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:0;height:24px;vertical-align:middle;width:24px;">
|
||||||
|
<a href="https://x.com/bitwarden" target="_blank">
|
||||||
|
<img alt height="24" src="https://assets.bitwarden.com/email/v1/social-icons-x-twitter.png" style="border-radius:3px;display:block;" width="24">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso | IE]></td><td><![endif]-->
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px;vertical-align:middle;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:24px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:0;height:24px;vertical-align:middle;width:24px;">
|
||||||
|
<a href="https://www.reddit.com/r/Bitwarden/" target="_blank">
|
||||||
|
<img alt height="24" src="https://assets.bitwarden.com/email/v1/social-icons-reddit.png" style="border-radius:3px;display:block;" width="24">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso | IE]></td><td><![endif]-->
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px;vertical-align:middle;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:24px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:0;height:24px;vertical-align:middle;width:24px;">
|
||||||
|
<a href="https://community.bitwarden.com/" target="_blank">
|
||||||
|
<img alt height="24" src="https://assets.bitwarden.com/email/v1/social-icons-discourse.png" style="border-radius:3px;display:block;" width="24">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso | IE]></td><td><![endif]-->
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px;vertical-align:middle;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:24px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:0;height:24px;vertical-align:middle;width:24px;">
|
||||||
|
<a href="https://github.com/bitwarden" target="_blank">
|
||||||
|
<img alt height="24" src="https://assets.bitwarden.com/email/v1/social-icons-github.png" style="border-radius:3px;display:block;" width="24">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso | IE]></td><td><![endif]-->
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px;vertical-align:middle;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:24px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:0;height:24px;vertical-align:middle;width:24px;">
|
||||||
|
<a href="https://www.youtube.com/channel/UCId9a_jQqvJre0_dE2lE_Rw" target="_blank">
|
||||||
|
<img alt height="24" src="https://assets.bitwarden.com/email/v1/social-icons-youtube.png" style="border-radius:3px;display:block;" width="24">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso | IE]></td><td><![endif]-->
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px;vertical-align:middle;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:24px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:0;height:24px;vertical-align:middle;width:24px;">
|
||||||
|
<a href="https://www.linkedin.com/company/bitwarden1/" target="_blank">
|
||||||
|
<img alt height="24" src="https://assets.bitwarden.com/email/v1/social-icons-linkedin.png" style="border-radius:3px;display:block;" width="24">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso | IE]></td><td><![endif]-->
|
||||||
|
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px;vertical-align:middle;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:24px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:0;height:24px;vertical-align:middle;width:24px;">
|
||||||
|
<a href="https://www.facebook.com/bitwarden/" target="_blank">
|
||||||
|
<img alt height="24" src="https://assets.bitwarden.com/email/v1/social-icons-facebook.png" style="border-radius:3px;display:block;" width="24">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||||
|
|
||||||
|
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:12px;line-height:16px;text-align:center;color:#5A6D91;"><p style="margin-bottom: 5px; margin-top: 5px">
|
||||||
|
© 2025 Bitwarden Inc. 1 N. Calle Cesar Chavez, Suite 102, Santa
|
||||||
|
Barbara, CA, USA
|
||||||
|
</p>
|
||||||
|
<p style="margin-top: 5px">
|
||||||
|
Always confirm you are on a trusted Bitwarden domain before logging
|
||||||
|
in:<br>
|
||||||
|
<a href="https://bitwarden.com/" style="text-decoration: none; color: #175ddc; font-weight: 400">bitwarden.com</a>
|
||||||
|
|
|
||||||
|
<a href="https://bitwarden.com/help/emails-from-bitwarden/" style="text-decoration: none; color: #175ddc; font-weight: 400">Learn why we include this</a>
|
||||||
|
</p></div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if mso | IE]></td></tr></table><![endif]-->
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
{{#>BasicTextLayout}}
|
||||||
|
Automatic user confirmation is now available!
|
||||||
|
|
||||||
|
A new global policy is available for your organization. It allows new users to be automatically confirmed while an
|
||||||
|
admin’s device is unlocked. Log in to the web app to turn on the policy.
|
||||||
|
{{/BasicTextLayout}}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
using System.Net;
|
||||||
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Models.Mail.Mailer.OrganizationUserAutoConfirmation;
|
||||||
|
using Bit.Core.Platform.Mail.Mailer;
|
||||||
|
using Bit.Core.Settings;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using OneOf.Types;
|
||||||
|
using CommandResult = Bit.Core.AdminConsole.Utilities.v2.Results.CommandResult;
|
||||||
|
using Error = Bit.Core.AdminConsole.Utilities.v2.Error;
|
||||||
|
|
||||||
|
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser;
|
||||||
|
|
||||||
|
public record OrganizationAutoConfirmEnabledNotificationRequest(Organization Organization, ICollection<string> Emails);
|
||||||
|
|
||||||
|
public record NoEmailsWereProvided() : Error("No emails were provided");
|
||||||
|
|
||||||
|
public record EmailSendingFailed() : Error("Failed to send email to organization admins");
|
||||||
|
|
||||||
|
public interface IOrganizationAutoConfirmEnabledNotificationCommand
|
||||||
|
{
|
||||||
|
Task<CommandResult> SendEmailAsync(OrganizationAutoConfirmEnabledNotificationRequest request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OrganizationAutoConfirmEnabledNotificationCommand(
|
||||||
|
IMailer mailer,
|
||||||
|
ILogger<OrganizationAutoConfirmEnabledNotificationCommand> logger,
|
||||||
|
GlobalSettings globalSettings) : IOrganizationAutoConfirmEnabledNotificationCommand
|
||||||
|
{
|
||||||
|
public async Task<CommandResult> SendEmailAsync(OrganizationAutoConfirmEnabledNotificationRequest request)
|
||||||
|
{
|
||||||
|
if (request.Emails.Count == 0)
|
||||||
|
{
|
||||||
|
return new NoEmailsWereProvided();
|
||||||
|
}
|
||||||
|
|
||||||
|
var mail = new OrganizationAutoConfirmationEnabled
|
||||||
|
{
|
||||||
|
ToEmails = request.Emails,
|
||||||
|
View = new OrganizationAutoConfirmationEnabledView
|
||||||
|
{
|
||||||
|
WebVaultUrl = globalSettings.BaseServiceUri.Vault + "#/organizations/" + request.Organization.Id + "/settings/policies"
|
||||||
|
},
|
||||||
|
Subject = $"Automatic user confirmation is available for {WebUtility.HtmlEncode(request.Organization.Name)}"
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await mailer.SendEmail(mail);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex,
|
||||||
|
"Failed to send email to organization admins for Auto Confirm feature enablement. Organization: {OrganizationId}",
|
||||||
|
request.Organization.Id);
|
||||||
|
|
||||||
|
return new EmailSendingFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new None();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
<mjml>
|
||||||
|
<mj-head>
|
||||||
|
<mj-include path="../../../components/head.mjml" />
|
||||||
|
</mj-head>
|
||||||
|
<mj-body>
|
||||||
|
<!-- Blue Header Section -->
|
||||||
|
<mj-wrapper css-class="border-fix" padding="20px 20px 0px 20px">
|
||||||
|
<mj-bw-simple-hero />
|
||||||
|
</mj-wrapper>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<mj-wrapper padding="0px 20px 10px 20px">
|
||||||
|
<mj-section background-color="#fff" padding="15px 10px 10px 10px">
|
||||||
|
<mj-column padding="15px 10px">
|
||||||
|
<mj-text font-family="roboto" font-weight="700" line-height="24px">
|
||||||
|
Automatic user confirmation is now available!
|
||||||
|
</mj-text>
|
||||||
|
<mj-text font-family="roboto" font-weight="400" line-height="24px">
|
||||||
|
A new global policy is available for your organization. It allows
|
||||||
|
new users to be automatically confirmed while an admin’s device is
|
||||||
|
unlocked. Log in to the web app to turn on the policy.
|
||||||
|
</mj-text>
|
||||||
|
<mj-button border-radius="20px" align="left" href="{{WebVaultUrl}}"
|
||||||
|
>Log in</mj-button
|
||||||
|
>
|
||||||
|
<mj-text
|
||||||
|
font-family="roboto"
|
||||||
|
line-height="16px"
|
||||||
|
font-weight="700"
|
||||||
|
font-size="13px"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="link"
|
||||||
|
href="https://bitwarden.com/help/automatic-confirmation/"
|
||||||
|
>Learn more about this policy</a
|
||||||
|
>
|
||||||
|
</mj-text>
|
||||||
|
</mj-column>
|
||||||
|
</mj-section>
|
||||||
|
</mj-wrapper>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<mj-include path="../../../components/footer.mjml" />
|
||||||
|
</mj-body>
|
||||||
|
</mjml>
|
||||||
@ -73,6 +73,12 @@ public static class OrganizationServiceCollectionExtensions
|
|||||||
services.AddOrganizationUserCommands();
|
services.AddOrganizationUserCommands();
|
||||||
services.AddOrganizationUserCommandsQueries();
|
services.AddOrganizationUserCommandsQueries();
|
||||||
services.AddBaseOrganizationSubscriptionCommandsQueries();
|
services.AddBaseOrganizationSubscriptionCommandsQueries();
|
||||||
|
services.AddOrganizationFeatureCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddOrganizationFeatureCommands(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddScoped<IOrganizationAutoConfirmEnabledNotificationCommand, OrganizationAutoConfirmEnabledNotificationCommand>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddOrganizationSignUpCommands(this IServiceCollection services)
|
private static void AddOrganizationSignUpCommands(this IServiceCollection services)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user