|  |  | @ -8,7 +8,7 @@ use lettre::{ | 
			
		
	
		
			
				
					|  |  |  |     transport::smtp::authentication::{Credentials, Mechanism as SmtpAuthMechanism}, | 
			
		
	
		
			
				
					|  |  |  |     transport::smtp::client::{Tls, TlsParameters}, | 
			
		
	
		
			
				
					|  |  |  |     transport::smtp::extension::ClientId, | 
			
		
	
		
			
				
					|  |  |  |     Address, SmtpTransport, Transport, | 
			
		
	
		
			
				
					|  |  |  |     Address, AsyncSmtpTransport, AsyncTransport, Tokio1Executor, | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | use crate::{ | 
			
		
	
	
		
			
				
					|  |  | @ -21,11 +21,11 @@ use crate::{ | 
			
		
	
		
			
				
					|  |  |  |     CONFIG, | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | fn mailer() -> SmtpTransport { | 
			
		
	
		
			
				
					|  |  |  | fn mailer() -> AsyncSmtpTransport<Tokio1Executor> { | 
			
		
	
		
			
				
					|  |  |  |     use std::time::Duration; | 
			
		
	
		
			
				
					|  |  |  |     let host = CONFIG.smtp_host().unwrap(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let smtp_client = SmtpTransport::builder_dangerous(host.as_str()) | 
			
		
	
		
			
				
					|  |  |  |     let smtp_client = AsyncSmtpTransport::<Tokio1Executor>::builder_dangerous(host.as_str()) | 
			
		
	
		
			
				
					|  |  |  |         .port(CONFIG.smtp_port()) | 
			
		
	
		
			
				
					|  |  |  |         .timeout(Some(Duration::from_secs(CONFIG.smtp_timeout()))); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -110,7 +110,7 @@ fn get_template(template_name: &str, data: &serde_json::Value) -> Result<(String | 
			
		
	
		
			
				
					|  |  |  |     Ok((subject, body)) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_password_hint(address: &str, hint: Option<String>) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_password_hint(address: &str, hint: Option<String>) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let template_name = if hint.is_some() { | 
			
		
	
		
			
				
					|  |  |  |         "email/pw_hint_some" | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
	
		
			
				
					|  |  | @ -119,10 +119,10 @@ pub fn send_password_hint(address: &str, hint: Option<String>) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text(template_name, json!({ "hint": hint, "url": CONFIG.domain() }))?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_delete_account(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_delete_account(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let claims = generate_delete_claims(uuid.to_string()); | 
			
		
	
		
			
				
					|  |  |  |     let delete_token = encode_jwt(&claims); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -136,10 +136,10 @@ pub fn send_delete_account(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_verify_email(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_verify_email(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let claims = generate_verify_email_claims(uuid.to_string()); | 
			
		
	
		
			
				
					|  |  |  |     let verify_email_token = encode_jwt(&claims); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -153,10 +153,10 @@ pub fn send_verify_email(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_welcome(address: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_welcome(address: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/welcome", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -164,10 +164,10 @@ pub fn send_welcome(address: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_welcome_must_verify(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_welcome_must_verify(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let claims = generate_verify_email_claims(uuid.to_string()); | 
			
		
	
		
			
				
					|  |  |  |     let verify_email_token = encode_jwt(&claims); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -180,10 +180,10 @@ pub fn send_welcome_must_verify(address: &str, uuid: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_2fa_removed_from_org(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_2fa_removed_from_org(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/send_2fa_removed_from_org", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -192,10 +192,10 @@ pub fn send_2fa_removed_from_org(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_single_org_removed_from_org(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_single_org_removed_from_org(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/send_single_org_removed_from_org", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -204,10 +204,10 @@ pub fn send_single_org_removed_from_org(address: &str, org_name: &str) -> EmptyR | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_invite( | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_invite( | 
			
		
	
		
			
				
					|  |  |  |     address: &str, | 
			
		
	
		
			
				
					|  |  |  |     uuid: &str, | 
			
		
	
		
			
				
					|  |  |  |     org_id: Option<String>, | 
			
		
	
	
		
			
				
					|  |  | @ -236,10 +236,10 @@ pub fn send_invite( | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_invite( | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_invite( | 
			
		
	
		
			
				
					|  |  |  |     address: &str, | 
			
		
	
		
			
				
					|  |  |  |     uuid: &str, | 
			
		
	
		
			
				
					|  |  |  |     emer_id: Option<String>, | 
			
		
	
	
		
			
				
					|  |  | @ -267,10 +267,10 @@ pub fn send_emergency_access_invite( | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_invite_accepted(address: &str, grantee_email: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_invite_accepted(address: &str, grantee_email: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/emergency_access_invite_accepted", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -279,10 +279,10 @@ pub fn send_emergency_access_invite_accepted(address: &str, grantee_email: &str) | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_invite_confirmed(address: &str, grantor_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_invite_confirmed(address: &str, grantor_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/emergency_access_invite_confirmed", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -291,10 +291,10 @@ pub fn send_emergency_access_invite_confirmed(address: &str, grantor_name: &str) | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_recovery_approved(address: &str, grantor_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_recovery_approved(address: &str, grantor_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/emergency_access_recovery_approved", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -303,10 +303,10 @@ pub fn send_emergency_access_recovery_approved(address: &str, grantor_name: &str | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_recovery_initiated( | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_recovery_initiated( | 
			
		
	
		
			
				
					|  |  |  |     address: &str, | 
			
		
	
		
			
				
					|  |  |  |     grantee_name: &str, | 
			
		
	
		
			
				
					|  |  |  |     atype: &str, | 
			
		
	
	
		
			
				
					|  |  | @ -322,10 +322,10 @@ pub fn send_emergency_access_recovery_initiated( | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_recovery_reminder( | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_recovery_reminder( | 
			
		
	
		
			
				
					|  |  |  |     address: &str, | 
			
		
	
		
			
				
					|  |  |  |     grantee_name: &str, | 
			
		
	
		
			
				
					|  |  |  |     atype: &str, | 
			
		
	
	
		
			
				
					|  |  | @ -341,10 +341,10 @@ pub fn send_emergency_access_recovery_reminder( | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_recovery_rejected(address: &str, grantor_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_recovery_rejected(address: &str, grantor_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/emergency_access_recovery_rejected", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -353,10 +353,10 @@ pub fn send_emergency_access_recovery_rejected(address: &str, grantor_name: &str | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_emergency_access_recovery_timed_out(address: &str, grantee_name: &str, atype: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_emergency_access_recovery_timed_out(address: &str, grantee_name: &str, atype: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/emergency_access_recovery_timed_out", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -366,10 +366,10 @@ pub fn send_emergency_access_recovery_timed_out(address: &str, grantee_name: &st | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_invite_accepted(new_user_email: &str, address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_invite_accepted(new_user_email: &str, address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/invite_accepted", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -379,10 +379,10 @@ pub fn send_invite_accepted(new_user_email: &str, address: &str, org_name: &str) | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_invite_confirmed(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_invite_confirmed(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/invite_confirmed", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -391,10 +391,10 @@ pub fn send_invite_confirmed(address: &str, org_name: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_new_device_logged_in(address: &str, ip: &str, dt: &NaiveDateTime, device: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_new_device_logged_in(address: &str, ip: &str, dt: &NaiveDateTime, device: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     use crate::util::upcase_first; | 
			
		
	
		
			
				
					|  |  |  |     let device = upcase_first(device); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -409,10 +409,10 @@ pub fn send_new_device_logged_in(address: &str, ip: &str, dt: &NaiveDateTime, de | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_incomplete_2fa_login(address: &str, ip: &str, dt: &NaiveDateTime, device: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_incomplete_2fa_login(address: &str, ip: &str, dt: &NaiveDateTime, device: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     use crate::util::upcase_first; | 
			
		
	
		
			
				
					|  |  |  |     let device = upcase_first(device); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -428,10 +428,10 @@ pub fn send_incomplete_2fa_login(address: &str, ip: &str, dt: &NaiveDateTime, de | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_token(address: &str, token: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_token(address: &str, token: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/twofactor_email", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -440,10 +440,10 @@ pub fn send_token(address: &str, token: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_change_email(address: &str, token: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_change_email(address: &str, token: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/change_email", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -452,10 +452,10 @@ pub fn send_change_email(address: &str, token: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | pub fn send_test(address: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | pub async fn send_test(address: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let (subject, body_html, body_text) = get_text( | 
			
		
	
		
			
				
					|  |  |  |         "email/smtp_test", | 
			
		
	
		
			
				
					|  |  |  |         json!({ | 
			
		
	
	
		
			
				
					|  |  | @ -463,10 +463,10 @@ pub fn send_test(address: &str) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |         }), | 
			
		
	
		
			
				
					|  |  |  |     )?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text) | 
			
		
	
		
			
				
					|  |  |  |     send_email(address, &subject, body_html, body_text).await | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | fn send_email(address: &str, subject: &str, body_html: String, body_text: String) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  | async fn send_email(address: &str, subject: &str, body_html: String, body_text: String) -> EmptyResult { | 
			
		
	
		
			
				
					|  |  |  |     let smtp_from = &CONFIG.smtp_from(); | 
			
		
	
		
			
				
					|  |  |  |     let email = Message::builder() | 
			
		
	
		
			
				
					|  |  |  |         .message_id(Some(format!("<{}@{}>", crate::util::get_uuid(), smtp_from.split('@').collect::<Vec<&str>>()[1]))) | 
			
		
	
	
		
			
				
					|  |  | @ -475,7 +475,7 @@ fn send_email(address: &str, subject: &str, body_html: String, body_text: String | 
			
		
	
		
			
				
					|  |  |  |         .subject(subject) | 
			
		
	
		
			
				
					|  |  |  |         .multipart(MultiPart::alternative_plain_html(body_text, body_html))?; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     match mailer().send(&email) { | 
			
		
	
		
			
				
					|  |  |  |     match mailer().send(email).await { | 
			
		
	
		
			
				
					|  |  |  |         Ok(_) => Ok(()), | 
			
		
	
		
			
				
					|  |  |  |         // Match some common errors and make them more user friendly
 | 
			
		
	
		
			
				
					|  |  |  |         Err(e) => { | 
			
		
	
	
		
			
				
					|  |  | 
 |