mirror of
https://github.com/bitwarden/server.git
synced 2026-02-03 17:43:03 -06:00
Merge branch 'main' into dbops/dbops-81/update-sql-cu
This commit is contained in:
commit
b207ff2c7e
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -263,7 +263,7 @@ jobs:
|
||||
|
||||
- name: Scan Docker image
|
||||
id: container-scan
|
||||
uses: anchore/scan-action@62b74fb7bb810d2c45b1865f47a77655621862a5 # v7.2.3
|
||||
uses: anchore/scan-action@0d444ed77d83ee2ba7f5ced0d90d640a1281d762 # v7.3.0
|
||||
with:
|
||||
image: ${{ steps.image-tags.outputs.primary_tag }}
|
||||
fail-build: false
|
||||
|
||||
@ -13,6 +13,10 @@
|
||||
<TreatWarningsAsErrors Condition="'$(TreatWarningsAsErrors)' == ''">true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BitIncludeAuthentication>false</BitIncludeAuthentication>
|
||||
<BitIncludeFeatures>false</BitIncludeFeatures>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Scim</UserSecretsId>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Sso</UserSecretsId>
|
||||
|
||||
@ -6,6 +6,6 @@
|
||||
"msbuild-sdks": {
|
||||
"Microsoft.Build.Traversal": "4.1.0",
|
||||
"Microsoft.Build.Sql": "1.0.0",
|
||||
"Bitwarden.Server.Sdk": "1.2.0"
|
||||
"Bitwarden.Server.Sdk": "1.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Admin</UserSecretsId>
|
||||
|
||||
@ -86,7 +86,7 @@ public class UsersController : Controller
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
var ciphers = await _cipherRepository.GetManyByUserIdAsync(id);
|
||||
var ciphers = await _cipherRepository.GetManyByUserIdAsync(id, withOrganizations: false);
|
||||
|
||||
var isTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user);
|
||||
var verifiedDomain = await _userService.IsClaimedByAnyOrganizationAsync(user.Id);
|
||||
|
||||
@ -8,7 +8,7 @@ public class Program
|
||||
{
|
||||
Host
|
||||
.CreateDefaultBuilder(args)
|
||||
.ConfigureCustomAppConfiguration(args)
|
||||
.UseBitwardenSdk()
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.ConfigureKestrel(o =>
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Api</UserSecretsId>
|
||||
<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
|
||||
|
||||
@ -8,7 +8,7 @@ public class Program
|
||||
{
|
||||
Host
|
||||
.CreateDefaultBuilder(args)
|
||||
.ConfigureCustomAppConfiguration(args)
|
||||
.UseBitwardenSdk()
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
|
||||
@ -74,11 +74,6 @@ public class ImportCiphersController : Controller
|
||||
throw new BadRequestException("You cannot import this much data at once.");
|
||||
}
|
||||
|
||||
if (model.Ciphers.Any(c => c.ArchivedDate.HasValue))
|
||||
{
|
||||
throw new BadRequestException("You cannot import archived items into an organization.");
|
||||
}
|
||||
|
||||
var orgId = new Guid(organizationId);
|
||||
var collections = model.Collections.Select(c => c.ToCollection(orgId)).ToList();
|
||||
|
||||
|
||||
@ -70,10 +70,6 @@ public static class StripeConstants
|
||||
public const string InvoiceApproved = "invoice_approved";
|
||||
public const string OrganizationId = "organizationId";
|
||||
public const string PayPalTransactionId = "btPayPalTransactionId";
|
||||
public const string PreviousAdditionalStorage = "previous_additional_storage";
|
||||
public const string PreviousPeriodEndDate = "previous_period_end_date";
|
||||
public const string PreviousPremiumPriceId = "previous_premium_price_id";
|
||||
public const string PreviousPremiumUserId = "previous_premium_user_id";
|
||||
public const string ProviderId = "providerId";
|
||||
public const string Region = "region";
|
||||
public const string RetiredBraintreeCustomerId = "btCustomerId_old";
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
using Bit.Core.Billing.Commands;
|
||||
using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Extensions;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Entities;
|
||||
@ -96,9 +95,6 @@ public class UpgradePremiumToOrganizationCommand(
|
||||
var storageItem = currentSubscription.Items.Data.FirstOrDefault(i =>
|
||||
i.Price.Id == usersPremiumPlan.Storage.StripePriceId);
|
||||
|
||||
// Capture the previous additional storage quantity for potential revert
|
||||
var previousAdditionalStorage = storageItem?.Quantity ?? 0;
|
||||
|
||||
if (storageItem != null)
|
||||
{
|
||||
subscriptionItemOptions.Add(new SubscriptionItemOptions
|
||||
@ -133,14 +129,10 @@ public class UpgradePremiumToOrganizationCommand(
|
||||
var subscriptionUpdateOptions = new SubscriptionUpdateOptions
|
||||
{
|
||||
Items = subscriptionItemOptions,
|
||||
ProrationBehavior = StripeConstants.ProrationBehavior.None,
|
||||
ProrationBehavior = StripeConstants.ProrationBehavior.CreateProrations,
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
[StripeConstants.MetadataKeys.OrganizationId] = organizationId.ToString(),
|
||||
[StripeConstants.MetadataKeys.PreviousPremiumPriceId] = usersPremiumPlan.Seat.StripePriceId,
|
||||
[StripeConstants.MetadataKeys.PreviousPeriodEndDate] = currentSubscription.GetCurrentPeriodEnd()?.ToString("O") ?? string.Empty,
|
||||
[StripeConstants.MetadataKeys.PreviousAdditionalStorage] = previousAdditionalStorage.ToString(),
|
||||
[StripeConstants.MetadataKeys.PreviousPremiumUserId] = user.Id.ToString(),
|
||||
[StripeConstants.MetadataKeys.UserId] = string.Empty // Remove userId to unlink subscription from User
|
||||
}
|
||||
};
|
||||
|
||||
@ -160,7 +160,6 @@ public static class FeatureFlagKeys
|
||||
public const string Otp6Digits = "pm-18612-otp-6-digits";
|
||||
public const string PM24579_PreventSsoOnExistingNonCompliantUsers = "pm-24579-prevent-sso-on-existing-non-compliant-users";
|
||||
public const string DisableAlternateLoginMethods = "pm-22110-disable-alternate-login-methods";
|
||||
public const string MJMLBasedEmailTemplates = "mjml-based-email-templates";
|
||||
public const string PM2035PasskeyUnlock = "pm-2035-passkey-unlock";
|
||||
public const string MjmlWelcomeEmailTemplates = "pm-21741-mjml-welcome-email";
|
||||
public const string OrganizationConfirmationEmail = "pm-28402-update-confirmed-to-org-email-template";
|
||||
|
||||
@ -1,28 +1,691 @@
|
||||
{{#>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 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">
|
||||
Verify your email to access this Bitwarden Send.
|
||||
</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">
|
||||
<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;" />
|
||||
Your verification code is: <b 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;">{{Token}}</b>
|
||||
</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">
|
||||
<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;" />
|
||||
This code can only be used once and expires in 5 minutes. After that you'll need to verify your email again.
|
||||
</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">
|
||||
<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;" />
|
||||
<hr />
|
||||
{{TheDate}} at {{TheTime}} {{TimeZone}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{{/FullHtmlLayout}}
|
||||
<!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]-->
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width:480px) {
|
||||
.mj-column-per-70 { width:70% !important; max-width: 70%; }
|
||||
.mj-column-per-30 { width:30% !important; max-width: 30%; }
|
||||
.mj-column-per-100 { width:100% !important; max-width: 100%; }
|
||||
.mj-column-per-90 { width:90% !important; max-width: 90%; }
|
||||
}
|
||||
</style>
|
||||
<style media="screen and (min-width:480px)">
|
||||
.moz-text-html .mj-column-per-70 { width:70% !important; max-width: 70%; }
|
||||
.moz-text-html .mj-column-per-30 { width:30% !important; max-width: 30%; }
|
||||
.moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; }
|
||||
.moz-text-html .mj-column-per-90 { width:90% !important; max-width: 90%; }
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.mj-bw-hero-responsive-img {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.mj-bw-learn-more-footer-responsive-img {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@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;
|
||||
}
|
||||
.send-bubble {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
width: 90% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body style="word-spacing:normal;background-color:#e6e9ef;">
|
||||
|
||||
|
||||
<div class="border-fix" 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 10px 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 0;text-align:center;">
|
||||
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:434px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-70 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 25px;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>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;padding-top:0;padding-bottom:0;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#ffffff;"><h1 style="font-weight: normal; font-size: 24px; line-height: 32px">
|
||||
Verify your email to access this Bitwarden Send
|
||||
</h1></div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<!--[if mso | IE]></td><td class="" style="vertical-align:bottom;width:186px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-30 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:bottom;width:100%;">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:bottom;" width="100%">
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="mj-bw-hero-responsive-img" style="font-size:0px;padding:0px;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:155px;">
|
||||
|
||||
<img alt src="https://assets.bitwarden.com/email/v1/spot-secure-send-round.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:16px;" width="155" height="auto">
|
||||
|
||||
</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:5px 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:20px 0;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" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align:top;padding:0px;">
|
||||
|
||||
<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:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#1B2029;">Your verification code is:</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:32px;line-height:1;text-align:left;color:#1B2029;"><b>{{Token}}</b></div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="font-size:0px;word-break:break-word;">
|
||||
|
||||
<div style="height:20px;line-height:20px;"> </div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#1B2029;">This code expires in {{Expiry}} minutes. After that, you'll need
|
||||
to verify your email again.</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><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:0px 0px 20px 0px;text-align:center;">
|
||||
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="send-bubble-outlook" style="vertical-align:top;width:558px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-90 mj-outlook-group-fix send-bubble" 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:0px;">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="background-color:#DBE5F6;border-radius:16px;" width="100%">
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#1B2029;"><p>
|
||||
Bitwarden Send transmits sensitive, temporary information to
|
||||
others easily and securely. Learn more about
|
||||
<a href="https://bitwarden.com/help/send" class="link" style="text-decoration: none; color: #175ddc; font-weight: 600;">Bitwarden Send</a>
|
||||
or
|
||||
<a href="https://bitwarden.com/signup" class="link" style="text-decoration: none; color: #175ddc; font-weight: 600;">sign up</a>
|
||||
to try it today.
|
||||
</p></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]-->
|
||||
|
||||
<!-- Learn More Section -->
|
||||
|
||||
<!--[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="" width="660px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:620px;" width="620" bgcolor="#F3F6F9" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
||||
|
||||
<div style="background:#F3F6F9;background-color:#F3F6F9;margin:0px auto;border-radius:0px 0px 4px 4px;max-width:620px;">
|
||||
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#F3F6F9;background-color:#F3F6F9;width:100%;border-radius:0px 0px 4px 4px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="direction:ltr;font-size:0px;padding:5px 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:420px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-70 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 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#1B2029;"><p style="font-size: 18px; line-height: 28px; font-weight: bold;">
|
||||
Learn more about Bitwarden
|
||||
</p>
|
||||
Find user guides, product documentation, and videos on the
|
||||
<a href="https://bitwarden.com/help/" class="link" style="text-decoration: none; color: #175ddc; font-weight: 600;"> Bitwarden Help Center</a>.</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<!--[if mso | IE]></td><td class="" style="vertical-align:top;width:180px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-30 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" class="mj-bw-learn-more-footer-responsive-img" style="font-size:0px;padding:10px 25px;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:94px;">
|
||||
|
||||
<img alt src="https://assets.bitwarden.com/email/v1/spot-community.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:16px;" width="94" height="auto">
|
||||
|
||||
</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>
|
||||
|
||||
@ -3,7 +3,7 @@ Verify your email to access this Bitwarden Send.
|
||||
|
||||
Your verification code is: {{Token}}
|
||||
|
||||
This code can only be used once and expires in 5 minutes. After that you'll need to verify your email again.
|
||||
This code can only be used once and expires in {{Expiry}} minutes. After that you'll need to verify your email again.
|
||||
|
||||
Date : {{TheDate}} at {{TheTime}} {{TimeZone}}
|
||||
{{/BasicTextLayout}}
|
||||
Bitwarden Send transmits sensitive, temporary information to others easily and securely. Learn more about Bitwarden Send or sign up to try it today.
|
||||
{{/BasicTextLayout}}
|
||||
|
||||
@ -1,691 +0,0 @@
|
||||
<!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]-->
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width:480px) {
|
||||
.mj-column-per-70 { width:70% !important; max-width: 70%; }
|
||||
.mj-column-per-30 { width:30% !important; max-width: 30%; }
|
||||
.mj-column-per-100 { width:100% !important; max-width: 100%; }
|
||||
.mj-column-per-90 { width:90% !important; max-width: 90%; }
|
||||
}
|
||||
</style>
|
||||
<style media="screen and (min-width:480px)">
|
||||
.moz-text-html .mj-column-per-70 { width:70% !important; max-width: 70%; }
|
||||
.moz-text-html .mj-column-per-30 { width:30% !important; max-width: 30%; }
|
||||
.moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; }
|
||||
.moz-text-html .mj-column-per-90 { width:90% !important; max-width: 90%; }
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.mj-bw-hero-responsive-img {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.mj-bw-learn-more-footer-responsive-img {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@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;
|
||||
}
|
||||
.send-bubble {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
width: 90% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body style="word-spacing:normal;background-color:#e6e9ef;">
|
||||
|
||||
|
||||
<div class="border-fix" 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 10px 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 0;text-align:center;">
|
||||
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:434px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-70 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 25px;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>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;padding-top:0;padding-bottom:0;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#ffffff;"><h1 style="font-weight: normal; font-size: 24px; line-height: 32px">
|
||||
Verify your email to access this Bitwarden Send
|
||||
</h1></div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<!--[if mso | IE]></td><td class="" style="vertical-align:bottom;width:186px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-30 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:bottom;width:100%;">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:bottom;" width="100%">
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="mj-bw-hero-responsive-img" style="font-size:0px;padding:0px;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:155px;">
|
||||
|
||||
<img alt src="https://assets.bitwarden.com/email/v1/spot-secure-send-round.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:16px;" width="155" height="auto">
|
||||
|
||||
</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:5px 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:20px 0;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" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align:top;padding:0px;">
|
||||
|
||||
<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:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#1B2029;">Your verification code is:</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:32px;line-height:1;text-align:left;color:#1B2029;"><b>{{Token}}</b></div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="font-size:0px;word-break:break-word;">
|
||||
|
||||
<div style="height:20px;line-height:20px;"> </div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#1B2029;">This code expires in {{Expiry}} minutes. After that, you'll need
|
||||
to verify your email again.</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><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:0px 0px 20px 0px;text-align:center;">
|
||||
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="send-bubble-outlook" style="vertical-align:top;width:558px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-90 mj-outlook-group-fix send-bubble" 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:0px;">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="background-color:#DBE5F6;border-radius:16px;" width="100%">
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#1B2029;"><p>
|
||||
Bitwarden Send transmits sensitive, temporary information to
|
||||
others easily and securely. Learn more about
|
||||
<a href="https://bitwarden.com/help/send" class="link" style="text-decoration: none; color: #175ddc; font-weight: 600;">Bitwarden Send</a>
|
||||
or
|
||||
<a href="https://bitwarden.com/signup" class="link" style="text-decoration: none; color: #175ddc; font-weight: 600;">sign up</a>
|
||||
to try it today.
|
||||
</p></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]-->
|
||||
|
||||
<!-- Learn More Section -->
|
||||
|
||||
<!--[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="" width="660px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:620px;" width="620" bgcolor="#F3F6F9" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
||||
|
||||
<div style="background:#F3F6F9;background-color:#F3F6F9;margin:0px auto;border-radius:0px 0px 4px 4px;max-width:620px;">
|
||||
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#F3F6F9;background-color:#F3F6F9;width:100%;border-radius:0px 0px 4px 4px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="direction:ltr;font-size:0px;padding:5px 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:420px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-70 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 25px;word-break:break-word;">
|
||||
|
||||
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#1B2029;"><p style="font-size: 18px; line-height: 28px; font-weight: bold;">
|
||||
Learn more about Bitwarden
|
||||
</p>
|
||||
Find user guides, product documentation, and videos on the
|
||||
<a href="https://bitwarden.com/help/" class="link" style="text-decoration: none; color: #175ddc; font-weight: 600;"> Bitwarden Help Center</a>.</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<!--[if mso | IE]></td><td class="" style="vertical-align:top;width:180px;" ><![endif]-->
|
||||
|
||||
<div class="mj-column-per-30 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" class="mj-bw-learn-more-footer-responsive-img" style="font-size:0px;padding:10px 25px;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:94px;">
|
||||
|
||||
<img alt src="https://assets.bitwarden.com/email/v1/spot-community.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:16px;" width="94" height="auto">
|
||||
|
||||
</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>
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
{{#>BasicTextLayout}}
|
||||
Verify your email to access this Bitwarden Send.
|
||||
|
||||
Your verification code is: {{Token}}
|
||||
|
||||
This code can only be used once and expires in {{Expiry}} minutes. After that you'll need to verify your email again.
|
||||
|
||||
Bitwarden Send transmits sensitive, temporary information to others easily and securely. Learn more about Bitwarden Send or sign up to try it today.
|
||||
{{/BasicTextLayout}}
|
||||
@ -209,26 +209,6 @@ public class HandlebarsMailService : IMailService
|
||||
}
|
||||
|
||||
public async Task SendSendEmailOtpEmailAsync(string email, string token, string subject)
|
||||
{
|
||||
var message = CreateDefaultMessage(subject, email);
|
||||
var requestDateTime = DateTime.UtcNow;
|
||||
var model = new DefaultEmailOtpViewModel
|
||||
{
|
||||
Token = token,
|
||||
TheDate = requestDateTime.ToLongDateString(),
|
||||
TheTime = requestDateTime.ToShortTimeString(),
|
||||
TimeZone = _utcTimeZoneDisplay,
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName,
|
||||
};
|
||||
await AddMessageContentAsync(message, "Auth.SendAccessEmailOtpEmail", model);
|
||||
message.MetaData.Add("SendGridBypassListManagement", true);
|
||||
// TODO - PM-25380 change to string constant
|
||||
message.Category = "SendEmailOtp";
|
||||
await _mailDeliveryService.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendSendEmailOtpEmailv2Async(string email, string token, string subject)
|
||||
{
|
||||
var message = CreateDefaultMessage(subject, email);
|
||||
var requestDateTime = DateTime.UtcNow;
|
||||
@ -242,7 +222,7 @@ public class HandlebarsMailService : IMailService
|
||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||
SiteName = _globalSettings.SiteName,
|
||||
};
|
||||
await AddMessageContentAsync(message, "Auth.SendAccessEmailOtpEmailv2", model);
|
||||
await AddMessageContentAsync(message, "Auth.SendAccessEmailOtpEmail", model);
|
||||
message.MetaData.Add("SendGridBypassListManagement", true);
|
||||
// TODO - PM-25380 change to string constant
|
||||
message.Category = "SendEmailOtp";
|
||||
|
||||
@ -51,17 +51,15 @@ public interface IMailService
|
||||
Task SendChangeEmailAlreadyExistsEmailAsync(string fromEmail, string toEmail);
|
||||
Task SendChangeEmailEmailAsync(string newEmailAddress, string token);
|
||||
Task SendTwoFactorEmailAsync(string email, string accountEmail, string token, string deviceIp, string deviceType, TwoFactorEmailPurpose purpose);
|
||||
Task SendSendEmailOtpEmailAsync(string email, string token, string subject);
|
||||
/// <summary>
|
||||
/// <see cref="DefaultOtpTokenProviderOptions"/> has a default expiry of 5 minutes so we set the expiry to that value int he view model.
|
||||
/// <see cref="DefaultOtpTokenProviderOptions"/> has a default expiry of 5 minutes so we set the expiry to that value in the view model.
|
||||
/// Sends OTP code token to the specified email address.
|
||||
/// will replace <see cref="SendSendEmailOtpEmailAsync"/> when MJML templates are fully accepted.
|
||||
/// </summary>
|
||||
/// <param name="email">Email address to send the OTP to</param>
|
||||
/// <param name="token">Otp code token</param>
|
||||
/// <param name="subject">subject line of the email</param>
|
||||
/// <param name="subject">Subject line of the email</param>
|
||||
/// <returns>Task</returns>
|
||||
Task SendSendEmailOtpEmailv2Async(string email, string token, string subject);
|
||||
Task SendSendEmailOtpEmailAsync(string email, string token, string subject);
|
||||
Task SendFailedTwoFactorAttemptEmailAsync(string email, TwoFactorProviderType type, DateTime utcNow, string ip);
|
||||
Task SendNoMasterPasswordHintEmailAsync(string email);
|
||||
Task SendMasterPasswordHintEmailAsync(string email, string hint);
|
||||
|
||||
@ -99,11 +99,6 @@ public class NoopMailService : IMailService
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendSendEmailOtpEmailv2Async(string email, string token, string subject)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendFailedTwoFactorAttemptEmailAsync(string email, TwoFactorProviderType failedType, DateTime utcNow, string ip)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
|
||||
@ -76,6 +76,12 @@ public class ImportCiphersCommand : IImportCiphersCommand
|
||||
{
|
||||
cipher.Favorites = $"{{\"{cipher.UserId.ToString().ToUpperInvariant()}\":true}}";
|
||||
}
|
||||
|
||||
if (cipher.UserId.HasValue && cipher.ArchivedDate.HasValue)
|
||||
{
|
||||
cipher.Archives = $"{{\"{cipher.UserId.Value.ToString().ToUpperInvariant()}\":\"" +
|
||||
$"{cipher.ArchivedDate.Value:yyyy-MM-ddTHH:mm:ss.fffffffZ}\"}}";
|
||||
}
|
||||
}
|
||||
|
||||
var userfoldersIds = (await _folderRepository.GetManyByUserIdAsync(importingUserId)).Select(f => f.Id).ToList();
|
||||
@ -135,10 +141,16 @@ public class ImportCiphersCommand : IImportCiphersCommand
|
||||
}
|
||||
}
|
||||
|
||||
// Init. ids for ciphers
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
// Init. ids for ciphers
|
||||
cipher.SetNewId();
|
||||
|
||||
if (cipher.ArchivedDate.HasValue)
|
||||
{
|
||||
cipher.Archives = $"{{\"{importingUserId.ToString().ToUpperInvariant()}\":\"" +
|
||||
$"{cipher.ArchivedDate.Value:yyyy-MM-ddTHH:mm:ss.fffffffZ}\"}}";
|
||||
}
|
||||
}
|
||||
|
||||
var organizationCollectionsIds = (await _collectionRepository.GetManyByOrganizationIdAsync(org.Id)).Select(c => c.Id).ToList();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Events</UserSecretsId>
|
||||
|
||||
@ -8,7 +8,7 @@ public class Program
|
||||
{
|
||||
Host
|
||||
.CreateDefaultBuilder(args)
|
||||
.ConfigureCustomAppConfiguration(args)
|
||||
.UseBitwardenSdk()
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-EventsProcessor</UserSecretsId>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Icons</UserSecretsId>
|
||||
|
||||
@ -8,6 +8,7 @@ public class Program
|
||||
{
|
||||
Host
|
||||
.CreateDefaultBuilder(args)
|
||||
.UseBitwardenSdk()
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Identity</UserSecretsId>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Auth.Identity;
|
||||
using Bit.Core.Auth.Identity.TokenProviders;
|
||||
using Bit.Core.Services;
|
||||
@ -13,7 +12,6 @@ using Duende.IdentityServer.Validation;
|
||||
namespace Bit.Identity.IdentityServer.RequestValidators.SendAccess;
|
||||
|
||||
public class SendEmailOtpRequestValidator(
|
||||
IFeatureService featureService,
|
||||
IOtpTokenProvider<DefaultOtpTokenProviderOptions> otpTokenProvider,
|
||||
IMailService mailService) : ISendAuthenticationMethodValidator<EmailOtp>
|
||||
{
|
||||
@ -66,20 +64,12 @@ public class SendEmailOtpRequestValidator(
|
||||
{
|
||||
return BuildErrorResult(SendAccessConstants.EmailOtpValidatorResults.OtpGenerationFailed);
|
||||
}
|
||||
if (featureService.IsEnabled(FeatureFlagKeys.MJMLBasedEmailTemplates))
|
||||
{
|
||||
await mailService.SendSendEmailOtpEmailv2Async(
|
||||
email,
|
||||
token,
|
||||
string.Format(SendAccessConstants.OtpEmail.Subject, token));
|
||||
}
|
||||
else
|
||||
{
|
||||
await mailService.SendSendEmailOtpEmailAsync(
|
||||
email,
|
||||
token,
|
||||
string.Format(SendAccessConstants.OtpEmail.Subject, token));
|
||||
}
|
||||
|
||||
await mailService.SendSendEmailOtpEmailAsync(
|
||||
email,
|
||||
token,
|
||||
string.Format(SendAccessConstants.OtpEmail.Subject, token));
|
||||
|
||||
return BuildErrorResult(SendAccessConstants.EmailOtpValidatorResults.EmailOtpSent);
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ public class Program
|
||||
{
|
||||
return Host
|
||||
.CreateDefaultBuilder(args)
|
||||
.ConfigureCustomAppConfiguration(args)
|
||||
.UseBitwardenSdk()
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
|
||||
@ -248,7 +248,7 @@ public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
|
||||
new { Ids = ids.ToGuidIdArrayTVP(), UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results;
|
||||
return DateTime.SpecifyKind(results, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -595,7 +595,7 @@ public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
|
||||
new { Ids = ids.ToGuidIdArrayTVP(), UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results;
|
||||
return DateTime.SpecifyKind(results, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,7 +608,7 @@ public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
|
||||
new { Ids = ids.ToGuidIdArrayTVP(), UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results;
|
||||
return DateTime.SpecifyKind(results, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -621,7 +621,7 @@ public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
|
||||
new { Ids = ids.ToGuidIdArrayTVP(), OrganizationId = organizationId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results;
|
||||
return DateTime.SpecifyKind(results, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Sdk Name="Bitwarden.Server.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<UserSecretsId>bitwarden-Notifications</UserSecretsId>
|
||||
|
||||
@ -8,7 +8,7 @@ public class Program
|
||||
{
|
||||
Host
|
||||
.CreateDefaultBuilder(args)
|
||||
.ConfigureCustomAppConfiguration(args)
|
||||
.UseBitwardenSdk()
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
|
||||
@ -806,63 +806,6 @@ public class ImportCiphersControllerTests
|
||||
Arg.Any<Guid>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task PostImportOrganization_ThrowsException_WhenAnyCipherIsArchived(
|
||||
SutProvider<ImportCiphersController> sutProvider,
|
||||
IFixture fixture,
|
||||
User user
|
||||
)
|
||||
{
|
||||
var orgId = Guid.NewGuid();
|
||||
|
||||
sutProvider.GetDependency<GlobalSettings>()
|
||||
.SelfHosted = false;
|
||||
sutProvider.GetDependency<GlobalSettings>()
|
||||
.ImportCiphersLimitation = _organizationCiphersLimitations;
|
||||
|
||||
SetupUserService(sutProvider, user);
|
||||
|
||||
var ciphers = fixture.Build<CipherRequestModel>()
|
||||
.With(_ => _.ArchivedDate, DateTime.UtcNow)
|
||||
.CreateMany(2).ToArray();
|
||||
|
||||
var request = new ImportOrganizationCiphersRequestModel
|
||||
{
|
||||
Collections = new List<CollectionWithIdRequestModel>().ToArray(),
|
||||
Ciphers = ciphers,
|
||||
CollectionRelationships = new List<KeyValuePair<int, int>>().ToArray(),
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>()
|
||||
.AccessImportExport(Arg.Any<Guid>())
|
||||
.Returns(false);
|
||||
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(),
|
||||
Arg.Any<IEnumerable<Collection>>(),
|
||||
Arg.Is<IEnumerable<IAuthorizationRequirement>>(reqs =>
|
||||
reqs.Contains(BulkCollectionOperations.ImportCiphers)))
|
||||
.Returns(AuthorizationResult.Failed());
|
||||
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(),
|
||||
Arg.Any<IEnumerable<Collection>>(),
|
||||
Arg.Is<IEnumerable<IAuthorizationRequirement>>(reqs =>
|
||||
reqs.Contains(BulkCollectionOperations.Create)))
|
||||
.Returns(AuthorizationResult.Success());
|
||||
|
||||
sutProvider.GetDependency<ICollectionRepository>()
|
||||
.GetManyByOrganizationIdAsync(orgId)
|
||||
.Returns(new List<Collection>());
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(async () =>
|
||||
{
|
||||
await sutProvider.Sut.PostImportOrganization(orgId.ToString(), request);
|
||||
});
|
||||
|
||||
Assert.Equal("You cannot import archived items into an organization.", exception.Message);
|
||||
}
|
||||
|
||||
private static void SetupUserService(SutProvider<ImportCiphersController> sutProvider, User user)
|
||||
{
|
||||
// This is a workaround for the NSubstitute issue with ambiguous arguments
|
||||
|
||||
@ -712,15 +712,15 @@ public class SubscriptionUpdatedHandlerTests
|
||||
Data =
|
||||
[
|
||||
new SubscriptionItem
|
||||
{
|
||||
CurrentPeriodEnd = DateTime.UtcNow.AddDays(10),
|
||||
Plan = new Plan { Id = "2023-enterprise-org-seat-annually" }
|
||||
},
|
||||
new SubscriptionItem
|
||||
{
|
||||
CurrentPeriodEnd = DateTime.UtcNow.AddDays(10),
|
||||
Plan = new Plan { Id = "secrets-manager-enterprise-seat-annually" }
|
||||
}
|
||||
{
|
||||
CurrentPeriodEnd = DateTime.UtcNow.AddDays(10),
|
||||
Plan = new Plan { Id = "2023-enterprise-org-seat-annually" }
|
||||
},
|
||||
new SubscriptionItem
|
||||
{
|
||||
CurrentPeriodEnd = DateTime.UtcNow.AddDays(10),
|
||||
Plan = new Plan { Id = "secrets-manager-enterprise-seat-annually" }
|
||||
}
|
||||
]
|
||||
},
|
||||
Customer = new Customer
|
||||
@ -760,7 +760,7 @@ public class SubscriptionUpdatedHandlerTests
|
||||
Data =
|
||||
[
|
||||
new SubscriptionItem { Plan = new Stripe.Plan { Id = "secrets-manager-teams-seat-annually" } },
|
||||
]
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -392,11 +392,6 @@ public class UpgradePremiumToOrganizationCommandTests
|
||||
"sub_123",
|
||||
Arg.Is<SubscriptionUpdateOptions>(opts =>
|
||||
opts.Metadata.ContainsKey(StripeConstants.MetadataKeys.OrganizationId) &&
|
||||
opts.Metadata.ContainsKey(StripeConstants.MetadataKeys.PreviousPremiumPriceId) &&
|
||||
opts.Metadata[StripeConstants.MetadataKeys.PreviousPremiumPriceId] == "premium-annually" &&
|
||||
opts.Metadata.ContainsKey(StripeConstants.MetadataKeys.PreviousPeriodEndDate) &&
|
||||
opts.Metadata.ContainsKey(StripeConstants.MetadataKeys.PreviousAdditionalStorage) &&
|
||||
opts.Metadata[StripeConstants.MetadataKeys.PreviousAdditionalStorage] == "0" &&
|
||||
opts.Metadata.ContainsKey(StripeConstants.MetadataKeys.UserId) &&
|
||||
opts.Metadata[StripeConstants.MetadataKeys.UserId] == string.Empty)); // Removes userId to unlink from User
|
||||
}
|
||||
@ -598,8 +593,6 @@ public class UpgradePremiumToOrganizationCommandTests
|
||||
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(
|
||||
"sub_123",
|
||||
Arg.Is<SubscriptionUpdateOptions>(opts =>
|
||||
opts.Metadata.ContainsKey(StripeConstants.MetadataKeys.PreviousAdditionalStorage) &&
|
||||
opts.Metadata[StripeConstants.MetadataKeys.PreviousAdditionalStorage] == "5" &&
|
||||
opts.Items.Count == 3 && // 2 deleted (premium + storage) + 1 new seat
|
||||
opts.Items.Count(i => i.Deleted == true) == 2));
|
||||
}
|
||||
|
||||
@ -254,21 +254,6 @@ public class HandlebarsMailServiceTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SendSendEmailOtpEmailAsync_SendsEmail()
|
||||
{
|
||||
// Arrange
|
||||
var email = "test@example.com";
|
||||
var token = "aToken";
|
||||
var subject = string.Format("Your Bitwarden Send verification code is {0}", token);
|
||||
|
||||
// Act
|
||||
await _sut.SendSendEmailOtpEmailAsync(email, token, subject);
|
||||
|
||||
// Assert
|
||||
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Any<MailMessage>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SendIndividualUserWelcomeEmailAsync_SendsCorrectEmail()
|
||||
{
|
||||
|
||||
@ -326,4 +326,101 @@ public class ImportCiphersAsyncCommandTests
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncVaultAsync(importingUserId);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task ImportIntoIndividualVaultAsync_WithArchivedCiphers_PreservesArchiveStatus(
|
||||
Guid importingUserId,
|
||||
List<CipherDetails> ciphers,
|
||||
SutProvider<ImportCiphersCommand> sutProvider)
|
||||
{
|
||||
var archivedDate = DateTime.UtcNow.AddDays(-1);
|
||||
ciphers[0].UserId = importingUserId;
|
||||
ciphers[0].ArchivedDate = archivedDate;
|
||||
|
||||
sutProvider.GetDependency<IPolicyService>()
|
||||
.AnyPoliciesApplicableToUserAsync(importingUserId, PolicyType.OrganizationDataOwnership)
|
||||
.Returns(false);
|
||||
|
||||
sutProvider.GetDependency<IFolderRepository>()
|
||||
.GetManyByUserIdAsync(importingUserId)
|
||||
.Returns(new List<Folder>());
|
||||
|
||||
var folders = new List<Folder>();
|
||||
var folderRelationships = new List<KeyValuePair<int, int>>();
|
||||
|
||||
await sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships, importingUserId);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.CreateAsync(importingUserId,
|
||||
Arg.Is<List<CipherDetails>>(c =>
|
||||
c[0].Archives != null &&
|
||||
c[0].Archives.Contains(importingUserId.ToString().ToUpperInvariant()) &&
|
||||
c[0].Archives.Contains(archivedDate.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"))),
|
||||
Arg.Any<List<Folder>>());
|
||||
}
|
||||
|
||||
/*
|
||||
* Archive functionality is a per-user function. When importing archived ciphers into an organization vault,
|
||||
* the Archives field should be set for the importing user only. This allows the importing user to see
|
||||
* items as archived, while other organization members will not see them as archived.
|
||||
*/
|
||||
[Theory, BitAutoData]
|
||||
public async Task ImportIntoOrganizationalVaultAsync_WithArchivedCiphers_SetsArchivesForImportingUserOnly(
|
||||
Organization organization,
|
||||
Guid importingUserId,
|
||||
OrganizationUser importingOrganizationUser,
|
||||
List<Collection> collections,
|
||||
List<CipherDetails> ciphers,
|
||||
SutProvider<ImportCiphersCommand> sutProvider)
|
||||
{
|
||||
var archivedDate = DateTime.UtcNow.AddDays(-1);
|
||||
organization.MaxCollections = null;
|
||||
importingOrganizationUser.OrganizationId = organization.Id;
|
||||
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
collection.OrganizationId = organization.Id;
|
||||
}
|
||||
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
cipher.OrganizationId = organization.Id;
|
||||
}
|
||||
|
||||
ciphers[0].ArchivedDate = archivedDate;
|
||||
ciphers[0].Archives = null;
|
||||
|
||||
KeyValuePair<int, int>[] collectionRelationships = {
|
||||
new(0, 0),
|
||||
new(1, 1),
|
||||
new(2, 2)
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
.GetByIdAsync(organization.Id)
|
||||
.Returns(organization);
|
||||
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.GetByOrganizationAsync(organization.Id, importingUserId)
|
||||
.Returns(importingOrganizationUser);
|
||||
|
||||
sutProvider.GetDependency<ICollectionRepository>()
|
||||
.GetManyByOrganizationIdAsync(organization.Id)
|
||||
.Returns(new List<Collection>());
|
||||
|
||||
await sutProvider.Sut.ImportIntoOrganizationalVaultAsync(collections, ciphers, collectionRelationships, importingUserId);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.CreateAsync(
|
||||
Arg.Is<List<CipherDetails>>(c =>
|
||||
c[0].ArchivedDate == archivedDate &&
|
||||
c[0].Archives != null &&
|
||||
c[0].Archives.Contains(importingUserId.ToString().ToUpperInvariant()) &&
|
||||
c[0].Archives.Contains(archivedDate.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"))),
|
||||
Arg.Any<IEnumerable<Collection>>(),
|
||||
Arg.Any<IEnumerable<CollectionCipher>>(),
|
||||
Arg.Any<IEnumerable<CollectionUser>>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,10 +270,8 @@ public class SendEmailOtpRequestValidatorTests
|
||||
// Arrange
|
||||
var otpTokenProvider = Substitute.For<IOtpTokenProvider<DefaultOtpTokenProviderOptions>>();
|
||||
var mailService = Substitute.For<IMailService>();
|
||||
var featureService = Substitute.For<IFeatureService>();
|
||||
|
||||
// Act
|
||||
var validator = new SendEmailOtpRequestValidator(featureService, otpTokenProvider, mailService);
|
||||
var validator = new SendEmailOtpRequestValidator(otpTokenProvider, mailService);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(validator);
|
||||
|
||||
@ -9,9 +9,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.10.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
||||
<PackageReference Include="xunit.v3" Version="3.0.1" />
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user