diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs index 8331dff95c1b..c48fe3320f3d 100644 --- a/crates/router/src/types/domain/user.rs +++ b/crates/router/src/types/domain/user.rs @@ -1,4 +1,8 @@ -use std::{collections::HashSet, ops, str::FromStr}; +use std::{ + collections::HashSet, + ops::{Deref, Not}, + str::FromStr, +}; use api_models::{ admin as admin_api, organization as api_org, user as user_api, user_role as user_role_api, @@ -153,7 +157,7 @@ impl TryFrom for UserEmail { } } -impl ops::Deref for UserEmail { +impl Deref for UserEmail { type Target = Secret; fn deref(&self) -> &Self::Target { @@ -565,10 +569,24 @@ pub struct NewUser { user_id: String, name: UserName, email: UserEmail, - password: Option, + password: Option, new_merchant: NewUserMerchant, } +#[derive(Clone)] +pub struct NewUserPassword { + password: UserPassword, + is_temporary: bool, +} + +impl Deref for NewUserPassword { + type Target = UserPassword; + + fn deref(&self) -> &Self::Target { + &self.password + } +} + impl NewUser { pub fn get_user_id(&self) -> String { self.user_id.clone() @@ -587,7 +605,9 @@ impl NewUser { } pub fn get_password(&self) -> Option { - self.password.clone() + self.password + .as_ref() + .map(|password| password.deref().clone()) } pub async fn insert_user_in_db( @@ -697,7 +717,9 @@ impl TryFrom for storage_user::UserNew { totp_status: TotpStatus::NotSet, totp_secret: None, totp_recovery_codes: None, - last_password_modified_at: value.password.is_some().then_some(now), + last_password_modified_at: value + .password + .and_then(|password_inner| password_inner.is_temporary.not().then_some(now)), }) } } @@ -708,7 +730,10 @@ impl TryFrom for NewUser { fn try_from(value: user_api::SignUpWithMerchantIdRequest) -> UserResult { let email = value.email.clone().try_into()?; let name = UserName::new(value.name.clone())?; - let password = UserPassword::new(value.password.clone())?; + let password = NewUserPassword { + password: UserPassword::new(value.password.clone())?, + is_temporary: false, + }; let user_id = uuid::Uuid::new_v4().to_string(); let new_merchant = NewUserMerchant::try_from(value)?; @@ -729,7 +754,10 @@ impl TryFrom for NewUser { let user_id = uuid::Uuid::new_v4().to_string(); let email = value.email.clone().try_into()?; let name = UserName::try_from(value.email.clone())?; - let password = UserPassword::new(value.password.clone())?; + let password = NewUserPassword { + password: UserPassword::new(value.password.clone())?, + is_temporary: false, + }; let new_merchant = NewUserMerchant::try_from(value)?; Ok(Self { @@ -770,7 +798,10 @@ impl TryFrom<(user_api::CreateInternalUserRequest, id_type::OrganizationId)> for let user_id = uuid::Uuid::new_v4().to_string(); let email = value.email.clone().try_into()?; let name = UserName::new(value.name.clone())?; - let password = UserPassword::new(value.password.clone())?; + let password = NewUserPassword { + password: UserPassword::new(value.password.clone())?, + is_temporary: false, + }; let new_merchant = NewUserMerchant::try_from((value, org_id))?; Ok(Self { @@ -789,16 +820,21 @@ impl TryFrom for NewUser { fn try_from(value: UserMerchantCreateRequestWithToken) -> Result { let user = value.0.clone(); let new_merchant = NewUserMerchant::try_from(value)?; + let password = user + .0 + .password + .map(UserPassword::new_password_without_validation) + .transpose()? + .map(|password| NewUserPassword { + password, + is_temporary: false, + }); Ok(Self { user_id: user.0.user_id, name: UserName::new(user.0.name)?, email: user.0.email.clone().try_into()?, - password: user - .0 - .password - .map(UserPassword::new_password_without_validation) - .transpose()?, + password, new_merchant, }) } @@ -810,8 +846,10 @@ impl TryFrom for NewUser { let user_id = uuid::Uuid::new_v4().to_string(); let email = value.0.email.clone().try_into()?; let name = UserName::new(value.0.name.clone())?; - let password = cfg!(not(feature = "email")) - .then_some(UserPassword::new(password::get_temp_password())?); + let password = cfg!(not(feature = "email")).then_some(NewUserPassword { + password: UserPassword::new(password::get_temp_password())?, + is_temporary: true, + }); let new_merchant = NewUserMerchant::try_from(value)?; Ok(Self {