From 22b0b95209f0630974fe51fd5ed58d40bc424ae1 Mon Sep 17 00:00:00 2001 From: TheMardy <36103454+TheMardy@users.noreply.github.com> Date: Sun, 10 Feb 2019 15:50:40 +0100 Subject: [PATCH 1/3] Added HTML templates (+14 squashed commit) Squashed commit: [ece2260] Plaintext send_org_invite [01d4884] Plaintext pw_hint_some [6ce5173] Plaintext pw_hint_none [881af3e] Plaintext invite_confirmed [ce78621] Plaintext invite_accepted [13a44a4] Rename send_org_invite.hbs to send_org_invite.html.hbs [b52bf2f] Rename pw_hint_some.hbs to pw_hint_some.html.hbs [e0d1aeb] Rename pw_hint_none.hbs to pw_hint_none.html.hbs [898dbcd] Rename invite_confirmed.hbs to invite_confirmed.html.hbs [107af31] Rename invite_accepted.hbs to invite_accepted.html.hbs [d26d662] Updated send_org_invite template [71f47af] Updated pw_hint_some template [c2ca3c2] Updated pw_hint_none template [50f8bfb] Updated invite_accepted template [17f96f8] Updated invite_confirmed template --- .../templates/email/invite_accepted.html.hbs | 138 +++++++++++++++++ .../templates/email/invite_confirmed.hbs | 2 +- .../templates/email/invite_confirmed.html.hbs | 134 +++++++++++++++++ .../templates/email/pw_hint_none.html.hbs | 133 +++++++++++++++++ .../templates/email/pw_hint_some.html.hbs | 139 +++++++++++++++++ .../templates/email/send_org_invite.html.hbs | 140 ++++++++++++++++++ 6 files changed, 685 insertions(+), 1 deletion(-) create mode 100644 src/static/templates/email/invite_accepted.html.hbs create mode 100644 src/static/templates/email/invite_confirmed.html.hbs create mode 100644 src/static/templates/email/pw_hint_none.html.hbs create mode 100644 src/static/templates/email/pw_hint_some.html.hbs create mode 100644 src/static/templates/email/send_org_invite.html.hbs diff --git a/src/static/templates/email/invite_accepted.html.hbs b/src/static/templates/email/invite_accepted.html.hbs new file mode 100644 index 00000000..71b8d174 --- /dev/null +++ b/src/static/templates/email/invite_accepted.html.hbs @@ -0,0 +1,138 @@ +Invitation accepted + + + + + + Bitwarden_rs + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + +
+ This email is to notify you that {{email}} has accepted your invitation to join {{org_name}}. +
+ Please log in to the bitwarden_rs server and confirm them from the organization management page. +
+ If you do not wish to confirm this user, you can also remove them from the organization on the same page. +
+
+ + + + + +
+
+ + diff --git a/src/static/templates/email/invite_confirmed.hbs b/src/static/templates/email/invite_confirmed.hbs index 7fc7db78..26704bba 100644 --- a/src/static/templates/email/invite_confirmed.hbs +++ b/src/static/templates/email/invite_confirmed.hbs @@ -5,4 +5,4 @@ Invitation to {{org_name}} confirmed Your invitation to join {{org_name}} was confirmed. It will now appear under the Organizations the next time you log in to the web vault.

