Add orgUserHasExistingUser parameters to org invite (#4827)

This commit is contained in:
Timshel 2024-09-01 15:55:41 +02:00 committed by GitHub
parent 55623ad9c6
commit 248e561b3f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 41 additions and 32 deletions

View file

@ -298,7 +298,7 @@ async fn invite_user(data: Json<InviteData>, _token: AdminToken, mut conn: DbCon
async fn _generate_invite(user: &User, conn: &mut DbConn) -> EmptyResult { async fn _generate_invite(user: &User, conn: &mut DbConn) -> EmptyResult {
if CONFIG.mail_enabled() { 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 { } else {
let invitation = Invitation::new(&user.email); let invitation = Invitation::new(&user.email);
invitation.save(conn).await invitation.save(conn).await
@ -474,7 +474,7 @@ async fn resend_user_invite(uuid: &str, _token: AdminToken, mut conn: DbConn) ->
} }
if CONFIG.mail_enabled() { 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 { } else {
Ok(()) Ok(())
} }

View file

@ -956,8 +956,7 @@ async fn send_invite(org_id: &str, data: Json<InviteData>, headers: AdminHeaders
}; };
mail::send_invite( mail::send_invite(
&email, &user,
&user.uuid,
Some(String::from(org_id)), Some(String::from(org_id)),
Some(new_user.uuid), Some(new_user.uuid),
&org_name, &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() { if CONFIG.mail_enabled() {
mail::send_invite( mail::send_invite(
&user.email, &user,
&user.uuid,
Some(org_id.to_string()), Some(org_id.to_string()),
Some(user_org.uuid), Some(user_org.uuid),
&org_name, &org_name,
@ -2037,8 +2035,7 @@ async fn import(org_id: &str, data: Json<OrgImportData>, headers: Headers, mut c
}; };
mail::send_invite( mail::send_invite(
&user_data.email, &user,
&user.uuid,
Some(String::from(org_id)), Some(String::from(org_id)),
Some(new_org_user.uuid), Some(new_org_user.uuid),
&org_name, &org_name,

View file

@ -123,15 +123,8 @@ async fn ldap_import(data: Json<OrgImportData>, token: PublicToken, mut conn: Db
None => err!("Error looking up organization"), None => err!("Error looking up organization"),
}; };
mail::send_invite( mail::send_invite(&user, Some(org_id.clone()), Some(new_org_user.uuid), &org_name, Some(org_email))
&user_data.email, .await?;
&user.uuid,
Some(org_id.clone()),
Some(new_org_user.uuid),
&org_name,
Some(org_email),
)
.await?;
} }
} }
} }

View file

@ -17,6 +17,7 @@ use crate::{
encode_jwt, generate_delete_claims, generate_emergency_access_invite_claims, generate_invite_claims, encode_jwt, generate_delete_claims, generate_emergency_access_invite_claims, generate_invite_claims,
generate_verify_email_claims, generate_verify_email_claims,
}, },
db::models::User,
error::Error, error::Error,
CONFIG, CONFIG,
}; };
@ -229,37 +230,55 @@ pub async fn send_single_org_removed_from_org(address: &str, org_name: &str) ->
} }
pub async fn send_invite( pub async fn send_invite(
address: &str, user: &User,
uuid: &str,
org_id: Option<String>, org_id: Option<String>,
org_user_id: Option<String>, org_user_id: Option<String>,
org_name: &str, org_name: &str,
invited_by_email: Option<String>, invited_by_email: Option<String>,
) -> EmptyResult { ) -> EmptyResult {
let claims = generate_invite_claims( let claims = generate_invite_claims(
uuid.to_string(), user.uuid.clone(),
String::from(address), user.email.clone(),
org_id.clone(), org_id.clone(),
org_user_id.clone(), org_user_id.clone(),
invited_by_email, invited_by_email,
); );
let invite_token = encode_jwt(&claims); 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( let (subject, body_html, body_text) = get_text(
"email/send_org_invite", "email/send_org_invite",
json!({ json!({
"url": CONFIG.domain(), "url": url,
"img_src": CONFIG._smtp_img_src(), "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, "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( pub async fn send_emergency_access_invite(

View file

@ -3,8 +3,8 @@ Join {{{org_name}}}
You have been invited to join the *{{org_name}}* organization. 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. If you do not wish to join this organization, you can safely ignore this email.
{{> email/email_footer_text }} {{> email/email_footer_text }}

View file

@ -9,7 +9,7 @@ Join {{{org_name}}}
</tr> </tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"> <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none; text-align: center;" valign="top" align="center"> <td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none; text-align: center;" valign="top" align="center">
<a href="{{url}}/#/accept-organization/?organizationId={{org_id}}&organizationUserId={{org_user_id}}&email={{email}}&organizationName={{org_name_encoded}}&token={{token}}" <a href="{{url}}"
clicktracking=off target="_blank" style="color: #ffffff; text-decoration: none; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; background-color: #3c8dbc; border-color: #3c8dbc; border-style: solid; border-width: 10px 20px; margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"> clicktracking=off target="_blank" style="color: #ffffff; text-decoration: none; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; background-color: #3c8dbc; border-color: #3c8dbc; border-style: solid; border-width: 10px 20px; margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
Join Organization Now Join Organization Now
</a> </a>
@ -21,4 +21,4 @@ Join {{{org_name}}}
</td> </td>
</tr> </tr>
</table> </table>
{{> email/email_footer }} {{> email/email_footer }}