1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-22 16:57:36 +01:00

[AC-2101] Update welcome emails from trial initiation and org creation (#3836)

* Add the email template

* add changes fro the trial initiation email

* adding featureFlags

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

* adding noopener

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

* Fix  the failing test

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

---------

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
This commit is contained in:
cyprain-okeke 2024-02-29 09:16:16 +01:00 committed by GitHub
parent b7dc9feb0e
commit 696883c5e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 192 additions and 0 deletions

View File

@ -537,6 +537,15 @@ public class OrganizationService : IOrganizationService
Storage = returnValue.Item1.MaxStorageGb,
// TODO: add reference events for SmSeats and Service Accounts - see AC-1481
});
var isAc2101UpdateTrialInitiationEmail =
_featureService.IsEnabled(FeatureFlagKeys.AC2101UpdateTrialInitiationEmail);
if (signup.IsFromSecretsManagerTrial && isAc2101UpdateTrialInitiationEmail)
{
await _mailService.SendTrialInitiationEmailAsync(signup.BillingEmail);
}
return returnValue;
}

View File

@ -132,6 +132,7 @@ public static class FeatureFlagKeys
public const string AC1607_PresentUsersWithOffboardingSurvey = "AC-1607_present-user-offboarding-survey";
public const string PM5766AutomaticTax = "PM-5766-automatic-tax";
public const string PM5864DollarThreshold = "PM-5864-dollar-threshold";
public const string AC2101UpdateTrialInitiationEmail = "AC-2101-update-trial-initiation-email";
public static List<string> GetAllKeys()
{

View File

@ -0,0 +1,75 @@
{{#>FullHtmlLayout}}
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
Welcome to Bitwarden! You can now get started with secure credential management and extend the benefits of end-to-end encryption across your entire organization.
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 10px; -webkit-text-size-adjust: none; text-align: center; border: 2px solid #175DDC; border-radius: 2px;" valign="top">
Your Master Password is <b>the only way</b> to unlock your account and only <b>you</b> hold the key. Memorize it, or write it down and keep it in a safe place.
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="h3" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 18px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; font-weight: bold; padding: 0 0 5px;" valign="top">
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
Install Bitwarden
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
Access your Bitwarden account from anywhere and any device at <a href="{{{WebVaultUrl}}}/?utm_source=welcome_email&utm_medium=email" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">{{{WebVaultUrlHostname}}}</a>! For added convenience, <a href="https://bitwarden.com/download/" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">download and install Bitwarden</a> on any desktop, device, and browser.
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
<a href="https://bitwarden.com/download/" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: auto; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: none;">
<img src="https://bitwarden.com/images/mail-download-options.png" alt="Windows, Mac, Linux, Android, Apple, Chrome, Safari, Firefox, Edge, Opera, Brave, Vivaldi, Tor" width="598" height="65" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; margin: auto; border: none; max-width: 100%; height: auto; display: block;" />
</a>
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="h3" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 18px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; font-weight: bold; padding: 0 0 5px;" valign="top">
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
Securely Share using Bitwarden Organizations
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
Bitwarden makes it easy for teams and enterprises to securely share passwords, developer secrets, and passkeys via Organizations. Join an Organization if invited, or launch a new one anytime from the <a href="{{{WebVaultUrl}}}/?utm_source=welcome_email&utm_medium=email" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">Web App</a> with the <b>+ New Organization</b> button.
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top" align="center">
<a href="{{{WebVaultUrl}}}/?utm_source=welcome_email&utm_medium=email" clicktracking=off target="_blank" rel="noopener" style="color: #ffffff; text-decoration: none; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; 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;">
Login to Bitwarden
</a>
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="h3" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 18px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; font-weight: bold; padding: 0 0 5px;" valign="top">
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
Bitwarden is Here for You
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
Check out the <a href="http://www.bitwarden.com/help" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">Help</a> site for documentation, join the <a href="https://community.bitwarden.com/" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">Bitwarden Community</a> forums and connect with other enthusiasts on <a href="https://www.reddit.com/r/Bitwarden/" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">Reddit</a>. If you have any questions or issues, <a href="http://www.bitwarden.com/contact" target="_blank" rel="noopener" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #175DDC; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">contact support.</a>
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
</td>
</tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block last" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none; font-weight: bold;" valign="top">
Stay safe and secure,<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
The Bitwarden Team
</td>
</tr>
</table>
{{/FullHtmlLayout}}

View File

@ -0,0 +1,39 @@
{{#>FullTextLayout}}
Welcome to Bitwarden! You can now get started with secure credential management and extend the benefits of end-to-end encryption across your entire organization.
Your Master Password is the only way to unlock your account and only you hold the key. Memorize it, or write it down and keep it in a safe place.
Install Bitwarden
============
Access your Bitwarden account from anywhere and any device at the web vault ({{WebVaultUrl}}/?utm_source=welcome_email&utm_medium=email). For added convenience, download and install Bitwarden on any desktop, device and browser (http://www.bitwarden.com/download).
Download Options
============
http://www.bitwarden.com/download
Securely Share using Bitwarden Organizations
============
Bitwarden makes it easy for teams and enterprises to securely share passwords, developer secrets, and passkeys via Organizations. Join an Organization if invited, or launch a new one anytime from the Web App ({{WebVaultUrl}}/?utm_source=welcome_email&utm_medium=email) with the + New Organization button.
Login to Bitwarden
============
{{WebVaultUrl}}/?utm_source=welcome_email&utm_medium=email
Bitwarden is Here for You
============
Check out our Help (http://www.bitwarden.com/help) site for documentation, join the Bitwarden Community forums (https://community.bitwarden.com/) and connect with other enthusiasts on Reddit (https://www.reddit.com/r/Bitwarden/). If you have any questions or issues, contact support (http://www.bitwarden.com/contact).
Stay safe and secure,
The Bitwarden Team
{{/FullTextLayout}}

View File

@ -77,5 +77,6 @@ public interface IMailService
Task SendSecretsManagerMaxSeatLimitReachedEmailAsync(Organization organization, int maxSeatCount, IEnumerable<string> ownerEmails);
Task SendSecretsManagerMaxServiceAccountLimitReachedEmailAsync(Organization organization, int maxSeatCount, IEnumerable<string> ownerEmails);
Task SendTrustedDeviceAdminApprovalEmailAsync(string email, DateTime utcNow, string ip, string deviceTypeAndIdentifier);
Task SendTrialInitiationEmailAsync(string email);
}

View File

@ -251,6 +251,19 @@ public class HandlebarsMailService : IMailService
await _mailDeliveryService.SendEmailAsync(message);
}
public async Task SendTrialInitiationEmailAsync(string userEmail)
{
var message = CreateDefaultMessage("Welcome to Bitwarden!", userEmail);
var model = new BaseMailModel
{
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
SiteName = _globalSettings.SiteName
};
await AddMessageContentAsync(message, "TrialInitiation", model);
message.Category = "Welcome";
await _mailDeliveryService.SendEmailAsync(message);
}
public async Task SendPasswordlessSignInAsync(string returnUrl, string token, string email)
{
var message = CreateDefaultMessage("[Admin] Continue Logging In", email);

View File

@ -262,5 +262,10 @@ public class NoopMailService : IMailService
{
return Task.FromResult(0);
}
public Task SendTrialInitiationEmailAsync(string email)
{
return Task.FromResult(0);
}
}

View File

@ -2363,6 +2363,55 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
Assert.Contains("custom users can only grant the same custom permissions that they have.", exception.Message.ToLowerInvariant());
}
[Theory]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly)]
[BitAutoData(PlanType.TeamsAnnually)]
[BitAutoData(PlanType.TeamsMonthly)]
public async Task SignUp_EmailSent_When_FromSecretsManagerTrial(PlanType planType, OrganizationSignup signup, SutProvider<OrganizationService> sutProvider)
{
signup.Plan = planType;
var plan = StaticStore.GetPlan(signup.Plan);
signup.UseSecretsManager = true;
signup.AdditionalSeats = 15;
signup.AdditionalSmSeats = 10;
signup.AdditionalServiceAccounts = 20;
signup.PaymentMethodType = PaymentMethodType.Card;
signup.PremiumAccessAddon = false;
signup.IsFromSecretsManagerTrial = true;
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.AC2101UpdateTrialInitiationEmail).Returns(true);
await sutProvider.Sut.SignUpAsync(signup);
await sutProvider.GetDependency<IMailService>().Received(1).SendTrialInitiationEmailAsync(signup.BillingEmail);
}
[Theory]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly)]
[BitAutoData(PlanType.TeamsAnnually)]
[BitAutoData(PlanType.TeamsMonthly)]
public async Task SignUp_NoEmailSent_When_NotFromSecretsManagerTrial(PlanType planType, OrganizationSignup signup, SutProvider<OrganizationService> sutProvider)
{
signup.Plan = planType;
var plan = StaticStore.GetPlan(signup.Plan);
signup.UseSecretsManager = true;
signup.AdditionalSeats = 15;
signup.AdditionalSmSeats = 10;
signup.AdditionalServiceAccounts = 20;
signup.PaymentMethodType = PaymentMethodType.Card;
signup.PremiumAccessAddon = false;
signup.IsFromSecretsManagerTrial = false;
await sutProvider.Sut.SignUpAsync(signup);
await sutProvider.GetDependency<IMailService>().Received(0).SendTrialInitiationEmailAsync(signup.BillingEmail);
}
// Must set real guids in order for dictionary of guids to not throw aggregate exceptions
private void SetupOrgUserRepositoryCreateManyAsyncMock(IOrganizationUserRepository organizationUserRepository)
{