1
0
mirror of https://github.com/bitwarden/server synced 2026-02-14 15:33:35 +00:00

[PM-30610] Address design feedback for the organization confirmation email templates. (#6873)

This commit is contained in:
Jimmy Vo
2026-02-13 12:34:29 -05:00
committed by GitHub
parent bf9cc01459
commit ea2b9b73c2
9 changed files with 2049 additions and 1768 deletions

View File

@@ -4,6 +4,9 @@
"components/mj-bw-simple-hero",
"components/mj-bw-icon-row",
"components/mj-bw-learn-more-footer",
"emails/AdminConsole/components/mj-bw-inviter-info"
"emails/AdminConsole/components/mj-bw-inviter-info",
"emails/AdminConsole/components/mj-bw-ac-hero",
"emails/AdminConsole/components/mj-bw-ac-icon-row",
"emails/AdminConsole/components/mj-bw-ac-learn-more-footer"
]
}

View File

@@ -1,50 +1,51 @@
<mjml>
<mj-head>
<mj-include path="../../../components/head.mjml" />
</mj-head>
<mj-head>
<!-- Include shared head styles -->
<mj-include path="../../../components/head.mjml" />
<mj-body css-class="border-fix">
<!-- Blue Header Section -->
<mj-wrapper css-class="border-fix" padding="20px 20px 10px 20px">
<mj-bw-hero
img-src="https://assets.bitwarden.com/email/v1/spot-enterprise.png"
title="You can now share passwords with members of <b>{{OrganizationName}}!</b>"
button-text="<b>Log in</b>"
button-url="{{WebVaultUrl}}"
/>
</mj-wrapper>
<!-- Main Content -->
<mj-wrapper padding="5px 20px 10px 20px">
<mj-section background-color="#fff" padding="15px 10px 10px 10px">
<mj-column>
<mj-text font-size="16px" line-height="24px" padding="10px 15px">
As a member of <b>{{OrganizationName}}</b>:
</mj-text>
</mj-column>
</mj-section>
<mj-bw-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-enterprise.png"
icon-alt="Organization Icon"
text="Your account is owned by {{OrganizationName}} and is subject to their security and management policies."
/>
<mj-bw-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-account-switching-new.png"
icon-alt="Group Users Icon"
text="You can easily access and share passwords with your team."
foot-url-text="Share passwords in Bitwarden"
foot-url="https://bitwarden.com/help/sharing"
/>
<mj-section background-color="#fff" padding="0 20px 20px 20px">
</mj-section>
</mj-wrapper>
</mj-head>
<!-- Learn More Section -->
<mj-wrapper padding="5px 20px 10px 20px">
<mj-bw-learn-more-footer />
</mj-wrapper>
<mj-body>
<!-- Blue Header Section -->
<mj-wrapper css-class="border-fix" padding="20px 20px 10px 20px">
<mj-bw-ac-hero
title="You can now share passwords with members of <b>{{OrganizationName}}!</b>"
img-src="https://assets.bitwarden.com/email/v1/ac-spot-enterprise.png"
button-text="<b>Log in</b>"
button-url="{{WebVaultUrl}}"
/>
</mj-wrapper>
<!-- Footer -->
<mj-include path="../../../components/footer.mjml" />
</mj-body>
<!-- Main Content -->
<mj-wrapper padding="5px 20px 8px 20px">
<mj-section background-color="#fff" padding="10px 10px 16px 10px">
<mj-column>
<mj-text font-size="16px" line-height="24px" padding="15px 15px 0px 15px">
As a member of <b>{{OrganizationName}}</b>:
</mj-text>
</mj-column>
</mj-section>
<mj-bw-ac-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-enterprise.png"
icon-alt="Organization Icon"
text="Your account is owned by {{OrganizationName}} and is subject to their security and management policies."
/>
<mj-bw-ac-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-account-switching-new.png"
icon-alt="Share Icon"
text="You can easily access and share passwords with your team."
foot-url-text="Share passwords in Bitwarden"
foot-url="https://bitwarden.com/help/sharing"
/>
</mj-wrapper>
<!-- Learn More Section -->
<mj-wrapper padding="8px 20px 10px 20px">
<mj-bw-ac-learn-more-footer />
</mj-wrapper>
<!-- Footer -->
<mj-include path="../../../components/footer.mjml" />
</mj-body>
</mjml>

View File

