Skip to content

Commit b0133f3

Browse files
authored
refactor(user): Deprecate Signin, Verify email and Invite v1 APIs (#4465)
1 parent 0c9ba1e commit b0133f3

File tree

7 files changed

+3
-351
lines changed

7 files changed

+3
-351
lines changed

crates/api_models/src/events/user.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use crate::user::{
1212
},
1313
AcceptInviteFromEmailRequest, AuthorizeResponse, ChangePasswordRequest, ConnectAccountRequest,
1414
CreateInternalUserRequest, DashboardEntryResponse, ForgotPasswordRequest,
15-
GetUserDetailsRequest, GetUserDetailsResponse, InviteUserRequest, InviteUserResponse,
16-
ListUsersResponse, ReInviteUserRequest, ResetPasswordRequest, SendVerifyEmailRequest,
17-
SignInResponse, SignUpRequest, SignUpWithMerchantIdRequest, SwitchMerchantIdRequest,
15+
GetUserDetailsRequest, GetUserDetailsResponse, InviteUserRequest, ListUsersResponse,
16+
ReInviteUserRequest, ResetPasswordRequest, SendVerifyEmailRequest, SignInResponse,
17+
SignUpRequest, SignUpWithMerchantIdRequest, SwitchMerchantIdRequest,
1818
UpdateUserAccountDetailsRequest, UserMerchantCreate, VerifyEmailRequest,
1919
};
2020

