From 2852a3ba156e3e2bd89d0a116990134268e7bee8 Mon Sep 17 00:00:00 2001 From: Mani Chandra <84711804+ThisIsMani@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:14:48 +0530 Subject: [PATCH] fix(users): Magic link is not expiring after one usage (#4971) --- crates/router/src/core/user.rs | 38 +++++++++++++------ crates/router/src/types/domain/user.rs | 4 ++ .../src/types/domain/user/decision_manager.rs | 8 ++-- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs index c78f2c8080..7e79e9e2e8 100644 --- a/crates/router/src/core/user.rs +++ b/crates/router/src/core/user.rs @@ -505,10 +505,8 @@ pub async fn reset_password_token_only_flow( let user = state .global_store - .update_user_by_email( - &email_token - .get_email() - .change_context(UserErrors::InternalServerError)?, + .update_user_by_user_id( + user_from_db.get_user_id(), storage_user::UserUpdate::PasswordUpdate { password: hash_password, }, @@ -516,6 +514,17 @@ pub async fn reset_password_token_only_flow( .await .change_context(UserErrors::InternalServerError)?; + if !user_from_db.is_verified() { + let _ = state + .global_store + .update_user_by_user_id( + user_from_db.get_user_id(), + storage_user::UserUpdate::VerifyUser, + ) + .await + .map_err(|e| logger::error!(?e)); + } + let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token) .await .map_err(|e| logger::error!(?e)); @@ -1021,6 +1030,17 @@ pub async fn accept_invite_from_email_token_only_flow( .await .change_context(UserErrors::InternalServerError)?; + if !user_from_db.is_verified() { + let _ = state + .global_store + .update_user_by_user_id( + user_from_db.get_user_id(), + storage_user::UserUpdate::VerifyUser, + ) + .await + .map_err(|e| logger::error!(?e)); + } + let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token) .await .map_err(|e| logger::error!(?e)); @@ -1476,13 +1496,9 @@ pub async fn verify_email_token_only_flow( .change_context(UserErrors::InternalServerError)? .into(); - if matches!(user_token.origin, domain::Origin::VerifyEmail) - || matches!(user_token.origin, domain::Origin::MagicLink) - { - let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token) - .await - .map_err(|e| logger::error!(?e)); - } + let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token) + .await + .map_err(|e| logger::error!(?e)); let current_flow = domain::CurrentFlow::new(user_token.origin, domain::SPTFlow::VerifyEmail.into())?; diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs index 47f26ce04e..5ff79b7fee 100644 --- a/crates/router/src/types/domain/user.rs +++ b/crates/router/src/types/domain/user.rs @@ -837,6 +837,10 @@ impl UserFromStorage { Ok(Some(days_left_for_verification.whole_days())) } + pub fn is_verified(&self) -> bool { + self.0.is_verified + } + pub fn is_password_rotate_required(&self, state: &SessionState) -> UserResult { let last_password_modified_at = if let Some(last_password_modified_at) = self.0.last_password_modified_at { diff --git a/crates/router/src/types/domain/user/decision_manager.rs b/crates/router/src/types/domain/user/decision_manager.rs index 41ae12350f..2ee9b38978 100644 --- a/crates/router/src/types/domain/user/decision_manager.rs +++ b/crates/router/src/types/domain/user/decision_manager.rs @@ -42,7 +42,7 @@ impl SPTFlow { Self::TOTP => Ok(true), // Main email APIs Self::AcceptInvitationFromEmail | Self::ResetPassword => Ok(true), - Self::VerifyEmail => Ok(!user.0.is_verified), + Self::VerifyEmail => Ok(true), // Final Checks Self::ForceSetPassword => user.is_password_rotate_required(state), Self::MerchantSelect => user @@ -154,17 +154,15 @@ const VERIFY_EMAIL_FLOW: [UserFlow; 5] = [ UserFlow::JWTFlow(JWTFlow::UserInfo), ]; -const ACCEPT_INVITATION_FROM_EMAIL_FLOW: [UserFlow; 5] = [ +const ACCEPT_INVITATION_FROM_EMAIL_FLOW: [UserFlow; 4] = [ UserFlow::SPTFlow(SPTFlow::TOTP), - UserFlow::SPTFlow(SPTFlow::VerifyEmail), UserFlow::SPTFlow(SPTFlow::AcceptInvitationFromEmail), UserFlow::SPTFlow(SPTFlow::ForceSetPassword), UserFlow::JWTFlow(JWTFlow::UserInfo), ]; -const RESET_PASSWORD_FLOW: [UserFlow; 3] = [ +const RESET_PASSWORD_FLOW: [UserFlow; 2] = [ UserFlow::SPTFlow(SPTFlow::TOTP), - UserFlow::SPTFlow(SPTFlow::VerifyEmail), UserFlow::SPTFlow(SPTFlow::ResetPassword), ];