@@ -1,55 +1,104 @@
<mjml>
<mj-head>
<mj-include path="../../../components/head.mjml" />
</mj-head>
<mj-head>
<!-- Include shared head styles -->
<mj-include path="../../../components/head.mjml" />
<mj-body css-class="border-fix">
<!-- Blue Header Section -->
<mj-wrapper css-class="border-fix" padding="20px 20px 10px 20px">
<mj-bw-hero
img-src="https://assets.bitwarden.com/email/v1/spot-family-homes.png"
title="You can now share passwords with members of <b>{{OrganizationName}}!</b>"
button-text="<b>Log in</b>"
button-url="{{WebVaultUrl}}"
/>
</mj-wrapper>
<!-- Include admin console shared styles --><mj-include path="../components/admin-console-head.mjml" />
</mj-head>
<!-- Main Content -->
<mj-wrapper padding="5px 20px 10px 20px">
<mj-section background-color="#fff" padding="15px 10px 10px 10px">
<mj-column>
<mj-text font-size="16px" line-height="24px" padding="10px 15px">
As a member of <b>{{OrganizationName}}</b>:
</mj-text>
</mj-column>
</mj-section>
<mj-bw-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-item-type.png"
icon-alt="Collections Icon"
text="You can access passwords {{OrganizationName}} has shared with you."
/>
<mj-bw-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-account-switching-new.png"
icon-alt="Group Users Icon"
text="You can easily share passwords with friends, family, or coworkers."
foot-url-text="Share passwords in Bitwarden"
foot-url="https://bitwarden.com/help/sharing"
/>
<mj-section background-color="#fff" padding="0 20px 20px 20px">
</mj-section>
</mj-wrapper>
<mj-body>
<!-- Blue Header Section -->
<mj-wrapper css-class="border-fix" padding="20px 20px 10px 20px">
<mj-bw-ac-hero
title="You can now share passwords with members of <b>{{OrganizationName}}!</b>"
img-src="https://assets.bitwarden.com/email/v1/ac-spot-family.png"
button-text="<b>Log in</b>"
button-url="{{WebVaultUrl}}">
</mj-bw-ac-hero>
</mj-wrapper>
<!-- Download Mobile Apps Section -->
<mj-wrapper padding="5px 20px 10px 20px">
<mj-include path="../components/mobile-app-download.mjml" />
</mj-wrapper>
<!-- Main Content -->
<mj-wrapper padding="5px 20px 8px 20px">
<mj-section background-color="#fff" padding="10px 10px 16px 10px">
<mj-column>
<mj-text font-size="16px" line-height="24px" padding="15px 15px 0px 15px">
As a member of <b>{{OrganizationName}}</b>:
</mj-text>
</mj-column>
</mj-section>
<mj-bw-ac-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-item-type.png"
icon-alt="Group Users Icon"
text="You can access passwords {{OrganizationName}} has shared with you.">
</mj-bw-ac-icon-row>
<mj-bw-ac-icon-row
icon-src="https://assets.bitwarden.com/email/v1/icon-account-switching-new.png"
icon-alt="Share Icon"
text="You can easily share passwords with friends, family, or coworkers."
foot-url-text="Share passwords in Bitwarden"
foot-url="https://bitwarden.com/help/sharing">
</mj-bw-ac-icon-row>
</mj-wrapper>
<!-- Learn More Section -->
<mj-wrapper padding="5px 20px 10px 20px">
<mj-bw-learn-more-footer />
</mj-wrapper>
<!-- Download Mobile Apps Section -->
<mj-wrapper padding="8px 20px 10px 20px">
<mj-section background-color="#fff" padding="32px 10px 0px 25px">
<mj-column>
<mj-text
font-size="18px"
font-weight="500"
line-height="24px"
padding="0 0 16px 0">
Download Bitwarden on all devices
</mj-text>
<!-- Footer -->
<mj-include path="../../../components/footer.mjml" />
</mj-body>
<mj-text
mj-class="ac-text"
padding="0 0 24px 0">
Already using the <a href="https://bitwarden.com/download/" class="link">browser extension</a>?
Download the Bitwarden mobile app from the
<a href="https://apps.apple.com/us/app/bitwarden-password-manager/id1137397744" class="link">App Store</a>
or <a href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden" class="link">Google Play</a>
to quickly save logins and autofill forms on the go.
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#fff" padding="0 10px 32px 25px">
<mj-group>
<mj-column width="159px">
<mj-image
css-class="hide-mobile"
href="https://apps.apple.com/us/app/bitwarden-password-manager/id1137397744"
src="https://assets.bitwarden.com/email/v1/ac-apple-store.png"
alt="Download on the App Store"
width="135px"
height="40px"
padding="0 24px 0 0"
/>
</mj-column>
<mj-column width="140px">
<mj-image
css-class="hide-mobile"
href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden"
src="https://assets.bitwarden.com/email/v1/ac-google-play.png"
alt="Get it on Google Play"
width="140px"
height="40px"
padding="0"
/>
</mj-column>
</mj-group>
</mj-section>
</mj-wrapper>
<!-- Learn More Section -->
<mj-wrapper padding="8px 20px 10px 20px">
<mj-bw-ac-learn-more-footer />
</mj-wrapper>
<!-- Footer -->
<mj-include path="../../../components/footer.mjml" />
</mj-body>
</mjml>

View File

@@ -0,0 +1,17 @@
<mj-attributes>
<mj-all
font-family="'Helvetica Neue','Inter',Helvetica,Arial,sans-serif" />
<mj-class
name="ac-text"
font-size="16px"
font-weight="400"
line-height="24px"
/>
</mj-attributes>
<mj-style>
@media only screen and (max-width: 480px) {
.hide-mobile { display: none !important; }
}
</mj-style>

View File

@@ -0,0 +1,92 @@
const { BodyComponent } = require("mjml-core");
class MjBwAcHero extends BodyComponent {
static dependencies = {
// Tell the validator which tags are allowed as our component's parent
"mj-column": ["mj-bw-ac-hero"],
"mj-wrapper": ["mj-bw-ac-hero"],
// Tell the validator which tags are allowed as our component's children
"mj-bw-ac-hero": [],
};
static allowedAttributes = {
"img-src": "string", // REQUIRED: Source for the image displayed in the right-hand side of the blue header area
title: "string", // REQUIRED: large text stating primary purpose of the email
"button-text": "string", // OPTIONAL: text to display in the button
"button-url": "string", // OPTIONAL: URL to navigate to when the button is clicked
"sub-title": "string", // OPTIONAL: smaller text providing additional context for the title
};
static defaultAttributes = {};
componentHeadStyle = breakpoint => {
return `
@media only screen and (max-width:${breakpoint}) {
.mj-bw-ac-hero-responsive-img {
display: none !important;
}
}
`
}
render() {
const buttonElement = this.getAttribute("button-text") && this.getAttribute("button-url") ?
`<mj-button
href="${this.getAttribute("button-url")}"
background-color="#fff"
color="#1A41AC"
border-radius="20px"
align="left"
inner-padding="12px 24px"
>
${this.getAttribute("button-text")}
</mj-button
>` : "";
const subTitleElement = this.getAttribute("sub-title") ?
`<mj-text color="#fff" padding-top="0" padding-bottom="0">
<h2 style="font-weight: normal; font-size: 16px; line-height: 0px">
${this.getAttribute("sub-title")}
</h2>
</mj-text>` : "";
return this.renderMJML(
`
<mj-section
full-width="full-width"
background-color="#175ddc"
border-radius="4px 4px 0px 0px"
>
<mj-column width="70%">
<mj-image
align="left"
src="https://bitwarden.com/images/logo-horizontal-white.png"
width="150px"
height="30px"
></mj-image>
<mj-text color="#fff" padding-top="0" padding-bottom="0">
<h1 style="font-weight: 400; font-size: 24px; line-height: 32px">
${this.getAttribute("title")}
</h1>
` +
subTitleElement +
`
</mj-text>` +
buttonElement +
`
</mj-column>
<mj-column width="30%" vertical-align="bottom">
<mj-image
src="${this.getAttribute("img-src")}"
alt=""
width="155px"
padding="0px 20px 0px 0px"
align="right"
css-class="mj-bw-ac-hero-responsive-img"
/>
</mj-column>
</mj-section>
`,
);
}
}
module.exports = MjBwAcHero;

View File