- \ No newline at end of file + diff --git a/src/static/templates/email/invite_confirmed.html.hbs b/src/static/templates/email/invite_confirmed.html.hbs new file mode 100644 index 00000000..746f96ed --- /dev/null +++ b/src/static/templates/email/invite_confirmed.html.hbs @@ -0,0 +1,134 @@ +Invitation to {{org_name}} confirmed + + + + + + Bitwarden_rs + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + + +
+ This email is to notify you that you have been confirmed as a user of {{org_name}}. +
+ Any collections and logins being shared with you by this organization will now appear in your Bitwarden vault.
+ Log in +
+
+ + + + + +
+
+ + diff --git a/src/static/templates/email/pw_hint_none.html.hbs b/src/static/templates/email/pw_hint_none.html.hbs new file mode 100644 index 00000000..4b97e57f --- /dev/null +++ b/src/static/templates/email/pw_hint_none.html.hbs @@ -0,0 +1,133 @@ +Sorry, you have no password hint... + + + + + + Bitwarden_rs + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + + +
+ You (or someone) recently requested your master password hint. Unfortunately, your account does not have a master password hint.
+
+ If you did not request your master password hint you can safely ignore this email. +
+
+ + + + + +
+
+ + diff --git a/src/static/templates/email/pw_hint_some.html.hbs b/src/static/templates/email/pw_hint_some.html.hbs new file mode 100644 index 00000000..44cb3856 --- /dev/null +++ b/src/static/templates/email/pw_hint_some.html.hbs @@ -0,0 +1,139 @@ +Your master password hint + + + + + + Bitwarden_rs + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + +
+ You (or someone) recently requested your master password hint. +
+ Your hint is: "{{hint}}"
+ Log in: Web Vault +
+ If you did not request your master password hint you can safely ignore this email. +
+
+ + + + + +
+
+ + diff --git a/src/static/templates/email/send_org_invite.html.hbs b/src/static/templates/email/send_org_invite.html.hbs new file mode 100644 index 00000000..0d8f32a1 --- /dev/null +++ b/src/static/templates/email/send_org_invite.html.hbs @@ -0,0 +1,140 @@ +Join {{org_name}} + + + + + + Bitwarden_rs + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + +
+ You have been invited to join the {{org_name}} organization. +
+ + Join Organization Now + +
+ If you do not wish to join this organization, you can safely ignore this email. +
+
+ + + + + +
+
+ + From d086a99e5bf6cb4f3c27f82904c5619f8325d53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Sun, 10 Feb 2019 19:12:34 +0100 Subject: [PATCH 2/3] Implemented HTML emails with text alternative --- src/config.rs | 14 +++++++++----- src/mail.rs | 33 +++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/config.rs b/src/config.rs index c6c0e18e..d7839a8e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -426,14 +426,18 @@ fn load_templates(path: &str) -> Handlebars { let template = include_str!(concat!("static/templates/", $name, ".hbs")); hb.register_template_string($name, template).unwrap(); }}; + ($name:expr, $ext:expr) => {{ + reg!($name); + reg!(concat!($name, $ext)); + }}; } // First register default templates here - reg!("email/invite_accepted"); - reg!("email/invite_confirmed"); - reg!("email/pw_hint_none"); - reg!("email/pw_hint_some"); - reg!("email/send_org_invite"); + reg!("email/invite_accepted", ".html"); + reg!("email/invite_confirmed", ".html"); + reg!("email/pw_hint_none", ".html"); + reg!("email/pw_hint_some", ".html"); + reg!("email/send_org_invite", ".html"); reg!("admin/base"); reg!("admin/login"); diff --git a/src/mail.rs b/src/mail.rs index 468fa37d..fb4cb9c4 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -36,8 +36,14 @@ fn mailer() -> SmtpTransport { .transport() } -fn get_text(template_name: &'static str, data: serde_json::Value) -> Result<(String, String), Error> { - let text = CONFIG.render_template(template_name, &data)?; +fn get_text(template_name: &'static str, data: serde_json::Value) -> Result<(String, String, String), Error> { + let (subject_html, body_html) = get_template(&format!("{}.html", template_name), &data)?; + let (_subject_text, body_text) = get_template(template_name, &data)?; + Ok((subject_html, body_html, body_text)) +} + +fn get_template(template_name: &str, data: &serde_json::Value) -> Result<(String, String), Error> { + let text = CONFIG.render_template(template_name, data)?; let mut text_split = text.split(""); let subject = match text_split.next() { @@ -60,9 +66,9 @@ pub fn send_password_hint(address: &str, hint: Option) -> EmptyResult { "email/pw_hint_none" }; - let (subject, body) = get_text(template_name, json!({ "hint": hint }))?; - - send_email(&address, &subject, &body) + let (subject, body_html, body_text) = get_text(template_name, json!({ "hint": hint }))?; + + send_email(&address, &subject, &body_html, &body_text) } pub fn send_invite( @@ -82,7 +88,7 @@ pub fn send_invite( ); let invite_token = encode_jwt(&claims); - let (subject, body) = get_text( + let (subject, body_html, body_text) = get_text( "email/send_org_invite", json!({ "url": CONFIG.domain(), @@ -94,11 +100,11 @@ pub fn send_invite( }), )?; - send_email(&address, &subject, &body) + send_email(&address, &subject, &body_html, &body_text) } pub fn send_invite_accepted(new_user_email: &str, address: &str, org_name: &str) -> EmptyResult { - let (subject, body) = get_text( + let (subject, body_html, body_text) = get_text( "email/invite_accepted", json!({ "url": CONFIG.domain(), @@ -107,11 +113,11 @@ pub fn send_invite_accepted(new_user_email: &str, address: &str, org_name: &str) }), )?; - send_email(&address, &subject, &body) + send_email(&address, &subject, &body_html, &body_text) } pub fn send_invite_confirmed(address: &str, org_name: &str) -> EmptyResult { - let (subject, body) = get_text( + let (subject, body_html, body_text) = get_text( "email/invite_confirmed", json!({ "url": CONFIG.domain(), @@ -119,16 +125,15 @@ pub fn send_invite_confirmed(address: &str, org_name: &str) -> EmptyResult { }), )?; - send_email(&address, &subject, &body) + send_email(&address, &subject, &body_html, &body_text) } -fn send_email(address: &str, subject: &str, body: &str) -> EmptyResult { +fn send_email(address: &str, subject: &str, body_html: &str, body_text: &str) -> EmptyResult { let email = EmailBuilder::new() .to(address) .from((CONFIG.smtp_from().as_str(), CONFIG.smtp_from_name().as_str())) .subject(subject) - .header(("Content-Type", "text/html")) - .body(body) + .alternative(body_html, body_text) .build() .map_err(|e| Error::new("Error building email", e.to_string()))?; From 79fdfd6524e929efd8709f5a096afaa385ec3972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Sun, 10 Feb 2019 21:40:20 +0100 Subject: [PATCH 3/3] Add missing url parameter --- src/mail.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mail.rs b/src/mail.rs index fb4cb9c4..731f7bb4 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -66,7 +66,7 @@ pub fn send_password_hint(address: &str, hint: Option) -> EmptyResult { "email/pw_hint_none" }; - let (subject, body_html, body_text) = get_text(template_name, json!({ "hint": hint }))?; + let (subject, body_html, body_text) = get_text(template_name, json!({ "hint": hint, "url": CONFIG.domain() }))?; send_email(&address, &subject, &body_html, &body_text) }