From 248e561b3fe6a8172751374df980c6cd43c841d5 Mon Sep 17 00:00:00 2001 From: Timshel Date: Sun, 1 Sep 2024 15:55:41 +0200 Subject: [PATCH] Add orgUserHasExistingUser parameters to org invite (#4827) --- src/api/admin.rs | 4 +- src/api/core/organizations.rs | 9 ++-- src/api/core/public.rs | 11 +---- src/mail.rs | 41 ++++++++++++++----- .../templates/email/send_org_invite.hbs | 4 +- .../templates/email/send_org_invite.html.hbs | 4 +- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/api/admin.rs b/src/api/admin.rs index 03d86920..961bbdb3 100644 --- a/src/api/admin.rs +++ b/src/api/admin.rs @@ -298,7 +298,7 @@ async fn invite_user(data: Json, _token: AdminToken, mut conn: DbCon async fn _generate_invite(user: &User, conn: &mut DbConn) -> EmptyResult { if CONFIG.mail_enabled() { - mail::send_invite(&user.email, &user.uuid, None, None, &CONFIG.invitation_org_name(), None).await + mail::send_invite(user, None, None, &CONFIG.invitation_org_name(), None).await } else { let invitation = Invitation::new(&user.email); invitation.save(conn).await @@ -474,7 +474,7 @@ async fn resend_user_invite(uuid: &str, _token: AdminToken, mut conn: DbConn) -> } if CONFIG.mail_enabled() { - mail::send_invite(&user.email, &user.uuid, None, None, &CONFIG.invitation_org_name(), None).await + mail::send_invite(&user, None, None, &CONFIG.invitation_org_name(), None).await } else { Ok(()) } diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index f1def030..e0c3f081 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -956,8 +956,7 @@ async fn send_invite(org_id: &str, data: Json, headers: AdminHeaders }; mail::send_invite( - &email, - &user.uuid, + &user, Some(String::from(org_id)), Some(new_user.uuid), &org_name, @@ -1033,8 +1032,7 @@ async fn _reinvite_user(org_id: &str, user_org: &str, invited_by_email: &str, co if CONFIG.mail_enabled() { mail::send_invite( - &user.email, - &user.uuid, + &user, Some(org_id.to_string()), Some(user_org.uuid), &org_name, @@ -2037,8 +2035,7 @@ async fn import(org_id: &str, data: Json, headers: Headers, mut c }; mail::send_invite( - &user_data.email, - &user.uuid, + &user, Some(String::from(org_id)), Some(new_org_user.uuid), &org_name, diff --git a/src/api/core/public.rs b/src/api/core/public.rs index 0cdcbb63..32b64463 100644 --- a/src/api/core/public.rs +++ b/src/api/core/public.rs @@ -123,15 +123,8 @@ async fn ldap_import(data: Json, token: PublicToken, mut conn: Db None => err!("Error looking up organization"), }; - mail::send_invite( - &user_data.email, - &user.uuid, - Some(org_id.clone()), - Some(new_org_user.uuid), - &org_name, - Some(org_email), - ) - .await?; + mail::send_invite(&user, Some(org_id.clone()), Some(new_org_user.uuid), &org_name, Some(org_email)) + .await?; } } } diff --git a/src/mail.rs b/src/mail.rs index 151554a1..ce570171 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -17,6 +17,7 @@ use crate::{ encode_jwt, generate_delete_claims, generate_emergency_access_invite_claims, generate_invite_claims, generate_verify_email_claims, }, + db::models::User, error::Error, CONFIG, }; @@ -229,37 +230,55 @@ pub async fn send_single_org_removed_from_org(address: &str, org_name: &str) -> } pub async fn send_invite( - address: &str, - uuid: &str, + user: &User, org_id: Option, org_user_id: Option, org_name: &str, invited_by_email: Option, ) -> EmptyResult { let claims = generate_invite_claims( - uuid.to_string(), - String::from(address), + user.uuid.clone(), + user.email.clone(), org_id.clone(), org_user_id.clone(), invited_by_email, ); let invite_token = encode_jwt(&claims); + let mut query = url::Url::parse("https://query.builder").unwrap(); + { + let mut query_params = query.query_pairs_mut(); + query_params + .append_pair("email", &user.email) + .append_pair("organizationName", org_name) + .append_pair("token", &invite_token); + if let Some(id) = org_id { + query_params.append_pair("organizationId", &id); + }; + if let Some(id) = org_user_id { + query_params.append_pair("organizationUserId", &id); + }; + if user.private_key.is_some() { + query_params.append_pair("orgUserHasExistingUser", "true"); + } + } + let query_string = match query.query() { + None => err!(format!("Failed to build invite URL query parameters")), + Some(query) => query, + }; + + // `url.Url` would place the anchor `#` after the query parameters + let url = format!("{}/#/accept-organization/?{}", CONFIG.domain(), query_string); let (subject, body_html, body_text) = get_text( "email/send_org_invite", json!({ - "url": CONFIG.domain(), + "url": url, "img_src": CONFIG._smtp_img_src(), - "org_id": org_id.as_deref().unwrap_or("_"), - "org_user_id": org_user_id.as_deref().unwrap_or("_"), - "email": percent_encode(address.as_bytes(), NON_ALPHANUMERIC).to_string(), - "org_name_encoded": percent_encode(org_name.as_bytes(), NON_ALPHANUMERIC).to_string(), "org_name": org_name, - "token": invite_token, }), )?; - send_email(address, &subject, body_html, body_text).await + send_email(&user.email, &subject, body_html, body_text).await } pub async fn send_emergency_access_invite( diff --git a/src/static/templates/email/send_org_invite.hbs b/src/static/templates/email/send_org_invite.hbs index be94d0e5..b2c46f50 100644 --- a/src/static/templates/email/send_org_invite.hbs +++ b/src/static/templates/email/send_org_invite.hbs @@ -3,8 +3,8 @@ Join {{{org_name}}} 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_encoded}}&token={{token}} +Click here to join: {{url}} If you do not wish to join this organization, you can safely ignore this email. -{{> email/email_footer_text }} \ No newline at end of file +{{> email/email_footer_text }} diff --git a/src/static/templates/email/send_org_invite.html.hbs b/src/static/templates/email/send_org_invite.html.hbs index 55b98145..a78a89e9 100644 --- a/src/static/templates/email/send_org_invite.html.hbs +++ b/src/static/templates/email/send_org_invite.html.hbs @@ -9,7 +9,7 @@ Join {{{org_name}}} - Join Organization Now @@ -21,4 +21,4 @@ Join {{{org_name}}} -{{> email/email_footer }} \ No newline at end of file +{{> email/email_footer }}