@@ -0,0 +1,103 @@
const { BodyComponent } = require("mjml-core");
const BODY_TEXT_STYLES = `
font-family="'Helvetica Neue', Helvetica, Arial, sans-serif"
font-size="16px"
font-weight="400"
line-height="24px"
`;
class MjBwAcIconRow extends BodyComponent {
static dependencies = {
"mj-column": ["mj-bw-ac-icon-row"],
"mj-wrapper": ["mj-bw-ac-icon-row"],
"mj-bw-ac-icon-row": [],
};
static allowedAttributes = {
"icon-src": "string",
"icon-alt": "string",
"head-url-text": "string",
"head-url": "string",
text: "string",
"foot-url-text": "string",
"foot-url": "string",
};
static defaultAttributes = {};
headStyle = (breakpoint) => {
return `
@media only screen and (max-width:${breakpoint}) {
.mj-bw-ac-icon-row-text {
padding-left: 15px !important;
padding-right: 15px !important;
line-height: 20px;
}
.mj-bw-ac-icon-row-icon {
display: none !important;
width: 0 !important;
max-width: 0 !important;
}
.mj-bw-ac-icon-row-text-column {
width: 100% !important;
}
}
`;
};
render() {
const headAnchorElement =
this.getAttribute("head-url-text") && this.getAttribute("head-url")
? `
<mj-text css-class="mj-bw-ac-icon-row-text" padding="5px 10px 0px 10px" ${BODY_TEXT_STYLES}>
<a href="${this.getAttribute("head-url")}" class="link">
${this.getAttribute("head-url-text")}
<span style="text-decoration: none">
<img src="https://assets.bitwarden.com/email/v1/bwi-external-link-16px.png"
alt="External Link Icon"
width="16px"
style="vertical-align: middle;"
/>
</span>
</a>
</mj-text>`
: "";
const footAnchorElement =
this.getAttribute("foot-url-text") && this.getAttribute("foot-url")
? `<mj-text css-class="mj-bw-ac-icon-row-text" padding="0px" ${BODY_TEXT_STYLES}>
<a href="${this.getAttribute("foot-url")}" class="link">
${this.getAttribute("foot-url-text")}
</a>
</mj-text>`
: "";
return this.renderMJML(
`
<mj-section background-color="#fff" padding="0px 10px 24px 10px">
<mj-group css-class="mj-bw-ac-icon-row">
<mj-column width="15%" vertical-align="middle" css-class="mj-bw-ac-icon-row-icon">
<mj-image
src="${this.getAttribute("icon-src")}"
alt="${this.getAttribute("icon-alt")}"
width="48px"
padding="0px 10px 0px 5px"
border-radius="8px"
/>
</mj-column>
<mj-column width="85%" vertical-align="middle" css-class="mj-bw-ac-icon-row-text-column">
${headAnchorElement}
<mj-text css-class="mj-bw-ac-icon-row-text" padding="0px 0px 0px 0px" ${BODY_TEXT_STYLES}>
${this.getAttribute("text")}
</mj-text>
${footAnchorElement}
</mj-column>
</mj-group>
</mj-section>
`,
);
}
}
module.exports = MjBwAcIconRow;

View File

@@ -0,0 +1,55 @@
const { BodyComponent } = require("mjml-core");
class MjBwAcLearnMoreFooter extends BodyComponent {
static dependencies = {
// Tell the validator which tags are allowed as our component's parent
"mj-column": ["mj-bw-ac-learn-more-footer"],
"mj-wrapper": ["mj-bw-ac-learn-more-footer"],
// Tell the validator which tags are allowed as our component's children
"mj-bw-ac-learn-more-footer": [],
};
static allowedAttributes = {};
static defaultAttributes = {};
componentHeadStyle = (breakpoint) => {
return `
@media only screen and (max-width:${breakpoint}) {
.mj-bw-ac-learn-more-footer-responsive-img {
display: none !important;
}
}
`;
};
render() {
return this.renderMJML(
`
<mj-section border-radius="0px 0px 4px 4px" background-color="#F3F6F9" padding="14px 10px 14px 10px">
<mj-column width="70%">
<mj-text padding="10px 15px 10px 15px">
<p style="font-size: 18px; line-height: 28px; font-weight: 500; margin: 0 0 8px 0;">
Learn more about Bitwarden
</p>
<p style="font-size: 16px; line-height: 24px; margin: 0;">
Find user guides, product documentation, and videos on the
<a href="https://bitwarden.com/help/" class="link"> Bitwarden Help Center</a>.
</p>
</mj-text>
</mj-column>
<mj-column width="30%" vertical-align="bottom">
<mj-image
src="https://assets.bitwarden.com/email/v1/spot-community.png"
css-class="mj-bw-ac-learn-more-footer-responsive-img"
width="94px"
padding="0px 15px 0px 0px"
align="right"
/>
</mj-column>
</mj-section>
`,
);
}
}
module.exports = MjBwAcLearnMoreFooter;