mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	feat(user): add support for resend invite (#3523)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -706,6 +706,63 @@ async fn handle_new_user_invitation( | ||||
|     }) | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "email")] | ||||
| pub async fn resend_invite( | ||||
|     state: AppState, | ||||
|     user_from_token: auth::UserFromToken, | ||||
|     request: user_api::ReInviteUserRequest, | ||||
| ) -> UserResponse<()> { | ||||
|     let invitee_email = domain::UserEmail::from_pii_email(request.email)?; | ||||
|     let user: domain::UserFromStorage = state | ||||
|         .store | ||||
|         .find_user_by_email(invitee_email.clone().get_secret().expose().as_str()) | ||||
|         .await | ||||
|         .map_err(|e| { | ||||
|             if e.current_context().is_db_not_found() { | ||||
|                 e.change_context(UserErrors::InvalidRoleOperation) | ||||
|                     .attach_printable("User not found in the records") | ||||
|             } else { | ||||
|                 e.change_context(UserErrors::InternalServerError) | ||||
|             } | ||||
|         })? | ||||
|         .into(); | ||||
|     let user_role = state | ||||
|         .store | ||||
|         .find_user_role_by_user_id_merchant_id(user.get_user_id(), &user_from_token.merchant_id) | ||||
|         .await | ||||
|         .map_err(|e| { | ||||
|             if e.current_context().is_db_not_found() { | ||||
|                 e.change_context(UserErrors::InvalidRoleOperation) | ||||
|                     .attach_printable("User role with given UserId MerchantId not found") | ||||
|             } else { | ||||
|                 e.change_context(UserErrors::InternalServerError) | ||||
|             } | ||||
|         })?; | ||||
|  | ||||
|     if !matches!(user_role.status, UserStatus::InvitationSent) { | ||||
|         return Err(UserErrors::InvalidRoleOperation.into()) | ||||
|             .attach_printable("Invalid Status for Reinvitation"); | ||||
|     } | ||||
|  | ||||
|     let email_contents = email_types::InviteUser { | ||||
|         recipient_email: invitee_email, | ||||
|         user_name: domain::UserName::new(user.get_name())?, | ||||
|         settings: state.conf.clone(), | ||||
|         subject: "You have been invited to join Hyperswitch Community!", | ||||
|         merchant_id: user_from_token.merchant_id, | ||||
|     }; | ||||
|     state | ||||
|         .email_client | ||||
|         .compose_and_send_email( | ||||
|             Box::new(email_contents), | ||||
|             state.conf.proxy.https_url.as_ref(), | ||||
|         ) | ||||
|         .await | ||||
|         .change_context(UserErrors::InternalServerError)?; | ||||
|  | ||||
|     Ok(ApplicationResponse::StatusOk) | ||||
| } | ||||
|  | ||||
| pub async fn create_internal_user( | ||||
|     state: AppState, | ||||
|     request: user_api::CreateInternalUserRequest, | ||||
|  | ||||
| @ -976,41 +976,12 @@ impl User { | ||||
|             .service(web::resource("/switch/list").route(web::get().to(list_merchant_ids_for_user))) | ||||
|             .service(web::resource("/permission_info").route(web::get().to(get_authorization_info))) | ||||
|             .service(web::resource("/update").route(web::post().to(update_user_account_details))) | ||||
|             .service( | ||||
|                 web::resource("/user/invite_multiple").route(web::post().to(invite_multiple_user)), | ||||
|             ) | ||||
|             .service( | ||||
|                 web::resource("/data") | ||||
|                     .route(web::get().to(get_multiple_dashboard_metadata)) | ||||
|                     .route(web::post().to(set_dashboard_metadata)), | ||||
|             ) | ||||
|             .service(web::resource("/user/delete").route(web::delete().to(delete_user_role))); | ||||
|             ); | ||||
|  | ||||
|         // User management | ||||
|         route = route.service( | ||||
|             web::scope("/user") | ||||
|                 .service(web::resource("/list").route(web::get().to(get_user_details))) | ||||
|                 .service(web::resource("/invite").route(web::post().to(invite_user))) | ||||
|                 .service(web::resource("/invite/accept").route(web::post().to(accept_invitation))) | ||||
|                 .service(web::resource("/update_role").route(web::post().to(update_user_role))), | ||||
|         ); | ||||
|  | ||||
|         // Role information | ||||
|         route = route.service( | ||||
|             web::scope("/role") | ||||
|                 .service(web::resource("").route(web::get().to(get_role_from_token))) | ||||
|                 .service(web::resource("/list").route(web::get().to(list_all_roles))) | ||||
|                 .service(web::resource("/{role_id}").route(web::get().to(get_role))), | ||||
|         ); | ||||
|  | ||||
|         #[cfg(feature = "dummy_connector")] | ||||
|         { | ||||
|             route = route.service( | ||||
|                 web::resource("/sample_data") | ||||
|                     .route(web::post().to(generate_sample_data)) | ||||
|                     .route(web::delete().to(delete_sample_data)), | ||||
|             ) | ||||
|         } | ||||
|         #[cfg(feature = "email")] | ||||
|         { | ||||
|             route = route | ||||
| @ -1031,12 +1002,43 @@ impl User { | ||||
|                 .service( | ||||
|                     web::resource("/verify_email_request") | ||||
|                         .route(web::post().to(verify_email_request)), | ||||
|                 ); | ||||
|                 ) | ||||
|                 .service(web::resource("/user/resend_invite").route(web::post().to(resend_invite))); | ||||
|         } | ||||
|         #[cfg(not(feature = "email"))] | ||||
|         { | ||||
|             route = route.service(web::resource("/signup").route(web::post().to(user_signup))) | ||||
|         } | ||||
|  | ||||
|         // User management | ||||
|         route = route.service( | ||||
|             web::scope("/user") | ||||
|                 .service(web::resource("/list").route(web::get().to(get_user_details))) | ||||
|                 .service(web::resource("/invite").route(web::post().to(invite_user))) | ||||
|                 .service( | ||||
|                     web::resource("/invite_multiple").route(web::post().to(invite_multiple_user)), | ||||
|                 ) | ||||
|                 .service(web::resource("/invite/accept").route(web::post().to(accept_invitation))) | ||||
|                 .service(web::resource("/update_role").route(web::post().to(update_user_role))) | ||||
|                 .service(web::resource("/delete").route(web::delete().to(delete_user_role))), | ||||
|         ); | ||||
|  | ||||
|         // Role information | ||||
|         route = route.service( | ||||
|             web::scope("/role") | ||||
|                 .service(web::resource("").route(web::get().to(get_role_from_token))) | ||||
|                 .service(web::resource("/list").route(web::get().to(list_all_roles))) | ||||
|                 .service(web::resource("/{role_id}").route(web::get().to(get_role))), | ||||
|         ); | ||||
|  | ||||
|         #[cfg(feature = "dummy_connector")] | ||||
|         { | ||||
|             route = route.service( | ||||
|                 web::resource("/sample_data") | ||||
|                     .route(web::post().to(generate_sample_data)) | ||||
|                     .route(web::delete().to(delete_sample_data)), | ||||
|             ) | ||||
|         } | ||||
|         route | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -182,6 +182,7 @@ impl From<Flow> for ApiIdentifier { | ||||
|             | Flow::ResetPassword | ||||
|             | Flow::InviteUser | ||||
|             | Flow::InviteMultipleUser | ||||
|             | Flow::ReInviteUser | ||||
|             | Flow::UserSignUpWithMerchantId | ||||
|             | Flow::VerifyEmailWithoutInviteChecks | ||||
|             | Flow::VerifyEmail | ||||
|  | ||||
| @ -401,6 +401,25 @@ pub async fn invite_multiple_user( | ||||
|     .await | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "email")] | ||||
| pub async fn resend_invite( | ||||
|     state: web::Data<AppState>, | ||||
|     req: HttpRequest, | ||||
|     payload: web::Json<user_api::ReInviteUserRequest>, | ||||
| ) -> HttpResponse { | ||||
|     let flow = Flow::ReInviteUser; | ||||
|     Box::pin(api::server_wrap( | ||||
|         flow, | ||||
|         state.clone(), | ||||
|         &req, | ||||
|         payload.into_inner(), | ||||
|         user_core::resend_invite, | ||||
|         &auth::JWTAuth(Permission::UsersWrite), | ||||
|         api_locking::LockAction::NotApplicable, | ||||
|     )) | ||||
|     .await | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "email")] | ||||
| pub async fn verify_email_without_invite_checks( | ||||
|     state: web::Data<AppState>, | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Apoorv Dixit
					Apoorv Dixit