mirror of
https://github.com/bitwarden/server.git
synced 2024-11-26 12:55:17 +01:00
handlebars template emails
This commit is contained in:
parent
cb902bf670
commit
b2e6b49b14
@ -6,63 +6,15 @@
|
||||
<GenerateUserSecretsAttribute>false</GenerateUserSecretsAttribute>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="MailTemplates\Markdown\InvoiceUpcoming.md" />
|
||||
<None Remove="MailTemplates\Markdown\PasswordlessSignIn.md" />
|
||||
<None Remove="MailTemplates\Razor\InvoiceUpcoming.cshtml" />
|
||||
<None Remove="MailTemplates\Razor\InvoiceUpcoming.text.cshtml" />
|
||||
<None Remove="MailTemplates\Razor\PasswordlessSignIn.cshtml" />
|
||||
<None Remove="MailTemplates\Razor\PasswordlessSignIn.text.cshtml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="licensing.cer" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\ChangeEmail.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\ChangeEmailAlreadyExists.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\MasterPasswordHint.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\NoMasterPasswordHint.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\InvoiceUpcoming.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\OrganizationUserAccepted.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\OrganizationUserConfirmed.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\PasswordlessSignIn.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\OrganizationUserInvited.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\TwoFactorEmail.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\VerifyDelete.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\VerifyEmail.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\Welcome.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\InvoiceUpcoming.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\InvoiceUpcoming.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\PasswordlessSignIn.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\PasswordlessSignIn.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\VerifyDelete.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\VerifyDelete.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\VerifyEmail.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\VerifyEmail.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\TwoFactorEmail.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\TwoFactorEmail.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\ChangeEmailAlreadyExists.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\ChangeEmailAlreadyExists.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\OrganizationUserInvited.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\OrganizationUserInvited.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\OrganizationUserAccepted.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\OrganizationUserAccepted.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\OrganizationUserConfirmed.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\OrganizationUserConfirmed.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\MasterPasswordHint.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\ChangeEmail.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\ChangeEmail.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\NoMasterPasswordHint.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\NoMasterPasswordHint.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\MasterPasswordHint.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\Welcome.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\Welcome.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\_MailLayout.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\_MailLayout.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\_BasicMailLayout.text.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\_BasicMailLayout.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Markdown\**\*.md" />
|
||||
<EmbeddedResource Include="MailTemplates\Razor\**\*.cshtml" />
|
||||
<EmbeddedResource Include="MailTemplates\Handlebars\**\*.hbs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.AzureStorage" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.2" />
|
||||
|
5
src/Core/MailTemplates/Handlebars/ChangeEmail.html.hbs
Normal file
5
src/Core/MailTemplates/Handlebars/ChangeEmail.html.hbs
Normal file
@ -0,0 +1,5 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
To finalize changing your email address enter the following code in the pop-up window: {{Token}}
|
||||
</p>
|
||||
{{/FullHtmlLayout}}
|
3
src/Core/MailTemplates/Handlebars/ChangeEmail.text.hbs
Normal file
3
src/Core/MailTemplates/Handlebars/ChangeEmail.text.hbs
Normal file
@ -0,0 +1,3 @@
|
||||
{{#>BasicTextLayout}}
|
||||
To finalize changing your email address enter the following code in the pop-up window: {{Token}}
|
||||
{{/BasicTextLayout}}
|
@ -0,0 +1,9 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
A user ({{FromEmail}}) recently tried to change their account to use this
|
||||
email address ({{ToEmail}}). An account already exists with this email ({{ToEmail}}).
|
||||
</p>
|
||||
<p>
|
||||
If you did not try to change an email address, you can safely ignore this email.
|
||||
</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,5 @@
|
||||
{{#>BasicTextLayout}}
|
||||
A user ({{FromEmail}}) recently tried to change their account to use this email address ({{ToEmail}}). An account already exists with this email ({{ToEmail}}).
|
||||
|
||||
If you did not try to change an email address, you can safely ignore this email.
|
||||
{{/BasicTextLayout}}
|
30
src/Core/MailTemplates/Handlebars/InvoiceUpcoming.html.hbs
Normal file
30
src/Core/MailTemplates/Handlebars/InvoiceUpcoming.html.hbs
Normal file
@ -0,0 +1,30 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
This is a reminder that your Bitwarden subscription is due for renewal soon.
|
||||
Your payment method on file will be charged for <b>{{usd AmountDue}}</b> on
|
||||
<b>{{date DueDate 'MMM dd, yyyy'}}</b>.
|
||||
</p>
|
||||
{{#if Items}}
|
||||
<p>
|
||||
<b><u>Summary Of Charges</u></b><br />
|
||||
{{#each Items}}
|
||||
{{this}}<br />
|
||||
{{/each}}
|
||||
</p>
|
||||
{{/if}}
|
||||
<p>
|
||||
To avoid any interruption in service, please ensure that your payment method
|
||||
on file is up to date and can be charged for the above amount. You can manage your
|
||||
subscription and payment method by logging into the web vault at
|
||||
{{{link WebVaultUrl}}}. Once logged in, navigate to the Billing page for your account.
|
||||
</p>
|
||||
{{#if MentionInvoices}}
|
||||
<p>
|
||||
Invoices for your payments can also be downloaded from Billing page for your account.
|
||||
</p>
|
||||
{{/if}}
|
||||
<p>
|
||||
If you have any questions or problems, please feel free to email us at
|
||||
hello@bitwarden.com.
|
||||
</p>
|
||||
{{/FullHtmlLayout}}
|
19
src/Core/MailTemplates/Handlebars/InvoiceUpcoming.text.hbs
Normal file
19
src/Core/MailTemplates/Handlebars/InvoiceUpcoming.text.hbs
Normal file
@ -0,0 +1,19 @@
|
||||
{{#>BasicTextLayout}}
|
||||
This is a reminder that your Bitwarden subscription is due for renewal soon. Your payment method on file will be charged for {{usd AmountDue}} on {{date DueDate 'MMM dd, yyyy'}}.
|
||||
{{#if Items}}
|
||||
|
||||
Summary Of Charges
|
||||
------------------
|
||||
{{#each Items}}
|
||||
{{this}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
To avoid any interruption in service, please ensure that your payment method on file is up to date and can be charged for the above amount. You can manage your subscription and payment method by logging into the web vault at {{{WebVaultUrl}}}. Once logged in, navigate to the Billing page for your account.
|
||||
{{#if MentionInvoices}}
|
||||
|
||||
Invoices for your payments can also be downloaded from Billing page for your account.
|
||||
{{/if}}
|
||||
|
||||
If you have any questions or problems, please feel free to email us at hello@bitwarden.com.
|
||||
{{/BasicTextLayout}}
|
10
src/Core/MailTemplates/Handlebars/Layouts/Basic.html.hbs
Normal file
10
src/Core/MailTemplates/Handlebars/Layouts/Basic.html.hbs
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
{{>@partial-block}}
|
||||
</body>
|
||||
</html>
|
1
src/Core/MailTemplates/Handlebars/Layouts/Basic.text.hbs
Normal file
1
src/Core/MailTemplates/Handlebars/Layouts/Basic.text.hbs
Normal file
@ -0,0 +1 @@
|
||||
{{>@partial-block}}
|
140
src/Core/MailTemplates/Handlebars/Layouts/Full.html.hbs
Normal file
140
src/Core/MailTemplates/Handlebars/Layouts/Full.html.hbs
Normal file
@ -0,0 +1,140 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0;">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Bitwarden</title>
|
||||
</head>
|
||||
|
||||
<body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; height: 100%; line-height: 25px; width: 100% !important;" bgcolor="#f6f6f6">
|
||||
<style type="text/css">
|
||||
body {
|
||||
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;
|
||||
}
|
||||
|
||||
body * {
|
||||
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;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: none;
|
||||
width: 100% !important;
|
||||
height: 100%;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.container-table {
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 0 10px 0 !important;
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
.invoice {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.main {
|
||||
border-right: none !important;
|
||||
border-left: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.logo {
|
||||
padding-top: 10px !important;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
|
||||
.indented {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<table class="body-wrap" cellpadding="0" cellspacing="0" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; width: 100%;" bgcolor="#f6f6f6">
|
||||
<tr style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0;">
|
||||
<td valign="middle" class="aligncenter middle logo" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; padding: 20px 0 10px;" align="center">
|
||||
<img src="https://bitwarden.com/images/logo-gray.png" alt="" width="250" height="39" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; max-width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0;">
|
||||
<td class="container" align="center" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; clear: both !important; color: #333; display: block !important; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0 auto; max-width: 600px !important; width: 600px;" valign="top">
|
||||
<table cellpadding="0" cellspacing="0" class="container-table" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; clear: both !important; color: #333; display: block !important; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0 auto; max-width: 600px !important; width: 600px;">
|
||||
<tr style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0;">
|
||||
<td class="content" align="center" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; display: block; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 0; line-height: 0; margin: 0 auto; max-width: 600px; padding-bottom: 20px;" valign="top">
|
||||
<table class="main" width="100%" cellpadding="0" cellspacing="0" 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; margin: 0; -webkit-text-size-adjust: none; border: 1px solid #e9e9e9; border-radius: 3px;" bgcolor="white">
|
||||
<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-wrap" 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: 20px; -webkit-text-size-adjust: none;" valign="top">
|
||||
|
||||
{{>@partial-block}}
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer" cellpadding="0" cellspacing="0" width="100%" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; clear: both; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 15px 0 0; width: 100%;">
|
||||
<tr style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0;">
|
||||
<td class="aligncenter social-icons" align="center" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0;" valign="top">
|
||||
<table cellpadding="0" cellspacing="0" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0 auto;">
|
||||
<tr style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0;">
|
||||
<td style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; padding: 0 10px;" valign="top"><a href="https://twitter.com/bitwarden_app" target="_blank" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; text-decoration: underline;"><img src="https://bitwarden.com/images/mail-twitter.png" alt="Twitter" width="30" height="30" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; max-width: 100%;" /></a></td>
|
||||
<td style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; padding: 0 10px;" valign="top"><a href="https://www.facebook.com/bitwarden/" target="_blank" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; text-decoration: underline;"><img src="https://bitwarden.com/images/mail-facebook.png" alt="Facebook" width="30" height="30" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; max-width: 100%;" /></a></td>
|
||||
<td style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; padding: 0 10px;" valign="top"><a href="https://plus.google.com/+bitwarden" target="_blank" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; text-decoration: underline;"><img src="https://bitwarden.com/images/mail-gplus.png" alt="Google+" width="30" height="30" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; max-width: 100%;" /></a></td>
|
||||
<td style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; padding: 0 10px;" valign="top"><a href="https://github.com/bitwarden" target="_blank" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0; text-decoration: underline;"><img src="https://bitwarden.com/images/mail-github.png" alt="GitHub" width="30" height="30" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; border: none; box-sizing: border-box; color: #333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25px; margin: 0; max-width: 100%;" /></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
8
src/Core/MailTemplates/Handlebars/Layouts/Full.text.hbs
Normal file
8
src/Core/MailTemplates/Handlebars/Layouts/Full.text.hbs
Normal file
@ -0,0 +1,8 @@
|
||||
{{>@partial-block}}
|
||||
|
||||
----------------------------
|
||||
|
||||
- Twitter: https://twitter.com/bitwarden_app
|
||||
- Facebook: https://www.facebook.com/bitwarden/
|
||||
- Google+: https://plus.google.com/+bitwarden
|
||||
- GitHub: https://github.com/bitwarden
|
@ -0,0 +1,8 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>You (or someone) recently requested your master password hint.</p>
|
||||
<p>
|
||||
Your hint is: "{{Hint}}"<br />
|
||||
Log in: {{{link WebVaultUrl}}}
|
||||
</p>
|
||||
<p>If you did not request your master password hint you can safely ignore this email.</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,8 @@
|
||||
{{#>BasicTextLayout}}
|
||||
You (or someone) recently requested your master password hint.
|
||||
|
||||
Your hint is: "{{Hint}}"
|
||||
Log in: {{{WebVaultUrl}}}
|
||||
|
||||
If you did not request your master password hint you can safely ignore this email.
|
||||
{{/BasicTextLayout}}
|
@ -0,0 +1,7 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
You (or someone) recently requested your master password hint.
|
||||
Unfortunately, your account does not have a master password hint.
|
||||
</p>
|
||||
<p>If you did not request your master password hint you can safely ignore this email.</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,5 @@
|
||||
{{#>BasicTextLayout}}
|
||||
You (or someone) recently requested your master password hint. Unfortunately, your account does not have a master password hint.
|
||||
|
||||
If you did not request your master password hint you can safely ignore this email.
|
||||
{{/BasicTextLayout}}
|
@ -0,0 +1,5 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>This email is to notify you that {{UserEmail}} has accepted your invitation to join {{OrganizationName}}.</p>
|
||||
<p>To confirm this user, log into the Bitwarden web vault, manage your organization "People, and confirm the user.</p>
|
||||
<p>If you do not wish to confirm this user, you can also remove them from the organization on the same page.</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,7 @@
|
||||
{{#>BasicTextLayout}}
|
||||
This email is to notify you that {{UserEmail}} has accepted your invitation to join {{OrganizationName}}.
|
||||
|
||||
To confirm this user, log into the Bitwarden web vault, manage your organization "People" and confirm the user.
|
||||
|
||||
If you do not wish to confirm this user, you can also remove them from the organization on the same page.
|
||||
{{/BasicTextLayout}}
|
@ -0,0 +1,4 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>This email is to notify you that you have been confirmed as a user of {{OrganizationName}}.</p>
|
||||
<p>Any collections and logins being shared with you by this organization will now appear in your Bitwarden vault.</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,5 @@
|
||||
{{#>BasicTextLayout}}
|
||||
This email is to notify you that you have been confirmed as a user of {{OrganizationName}}.
|
||||
|
||||
Any collections and logins being shared with you by this organization will now appear in your Bitwarden vault.
|
||||
{{/BasicTextLayout}}
|
@ -0,0 +1,11 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
You have been invited to join the {{OrganizationName}} organization.
|
||||
To accept this invite, click the following link:
|
||||
</p>
|
||||
<p>{{{link Url 'true'}}}</p>
|
||||
<p>
|
||||
If you do not wish to join this organization, you can safely ignore
|
||||
this email.
|
||||
</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,7 @@
|
||||
{{#>BasicTextLayout}}
|
||||
You have been invited to join the {{OrganizationName}} organization. To accept this invite, click the following link:
|
||||
|
||||
{{{Url}}}
|
||||
|
||||
If you do not wish to join this organization, you can safely ignore this email.
|
||||
{{/BasicTextLayout}}
|
@ -0,0 +1,9 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
Click the following link to log in:
|
||||
</p>
|
||||
<p>{{{link Url 'true'}}}</p>
|
||||
<p>
|
||||
If you did not request to log in, you can safely ignore this email.
|
||||
</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,7 @@
|
||||
{{#>BasicTextLayout}}
|
||||
Click the following link to log in:
|
||||
|
||||
{{{Url}}}
|
||||
|
||||
If you did not request to log in, you can safely ignore this email.
|
||||
{{/BasicTextLayout}}
|
@ -0,0 +1,8 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
Your two-step verification code is: {{Token}}
|
||||
</p>
|
||||
<p>
|
||||
Use this code to complete logging in with Bitwarden.
|
||||
</p>
|
||||
{{/FullHtmlLayout}}
|
@ -0,0 +1,5 @@
|
||||
{{#>BasicTextLayout}}
|
||||
Your two-step verification code is: {{Token}}
|
||||
|
||||
Use this code to complete logging in with Bitwarden.
|
||||
{{/BasicTextLayout}}
|
7
src/Core/MailTemplates/Handlebars/VerifyDelete.html.hbs
Normal file
7
src/Core/MailTemplates/Handlebars/VerifyDelete.html.hbs
Normal file
@ -0,0 +1,7 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
Click the link below to delete your Bitwarden account ({{Email}}).
|
||||
If you did not request this email to delete your Bitwarden account, you can safely ignore it.
|
||||
</p>
|
||||
<p>{{{link Url 'true'}}}</p>
|
||||
{{/FullHtmlLayout}}
|
5
src/Core/MailTemplates/Handlebars/VerifyDelete.text.hbs
Normal file
5
src/Core/MailTemplates/Handlebars/VerifyDelete.text.hbs
Normal file
@ -0,0 +1,5 @@
|
||||
{{#>BasicTextLayout}}
|
||||
Click the link below to delete your Bitwarden account ({{Email}}). If you did not request this email to delete your Bitwarden account, you can safely ignore it.
|
||||
|
||||
{{{Url}}}
|
||||
{{/BasicTextLayout}}
|
7
src/Core/MailTemplates/Handlebars/VerifyEmail.html.hbs
Normal file
7
src/Core/MailTemplates/Handlebars/VerifyEmail.html.hbs
Normal file
@ -0,0 +1,7 @@
|
||||
{{#>FullHtmlLayout}}
|
||||
<p>
|
||||
Verify this email address for your Bitwarden account by clicking the following link.
|
||||
If you did not request this email to verify a Bitwarden account, you can safely ignore it.
|
||||
</p>
|
||||
<p>{{{link Url 'true'}}}</p>
|
||||
{{/FullHtmlLayout}}
|
5
src/Core/MailTemplates/Handlebars/VerifyEmail.text.hbs
Normal file
5
src/Core/MailTemplates/Handlebars/VerifyEmail.text.hbs
Normal file
@ -0,0 +1,5 @@
|
||||
{{#>BasicTextLayout}}
|
||||
Verify this email address for your Bitwarden account by clicking the following link. If you did not request this email to verify a Bitwarden account, you can safely ignore it.
|
||||
|
||||
{{{Url}}}
|
||||
{{/BasicTextLayout}}
|
93
src/Core/MailTemplates/Handlebars/Welcome.html.hbs
Normal file
93
src/Core/MailTemplates/Handlebars/Welcome.html.hbs
Normal file
@ -0,0 +1,93 @@
|
||||
{{#>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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
Thank you for creating an account with Bitwarden. You may now log in with your new account.
|
||||
</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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
Did you know that Bitwarden is free to sync with all of your devices? Download Bitwarden today on:
|
||||
</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;" valign="top">
|
||||
Desktop
|
||||
</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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
Access Bitwarden on Windows, macOS, and Linux desktops with our native desktop application.
|
||||
</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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
<a href="https://bitwarden.com/#download" target="_blank" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #3c8dbc; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">
|
||||
<img src="https://bitwarden.com/images/mail-os.png" alt="Windows, macOS, and Linux" width="550" height="110" 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: 0; 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;" valign="top">
|
||||
Web Browser
|
||||
</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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
Integrate Bitwarden directly into your favorite browser. Use our browser extensions for a seamless browsing experience.
|
||||
</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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
<a href="https://bitwarden.com/#download-browser" target="_blank" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #3c8dbc; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">
|
||||
<img src="https://bitwarden.com/images/mail-browsers.png" alt="Chrome, Firefox, Opera, Edge, Safari, and more" width="550" height="90" 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: 0; 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;" valign="top">
|
||||
Mobile
|
||||
</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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
Take Bitwarden on the go with our mobile apps for your phone or tablet device.
|
||||
</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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
<a href="https://bitwarden.com/#download-mobile" target="_blank" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #3c8dbc; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">
|
||||
<img src="https://bitwarden.com/images/mail-stores.png" alt="App Store and Google Play" width="550" height="85" 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: 0; 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;" valign="top">
|
||||
Web
|
||||
</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 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;" valign="top">
|
||||
Stuck without any of your devices? Using a friend's computer? You can access your Bitwarden vault from any web enabled device by using the web vault.
|
||||
</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 h3 biglink" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 18px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; margin: 0; -webkit-text-size-adjust: none; padding: 0 0 10px; font-weight: bold;" valign="top">
|
||||
<a target="_blank" href="{{{WebVaultUrl}}}/?utm_source=welcome_email&utm_medium=email" style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; box-sizing: border-box; color: #3c8dbc; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 20px; line-height: 25px; margin: 0; text-decoration: underline;">{{{WebVaultUrlHostname}}}</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" 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 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||
If you have any questions or problems you can email us from our website at <a target="_blank" href="https://bitwarden.com/contact/?utm_source=welcome_email&utm_medium=email" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #3c8dbc; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; text-decoration: underline;">https://bitwarden.com/contact</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="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;" valign="top">
|
||||
Thank you!<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}}
|
35
src/Core/MailTemplates/Handlebars/Welcome.text.hbs
Normal file
35
src/Core/MailTemplates/Handlebars/Welcome.text.hbs
Normal file
@ -0,0 +1,35 @@
|
||||
{{#>FullTextLayout}}
|
||||
Thank you for creating an account with Bitwarden. You may now log in with your new account.
|
||||
|
||||
Did you know that Bitwarden is free to sync with all of your devices? Download Bitwarden today on:
|
||||
|
||||
Desktop
|
||||
============
|
||||
|
||||
Access Bitwarden on Windows, macOS, and Linux desktops with our native desktop application.
|
||||
https://bitwarden.com/#download
|
||||
|
||||
Web Browser
|
||||
============
|
||||
|
||||
Integrate Bitwarden directly into your favorite browser. Use our browser extensions for a seamless browsing experience.
|
||||
https://bitwarden.com/#download-browser
|
||||
|
||||
Mobile
|
||||
============
|
||||
|
||||
Take Bitwarden on the go with our mobile apps for your phone or tablet device.
|
||||
https://bitwarden.com/#download-mobile
|
||||
|
||||
Web
|
||||
============
|
||||
|
||||
Stuck without any of your devices? Using a friend's computer? You can access your Bitwarden vault from any web enabled device by using the web vault.
|
||||
{{WebVaultUrl}}/?utm_source=welcome_email&utm_medium=email
|
||||
|
||||
|
||||
If you have any questions or problems you can email us from our website at: https://bitwarden.com/contact/?utm_source=welcome_email&utm_medium=email
|
||||
|
||||
Thank you!
|
||||
The Bitwarden Team
|
||||
{{/FullTextLayout}}
|
376
src/Core/Services/Implementations/HandlebarsMailService.cs
Normal file
376
src/Core/Services/Implementations/HandlebarsMailService.cs
Normal file
@ -0,0 +1,376 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Models.Mail;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using HandlebarsDotNet;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class HandlebarsMailService : IMailService
|
||||
{
|
||||
private const string Namespace = "Bit.Core.MailTemplates.Handlebars";
|
||||
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IMailDeliveryService _mailDeliveryService;
|
||||
private readonly Dictionary<string, Func<object, string>> _templateCache =
|
||||
new Dictionary<string, Func<object, string>>();
|
||||
|
||||
private bool _registeredHelpersAndPartials = false;
|
||||
|
||||
public HandlebarsMailService(
|
||||
GlobalSettings globalSettings,
|
||||
IMailDeliveryService mailDeliveryService)
|
||||
{
|
||||
_globalSettings = globalSettings;
|
||||
_mailDeliveryService = mailDeliveryService;
|
||||
}
|
||||
|
||||
public async Task SendVerifyEmailEmailAsync(string email, Guid userId, string token)
|
||||
{
|
||||
var message = CreateDefaultMessage("Verify Your Email", email);
|
||||
var model = new VerifyEmailModel
|
||||
{
|
||||
Token = WebUtility.UrlEncode(token),
|
||||
UserId = userId,
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "VerifyEmail", model);
|
||||
message.MetaData.Add("SendGridBypassListManagement", true);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendVerifyDeleteEmailAsync(string email, Guid userId, string token)
|
||||
{
|
||||
var message = CreateDefaultMessage("Delete Your Account", email);
|
||||
var model = new VerifyDeleteModel
|
||||
{
|
||||
Token = WebUtility.UrlEncode(token),
|
||||
UserId = userId,
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName,
|
||||
Email = email,
|
||||
EmailEncoded = WebUtility.UrlEncode(email)
|
||||
};
|
||||
await AddMessageContentAsync(message, "VerifyDelete", model);
|
||||
message.MetaData.Add("SendGridBypassListManagement", true);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendChangeEmailAlreadyExistsEmailAsync(string fromEmail, string toEmail)
|
||||
{
|
||||
var message = CreateDefaultMessage("Your Email Change", toEmail);
|
||||
var model = new ChangeEmailExistsViewModel
|
||||
{
|
||||
FromEmail = fromEmail,
|
||||
ToEmail = toEmail,
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "ChangeEmailAlreadyExists", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendChangeEmailEmailAsync(string newEmailAddress, string token)
|
||||
{
|
||||
var message = CreateDefaultMessage("Your Email Change", newEmailAddress);
|
||||
var model = new EmailTokenViewModel
|
||||
{
|
||||
Token = token,
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "ChangeEmail", model);
|
||||
message.MetaData.Add("SendGridBypassListManagement", true);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendTwoFactorEmailAsync(string email, string token)
|
||||
{
|
||||
var message = CreateDefaultMessage("Your Two-step Login Verification Code", email);
|
||||
var model = new EmailTokenViewModel
|
||||
{
|
||||
Token = token,
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "TwoFactorEmail", model);
|
||||
message.MetaData.Add("SendGridBypassListManagement", true);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendMasterPasswordHintEmailAsync(string email, string hint)
|
||||
{
|
||||
var message = CreateDefaultMessage("Your Master Password Hint", email);
|
||||
var model = new MasterPasswordHintViewModel
|
||||
{
|
||||
Hint = CoreHelpers.SanitizeForEmail(hint),
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "MasterPasswordHint", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendNoMasterPasswordHintEmailAsync(string email)
|
||||
{
|
||||
var message = CreateDefaultMessage("Your Master Password Hint", email);
|
||||
var model = new BaseMailModel
|
||||
{
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "NoMasterPasswordHint", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendOrganizationAcceptedEmailAsync(string organizationName, string userEmail,
|
||||
IEnumerable<string> adminEmails)
|
||||
{
|
||||
var message = CreateDefaultMessage($"User {userEmail} Has Accepted Invite", adminEmails);
|
||||
var model = new OrganizationUserAcceptedViewModel
|
||||
{
|
||||
OrganizationName = CoreHelpers.SanitizeForEmail(organizationName),
|
||||
UserEmail = userEmail,
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "OrganizationUserAccepted", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendOrganizationConfirmedEmailAsync(string organizationName, string email)
|
||||
{
|
||||
var message = CreateDefaultMessage($"You Have Been Confirmed To {organizationName}", email);
|
||||
var model = new OrganizationUserConfirmedViewModel
|
||||
{
|
||||
OrganizationName = CoreHelpers.SanitizeForEmail(organizationName),
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "OrganizationUserConfirmed", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendOrganizationInviteEmailAsync(string organizationName, OrganizationUser orgUser, string token)
|
||||
{
|
||||
var message = CreateDefaultMessage($"Join {organizationName}", orgUser.Email);
|
||||
var model = new OrganizationUserInvitedViewModel
|
||||
{
|
||||
OrganizationName = CoreHelpers.SanitizeForEmail(organizationName),
|
||||
Email = WebUtility.UrlEncode(orgUser.Email),
|
||||
OrganizationId = orgUser.OrganizationId.ToString(),
|
||||
OrganizationUserId = orgUser.Id.ToString(),
|
||||
Token = WebUtility.UrlEncode(token),
|
||||
OrganizationNameUrlEncoded = WebUtility.UrlEncode(organizationName),
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "OrganizationUserInvited", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendWelcomeEmailAsync(User user)
|
||||
{
|
||||
var message = CreateDefaultMessage("Welcome", user.Email);
|
||||
var model = new BaseMailModel
|
||||
{
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName
|
||||
};
|
||||
await AddMessageContentAsync(message, "Welcome", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendPasswordlessSignInAsync(string returnUrl, string token, string email)
|
||||
{
|
||||
var message = CreateDefaultMessage("[Admin] Continue Logging In", email);
|
||||
var url = CoreHelpers.ExtendQuery(new Uri($"{_globalSettings.BaseServiceUri.Admin}/login/confirm"),
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["returnUrl"] = returnUrl,
|
||||
["email"] = email,
|
||||
["token"] = token,
|
||||
});
|
||||
var model = new PasswordlessSignInModel
|
||||
{
|
||||
Url = url.ToString()
|
||||
};
|
||||
await AddMessageContentAsync(message, "PasswordlessSignIn", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendInvoiceUpcomingAsync(string email, decimal amount, DateTime dueDate,
|
||||
List<string> items, bool mentionInvoices)
|
||||
{
|
||||
var message = CreateDefaultMessage("Your Subscription Will Renew Soon", email);
|
||||
var model = new InvoiceUpcomingViewModel
|
||||
{
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName,
|
||||
AmountDue = amount,
|
||||
DueDate = dueDate,
|
||||
Items = items,
|
||||
MentionInvoices = mentionInvoices
|
||||
};
|
||||
await AddMessageContentAsync(message, "InvoiceUpcoming", model);
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
private MailMessage CreateDefaultMessage(string subject, string toEmail)
|
||||
{
|
||||
return CreateDefaultMessage(subject, new List<string> { toEmail });
|
||||
}
|
||||
|
||||
private MailMessage CreateDefaultMessage(string subject, IEnumerable<string> toEmails)
|
||||
{
|
||||
return new MailMessage
|
||||
{
|
||||
ToEmails = toEmails,
|
||||
Subject = subject,
|
||||
MetaData = new Dictionary<string, object>()
|
||||
};
|
||||
}
|
||||
|
||||
private async Task AddMessageContentAsync<T>(MailMessage message, string templateName, T model)
|
||||
{
|
||||
message.HtmlContent = await RenderAsync($"{templateName}.html", model);
|
||||
message.TextContent = await RenderAsync($"{templateName}.text", model);
|
||||
}
|
||||
|
||||
private async Task<string> RenderAsync<T>(string templateName, T model)
|
||||
{
|
||||
await RegisterHelpersAndPartialsAsync();
|
||||
if(!_templateCache.TryGetValue(templateName, out var template))
|
||||
{
|
||||
var source = await ReadSourceAsync(templateName);
|
||||
if(source != null)
|
||||
{
|
||||
template = Handlebars.Compile(source);
|
||||
_templateCache.Add(templateName, template);
|
||||
}
|
||||
}
|
||||
return template != null ? template(model) : null;
|
||||
}
|
||||
|
||||
private async Task<string> ReadSourceAsync(string templateName)
|
||||
{
|
||||
var assembly = typeof(HandlebarsMailService).GetTypeInfo().Assembly;
|
||||
var fullTemplateName = $"{Namespace}.{templateName}.hbs";
|
||||
if(!assembly.GetManifestResourceNames().Any(f => f == fullTemplateName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
using(var s = assembly.GetManifestResourceStream(fullTemplateName))
|
||||
using(var sr = new StreamReader(s))
|
||||
{
|
||||
return await sr.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RegisterHelpersAndPartialsAsync()
|
||||
{
|
||||
if(_registeredHelpersAndPartials)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_registeredHelpersAndPartials = true;
|
||||
|
||||
var basicHtmlLayoutSource = await ReadSourceAsync("Layouts.Basic.html");
|
||||
Handlebars.RegisterTemplate("BasicHtmlLayout", basicHtmlLayoutSource);
|
||||
var basicTextLayoutSource = await ReadSourceAsync("Layouts.Basic.text");
|
||||
Handlebars.RegisterTemplate("BasicTextLayout", basicTextLayoutSource);
|
||||
var fullHtmlLayoutSource = await ReadSourceAsync("Layouts.Full.html");
|
||||
Handlebars.RegisterTemplate("FullHtmlLayout", fullHtmlLayoutSource);
|
||||
var fullTextLayoutSource = await ReadSourceAsync("Layouts.Full.text");
|
||||
Handlebars.RegisterTemplate("FullTextLayout", fullTextLayoutSource);
|
||||
|
||||
Handlebars.RegisterHelper("date", (writer, context, parameters) =>
|
||||
{
|
||||
if(parameters.Length == 0 || !(parameters[0] is DateTime))
|
||||
{
|
||||
writer.WriteSafeString(string.Empty);
|
||||
return;
|
||||
}
|
||||
if(parameters.Length > 0 && parameters[1] is string)
|
||||
{
|
||||
writer.WriteSafeString(((DateTime)parameters[0]).ToString(parameters[1].ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteSafeString(((DateTime)parameters[0]).ToString());
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("usd", (writer, context, parameters) =>
|
||||
{
|
||||
if(parameters.Length == 0 || !(parameters[0] is decimal))
|
||||
{
|
||||
writer.WriteSafeString(string.Empty);
|
||||
return;
|
||||
}
|
||||
writer.WriteSafeString(((decimal)parameters[0]).ToString("C"));
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("link", (writer, context, parameters) =>
|
||||
{
|
||||
if(parameters.Length == 0)
|
||||
{
|
||||
writer.WriteSafeString(string.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
var text = parameters[0].ToString();
|
||||
var href = text;
|
||||
var clickTrackingOff = false;
|
||||
if(parameters.Length == 2)
|
||||
{
|
||||
if(parameters[1] is string)
|
||||
{
|
||||
var p1 = parameters[1].ToString();
|
||||
if(p1 == "true" || p1 == "false")
|
||||
{
|
||||
clickTrackingOff = p1 == "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
href = p1;
|
||||
}
|
||||
}
|
||||
else if(parameters[1] is bool)
|
||||
{
|
||||
clickTrackingOff = (bool)parameters[1];
|
||||
}
|
||||
}
|
||||
else if(parameters.Length > 2)
|
||||
{
|
||||
if(parameters[1] is string)
|
||||
{
|
||||
href = parameters[1].ToString();
|
||||
}
|
||||
if(parameters[2] is string)
|
||||
{
|
||||
var p2 = parameters[2].ToString();
|
||||
if(p2 == "true" || p2 == "false")
|
||||
{
|
||||
clickTrackingOff = p2 == "true";
|
||||
}
|
||||
}
|
||||
else if(parameters[2] is bool)
|
||||
{
|
||||
clickTrackingOff = (bool)parameters[2];
|
||||
}
|
||||
}
|
||||
|
||||
var clickTrackingText = (clickTrackingOff ? "clicktracking=off" : string.Empty);
|
||||
writer.WriteSafeString($"<a href=\"{href}\" target=\"_blank\" {clickTrackingText}>{text}</a>");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -66,7 +66,7 @@ namespace Bit.Core.Utilities
|
||||
|
||||
public static void AddDefaultServices(this IServiceCollection services, GlobalSettings globalSettings)
|
||||
{
|
||||
services.AddSingleton<IMailService, BackupMailService>();
|
||||
services.AddSingleton<IMailService, HandlebarsMailService>();
|
||||
services.AddSingleton<ILicensingService, LicensingService>();
|
||||
services.AddSingleton<IApplicationCacheService, InMemoryApplicationCacheService>();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user