mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 01:57:45 +08:00 
			
		
		
		
	fix(authentication): fixed terminal state persistence for redirect response (#8916)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -7655,6 +7655,10 @@ impl TransactionStatus { | |||||||
|             Self::ChallengeRequired | Self::ChallengeRequiredDecoupledAuthentication |             Self::ChallengeRequired | Self::ChallengeRequiredDecoupledAuthentication | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn is_terminal_state(self) -> bool { | ||||||
|  |         matches!(self, Self::Success | Self::Failure) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive( | #[derive( | ||||||
|  | |||||||
| @ -903,6 +903,9 @@ pub async fn authentication_eligibility_core( | |||||||
|             ) |             ) | ||||||
|         }) |         }) | ||||||
|         .transpose()?; |         .transpose()?; | ||||||
|  |  | ||||||
|  |     ensure_not_terminal_status(authentication.trans_status.clone())?; | ||||||
|  |  | ||||||
|     let key_manager_state = (&state).into(); |     let key_manager_state = (&state).into(); | ||||||
|  |  | ||||||
|     let profile_id = core_utils::get_profile_id_from_business_details( |     let profile_id = core_utils::get_profile_id_from_business_details( | ||||||
| @ -1172,6 +1175,8 @@ pub async fn authentication_authenticate_core( | |||||||
|         }) |         }) | ||||||
|         .transpose()?; |         .transpose()?; | ||||||
|  |  | ||||||
|  |     ensure_not_terminal_status(authentication.trans_status.clone())?; | ||||||
|  |  | ||||||
|     let key_manager_state = (&state).into(); |     let key_manager_state = (&state).into(); | ||||||
|  |  | ||||||
|     let profile_id = authentication.profile_id.clone(); |     let profile_id = authentication.profile_id.clone(); | ||||||
| @ -1656,6 +1661,9 @@ pub async fn authentication_post_sync_core( | |||||||
|         .to_not_found_response(ApiErrorResponse::AuthenticationNotFound { |         .to_not_found_response(ApiErrorResponse::AuthenticationNotFound { | ||||||
|             id: authentication_id.get_string_repr().to_owned(), |             id: authentication_id.get_string_repr().to_owned(), | ||||||
|         })?; |         })?; | ||||||
|  |  | ||||||
|  |     ensure_not_terminal_status(authentication.trans_status.clone())?; | ||||||
|  |  | ||||||
|     let key_manager_state = (&state).into(); |     let key_manager_state = (&state).into(); | ||||||
|     let business_profile = db |     let business_profile = db | ||||||
|         .find_business_profile_by_profile_id( |         .find_business_profile_by_profile_id( | ||||||
| @ -1691,7 +1699,7 @@ pub async fn authentication_post_sync_core( | |||||||
|         ) |         ) | ||||||
|         .await?; |         .await?; | ||||||
|  |  | ||||||
|     utils::external_authentication_update_trackers( |     let updated_authentication = utils::external_authentication_update_trackers( | ||||||
|         &state, |         &state, | ||||||
|         post_auth_response, |         post_auth_response, | ||||||
|         authentication.clone(), |         authentication.clone(), | ||||||
| @ -1711,7 +1719,7 @@ pub async fn authentication_post_sync_core( | |||||||
|         .attach_printable("authentication_connector_details not configured by the merchant")?; |         .attach_printable("authentication_connector_details not configured by the merchant")?; | ||||||
|  |  | ||||||
|     let authentication_response = AuthenticationAuthenticateResponse::foreign_try_from(( |     let authentication_response = AuthenticationAuthenticateResponse::foreign_try_from(( | ||||||
|         &authentication, |         &updated_authentication, | ||||||
|         None, |         None, | ||||||
|         None, |         None, | ||||||
|         authentication_details, |         authentication_details, | ||||||
| @ -1723,13 +1731,30 @@ pub async fn authentication_post_sync_core( | |||||||
|         &authentication_response, |         &authentication_response, | ||||||
|         authentication_connector.to_string(), |         authentication_connector.to_string(), | ||||||
|         authentication.return_url, |         authentication.return_url, | ||||||
|         authentication |         updated_authentication | ||||||
|             .authentication_client_secret |             .authentication_client_secret | ||||||
|             .clone() |             .clone() | ||||||
|             .map(masking::Secret::new) |             .map(masking::Secret::new) | ||||||
|             .as_ref(), |             .as_ref(), | ||||||
|         authentication.amount, |         updated_authentication.amount, | ||||||
|     )?; |     )?; | ||||||
|  |  | ||||||
|     Ok(hyperswitch_domain_models::api::ApplicationResponse::JsonForRedirection(redirect_response)) |     Ok(hyperswitch_domain_models::api::ApplicationResponse::JsonForRedirection(redirect_response)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | fn ensure_not_terminal_status( | ||||||
|  |     status: Option<common_enums::TransactionStatus>, | ||||||
|  | ) -> Result<(), error_stack::Report<ApiErrorResponse>> { | ||||||
|  |     status | ||||||
|  |         .filter(|s| s.clone().is_terminal_state()) | ||||||
|  |         .map(|s| { | ||||||
|  |             Err(error_stack::Report::new( | ||||||
|  |                 ApiErrorResponse::UnprocessableEntity { | ||||||
|  |                     message: format!( | ||||||
|  |                         "authentication status for the given authentication_id is already in {s}" | ||||||
|  |                     ), | ||||||
|  |                 }, | ||||||
|  |             )) | ||||||
|  |         }) | ||||||
|  |         .unwrap_or(Ok(())) | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Sahkal Poddar
					Sahkal Poddar