mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-04 05:59:48 +08:00
refactor(user): Deprecate Signin, Verify email and Invite v1 APIs (#4465)
This commit is contained in:
@ -100,34 +100,6 @@ pub async fn signup(
|
||||
auth::cookies::set_cookie_response(response, token)
|
||||
}
|
||||
|
||||
pub async fn signin_without_invite_checks(
|
||||
state: AppState,
|
||||
request: user_api::SignInRequest,
|
||||
) -> UserResponse<user_api::DashboardEntryResponse> {
|
||||
let user_from_db: domain::UserFromStorage = state
|
||||
.store
|
||||
.find_user_by_email(&request.email)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if e.current_context().is_db_not_found() {
|
||||
e.change_context(UserErrors::InvalidCredentials)
|
||||
} else {
|
||||
e.change_context(UserErrors::InternalServerError)
|
||||
}
|
||||
})?
|
||||
.into();
|
||||
|
||||
user_from_db.compare_password(request.password)?;
|
||||
|
||||
let user_role = user_from_db.get_role_from_db(state.clone()).await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
|
||||
let token = utils::user::generate_jwt_auth_token(&state, &user_from_db, &user_role).await?;
|
||||
let response =
|
||||
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
|
||||
auth::cookies::set_cookie_response(response, token)
|
||||
}
|
||||
|
||||
pub async fn signin(
|
||||
state: AppState,
|
||||
request: user_api::SignInRequest,
|
||||
@ -424,206 +396,6 @@ pub async fn reset_password(
|
||||
Ok(ApplicationResponse::StatusOk)
|
||||
}
|
||||
|
||||
pub async fn invite_user(
|
||||
state: AppState,
|
||||
request: user_api::InviteUserRequest,
|
||||
user_from_token: auth::UserFromToken,
|
||||
req_state: ReqState,
|
||||
) -> UserResponse<user_api::InviteUserResponse> {
|
||||
let inviter_user = state
|
||||
.store
|
||||
.find_user_by_id(user_from_token.user_id.as_str())
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
if inviter_user.email == request.email {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"User Inviting themselves".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let role_info = roles::RoleInfo::from_role_id(
|
||||
&state,
|
||||
&request.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleId)?;
|
||||
|
||||
if !role_info.is_invitable() {
|
||||
return Err(report!(UserErrors::InvalidRoleId))
|
||||
.attach_printable(format!("role_id = {} is not invitable", request.role_id));
|
||||
}
|
||||
|
||||
let invitee_email = domain::UserEmail::from_pii_email(request.email.clone())?;
|
||||
|
||||
let invitee_user = state
|
||||
.store
|
||||
.find_user_by_email(&invitee_email.clone().into_inner())
|
||||
.await;
|
||||
|
||||
if let Ok(invitee_user) = invitee_user {
|
||||
let invitee_user_from_db = domain::UserFromStorage::from(invitee_user);
|
||||
|
||||
let now = common_utils::date_time::now();
|
||||
state
|
||||
.store
|
||||
.insert_user_role(UserRoleNew {
|
||||
user_id: invitee_user_from_db.get_user_id().to_owned(),
|
||||
merchant_id: user_from_token.merchant_id.clone(),
|
||||
role_id: request.role_id,
|
||||
org_id: user_from_token.org_id,
|
||||
status: {
|
||||
if cfg!(feature = "email") {
|
||||
UserStatus::InvitationSent
|
||||
} else {
|
||||
UserStatus::Active
|
||||
}
|
||||
},
|
||||
created_by: user_from_token.user_id.clone(),
|
||||
last_modified_by: user_from_token.user_id,
|
||||
created_at: now,
|
||||
last_modified: now,
|
||||
})
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if e.current_context().is_db_unique_violation() {
|
||||
e.change_context(UserErrors::UserExists)
|
||||
} else {
|
||||
e.change_context(UserErrors::InternalServerError)
|
||||
}
|
||||
})?;
|
||||
|
||||
let is_email_sent;
|
||||
#[cfg(feature = "email")]
|
||||
{
|
||||
let email_contents = email_types::InviteRegisteredUser {
|
||||
recipient_email: invitee_email,
|
||||
user_name: domain::UserName::new(invitee_user_from_db.get_name())?,
|
||||
settings: state.conf.clone(),
|
||||
subject: "You have been invited to join Hyperswitch Community!",
|
||||
merchant_id: user_from_token.merchant_id,
|
||||
};
|
||||
|
||||
is_email_sent = state
|
||||
.email_client
|
||||
.compose_and_send_email(
|
||||
Box::new(email_contents),
|
||||
state.conf.proxy.https_url.as_ref(),
|
||||
)
|
||||
.await
|
||||
.map(|email_result| logger::info!(?email_result))
|
||||
.map_err(|email_result| logger::error!(?email_result))
|
||||
.is_ok();
|
||||
}
|
||||
#[cfg(not(feature = "email"))]
|
||||
{
|
||||
is_email_sent = false;
|
||||
}
|
||||
Ok(ApplicationResponse::Json(user_api::InviteUserResponse {
|
||||
is_email_sent,
|
||||
password: None,
|
||||
}))
|
||||
} else if invitee_user
|
||||
.as_ref()
|
||||
.map_err(|e| e.current_context().is_db_not_found())
|
||||
.err()
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let new_user = domain::NewUser::try_from((request.clone(), user_from_token.clone()))?;
|
||||
|
||||
new_user
|
||||
.insert_user_in_db(state.store.as_ref())
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let invitation_status = if cfg!(feature = "email") {
|
||||
UserStatus::InvitationSent
|
||||
} else {
|
||||
UserStatus::Active
|
||||
};
|
||||
|
||||
let now = common_utils::date_time::now();
|
||||
state
|
||||
.store
|
||||
.insert_user_role(UserRoleNew {
|
||||
user_id: new_user.get_user_id().to_owned(),
|
||||
merchant_id: user_from_token.merchant_id.clone(),
|
||||
role_id: request.role_id.clone(),
|
||||
org_id: user_from_token.org_id.clone(),
|
||||
status: invitation_status,
|
||||
created_by: user_from_token.user_id.clone(),
|
||||
last_modified_by: user_from_token.user_id,
|
||||
created_at: now,
|
||||
last_modified: now,
|
||||
})
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if e.current_context().is_db_unique_violation() {
|
||||
e.change_context(UserErrors::UserExists)
|
||||
} else {
|
||||
e.change_context(UserErrors::InternalServerError)
|
||||
}
|
||||
})?;
|
||||
|
||||
let is_email_sent;
|
||||
#[cfg(feature = "email")]
|
||||
{
|
||||
// Doing this to avoid clippy lints
|
||||
// will add actual usage for this later
|
||||
let _ = req_state.clone();
|
||||
let email_contents = email_types::InviteUser {
|
||||
recipient_email: invitee_email,
|
||||
user_name: domain::UserName::new(new_user.get_name())?,
|
||||
settings: state.conf.clone(),
|
||||
subject: "You have been invited to join Hyperswitch Community!",
|
||||
merchant_id: user_from_token.merchant_id,
|
||||
};
|
||||
let send_email_result = state
|
||||
.email_client
|
||||
.compose_and_send_email(
|
||||
Box::new(email_contents),
|
||||
state.conf.proxy.https_url.as_ref(),
|
||||
)
|
||||
.await;
|
||||
logger::info!(?send_email_result);
|
||||
is_email_sent = send_email_result.is_ok();
|
||||
}
|
||||
#[cfg(not(feature = "email"))]
|
||||
{
|
||||
is_email_sent = false;
|
||||
let invited_user_token = auth::UserFromToken {
|
||||
user_id: new_user.get_user_id(),
|
||||
merchant_id: user_from_token.merchant_id,
|
||||
org_id: user_from_token.org_id,
|
||||
role_id: request.role_id,
|
||||
};
|
||||
|
||||
let set_metadata_request = SetMetaDataRequest::IsChangePasswordRequired;
|
||||
dashboard_metadata::set_metadata(
|
||||
state.clone(),
|
||||
invited_user_token,
|
||||
set_metadata_request,
|
||||
req_state,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(ApplicationResponse::Json(user_api::InviteUserResponse {
|
||||
is_email_sent,
|
||||
password: if cfg!(not(feature = "email")) {
|
||||
Some(new_user.get_password().get_secret())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}))
|
||||
} else {
|
||||
Err(report!(UserErrors::InternalServerError))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn invite_multiple_user(
|
||||
state: AppState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
@ -1317,44 +1089,6 @@ pub async fn list_users_for_merchant_account(
|
||||
)))
|
||||
}
|
||||
|
||||
#[cfg(feature = "email")]
|
||||
pub async fn verify_email_without_invite_checks(
|
||||
state: AppState,
|
||||
req: user_api::VerifyEmailRequest,
|
||||
) -> UserResponse<user_api::DashboardEntryResponse> {
|
||||
let token = req.token.clone().expose();
|
||||
let email_token = auth::decode_jwt::<email_types::EmailToken>(&token, &state)
|
||||
.await
|
||||
.change_context(UserErrors::LinkInvalid)?;
|
||||
auth::blacklist::check_email_token_in_blacklist(&state, &token).await?;
|
||||
let user = state
|
||||
.store
|
||||
.find_user_by_email(
|
||||
&email_token
|
||||
.get_email()
|
||||
.change_context(UserErrors::InternalServerError)?,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
let user = state
|
||||
.store
|
||||
.update_user_by_user_id(user.user_id.as_str(), storage_user::UserUpdate::VerifyUser)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
let user_from_db: domain::UserFromStorage = user.into();
|
||||
let user_role = user_from_db.get_role_from_db(state.clone()).await?;
|
||||
let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token)
|
||||
.await
|
||||
.map_err(|e| logger::error!(?e));
|
||||
let token = utils::user::generate_jwt_auth_token(&state, &user_from_db, &user_role).await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
|
||||
let response =
|
||||
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
|
||||
|
||||
auth::cookies::set_cookie_response(response, token)
|
||||
}
|
||||
|
||||
#[cfg(feature = "email")]
|
||||
pub async fn verify_email(
|
||||
state: AppState,
|
||||
|
||||
Reference in New Issue
Block a user