mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-07-13 07:44:59 +00:00
Upgrade dependencies and swap lettre to async transport
This commit is contained in:
parent
0c4e79cff6
commit
b64cf27038
10 changed files with 141 additions and 125 deletions
|
@ -276,7 +276,7 @@ async fn invite_user(data: Json<InviteData>, _token: AdminToken, conn: DbConn) -
|
|||
|
||||
async fn _generate_invite(user: &User, conn: &DbConn) -> EmptyResult {
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_invite(&user.email, &user.uuid, None, None, &CONFIG.invitation_org_name(), None)
|
||||
mail::send_invite(&user.email, &user.uuid, None, None, &CONFIG.invitation_org_name(), None).await
|
||||
} else {
|
||||
let invitation = Invitation::new(user.email.clone());
|
||||
invitation.save(conn).await
|
||||
|
@ -290,11 +290,11 @@ async fn invite_user(data: Json<InviteData>, _token: AdminToken, conn: DbConn) -
|
|||
}
|
||||
|
||||
#[post("/test/smtp", data = "<data>")]
|
||||
fn test_smtp(data: Json<InviteData>, _token: AdminToken) -> EmptyResult {
|
||||
async fn test_smtp(data: Json<InviteData>, _token: AdminToken) -> EmptyResult {
|
||||
let data: InviteData = data.into_inner();
|
||||
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_test(&data.email)
|
||||
mail::send_test(&data.email).await
|
||||
} else {
|
||||
err!("Mail is not enabled")
|
||||
}
|
||||
|
|
|
@ -168,12 +168,12 @@ async fn register(data: JsonUpcase<RegisterData>, conn: DbConn) -> EmptyResult {
|
|||
|
||||
if CONFIG.mail_enabled() {
|
||||
if CONFIG.signups_verify() {
|
||||
if let Err(e) = mail::send_welcome_must_verify(&user.email, &user.uuid) {
|
||||
if let Err(e) = mail::send_welcome_must_verify(&user.email, &user.uuid).await {
|
||||
error!("Error sending welcome email: {:#?}", e);
|
||||
}
|
||||
|
||||
user.last_verifying_at = Some(user.created_at);
|
||||
} else if let Err(e) = mail::send_welcome(&user.email) {
|
||||
} else if let Err(e) = mail::send_welcome(&user.email).await {
|
||||
error!("Error sending welcome email: {:#?}", e);
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ async fn post_email_token(data: JsonUpcase<EmailTokenData>, headers: Headers, co
|
|||
let token = crypto::generate_email_token(6);
|
||||
|
||||
if CONFIG.mail_enabled() {
|
||||
if let Err(e) = mail::send_change_email(&data.NewEmail, &token) {
|
||||
if let Err(e) = mail::send_change_email(&data.NewEmail, &token).await {
|
||||
error!("Error sending change-email email: {:#?}", e);
|
||||
}
|
||||
}
|
||||
|
@ -485,14 +485,14 @@ async fn post_email(data: JsonUpcase<ChangeEmailData>, headers: Headers, conn: D
|
|||
}
|
||||
|
||||
#[post("/accounts/verify-email")]
|
||||
fn post_verify_email(headers: Headers) -> EmptyResult {
|
||||
async fn post_verify_email(headers: Headers) -> EmptyResult {
|
||||
let user = headers.user;
|
||||
|
||||
if !CONFIG.mail_enabled() {
|
||||
err!("Cannot verify email address");
|
||||
}
|
||||
|
||||
if let Err(e) = mail::send_verify_email(&user.email, &user.uuid) {
|
||||
if let Err(e) = mail::send_verify_email(&user.email, &user.uuid).await {
|
||||
error!("Error sending verify_email email: {:#?}", e);
|
||||
}
|
||||
|
||||
|
@ -544,7 +544,7 @@ async fn post_delete_recover(data: JsonUpcase<DeleteRecoverData>, conn: DbConn)
|
|||
|
||||
if CONFIG.mail_enabled() {
|
||||
if let Some(user) = User::find_by_mail(&data.Email, &conn).await {
|
||||
if let Err(e) = mail::send_delete_account(&user.email, &user.uuid) {
|
||||
if let Err(e) = mail::send_delete_account(&user.email, &user.uuid).await {
|
||||
error!("Error sending delete account email: {:#?}", e);
|
||||
}
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ async fn password_hint(data: JsonUpcase<PasswordHintData>, conn: DbConn) -> Empt
|
|||
Some(user) => {
|
||||
let hint: Option<String> = user.password_hint;
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_password_hint(email, hint)?;
|
||||
mail::send_password_hint(email, hint).await?;
|
||||
Ok(())
|
||||
} else if let Some(hint) = hint {
|
||||
err!(format!("Your password hint is: {}", hint));
|
||||
|
|
|
@ -251,7 +251,8 @@ async fn send_invite(data: JsonUpcase<EmergencyAccessInviteData>, headers: Heade
|
|||
Some(new_emergency_access.uuid),
|
||||
Some(grantor_user.name.clone()),
|
||||
Some(grantor_user.email),
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
// Automatically mark user as accepted if no email invites
|
||||
match User::find_by_mail(&email, &conn).await {
|
||||
|
@ -304,7 +305,8 @@ async fn resend_invite(emer_id: String, headers: Headers, conn: DbConn) -> Empty
|
|||
Some(emergency_access.uuid),
|
||||
Some(grantor_user.name.clone()),
|
||||
Some(grantor_user.email),
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
if Invitation::find_by_mail(&email, &conn).await.is_none() {
|
||||
let invitation = Invitation::new(email);
|
||||
|
@ -366,7 +368,7 @@ async fn accept_invite(emer_id: String, data: JsonUpcase<AcceptData>, conn: DbCo
|
|||
}
|
||||
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_emergency_access_invite_accepted(&grantor_user.email, &grantee_user.email)?;
|
||||
mail::send_emergency_access_invite_accepted(&grantor_user.email, &grantee_user.email).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -449,7 +451,7 @@ async fn confirm_emergency_access(
|
|||
emergency_access.save(&conn).await?;
|
||||
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_emergency_access_invite_confirmed(&grantee_user.email, &grantor_user.name)?;
|
||||
mail::send_emergency_access_invite_confirmed(&grantee_user.email, &grantor_user.name).await?;
|
||||
}
|
||||
Ok(Json(emergency_access.to_json()))
|
||||
} else {
|
||||
|
@ -495,7 +497,8 @@ async fn initiate_emergency_access(emer_id: String, headers: Headers, conn: DbCo
|
|||
&initiating_user.name,
|
||||
emergency_access.get_type_as_str(),
|
||||
&emergency_access.wait_time_days.clone().to_string(),
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(Json(emergency_access.to_json()))
|
||||
}
|
||||
|
@ -531,7 +534,7 @@ async fn approve_emergency_access(emer_id: String, headers: Headers, conn: DbCon
|
|||
emergency_access.save(&conn).await?;
|
||||
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_emergency_access_recovery_approved(&grantee_user.email, &grantor_user.name)?;
|
||||
mail::send_emergency_access_recovery_approved(&grantee_user.email, &grantor_user.name).await?;
|
||||
}
|
||||
Ok(Json(emergency_access.to_json()))
|
||||
} else {
|
||||
|
@ -571,7 +574,7 @@ async fn reject_emergency_access(emer_id: String, headers: Headers, conn: DbConn
|
|||
emergency_access.save(&conn).await?;
|
||||
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_emergency_access_recovery_rejected(&grantee_user.email, &grantor_user.name)?;
|
||||
mail::send_emergency_access_recovery_rejected(&grantee_user.email, &grantor_user.name).await?;
|
||||
}
|
||||
Ok(Json(emergency_access.to_json()))
|
||||
} else {
|
||||
|
@ -779,9 +782,11 @@ pub async fn emergency_request_timeout_job(pool: DbPool) {
|
|||
&grantee_user.name.clone(),
|
||||
emer.get_type_as_str(),
|
||||
)
|
||||
.await
|
||||
.expect("Error on sending email");
|
||||
|
||||
mail::send_emergency_access_recovery_approved(&grantee_user.email, &grantor_user.name.clone())
|
||||
.await
|
||||
.expect("Error on sending email");
|
||||
}
|
||||
}
|
||||
|
@ -831,6 +836,7 @@ pub async fn emergency_notification_reminder_job(pool: DbPool) {
|
|||
emer.get_type_as_str(),
|
||||
&emer.wait_time_days.to_string(), // TODO(jjlin): This should be the number of days left.
|
||||
)
|
||||
.await
|
||||
.expect("Error on sending email");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -652,7 +652,8 @@ async fn send_invite(org_id: String, data: JsonUpcase<InviteData>, headers: Admi
|
|||
Some(new_user.uuid),
|
||||
&org_name,
|
||||
Some(headers.user.email.clone()),
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -732,7 +733,8 @@ async fn _reinvite_user(org_id: &str, user_org: &str, invited_by_email: &str, co
|
|||
Some(user_org.uuid),
|
||||
&org_name,
|
||||
Some(invited_by_email.to_string()),
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
let invitation = Invitation::new(user.email);
|
||||
invitation.save(conn).await?;
|
||||
|
@ -830,10 +832,10 @@ async fn accept_invite(
|
|||
};
|
||||
if let Some(invited_by_email) = &claims.invited_by_email {
|
||||
// User was invited to an organization, so they must be confirmed manually after acceptance
|
||||
mail::send_invite_accepted(&claims.email, invited_by_email, &org_name)?;
|
||||
mail::send_invite_accepted(&claims.email, invited_by_email, &org_name).await?;
|
||||
} else {
|
||||
// User was invited from /admin, so they are automatically confirmed
|
||||
mail::send_invite_confirmed(&claims.email, &org_name)?;
|
||||
mail::send_invite_confirmed(&claims.email, &org_name).await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -928,7 +930,7 @@ async fn _confirm_invite(
|
|||
Some(user) => user.email,
|
||||
None => err!("Error looking up user."),
|
||||
};
|
||||
mail::send_invite_confirmed(&address, &org_name)?;
|
||||
mail::send_invite_confirmed(&address, &org_name).await?;
|
||||
}
|
||||
|
||||
user_to_confirm.save(conn).await
|
||||
|
@ -1298,7 +1300,7 @@ async fn put_policy(
|
|||
let org = Organization::find_by_uuid(&member.org_uuid, &conn).await.unwrap();
|
||||
let user = User::find_by_uuid(&member.user_uuid, &conn).await.unwrap();
|
||||
|
||||
mail::send_2fa_removed_from_org(&user.email, &org.name)?;
|
||||
mail::send_2fa_removed_from_org(&user.email, &org.name).await?;
|
||||
}
|
||||
member.delete(&conn).await?;
|
||||
}
|
||||
|
@ -1323,7 +1325,7 @@ async fn put_policy(
|
|||
let org = Organization::find_by_uuid(&member.org_uuid, &conn).await.unwrap();
|
||||
let user = User::find_by_uuid(&member.user_uuid, &conn).await.unwrap();
|
||||
|
||||
mail::send_single_org_removed_from_org(&user.email, &org.name)?;
|
||||
mail::send_single_org_removed_from_org(&user.email, &org.name).await?;
|
||||
}
|
||||
member.delete(&conn).await?;
|
||||
}
|
||||
|
@ -1462,7 +1464,8 @@ async fn import(org_id: String, data: JsonUpcase<OrgImportData>, headers: Header
|
|||
Some(new_org_user.uuid),
|
||||
&org_name,
|
||||
Some(headers.user.email.clone()),
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ pub async fn send_token(user_uuid: &str, conn: &DbConn) -> EmptyResult {
|
|||
twofactor.data = twofactor_data.to_json();
|
||||
twofactor.save(conn).await?;
|
||||
|
||||
mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?)?;
|
||||
mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ async fn send_email(data: JsonUpcase<SendEmailData>, headers: Headers, conn: DbC
|
|||
let twofactor = TwoFactor::new(user.uuid, TwoFactorType::EmailVerificationChallenge, twofactor_data.to_json());
|
||||
twofactor.save(&conn).await?;
|
||||
|
||||
mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?)?;
|
||||
mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ async fn disable_twofactor(data: JsonUpcase<DisableTwoFactorData>, headers: Head
|
|||
if user_org.atype < UserOrgType::Admin {
|
||||
if CONFIG.mail_enabled() {
|
||||
let org = Organization::find_by_uuid(&user_org.org_uuid, &conn).await.unwrap();
|
||||
mail::send_2fa_removed_from_org(&user.email, &org.name)?;
|
||||
mail::send_2fa_removed_from_org(&user.email, &org.name).await?;
|
||||
}
|
||||
user_org.delete(&conn).await?;
|
||||
}
|
||||
|
@ -183,6 +183,7 @@ pub async fn send_incomplete_2fa_notifications(pool: DbPool) {
|
|||
user.email, login.ip_address
|
||||
);
|
||||
mail::send_incomplete_2fa_login(&user.email, &login.ip_address, &login.login_time, &login.device_name)
|
||||
.await
|
||||
.expect("Error sending incomplete 2FA email");
|
||||
login.delete(&conn).await.expect("Error deleting incomplete 2FA record");
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ async fn _password_login(data: ConnectData, conn: DbConn, ip: &ClientIp) -> Json
|
|||
error!("Error updating user: {:#?}", e);
|
||||
}
|
||||
|
||||
if let Err(e) = mail::send_verify_email(&user.email, &user.uuid) {
|
||||
if let Err(e) = mail::send_verify_email(&user.email, &user.uuid).await {
|
||||
error!("Error auto-sending email verification email: {:#?}", e);
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ async fn _password_login(data: ConnectData, conn: DbConn, ip: &ClientIp) -> Json
|
|||
let twofactor_token = twofactor_auth(&user.uuid, &data, &mut device, ip, &conn).await?;
|
||||
|
||||
if CONFIG.mail_enabled() && new_device {
|
||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device.name) {
|
||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device.name).await {
|
||||
error!("Error sending new device email: {:#?}", e);
|
||||
|
||||
if CONFIG.require_device_email() {
|
||||
|
@ -225,7 +225,7 @@ async fn _api_key_login(data: ConnectData, conn: DbConn, ip: &ClientIp) -> JsonR
|
|||
|
||||
if CONFIG.mail_enabled() && new_device {
|
||||
let now = Utc::now().naive_utc();
|
||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device.name) {
|
||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device.name).await {
|
||||
error!("Error sending new device email: {:#?}", e);
|
||||
|
||||
if CONFIG.require_device_email() {
|
||||
|
|
102
src/mail.rs
102
src/mail.rs
|
@ -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) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue