Skip to content

Commit 9ce1ecb

Browse files
[PM-25240] Send Access OTP email in MJML format (#6411)
feat: Add MJML email templates for Send Email OTP feat: Implement MJML-based email templates for Send OTP functionality feat: Add feature flag support for Send Email OTP v2 emails feat: Update email view models and call sites for Send Email OTP fix: Modify the directory structure for MJML templates to have Auth directory for better team ownership fix: Rename `hero.js` to `mj-bw-hero.js` --- Co-authored-by: Todd Martin <[email protected]>
1 parent 6a3fc08 commit 9ce1ecb

File tree

18 files changed

+945
-105
lines changed

18 files changed

+945
-105
lines changed

src/Core/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ public static class FeatureFlagKeys
154154
public const string DisableAlternateLoginMethods = "pm-22110-disable-alternate-login-methods";
155155
public const string PM23174ManageAccountRecoveryPermissionDrivesTheNeedToSetMasterPassword =
156156
"pm-23174-manage-account-recovery-permission-drives-the-need-to-set-master-password";
157+
public const string MJMLBasedEmailTemplates = "mjml-based-email-templates";
157158

158159
/* Autofill Team */
159160
public const string IdpAutoSubmitLogin = "idp-auto-submit-login";

src/Core/MailTemplates/Handlebars/Auth/SendAccessEmailOtpEmailv2.html.hbs

Lines changed: 675 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{{#>BasicTextLayout}}
2+
Verify your email to access this Bitwarden Send.
3+
4+
Your verification code is: {{Token}}
5+
6+
This code can only be used once and expires in {{Expiry}} minutes. After that you'll need to verify your email again.
7+
8+
Bitwarden Send transmits sensitive, temporary information to others easily and securely. Learn more about Bitwarden Send or sign up to try it today.
9+
{{/BasicTextLayout}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"packages": [
3-
"components/hero"
3+
"components/mj-bw-hero"
44
]
55
}

src/Core/MailTemplates/Mjml/components/footer.mjml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,38 @@
22
<mj-column>
33
<mj-social icon-size="30px" inner-padding="10px" padding="0">
44
<mj-social-element
5-
href="https://twitter.com/bitwarden"
6-
src="https://bitwarden.com/images/mail-twitter.png"
5+
href="https://x.com/bitwarden"
6+
src="https://assets.bitwarden.com/email/v1/mail-x.png"
77
></mj-social-element>
88

99
<mj-social-element
1010
href="https://www.reddit.com/r/Bitwarden/"
11-
src="https://bitwarden.com/images/mail-reddit.png"
11+
src="https://assets.bitwarden.com/email/v1/mail-reddit.png"
1212
></mj-social-element>
1313

1414
<mj-social-element
1515
href="https://community.bitwarden.com/"
16-
src="https://bitwarden.com/images/mail-discourse.png"
16+
src="https://assets.bitwarden.com/email/v1/mail-discourse.png"
1717
></mj-social-element>
1818

1919
<mj-social-element
2020
href="https://github.com/bitwarden"
21-
src="https://bitwarden.com/images/mail-github.png"
21+
src="https://assets.bitwarden.com/email/v1/mail-github.png"
2222
></mj-social-element>
2323

2424
<mj-social-element
2525
href="https://www.youtube.com/channel/UCId9a_jQqvJre0_dE2lE_Rw"
26-
src="https://bitwarden.com/images/mail-youtube.png"
26+
src="https://assets.bitwarden.com/email/v1/mail-youtube.png"
2727
></mj-social-element>
2828

2929
<mj-social-element
3030
href="https://www.linkedin.com/company/bitwarden1/"
31-
src="https://bitwarden.com/images/mail-linkedin.png"
31+
src="https://assets.bitwarden.com/email/v1/mail-linkedin.png"
3232
></mj-social-element>
3333

3434
<mj-social-element
3535
href="https://www.facebook.com/bitwarden/"
36-
src="https://bitwarden.com/images/mail-facebook.png"
36+
src="https://assets.bitwarden.com/email/v1/mail-facebook.png"
3737
></mj-social-element>
3838
</mj-social>
3939

@@ -45,8 +45,8 @@
4545
<p style="margin-top: 5px">
4646
Always confirm you are on a trusted Bitwarden domain before logging
4747
in:<br />
48-
<a href="#">bitwarden.com</a> |
49-
<a href="#">Learn why we include this</a>
48+
<a href="https://bitwarden.com/">bitwarden.com</a> |
49+
<a href="https://bitwarden.com/help/emails-from-bitwarden/">Learn why we include this</a>
5050
</p>
5151
</mj-text>
5252
</mj-column>

src/Core/MailTemplates/Mjml/components/head.mjml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
font-size="16px"
55
/>
66
<mj-button background-color="#175ddc" />
7-
<mj-text color="#333" />
7+
<mj-text color="#1B2029" />
88
<mj-body background-color="#e6e9ef" width="660px" />
99
</mj-attributes>
1010
<mj-style inline="inline">
@@ -22,3 +22,9 @@
2222
border-radius: 3px;
2323
}
2424
</mj-style>
25+
26+
<!-- Responsive icon visibility -->
27+
<mj-style>
28+
@media only screen and
29+
(max-width: 480px) { .hide-small-img { display: none !important; } .send-bubble { padding-left: 20px; padding-right: 20px; width: 90% !important; } }
30+
</mj-style>

src/Core/MailTemplates/Mjml/components/hero.js

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<mj-section border-radius="0px 0px 4px 4px" background-color="#f6f6f6" padding="5px 20px 10px 20px">
2+
<mj-column width="70%">
3+
<mj-text line-height="24px">
4+
<h3 style="font-size: 20px; margin: 0; line-height: 28px">
5+
Learn more about Bitwarden
6+
</h3>
7+
Find user guides, product documentation, and videos on the
8+
<a href="https://bitwarden.com/help/" class="link"> Bitwarden Help Center</a>.
9+
</mj-text>
10+
</mj-column>
11+
<mj-column width="30%">
12+
<mj-image
13+
src="https://assets.bitwarden.com/email/v1/spot-community.png"
14+
css-class="hide-small-img"
15+
width="94px"
16+
/>
17+
</mj-column>
18+
</mj-section>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
const { BodyComponent } = require("mjml-core");
2+
class MjBwHero extends BodyComponent {
3+
static dependencies = {
4+
// Tell the validator which tags are allowed as our component's parent
5+
"mj-column": ["mj-bw-hero"],
6+
"mj-wrapper": ["mj-bw-hero"],
7+
// Tell the validator which tags are allowed as our component's children
8+
"mj-bw-hero": [],
9+
};
10+
11+
static allowedAttributes = {
12+
"img-src": "string", // REQUIRED: Source for the image displayed in the right-hand side of the blue header area
13+
title: "string", // REQUIRED: large text stating primary purpose of the email
14+
"button-text": "string", // OPTIONAL: text to display in the button
15+
"button-url": "string", // OPTIONAL: URL to navigate to when the button is clicked
16+
"sub-title": "string", // OPTIONAL: smaller text providing additional context for the title
17+
};
18+
19+
static defaultAttributes = {};
20+
21+
render() {
22+
if (this.getAttribute("button-text") && this.getAttribute("button-url")) {
23+
return this.renderMJML(`
24+
<mj-section
25+
full-width="full-width"
26+
background-color="#175ddc"
27+
border-radius="4px 4px 0px 0px"
28+
>
29+
<mj-column width="70%">
30+
<mj-image
31+
align="left"
32+
src="https://bitwarden.com/images/logo-horizontal-white.png"
33+
width="150px"
34+
height="30px"
35+
></mj-image>
36+
<mj-text color="#fff" padding-top="0" padding-bottom="0">
37+
<h1 style="font-weight: normal; font-size: 24px; line-height: 32px">
38+
${this.getAttribute("title")}
39+
</h1>
40+
</mj-text>
41+
<mj-button
42+
href="${this.getAttribute("button-url")}"
43+
background-color="#fff"
44+
color="#1A41AC"
45+
border-radius="20px"
46+
align="left"
47+
>
48+
${this.getAttribute("button-text")}
49+
</mj-button
50+
>
51+
</mj-column>
52+
<mj-column width="30%" vertical-align="bottom">
53+
<mj-image
54+
src="${this.getAttribute("img-src")}"
55+
alt=""
56+
width="140px"
57+
height="140px"
58+
padding="0px"
59+
css-class="hide-small-img"
60+
/>
61+
</mj-column>
62+
</mj-section>
63+
`);
64+
} else {
65+
return this.renderMJML(`
66+
<mj-section
67+
full-width="full-width"
68+
background-color="#175ddc"
69+
border-radius="4px 4px 0px 0px"
70+
>
71+
<mj-column width="70%">
72+
<mj-image
73+
align="left"
74+
src="https://bitwarden.com/images/logo-horizontal-white.png"
75+
width="150px"
76+
height="30px"
77+
></mj-image>
78+
<mj-text color="#fff" padding-top="0" padding-bottom="0">
79+
<h1 style="font-weight: normal; font-size: 24px; line-height: 32px">
80+
${this.getAttribute("title")}
81+
</h1>
82+
</mj-text>
83+
</mj-column>
84+
<mj-column width="30%" vertical-align="bottom">
85+
<mj-image
86+
src="${this.getAttribute("img-src")}"
87+
alt=""
88+
width="140px"
89+
height="140px"
90+
padding="0px"
91+
css-class="hide-small-img"
92+
/>
93+
</mj-column>
94+
</mj-section>
95+
`);
96+
}
97+
}
98+
}
99+
100+
module.exports = MjBwHero;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<mjml>
2+
<mj-head>
3+
<mj-include path="../../components/head.mjml" />
4+
<mj-style> </mj-style>
5+
</mj-head>
6+
7+
<mj-body css-class="border-fix">
8+
<!-- Blue Header Section -->
9+
<mj-wrapper css-class="border-fix" padding="20px 20px 10px 20px">
10+
<mj-bw-hero
11+
img-src="https://assets.bitwarden.com/email/v1/spot-secure-send-round.png"
12+
title="Verify your email to access this Bitwarden Send"
13+
/>
14+
</mj-wrapper>
15+
16+
<!-- Main Content -->
17+
<mj-wrapper padding="5px 20px 10px 20px">
18+
<mj-section background-color="#fff">
19+
<mj-column padding="0px">
20+
<mj-text> Your verification code is: </mj-text>
21+
<mj-text font-size="32px"> <b>{{Token}}</b> </mj-text>
22+
<mj-spacer height="20px" />
23+
<mj-text>
24+
This code expires in {{Expiry}} minutes. After that, you'll need to
25+
verify your email again.
26+
</mj-text>
27+
</mj-column>
28+
</mj-section>
29+
<mj-section
30+
background-color="#fff"
31+
padding="0px 0px 20px 0px"
32+
>
33+
<mj-column
34+
css-class="send-bubble"
35+
width="90%"
36+
inner-background-color="#DBE5F6"
37+
inner-border-radius="16px"
38+
padding="0px"
39+
>
40+
<mj-text>
41+
<p>
42+
Bitwarden Send transmits sensitive, temporary information to
43+
others easily and securely. Learn more about
44+
<a href="https://bitwarden.com/help/send" class="link"
45+
>Bitwarden Send</a
46+
>
47+
or
48+
<a href="https://bitwarden.com/signup" class="link">sign up</a>
49+
to try it today.
50+
</p>
51+
</mj-text>
52+
</mj-column>
53+
</mj-section>
54+
</mj-wrapper>
55+
56+
<!-- Learn More Section -->
57+
<mj-wrapper padding="5px 20px 10px 20px">
58+
<mj-include path="../../components/learn-more-footer.mjml" />
59+
</mj-wrapper>
60+
61+
<!-- Footer -->
62+
<mj-include path="../../components/footer.mjml" />
63+
</mj-body>
64+
</mjml>

0 commit comments

Comments
 (0)