mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
fix(users): Add force rotate password on first login for non-email flow (#6483)
This commit is contained in:
@ -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<pii::Email> for UserEmail {
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Deref for UserEmail {
|
||||
impl Deref for UserEmail {
|
||||
type Target = Secret<String, pii::EmailStrategy>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
@ -565,10 +569,24 @@ pub struct NewUser {
|
||||
user_id: String,
|
||||
name: UserName,
|
||||
email: UserEmail,
|
||||
password: Option<UserPassword>,
|
||||
password: Option<NewUserPassword>,
|
||||
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<UserPassword> {
|
||||
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<NewUser> 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<user_api::SignUpWithMerchantIdRequest> for NewUser {
|
||||
fn try_from(value: user_api::SignUpWithMerchantIdRequest) -> UserResult<Self> {
|
||||
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<user_api::SignUpRequest> 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<UserMerchantCreateRequestWithToken> for NewUser {
|
||||
fn try_from(value: UserMerchantCreateRequestWithToken) -> Result<Self, Self::Error> {
|
||||
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<InviteeUserRequestWithInvitedUserToken> 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 {
|
||||
|
||||
Reference in New Issue
Block a user