vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

commit 5379329ef71ba4b600eb028d721806a16e62535f
parent 558410c5bdad41232ef9479937ca7b9a65db8463
Author: Daniel GarcĂ­a <dani-garcia@users.noreply.github.com>
Date:   Wed, 18 Nov 2020 16:16:27 +0100

Merge pull request #1229 from BlackDex/email-fixes

Email fixes
Diffstat:
M.env.template | 22+++++++++++++++++++---
MCargo.lock | 72++++++++++++++++++++++++++++++++++++++++++------------------------------
MCargo.toml | 2+-
Msrc/config.rs | 30++++++++++++++++++------------
Msrc/mail.rs | 31++++++++++++++++++++++---------
Msrc/main.rs | 10++++++++++
Msrc/static/templates/admin/settings.hbs | 47+++++++++++++++++++++++++++++++++++++++++------
Msrc/static/templates/email/change_email.hbs | 10++++++----
Msrc/static/templates/email/delete_account.hbs | 18++++++++----------
Msrc/static/templates/email/invite_accepted.hbs | 11+++++------
Msrc/static/templates/email/invite_confirmed.hbs | 11+++++------
Msrc/static/templates/email/new_device_logged_in.hbs | 18++++++++----------
Msrc/static/templates/email/pw_hint_none.hbs | 5++++-
Msrc/static/templates/email/pw_hint_some.hbs | 9++++++---
Msrc/static/templates/email/send_org_invite.hbs | 20++++++++++----------
Msrc/static/templates/email/smtp_test.hbs | 12++++++------
Msrc/static/templates/email/twofactor_email.hbs | 11+++++------
Msrc/static/templates/email/verify_email.hbs | 16+++++++---------
Msrc/static/templates/email/welcome.hbs | 12++++++------
Msrc/static/templates/email/welcome_must_verify.hbs | 18++++++++----------
20 files changed, 237 insertions(+), 148 deletions(-)

diff --git a/.env.template b/.env.template @@ -242,9 +242,9 @@ # SMTP_HOST=smtp.domain.tld # SMTP_FROM=bitwarden-rs@domain.tld # SMTP_FROM_NAME=Bitwarden_RS -# SMTP_PORT=587 -# SMTP_SSL=true # (Explicit) - This variable by default configures Explicit STARTTLS, it will upgrade an insecure connection to a secure one. Unless SMTP_EXPLICIT_TLS is set to true. -# SMTP_EXPLICIT_TLS=true # (Implicit) - N.B. This variable configures Implicit TLS. It's currently mislabelled (see bug #851) - SMTP_SSL Needs to be set to true for this option to work. +# SMTP_PORT=587 # Ports 587 (submission) and 25 (smtp) are standard without encryption and with encryption via STARTTLS (Explicit TLS). Port 465 is outdated and used with Implicit TLS. +# SMTP_SSL=true # (Explicit) - This variable by default configures Explicit STARTTLS, it will upgrade an insecure connection to a secure one. Unless SMTP_EXPLICIT_TLS is set to true. Either port 587 or 25 are default. +# SMTP_EXPLICIT_TLS=true # (Implicit) - N.B. This variable configures Implicit TLS. It's currently mislabelled (see bug #851) - SMTP_SSL Needs to be set to true for this option to work. Usually port 465 is used here. # SMTP_USERNAME=username # SMTP_PASSWORD=password # SMTP_TIMEOUT=15 @@ -259,6 +259,22 @@ ## but might need to be changed in case it trips some anti-spam filters # HELO_NAME= +## SMTP debugging +## When set to true this will output very detailed SMTP messages. +## WARNING: This could contain sensitive information like passwords and usernames! Only enable this during troubleshooting! +# SMTP_DEBUG=false + +## Accept Invalid Hostnames +## DANGEROUS: This option introduces significant vulnerabilities to man-in-the-middle attacks! +## Only use this as a last resort if you are not able to use a valid certificate. +# SMTP_ACCEPT_INVALID_HOSTNAMES=false + +## Accept Invalid Certificates +## DANGEROUS: This option introduces significant vulnerabilities to man-in-the-middle attacks! +## Only use this as a last resort if you are not able to use a valid certificate. +## If the Certificate is valid but the hostname doesn't match, please use SMTP_ACCEPT_INVALID_HOSTNAMES instead. +# SMTP_ACCEPT_INVALID_CERTS=false + ## Require new device emails. When a user logs in an email is required to be sent. ## If sending the email fails the login attempt will fail!! # REQUIRE_DEVICE_EMAIL=false diff --git a/Cargo.lock b/Cargo.lock @@ -34,12 +34,6 @@ dependencies = [ ] [[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -132,6 +126,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] +name = "bitvec" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] name = "bitwarden_rs" version = "1.0.0" dependencies = [ @@ -639,6 +645,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] +name = "funty" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" + +[[package]] name = "futf" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1144,9 +1156,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "lettre" -version = "0.10.0-alpha.3" +version = "0.10.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e422b6c03563bc47db09bb61a8ece4f1462de131455beb96c091e2998fa316a2" +checksum = "dc8c2fc7873920aca23647e5e86d44ff3f40bbc5a5efaab445c9eb0e001c9f71" dependencies = [ "base64 0.13.0", "hostname", @@ -1160,23 +1172,11 @@ dependencies = [ "rand 0.7.3", "regex", "serde", + "tracing", "uuid", ] [[package]] -name = "lexical-core" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616" -dependencies = [ - "arrayvec", - "bitflags", - "cfg-if 0.1.10", - "ryu", - "static_assertions", -] - -[[package]] name = "libc" version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1448,11 +1448,11 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nom" -version = "5.1.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "4489ccc7d668957ddf64af7cd027c081728903afa6479d35da7e99bf5728f75f" dependencies = [ - "lexical-core", + "bitvec", "memchr", "version_check 0.9.2", ] @@ -1979,6 +1979,12 @@ dependencies = [ ] [[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + +[[package]] name = "rand" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2618,12 +2624,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483" [[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] name = "stdweb" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2783,6 +2783,12 @@ dependencies = [ ] [[package]] +name = "tap" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" + +[[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3372,6 +3378,12 @@ dependencies = [ ] [[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] name = "yansi" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -100,7 +100,7 @@ num-traits = "0.2.14" num-derive = "0.3.3" # Email libraries -lettre = { version = "0.10.0-alpha.3", features = ["smtp-transport", "builder", "serde", "native-tls", "hostname"], default-features = false } +lettre = { version = "0.10.0-alpha.4", features = ["smtp-transport", "builder", "serde", "native-tls", "hostname", "tracing"], default-features = false } newline-converter = "0.1.0" # Template library diff --git a/src/config.rs b/src/config.rs @@ -413,29 +413,35 @@ make_config! { /// SMTP Email Settings smtp: _enable_smtp { /// Enabled - _enable_smtp: bool, true, def, true; + _enable_smtp: bool, true, def, true; /// Host - smtp_host: String, true, option; + smtp_host: String, true, option; /// Enable Secure SMTP |> (Explicit) - Enabling this by default would use STARTTLS (Standard ports 587 or 25) - smtp_ssl: bool, true, def, true; + smtp_ssl: bool, true, def, true; /// Force TLS |> (Implicit) - Enabling this would force the use of an SSL/TLS connection, instead of upgrading an insecure one with STARTTLS (Standard port 465) - smtp_explicit_tls: bool, true, def, false; + smtp_explicit_tls: bool, true, def, false; /// Port - smtp_port: u16, true, auto, |c| if c.smtp_explicit_tls {465} else if c.smtp_ssl {587} else {25}; + smtp_port: u16, true, auto, |c| if c.smtp_explicit_tls {465} else if c.smtp_ssl {587} else {25}; /// From Address - smtp_from: String, true, def, String::new(); + smtp_from: String, true, def, String::new(); /// From Name - smtp_from_name: String, true, def, "Bitwarden_RS".to_string(); + smtp_from_name: String, true, def, "Bitwarden_RS".to_string(); /// Username - smtp_username: String, true, option; + smtp_username: String, true, option; /// Password - smtp_password: Pass, true, option; + smtp_password: Pass, true, option; /// SMTP Auth mechanism |> Defaults for SSL is "Plain" and "Login" and nothing for Non-SSL connections. Possible values: ["Plain", "Login", "Xoauth2"]. Multiple options need to be separated by a comma ','. - smtp_auth_mechanism: String, true, option; + smtp_auth_mechanism: String, true, option; /// SMTP connection timeout |> Number of seconds when to stop trying to connect to the SMTP server - smtp_timeout: u64, true, def, 15; + smtp_timeout: u64, true, def, 15; /// Server name sent during HELO |> By default this value should be is on the machine's hostname, but might need to be changed in case it trips some anti-spam filters - helo_name: String, true, option; + helo_name: String, true, option; + /// Enable SMTP debugging (Know the risks!) |> DANGEROUS: Enabling this will output very detailed SMTP messages. This could contain sensitive information like passwords and usernames! Only enable this during troubleshooting! + smtp_debug: bool, true, def, false; + /// Accept Invalid Certs (Know the risks!) |> DANGEROUS: Allow invalid certificates. This option introduces significant vulnerabilities to man-in-the-middle attacks! + smtp_accept_invalid_certs: bool, true, def, false; + /// Accept Invalid Hostnames (Know the risks!) |> DANGEROUS: Allow invalid hostnames. This option introduces significant vulnerabilities to man-in-the-middle attacks! + smtp_accept_invalid_hostnames: bool, true, def, false; }, /// Email 2FA Settings diff --git a/src/mail.rs b/src/mail.rs @@ -7,6 +7,7 @@ use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; use lettre::{ message::{header, Mailbox, Message, MultiPart, SinglePart}, transport::smtp::authentication::{Credentials, Mechanism as SmtpAuthMechanism}, + transport::smtp::client::{Tls, TlsParameters}, transport::smtp::extension::ClientId, Address, SmtpTransport, Transport, }; @@ -22,21 +23,30 @@ fn mailer() -> SmtpTransport { use std::time::Duration; let host = CONFIG.smtp_host().unwrap(); + let smtp_client = SmtpTransport::builder_dangerous(host.as_str()) + .port(CONFIG.smtp_port()) + .timeout(Some(Duration::from_secs(CONFIG.smtp_timeout()))); + // Determine security let smtp_client = if CONFIG.smtp_ssl() { + let mut tls_parameters = TlsParameters::builder(host); + if CONFIG.smtp_accept_invalid_hostnames() { + tls_parameters.dangerous_accept_invalid_hostnames(true); + } + if CONFIG.smtp_accept_invalid_certs() { + tls_parameters.dangerous_accept_invalid_certs(true); + } + let tls_parameters = tls_parameters.build().unwrap(); + if CONFIG.smtp_explicit_tls() { - SmtpTransport::relay(host.as_str()) + smtp_client.tls(Tls::Wrapper(tls_parameters)) } else { - SmtpTransport::starttls_relay(host.as_str()) + smtp_client.tls(Tls::Required(tls_parameters)) } } else { - Ok(SmtpTransport::builder_dangerous(host.as_str())) + smtp_client }; - let smtp_client = smtp_client.unwrap() - .port(CONFIG.smtp_port()) - .timeout(Some(Duration::from_secs(CONFIG.smtp_timeout()))); - let smtp_client = match (CONFIG.smtp_username(), CONFIG.smtp_password()) { (Some(user), Some(pass)) => smtp_client.credentials(Credentials::new(user, pass)), _ => smtp_client, @@ -318,14 +328,17 @@ fn send_email(address: &str, subject: &str, body_html: &str, body_text: &str) -> // The boundary generated by Lettre it self is mostly too large based on the RFC822, so we generate one our selfs. use uuid::Uuid; - let boundary = format!("_Part_{}_", Uuid::new_v4().to_simple()); + let unique_id = Uuid::new_v4().to_simple(); + let boundary = format!("_Part_{}_", unique_id); let alternative = MultiPart::alternative().boundary(boundary).singlepart(text).singlepart(html); + let smtp_from = &CONFIG.smtp_from(); let email = Message::builder() + .message_id(Some(format!("<{}.{}>", unique_id, smtp_from))) .to(Mailbox::new(None, Address::from_str(&address)?)) .from(Mailbox::new( Some(CONFIG.smtp_from_name()), - Address::from_str(&CONFIG.smtp_from())?, + Address::from_str(smtp_from)?, )) .subject(subject) .multipart(alternative)?; diff --git a/src/main.rs b/src/main.rs @@ -115,6 +115,16 @@ fn init_logging(level: log::LevelFilter) -> Result<(), fern::InitError> { .level_for("rocket::fairing", log::LevelFilter::Off) .chain(std::io::stdout()); + // Enable smtp debug logging only specifically for smtp when need. + // This can contain sensitive information we do not want in the default debug/trace logging. + if CONFIG.smtp_debug() { + println!("[WARNING] SMTP Debugging is enabled (SMTP_DEBUG=true). Sensitive information could be disclosed via logs!"); + println!("[WARNING] Only enable SMTP_DEBUG during troubleshooting!\n"); + logger = logger.level_for("lettre::transport::smtp", log::LevelFilter::Debug) + } else { + logger = logger.level_for("lettre::transport::smtp", log::LevelFilter::Off) + } + if CONFIG.extended_logging() { logger = logger.format(|out, message, record| { out.finish(format_args!( diff --git a/src/static/templates/admin/settings.hbs b/src/static/templates/admin/settings.hbs @@ -17,7 +17,7 @@ <div id="g_{{group}}" class="card-body collapse" data-parent="#config-form"> {{#each elements}} {{#if editable}} - <div class="form-group row" title="[{{name}}] {{doc.description}}"> + <div class="form-group row align-items-center" title="[{{name}}] {{doc.description}}"> {{#case type "text" "number" "password"}} <label for="input_{{name}}" class="col-sm-3 col-form-label">{{doc.name}}</label> <div class="col-sm-8 input-group"> @@ -34,7 +34,7 @@ </div> {{/case}} {{#case type "checkbox"}} - <div class="col-sm-3">{{doc.name}}</div> + <div class="col-sm-3 col-form-label">{{doc.name}}</div> <div class="col-sm-8"> <div class="form-check"> <input class="form-check-input conf-{{type}}" type="checkbox" id="input_{{name}}" @@ -48,7 +48,7 @@ {{/if}} {{/each}} {{#case group "smtp"}} - <div class="form-group row pt-3 border-top" title="Send a test email to given email address"> + <div class="form-group row align-items-center pt-3 border-top" title="Send a test email to given email address"> <label for="smtp-test-email" class="col-sm-3 col-form-label">Test SMTP</label> <div class="col-sm-8 input-group"> <input class="form-control" id="smtp-test-email" type="email" placeholder="Enter test email"> @@ -76,7 +76,7 @@ {{#each config}} {{#each elements}} {{#unless editable}} - <div class="form-group row" title="[{{name}}] {{doc.description}}"> + <div class="form-group row align-items-center" title="[{{name}}] {{doc.description}}"> {{#case type "text" "number" "password"}} <label for="input_{{name}}" class="col-sm-3 col-form-label">{{doc.name}}</label> <div class="col-sm-8 input-group"> @@ -92,9 +92,9 @@ </div> {{/case}} {{#case type "checkbox"}} - <div class="col-sm-3">{{doc.name}}</div> + <div class="col-sm-3 col-form-label">{{doc.name}}</div> <div class="col-sm-8"> - <div class="form-check"> + <div class="form-check align-middle"> <input disabled class="form-check-input" type="checkbox" id="input_{{name}}" {{#if value}} checked {{/if}}> @@ -139,6 +139,10 @@ <script> function smtpTest() { + if (formHasChanges(config_form)) { + alert("Config has been changed but not yet saved.\nPlease save the changes first before sending a test email."); + return false; + } test_email = document.getElementById("smtp-test-email"); data = JSON.stringify({ "email": test_email.value }); _post("{{urlpath}}/admin/test/smtp/", @@ -205,4 +209,35 @@ // {{#each config}} {{#if grouptoggle}} masterCheck("input_{{grouptoggle}}", "#g_{{group}} input"); // {{/if}} {{/each}} + + // Two functions to help check if there were changes to the form fields + // Useful for example during the smtp test to prevent people from clicking save before testing there new settings + function initChangeDetection(form) { + const ignore_fields = ["smtp-test-email"]; + Array.from(form).forEach((el) => { + if (! ignore_fields.includes(el.id)) { + el.dataset.origValue = el.value + } + }); + } + function formHasChanges(form) { + return Array.from(form).some(el => 'origValue' in el.dataset && ( el.dataset.origValue !== el.value)); + } + + // Trigger Form Change Detection + const config_form = document.getElementById('config-form'); + initChangeDetection(config_form); + + // Colorize some settings which are high risk + const risk_items = document.getElementsByClassName('col-form-label'); + function colorRiskSettings(risk_el) { + Array.from(risk_el).forEach((el) => { + if (el.innerText.toLowerCase().includes('risks') ) { + el.parentElement.className += ' alert-danger' + console.log(el) + } + }); + } + colorRiskSettings(risk_items); + </script> diff --git a/src/static/templates/email/change_email.hbs b/src/static/templates/email/change_email.hbs @@ -1,6 +1,8 @@ Your Email Change <!----------------> -<html> -<p>To finalize changing your email address enter the following code in web vault: <b>{{token}}</b></p> -<p>If you did not try to change an email address, you can safely ignore this email.</p> -</html> +To finalize changing your email address enter the following code in web vault: {{token}} + +If you did not try to change an email address, you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/delete_account.hbs b/src/static/templates/email/delete_account.hbs @@ -1,12 +1,10 @@ Delete Your Account <!----------------> -<html> -<p> -click the link below to delete your account. -<br> -<br> -<a href="{{url}}/#/verify-recover-delete?userId={{user_id}}&token={{token}}&email={{email}}"> -Delete Your Account</a> -</p> -<p>If you did not request this email to delete your account, you can safely ignore this email.</p> -</html> +Click the link below to delete your account. + +Delete Your Account: {{url}}/#/verify-recover-delete?userId={{user_id}}&token={{token}}&email={{email}} + +If you did not request this email to delete your account, you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/invite_accepted.hbs b/src/static/templates/email/invite_accepted.hbs @@ -1,8 +1,7 @@ Invitation to {{{org_name}}} accepted <!----------------> -<html> -<p> - Your invitation for <b>{{email}}</b> to join <b>{{org_name}}</b> was accepted. - Please <a href="{{url}}/">log in</a> to the bitwarden_rs server and confirm them from the organization management page. -</p> -</html> +Your invitation for *{{email}}* to join *{{org_name}}* was accepted. +Please log in via {{url}} to the bitwarden_rs server and confirm them from the organization management page. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/invite_confirmed.hbs b/src/static/templates/email/invite_confirmed.hbs @@ -1,8 +1,7 @@ Invitation to {{{org_name}}} confirmed <!----------------> -<html> -<p> - Your invitation to join <b>{{org_name}}</b> was confirmed. - It will now appear under the Organizations the next time you <a href="{{url}}/">log in</a> to the web vault. -</p> -</html> +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 at {{url}}. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/new_device_logged_in.hbs b/src/static/templates/email/new_device_logged_in.hbs @@ -1,14 +1,12 @@ New Device Logged In From {{{device}}} <!----------------> -<html> -<p> - Your account was just logged into from a new device. +Your account was just logged into from a new device. - Date: {{datetime}} - IP Address: {{ip}} - Device Type: {{device}} +* Date: {{datetime}} +* IP Address: {{ip}} +* Device Type: {{device}} - You can deauthorize all devices that have access to your account from the - <a href="{{url}}/">web vault</a> under Settings > My Account > Deauthorize Sessions. -</p> -</html> +You can deauthorize all devices that have access to your account from the web vault ( {{url}} ) under Settings > My Account > Deauthorize Sessions. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/pw_hint_none.hbs b/src/static/templates/email/pw_hint_none.hbs @@ -2,6 +2,9 @@ Your master password hint <!----------------> You (or someone) recently requested your master password hint. Unfortunately, your account does not have a master password hint. -If you cannot remember your master password, there is no way to recover your data. The only option to gain access to your account again is to <a href="{{url}}/#/recover-delete">delete the account</a> so that you can register again and start over. All data associated with your account will be deleted. +If you cannot remember your master password, there is no way to recover your data. The only option to gain access to your account again is to delete the account ( {{url}}/#/recover-delete ) so that you can register again and start over. All data associated with your account will be deleted. If you did not request your master password hint you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/pw_hint_some.hbs b/src/static/templates/email/pw_hint_some.hbs @@ -2,9 +2,12 @@ Your master password hint <!----------------> You (or someone) recently requested your master password hint. -Your hint is: "{{hint}}" -Log in: <a href="{{url}}/">Web Vault</a> +Your hint is: *{{hint}}* +Log in to the web vault: {{url}} -If you cannot remember your master password, there is no way to recover your data. The only option to gain access to your account again is to <a href="{{url}}/#/recover-delete">delete the account</a> so that you can register again and start over. All data associated with your account will be deleted. +If you cannot remember your master password, there is no way to recover your data. The only option to gain access to your account again is to delete the account ( {{url}}/#/recover-delete ) so that you can register again and start over. All data associated with your account will be deleted. If you did not request your master password hint you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/send_org_invite.hbs b/src/static/templates/email/send_org_invite.hbs @@ -1,12 +1,12 @@ Join {{{org_name}}} <!----------------> -<html> -<p> -You have been invited to join the <b>{{org_name}}</b> organization. -<br> -<br> -<a href="{{url}}/#/accept-organization/?organizationId={{org_id}}&organizationUserId={{org_user_id}}&email={{email}}&organizationName={{org_name}}&token={{token}}"> -Click here to join</a> -</p> -<p>If you do not wish to join this organization, you can safely ignore this email.</p> -</html> +You have been invited to join the *{{org_name}}* organization. + + +Click here to join: {{url}}/#/accept-organization/?organizationId={{org_id}}&organizationUserId={{org_user_id}}&email={{email}}&organizationName={{org_name}}&token={{token}} + + +If you do not wish to join this organization, you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/smtp_test.hbs b/src/static/templates/email/smtp_test.hbs @@ -1,8 +1,8 @@ Bitwarden_rs SMTP Test <!----------------> -<html> -<p> -This is a test email to verify the SMTP configuration for <a href="{{url}}">{{url}}</a>. -</p> -<p>When you can read this email it is probably configured correctly.</p> -</html> +This is a test email to verify the SMTP configuration for {{url}}. + +When you can read this email it is probably configured correctly. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/twofactor_email.hbs b/src/static/templates/email/twofactor_email.hbs @@ -1,9 +1,8 @@ Your Two-step Login Verification Code <!----------------> -<html> -<p> - Your two-step verification code is: <b>{{token}}</b> +Your two-step verification code is: {{token}} - Use this code to complete logging in with Bitwarden. -</p> -</html> +Use this code to complete logging in with Bitwarden. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/verify_email.hbs b/src/static/templates/email/verify_email.hbs @@ -1,12 +1,10 @@ Verify Your Email <!----------------> -<html> -<p> Verify this email address for your account by clicking the link below. -<br> -<br> -<a href="{{url}}/#/verify-email/?userId={{user_id}}&token={{token}}"> -Verify Email Address Now</a> -</p> -<p>If you did not request to verify your account, you can safely ignore this email.</p> -</html> + +Verify Email Address Now: {{url}}/#/verify-email/?userId={{user_id}}&token={{token}} + +If you did not request to verify your account, you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/welcome.hbs b/src/static/templates/email/welcome.hbs @@ -1,8 +1,8 @@ Welcome <!----------------> -<html> -<p> -Thank you for creating an account at <a href="{{url}}/">{{url}}</a>. You may now log in with your new account. -</p> -<p>If you did not request to create an account, you can safely ignore this email.</p> -</html> +Thank you for creating an account at {{url}}. You may now log in with your new account. + +If you did not request to create an account, you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs diff --git a/src/static/templates/email/welcome_must_verify.hbs b/src/static/templates/email/welcome_must_verify.hbs @@ -1,12 +1,10 @@ Welcome <!----------------> -<html> -<p> -Thank you for creating an account at <a href="{{url}}/">{{url}}</a>. Before you can login with your new account, you must verify this email address by clicking the link below. -<br> -<br> -<a href="{{url}}/#/verify-email/?userId={{user_id}}&token={{token}}"> -Verify Email Address Now</a> -</p> -<p>If you did not request to create an account, you can safely ignore this email.</p> -</html> +Thank you for creating an account at {{url}}. Before you can login with your new account, you must verify this email address by clicking the link below. + +Verify Email Address Now: {{url}}/#/verify-email/?userId={{user_id}}&token={{token}} + +If you did not request to create an account, you can safely ignore this email. + +=== +Github: https://github.com/dani-garcia/bitwarden_rs