From 736c0e62f25b17a650a854e4718f337dcd2c895d Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Wed, 2 Jan 2019 22:20:39 -0500 Subject: [PATCH] Send emails to inviters/invitees when invites are accepted/confirmed --- src/api/core/organizations.rs | 71 +++++++++++++++++++++++++++++------ src/auth.rs | 1 + 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index b1148431..dd59fb48 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -513,9 +513,19 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade user.email.clone(), org_id.clone(), Some(new_user.uuid.clone()), + headers.user.email.clone(), ); let invite_token = encode_jwt(&claims); - mail::send_invite(&email, &org_id, &new_user.uuid, &invite_token, &org_name, mail_config)?; + let subject = format!("Join {}", &org_name); + let body = format!( + " +

You have been invited to join the {} organization.

+ Click here to join

+

If you do not wish to join this organization, you can safely ignore this email.

+ ", + org_name, CONFIG.domain, org_id, &new_user.uuid, &user.email, org_name, invite_token + ); + mail::send_email(&user.email, &subject, &body, mail_config)?; } } @@ -523,7 +533,7 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade } #[post("/organizations//users//reinvite")] -fn reinvite_user(org_id: String, user_org: String, _headers: AdminHeaders, conn: DbConn) -> EmptyResult { +fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { if !CONFIG.invitations_allowed { err!("Invitations are not allowed.") } @@ -556,17 +566,20 @@ fn reinvite_user(org_id: String, user_org: String, _headers: AdminHeaders, conn: user.email.clone(), org_id.clone(), Some(user_org.uuid.clone()), + headers.user.email.clone(), ); let invite_token = encode_jwt(&claims); if let Some(ref mail_config) = CONFIG.mail { - mail::send_invite( - &user.email, - &org_id, - &user_org.uuid, - &invite_token, - &org_name, - mail_config, - )?; + let subject = format!("Join {}", &org_name); + let body = format!( + " +

You have been invited to join the {} organization.

+ Click here to join

+

If you do not wish to join this organization, you can safely ignore this email.

+ ", + org_name, CONFIG.domain, org_id, user_org.uuid, &user.email, org_name, invite_token + ); + mail::send_email(&user.email, &subject, &body, mail_config)?; } Ok(()) @@ -578,7 +591,12 @@ struct AcceptData { Token: String, } -fn generate_invite_claims(uuid: String, email: String, org_id: String, org_user_id: Option) -> InviteJWTClaims { +fn generate_invite_claims(uuid: String, + email: String, + org_id: String, + org_user_id: Option, + inviter_email: String, +) -> InviteJWTClaims { let time_now = Utc::now().naive_utc(); InviteJWTClaims { nbf: time_now.timestamp(), @@ -588,6 +606,7 @@ fn generate_invite_claims(uuid: String, email: String, org_id: String, org_user_ email: email.clone(), org_id: org_id.clone(), user_org_id: org_user_id.clone(), + inviter_email: inviter_email.clone(), } } @@ -617,6 +636,19 @@ fn accept_invite(_org_id: String, _org_user_id: String, data: JsonUpcase err!("Invited user not found"), } + if let Some(ref mail_config) = CONFIG.mail { + let org_name = match Organization::find_by_uuid(&claims.org_id, &conn) { + Some(org) => org.name, + None => err!("Error looking up organization."), + }; + let subject = "Invitation accepted"; + let body = format!( + " +

Your invitation to {} to join {} was accepted. Please log in to the bitwarden_rs server and confirm them from the organization management page.

+ ", claims.email, org_name); + mail::send_email(&claims.inviter_email, &subject, &body, mail_config)?; + } + Ok(()) } @@ -649,6 +681,23 @@ fn confirm_invite( None => err!("Invalid key provided"), }; + if let Some(ref mail_config) = CONFIG.mail { + let org_name = match Organization::find_by_uuid(&org_id, &conn) { + Some(org) => org.name, + None => err!("Error looking up organization."), + }; + let address = match User::find_by_uuid(&user_to_confirm.user_uuid, &conn) { + Some(user) => user.email, + None => err!("Error looking up user."), + }; + let subject = format!("Invitation to {} confirmed", org_name); + let body = format!( + " +

Your invitation to join {} was accepted. It will now appear under the Organizations the next time you log into the web vault.

+ ", org_name); + mail::send_email(&address, &subject, &body, mail_config)?; + } + user_to_confirm.save(&conn) } diff --git a/src/auth.rs b/src/auth.rs index 6eb029e6..65a72427 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -118,6 +118,7 @@ pub struct InviteJWTClaims { pub email: String, pub org_id: String, pub user_org_id: Option, + pub inviter_email: String, } //