From a89fc946b9a3a4d611de3cde301eeb216604b99b Mon Sep 17 00:00:00 2001 From: tom27052006 <83423411+tom27052006@users.noreply.github.com> Date: Wed, 30 Sep 2026 12:34:31 +0200 Subject: [PATCH] Add registration email verification clicked endpoint --- src/api/identity.rs | 27 +++++++++++++++++++++++++++ src/mail.rs | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/api/identity.rs b/src/api/identity.rs index 6808ddde..37d0adc4 100644 --- a/src/api/identity.rs +++ b/src/api/identity.rs @@ -48,6 +48,7 @@ pub fn routes() -> Vec { prelogin_password, identity_register, register_verification_email, + register_verification_email_clicked, register_finish, prevalidate, authorize, @@ -1078,6 +1079,13 @@ struct RegisterVerificationData { // receiveMarketingEmails: bool, } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct RegisterVerificationEmailClickedData { + email: String, + email_verification_token: String, +} + #[derive(rocket::Responder)] enum RegisterVerificationResponse { #[response(status = 204)] @@ -1140,6 +1148,25 @@ async fn register_verification_email( } } +#[post("/accounts/register/verification-email-clicked", data = "")] +async fn register_verification_email_clicked( + data: Json, + conn: DbConn, +) -> EmptyResult { + let data = data.into_inner(); + let token_valid = auth::decode_register_verify(&data.email_verification_token) + .is_ok_and(|claims| claims.verified && claims.sub.eq_ignore_ascii_case(&data.email)); + let user_exists = User::find_by_mail(&data.email, &conn) + .await + .is_some_and(|user| !user.password_hash.is_empty() || user.private_key.is_some()); + + if !token_valid || user_exists { + err!("Expired link. Please restart registration or try logging in. You may already have an account") + } + + Ok(()) +} + #[post("/accounts/register/finish", data = "")] async fn register_finish(data: Json, conn: DbConn) -> JsonResult { register(data, true, conn).await diff --git a/src/mail.rs b/src/mail.rs index b20f2853..9350a8b3 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -206,7 +206,7 @@ pub async fn send_verify_email(address: &str, user_id: &UserId) -> EmptyResult { pub async fn send_register_verify_email(email: &str, token: &str) -> EmptyResult { let mut query = url::Url::parse("https://query.builder").unwrap(); - query.query_pairs_mut().append_pair("email", email).append_pair("token", token); + query.query_pairs_mut().append_pair("email", email).append_pair("token", token).append_pair("fromEmail", "true"); let Some(query_string) = query.query() else { err!("Failed to build verify URL query parameters") };