@@ -54,7 +54,6 @@ common_utils::impl_misc_api_event_type!(
5454
ForgotPasswordRequest,
5555
ResetPasswordRequest,
5656
InviteUserRequest,
57-
InviteUserResponse,
5857
ReInviteUserRequest,
5958
VerifyEmailRequest,
6059
SendVerifyEmailRequest,

crates/api_models/src/user.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,6 @@ pub struct InviteUserRequest {
9898
pub role_id: String,
9999
}
100100

101-
#[derive(Debug, serde::Serialize)]
102-
pub struct InviteUserResponse {
103-
pub is_email_sent: bool,
104-
pub password: Option<Secret<String>>,
105-
}
106-
107101
#[derive(Debug, serde::Serialize)]
108102
pub struct InviteMultipleUserResponse {
109103
pub email: pii::Email,

crates/router/src/core/user.rs

Lines changed: 0 additions & 266 deletions
Original file line numberDiff line numberDiff line change
@@ -100,34 +100,6 @@ pub async fn signup(
100100
auth::cookies::set_cookie_response(response, token)
101101
}
102102

103-
pub async fn signin_without_invite_checks(
104-
state: AppState,
105-
request: user_api::SignInRequest,
106-
) -> UserResponse<user_api::DashboardEntryResponse> {
107-
let user_from_db: domain::UserFromStorage = state
108-
.store
109-
.find_user_by_email(&request.email)
110-
.await
111-
.map_err(|e| {
112-
if e.current_context().is_db_not_found() {
113-
e.change_context(UserErrors::InvalidCredentials)
114-
} else {
115-
e.change_context(UserErrors::InternalServerError)
116-
}
117-
})?
118-
.into();
119-
120-
user_from_db.compare_password(request.password)?;
121-
122-
let user_role = user_from_db.get_role_from_db(state.clone()).await?;
123-
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
124-
125-
let token = utils::user::generate_jwt_auth_token(&state, &user_from_db, &user_role).await?;
126-
let response =
127-
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
128-
auth::cookies::set_cookie_response(response, token)
129-
}
130-
131103
pub async fn signin(
132104
state: AppState,
133105
request: user_api::SignInRequest,
@@ -424,206 +396,6 @@ pub async fn reset_password(
424396
Ok(ApplicationResponse::StatusOk)
425397
}
426398

427-
pub async fn invite_user(
428-
state: AppState,
429-
request: user_api::InviteUserRequest,
430-
user_from_token: auth::UserFromToken,
431-
req_state: ReqState,
432-
) -> UserResponse<user_api::InviteUserResponse> {
433-
let inviter_user = state
434-
.store
435-
.find_user_by_id(user_from_token.user_id.as_str())
436-
.await
437-
.change_context(UserErrors::InternalServerError)?;
438-
439-
if inviter_user.email == request.email {
440-
return Err(UserErrors::InvalidRoleOperationWithMessage(
441-
"User Inviting themselves".to_string(),
442-
)
443-
.into());
444-
}
445-
446-
let role_info = roles::RoleInfo::from_role_id(
447-
&state,
448-
&request.role_id,
449-
&user_from_token.merchant_id,
450-
&user_from_token.org_id,
451-
)
452-
.await
453-
.to_not_found_response(UserErrors::InvalidRoleId)?;
454-
455-
if !role_info.is_invitable() {
456-
return Err(report!(UserErrors::InvalidRoleId))
457-
.attach_printable(format!("role_id = {} is not invitable", request.role_id));
458-
}
459-
460-
let invitee_email = domain::UserEmail::from_pii_email(request.email.clone())?;
461-
462-
let invitee_user = state
463-
.store
464-
.find_user_by_email(&invitee_email.clone().into_inner())
465-
.await;
466-
467-
if let Ok(invitee_user) = invitee_user {
468-
let invitee_user_from_db = domain::UserFromStorage::from(invitee_user);
469-
470-
let now = common_utils::date_time::now();
471-
state
472-
.store
473-
.insert_user_role(UserRoleNew {
474-
user_id: invitee_user_from_db.get_user_id().to_owned(),
475-
merchant_id: user_from_token.merchant_id.clone(),
476-
role_id: request.role_id,
477-
org_id: user_from_token.org_id,
478-
status: {
479-
if cfg!(feature = "email") {
480-
UserStatus::InvitationSent
481-
} else {
482-
UserStatus::Active
483-
}
484-
},
485-
created_by: user_from_token.user_id.clone(),
486-
last_modified_by: user_from_token.user_id,
487-
created_at: now,
488-
last_modified: now,
489-
})
490-
.await
491-
.map_err(|e| {
492-
if e.current_context().is_db_unique_violation() {
493-
e.change_context(UserErrors::UserExists)
494-
} else {
495-
e.change_context(UserErrors::InternalServerError)
496-
}
497-
})?;
498-
499-
let is_email_sent;
500-
#[cfg(feature = "email")]
501-
{
502-
let email_contents = email_types::InviteRegisteredUser {
503-
recipient_email: invitee_email,
504-
user_name: domain::UserName::new(invitee_user_from_db.get_name())?,
505-
settings: state.conf.clone(),
506-
subject: "You have been invited to join Hyperswitch Community!",
507-
merchant_id: user_from_token.merchant_id,
508-
};
509-
510-
is_email_sent = state
511-
.email_client
512-
.compose_and_send_email(
513-
Box::new(email_contents),
514-
state.conf.proxy.https_url.as_ref(),
515-
)
516-
.await
517-
.map(|email_result| logger::info!(?email_result))
518-
.map_err(|email_result| logger::error!(?email_result))
519-
.is_ok();
520-
}
521-
#[cfg(not(feature = "email"))]
522-
{
523-
is_email_sent = false;
524-
}
525-
Ok(ApplicationResponse::Json(user_api::InviteUserResponse {
526-
is_email_sent,
527-
password: None,
528-
}))
529-
} else if invitee_user
530-
.as_ref()
531-
.map_err(|e| e.current_context().is_db_not_found())
532-
.err()
533-
.unwrap_or(false)
534-
{
535-
let new_user = domain::NewUser::try_from((request.clone(), user_from_token.clone()))?;
536-
537-
new_user
538-
.insert_user_in_db(state.store.as_ref())
539-
.await
540-
.change_context(UserErrors::InternalServerError)?;
541-
542-
let invitation_status = if cfg!(feature = "email") {
543-
UserStatus::InvitationSent
544-
} else {
545-
UserStatus::Active
546-
};
547-
548-
let now = common_utils::date_time::now();
549-
state
550-
.store
551-
.insert_user_role(UserRoleNew {
552-
user_id: new_user.get_user_id().to_owned(),
553-
merchant_id: user_from_token.merchant_id.clone(),
554-
role_id: request.role_id.clone(),
555-
org_id: user_from_token.org_id.clone(),
556-
status: invitation_status,
557-
created_by: user_from_token.user_id.clone(),
558-
last_modified_by: user_from_token.user_id,
559-
created_at: now,
560-
last_modified: now,
561-
})
562-
.await
563-
.map_err(|e| {
564-
if e.current_context().is_db_unique_violation() {
565-
e.change_context(UserErrors::UserExists)
566-
} else {
567-
e.change_context(UserErrors::InternalServerError)
568-
}
569-
})?;
570-
571-
let is_email_sent;
572-
#[cfg(feature = "email")]
573-
{
574-
// Doing this to avoid clippy lints
575-
// will add actual usage for this later
576-
let _ = req_state.clone();
577-
let email_contents = email_types::InviteUser {
578-
recipient_email: invitee_email,
579-
user_name: domain::UserName::new(new_user.get_name())?,
580-
settings: state.conf.clone(),
581-
subject: "You have been invited to join Hyperswitch Community!",
582-
merchant_id: user_from_token.merchant_id,
583-
};
584-
let send_email_result = state
585-
.email_client
586-
.compose_and_send_email(
587-
Box::new(email_contents),
588-
state.conf.proxy.https_url.as_ref(),
589-
)
590-
.await;
591-
logger::info!(?send_email_result);
592-
is_email_sent = send_email_result.is_ok();
593-
}
594-
#[cfg(not(feature = "email"))]
595-
{
596-
is_email_sent = false;
597-
let invited_user_token = auth::UserFromToken {
598-
user_id: new_user.get_user_id(),
599-
merchant_id: user_from_token.merchant_id,
600-
org_id: user_from_token.org_id,
601-
role_id: request.role_id,
602-
};
603-
604-
let set_metadata_request = SetMetaDataRequest::IsChangePasswordRequired;
605-
dashboard_metadata::set_metadata(
606-
state.clone(),
607-
invited_user_token,
608-
set_metadata_request,
609-
req_state,
610-
)
611-
.await?;
612-
}
613-
614-
Ok(ApplicationResponse::Json(user_api::InviteUserResponse {
615-
is_email_sent,
616-
password: if cfg!(not(feature = "email")) {
617-
Some(new_user.get_password().get_secret())
618-
} else {
619-
None
620-
},
621-
}))
622-
} else {
623-
Err(report!(UserErrors::InternalServerError))
624-
}
625-
}
626-
627399
pub async fn invite_multiple_user(
628400
state: AppState,
629401
user_from_token: auth::UserFromToken,
@@ -1317,44 +1089,6 @@ pub async fn list_users_for_merchant_account(
13171089
)))
13181090
}
13191091

1320-
#[cfg(feature = "email")]
1321-
pub async fn verify_email_without_invite_checks(
1322-
state: AppState,
1323-
req: user_api::VerifyEmailRequest,
1324-
) -> UserResponse<user_api::DashboardEntryResponse> {
1325-
let token = req.token.clone().expose();
1326-
let email_token = auth::decode_jwt::<email_types::EmailToken>(&token, &state)
1327-
.await
1328-
.change_context(UserErrors::LinkInvalid)?;
1329-
auth::blacklist::check_email_token_in_blacklist(&state, &token).await?;
1330-
let user = state
1331-
.store
1332-
.find_user_by_email(
1333-
&email_token
1334-
.get_email()
1335-
.change_context(UserErrors::InternalServerError)?,
1336-
)
1337-
.await
1338-
.change_context(UserErrors::InternalServerError)?;
1339-
let user = state
1340-
.store
1341-
.update_user_by_user_id(user.user_id.as_str(), storage_user::UserUpdate::VerifyUser)
1342-
.await
1343-
.change_context(UserErrors::InternalServerError)?;
1344-
let user_from_db: domain::UserFromStorage = user.into();
1345-
let user_role = user_from_db.get_role_from_db(state.clone()).await?;
1346-
let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token)
1347-
.await
1348-
.map_err(|e| logger::error!(?e));
1349-
let token = utils::user::generate_jwt_auth_token(&state, &user_from_db, &user_role).await?;
1350-
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
1351-
1352-
let response =
1353-
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
1354-
1355-
auth::cookies::set_cookie_response(response, token)
1356-
}
1357-
13581092
#[cfg(feature = "email")]
13591093
pub async fn verify_email(
13601094
state: AppState,

crates/router/src/routes/app.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,9 +1160,6 @@ impl User {
11601160
let mut route = web::scope("/user").app_data(web::Data::new(state));
11611161

11621162
route = route
1163-
.service(
1164-
web::resource("/signin").route(web::post().to(user_signin_without_invite_checks)),
1165-
)
11661163
.service(web::resource("/v2/signin").route(web::post().to(user_signin)))
11671164
.service(web::resource("/signout").route(web::post().to(signout)))
11681165
.service(web::resource("/change_password").route(web::post().to(change_password)))
@@ -1195,10 +1192,6 @@ impl User {
11951192
web::resource("/signup_with_merchant_id")
11961193
.route(web::post().to(user_signup_with_merchant_id)),
11971194
)
1198-
.service(
1199-
web::resource("/verify_email")
1200-
.route(web::post().to(verify_email_without_invite_checks)),
1201-
)
12021195
.service(web::resource("/v2/verify_email").route(web::post().to(verify_email)))
12031196
.service(
12041197
web::resource("/verify_email_request")
@@ -1222,7 +1215,6 @@ impl User {
12221215
.service(
12231216
web::resource("/list").route(web::get().to(list_users_for_merchant_account)),
12241217
)
1225-
.service(web::resource("/invite").route(web::post().to(invite_user)))
12261218
.service(
12271219
web::resource("/invite_multiple").route(web::post().to(invite_multiple_user)),
12281220
)

crates/router/src/routes/lock_utils.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ impl From<Flow> for ApiIdentifier {
184184

185185
Flow::UserConnectAccount
186186
| Flow::UserSignUp
187-
| Flow::UserSignInWithoutInviteChecks
188187
| Flow::UserSignIn
189188
| Flow::Signout
190189
| Flow::ChangePassword
@@ -201,11 +200,9 @@ impl From<Flow> for ApiIdentifier {
201200
| Flow::ListUsersForMerchantAccount
202201
| Flow::ForgotPassword
203202
| Flow::ResetPassword
204-
| Flow::InviteUser
205203
| Flow::InviteMultipleUser
206204
| Flow::ReInviteUser
207205
| Flow::UserSignUpWithMerchantId
208-
| Flow::VerifyEmailWithoutInviteChecks
209206
| Flow::VerifyEmail
210207
| Flow::AcceptInviteFromEmail
211208
| Flow::VerifyEmailRequest

0 commit comments

Comments
 (0)