@ -1,3 +1,4 @@
use std ::env ;
use std ::str ::FromStr ;
use std ::str ::FromStr ;
use lettre ::message ::{ header , Mailbox , Message , MultiPart , SinglePart } ;
use lettre ::message ::{ header , Mailbox , Message , MultiPart , SinglePart } ;
@ -12,7 +13,9 @@ use crate::api::EmptyResult;
use crate ::auth ::{ encode_jwt , generate_delete_claims , generate_invite_claims , generate_verify_email_claims } ;
use crate ::auth ::{ encode_jwt , generate_delete_claims , generate_invite_claims , generate_verify_email_claims } ;
use crate ::error ::Error ;
use crate ::error ::Error ;
use crate ::CONFIG ;
use crate ::CONFIG ;
use chrono ::NaiveDateTime ;
use chrono ::{ DateTime , Local } ;
use chrono_tz ::Tz ;
fn mailer ( ) -> SmtpTransport {
fn mailer ( ) -> SmtpTransport {
let host = CONFIG . smtp_host ( ) . unwrap ( ) ;
let host = CONFIG . smtp_host ( ) . unwrap ( ) ;
@ -87,6 +90,22 @@ fn get_template(template_name: &str, data: &serde_json::Value) -> Result<(String
Ok ( ( subject , body ) )
Ok ( ( subject , body ) )
}
}
pub fn format_datetime ( dt : & DateTime < Local > ) -> String {
let fmt = "%A, %B %_d, %Y at %r %Z" ;
// With a DateTime<Local>, `%Z` formats as the time zone's UTC offset
// (e.g., `+00:00`). If the `TZ` environment variable is set, try to
// format as a time zone abbreviation instead (e.g., `UTC`).
if let Ok ( tz ) = env ::var ( "TZ" ) {
if let Ok ( tz ) = tz . parse ::< Tz > ( ) {
return dt . with_timezone ( & tz ) . format ( fmt ) . to_string ( ) ;
}
}
// Otherwise, fall back to just displaying the UTC offset.
dt . format ( fmt ) . to_string ( )
}
pub fn send_password_hint ( address : & str , hint : Option < String > ) -> EmptyResult {
pub fn send_password_hint ( address : & str , hint : Option < String > ) -> EmptyResult {
let template_name = if hint . is_some ( ) {
let template_name = if hint . is_some ( ) {
"email/pw_hint_some"
"email/pw_hint_some"
@ -217,19 +236,17 @@ 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 )
}
}
pub fn send_new_device_logged_in ( address : & str , ip : & str , dt : & Naive DateTime, device : & str ) -> EmptyResult {
pub fn send_new_device_logged_in ( address : & str , ip : & str , dt : & DateTime < Local > , device : & str ) -> EmptyResult {
use crate ::util ::upcase_first ;
use crate ::util ::upcase_first ;
let device = upcase_first ( device ) ;
let device = upcase_first ( device ) ;
let datetime = dt . format ( "%A, %B %_d, %Y at %H:%M" ) . to_string ( ) ;
let ( subject , body_html , body_text ) = get_text (
let ( subject , body_html , body_text ) = get_text (
"email/new_device_logged_in" ,
"email/new_device_logged_in" ,
json ! ( {
json ! ( {
"url" : CONFIG . domain ( ) ,
"url" : CONFIG . domain ( ) ,
"ip" : ip ,
"ip" : ip ,
"device" : device ,
"device" : device ,
"datetime" : datetime ,
"datetime" : format_ datetime( dt ) ,
} ) ,
} ) ,
) ? ;
) ? ;