mirror of
				https://github.com/dani-garcia/vaultwarden.git
				synced 2025-10-26 11:21:14 +00:00 
			
		
		
		
	
				commit
				
					
						5379329ef7
					
				
			
		
					 20 changed files with 242 additions and 153 deletions
				
			
		|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										72
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										72
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -33,12 +33,6 @@ dependencies = [ | |||
|  "winapi 0.3.9", | ||||
| ] | ||||
| 
 | ||||
| [[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" | ||||
|  | @ -131,6 +125,18 @@ version = "1.2.1" | |||
| 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" | ||||
|  | @ -638,6 +644,12 @@ version = "0.3.3" | |||
| 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" | ||||
|  | @ -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,22 +1172,10 @@ 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" | ||||
|  | @ -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", | ||||
| ] | ||||
|  | @ -1978,6 +1978,12 @@ dependencies = [ | |||
|  "scheduled-thread-pool", | ||||
| ] | ||||
| 
 | ||||
| [[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" | ||||
|  | @ -2617,12 +2623,6 @@ version = "0.4.2" | |||
| 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" | ||||
|  | @ -2782,6 +2782,12 @@ dependencies = [ | |||
|  "time 0.1.44", | ||||
| ] | ||||
| 
 | ||||
| [[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" | ||||
|  | @ -3371,6 +3377,12 @@ dependencies = [ | |||
|  "winapi-build", | ||||
| ] | ||||
| 
 | ||||
| [[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" | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -436,6 +436,12 @@ make_config! { | |||
|         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; | ||||
|         /// 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
 | ||||
|  |  | |||
							
								
								
									
										41
									
								
								src/mail.rs
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								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(); | ||||
| 
 | ||||
|     // Determine security
 | ||||
|     let smtp_client = if CONFIG.smtp_ssl() { | ||||
|         if CONFIG.smtp_explicit_tls() { | ||||
|             SmtpTransport::relay(host.as_str()) | ||||
|         } else { | ||||
|             SmtpTransport::starttls_relay(host.as_str()) | ||||
|         } | ||||
|     } else { | ||||
|         Ok(SmtpTransport::builder_dangerous(host.as_str())) | ||||
|     }; | ||||
| 
 | ||||
|     let smtp_client = smtp_client.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() { | ||||
|             smtp_client.tls(Tls::Wrapper(tls_parameters)) | ||||
|         } else { | ||||
|             smtp_client.tls(Tls::Required(tls_parameters)) | ||||
|         } | ||||
|     } else { | ||||
|         smtp_client | ||||
|     }; | ||||
| 
 | ||||
|     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)?; | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								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!( | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue