mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 18:17:13 +08:00 
			
		
		
		
	feat(user): implement force password reset (#3572)
This commit is contained in:
		| @ -24,6 +24,8 @@ pub enum SetMetaDataRequest { | |||||||
|     ConfigureWoocom, |     ConfigureWoocom, | ||||||
|     SetupWoocomWebhook, |     SetupWoocomWebhook, | ||||||
|     IsMultipleConfiguration, |     IsMultipleConfiguration, | ||||||
|  |     #[serde(skip)] | ||||||
|  |     IsChangePasswordRequired, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, serde::Deserialize, serde::Serialize)] | #[derive(Debug, serde::Deserialize, serde::Serialize)] | ||||||
| @ -110,6 +112,7 @@ pub enum GetMetaDataRequest { | |||||||
|     ConfigureWoocom, |     ConfigureWoocom, | ||||||
|     SetupWoocomWebhook, |     SetupWoocomWebhook, | ||||||
|     IsMultipleConfiguration, |     IsMultipleConfiguration, | ||||||
|  |     IsChangePasswordRequired, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, serde::Deserialize, serde::Serialize)] | #[derive(Debug, serde::Deserialize, serde::Serialize)] | ||||||
| @ -146,4 +149,5 @@ pub enum GetMetaDataResponse { | |||||||
|     ConfigureWoocom(bool), |     ConfigureWoocom(bool), | ||||||
|     SetupWoocomWebhook(bool), |     SetupWoocomWebhook(bool), | ||||||
|     IsMultipleConfiguration(bool), |     IsMultipleConfiguration(bool), | ||||||
|  |     IsChangePasswordRequired(bool), | ||||||
| } | } | ||||||
|  | |||||||
| @ -498,4 +498,5 @@ pub enum DashboardMetadata { | |||||||
|     ConfigureWoocom, |     ConfigureWoocom, | ||||||
|     SetupWoocomWebhook, |     SetupWoocomWebhook, | ||||||
|     IsMultipleConfiguration, |     IsMultipleConfiguration, | ||||||
|  |     IsChangePasswordRequired, | ||||||
| } | } | ||||||
|  | |||||||
| @ -105,7 +105,7 @@ impl DashboardMetadata { | |||||||
|         .await |         .await | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub async fn delete_user_scoped_dashboard_metadata_by_merchant_id( |     pub async fn delete_all_user_scoped_dashboard_metadata_by_merchant_id( | ||||||
|         conn: &PgPooledConn, |         conn: &PgPooledConn, | ||||||
|         user_id: String, |         user_id: String, | ||||||
|         merchant_id: String, |         merchant_id: String, | ||||||
| @ -118,4 +118,20 @@ impl DashboardMetadata { | |||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub async fn delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |         conn: &PgPooledConn, | ||||||
|  |         user_id: String, | ||||||
|  |         merchant_id: String, | ||||||
|  |         data_key: enums::DashboardMetadata, | ||||||
|  |     ) -> StorageResult<Self> { | ||||||
|  |         generics::generic_delete_one_with_result::<<Self as HasTable>::Table, _, _>( | ||||||
|  |             conn, | ||||||
|  |             dsl::user_id | ||||||
|  |                 .eq(user_id) | ||||||
|  |                 .and(dsl::merchant_id.eq(merchant_id)) | ||||||
|  |                 .and(dsl::data_key.eq(data_key)), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -8,8 +8,9 @@ use error_stack::ResultExt; | |||||||
| use masking::ExposeInterface; | use masking::ExposeInterface; | ||||||
| #[cfg(feature = "email")] | #[cfg(feature = "email")] | ||||||
| use router_env::env; | use router_env::env; | ||||||
| #[cfg(feature = "email")] |  | ||||||
| use router_env::logger; | use router_env::logger; | ||||||
|  | #[cfg(not(feature = "email"))] | ||||||
|  | use user_api::dashboard_metadata::SetMetaDataRequest; | ||||||
|  |  | ||||||
| use super::errors::{StorageErrorExt, UserErrors, UserResponse, UserResult}; | use super::errors::{StorageErrorExt, UserErrors, UserResponse, UserResult}; | ||||||
| #[cfg(feature = "email")] | #[cfg(feature = "email")] | ||||||
| @ -310,6 +311,20 @@ pub async fn change_password( | |||||||
|         .await |         .await | ||||||
|         .change_context(UserErrors::InternalServerError)?; |         .change_context(UserErrors::InternalServerError)?; | ||||||
|  |  | ||||||
|  |     #[cfg(not(feature = "email"))] | ||||||
|  |     { | ||||||
|  |         state | ||||||
|  |             .store | ||||||
|  |             .delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |                 &user_from_token.user_id, | ||||||
|  |                 &user_from_token.merchant_id, | ||||||
|  |                 diesel_models::enums::DashboardMetadata::IsChangePasswordRequired, | ||||||
|  |             ) | ||||||
|  |             .await | ||||||
|  |             .map_err(|e| logger::error!("Error while deleting dashboard metadata {}", e)) | ||||||
|  |             .ok(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Ok(ApplicationResponse::StatusOk) |     Ok(ApplicationResponse::StatusOk) | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -483,8 +498,8 @@ pub async fn invite_user( | |||||||
|             .insert_user_role(UserRoleNew { |             .insert_user_role(UserRoleNew { | ||||||
|                 user_id: new_user.get_user_id().to_owned(), |                 user_id: new_user.get_user_id().to_owned(), | ||||||
|                 merchant_id: user_from_token.merchant_id.clone(), |                 merchant_id: user_from_token.merchant_id.clone(), | ||||||
|                 role_id: request.role_id, |                 role_id: request.role_id.clone(), | ||||||
|                 org_id: user_from_token.org_id, |                 org_id: user_from_token.org_id.clone(), | ||||||
|                 status: invitation_status, |                 status: invitation_status, | ||||||
|                 created_by: user_from_token.user_id.clone(), |                 created_by: user_from_token.user_id.clone(), | ||||||
|                 last_modified_by: user_from_token.user_id, |                 last_modified_by: user_from_token.user_id, | ||||||
| @ -523,6 +538,20 @@ pub async fn invite_user( | |||||||
|         #[cfg(not(feature = "email"))] |         #[cfg(not(feature = "email"))] | ||||||
|         { |         { | ||||||
|             is_email_sent = false; |             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, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Ok(ApplicationResponse::Json(user_api::InviteUserResponse { |         Ok(ApplicationResponse::Json(user_api::InviteUserResponse { | ||||||
| @ -706,6 +735,17 @@ async fn handle_new_user_invitation( | |||||||
|     #[cfg(not(feature = "email"))] |     #[cfg(not(feature = "email"))] | ||||||
|     { |     { | ||||||
|         is_email_sent = false; |         is_email_sent = false; | ||||||
|  |  | ||||||
|  |         let invited_user_token = auth::UserFromToken { | ||||||
|  |             user_id: new_user.get_user_id(), | ||||||
|  |             merchant_id: user_from_token.merchant_id.clone(), | ||||||
|  |             org_id: user_from_token.org_id.clone(), | ||||||
|  |             role_id: request.role_id.clone(), | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         let set_metadata_request = SetMetaDataRequest::IsChangePasswordRequired; | ||||||
|  |         dashboard_metadata::set_metadata(state.clone(), invited_user_token, set_metadata_request) | ||||||
|  |             .await?; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Ok(InviteMultipleUserResponse { |     Ok(InviteMultipleUserResponse { | ||||||
|  | |||||||
| @ -105,6 +105,9 @@ fn parse_set_request(data_enum: api::SetMetaDataRequest) -> UserResult<types::Me | |||||||
|         api::SetMetaDataRequest::IsMultipleConfiguration => { |         api::SetMetaDataRequest::IsMultipleConfiguration => { | ||||||
|             Ok(types::MetaData::IsMultipleConfiguration(true)) |             Ok(types::MetaData::IsMultipleConfiguration(true)) | ||||||
|         } |         } | ||||||
|  |         api::SetMetaDataRequest::IsChangePasswordRequired => { | ||||||
|  |             Ok(types::MetaData::IsChangePasswordRequired(true)) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -131,6 +134,7 @@ fn parse_get_request(data_enum: api::GetMetaDataRequest) -> DBEnum { | |||||||
|         api::GetMetaDataRequest::ConfigureWoocom => DBEnum::ConfigureWoocom, |         api::GetMetaDataRequest::ConfigureWoocom => DBEnum::ConfigureWoocom, | ||||||
|         api::GetMetaDataRequest::SetupWoocomWebhook => DBEnum::SetupWoocomWebhook, |         api::GetMetaDataRequest::SetupWoocomWebhook => DBEnum::SetupWoocomWebhook, | ||||||
|         api::GetMetaDataRequest::IsMultipleConfiguration => DBEnum::IsMultipleConfiguration, |         api::GetMetaDataRequest::IsMultipleConfiguration => DBEnum::IsMultipleConfiguration, | ||||||
|  |         api::GetMetaDataRequest::IsChangePasswordRequired => DBEnum::IsChangePasswordRequired, | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -207,6 +211,9 @@ fn into_response( | |||||||
|         DBEnum::IsMultipleConfiguration => Ok(api::GetMetaDataResponse::IsMultipleConfiguration( |         DBEnum::IsMultipleConfiguration => Ok(api::GetMetaDataResponse::IsMultipleConfiguration( | ||||||
|             data.is_some(), |             data.is_some(), | ||||||
|         )), |         )), | ||||||
|  |         DBEnum::IsChangePasswordRequired => Ok(api::GetMetaDataResponse::IsChangePasswordRequired( | ||||||
|  |             data.is_some(), | ||||||
|  |         )), | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -520,6 +527,17 @@ async fn insert_metadata( | |||||||
|             ) |             ) | ||||||
|             .await |             .await | ||||||
|         } |         } | ||||||
|  |         types::MetaData::IsChangePasswordRequired(data) => { | ||||||
|  |             utils::insert_user_scoped_metadata_to_db( | ||||||
|  |                 state, | ||||||
|  |                 user.user_id, | ||||||
|  |                 user.merchant_id, | ||||||
|  |                 user.org_id, | ||||||
|  |                 metadata_key, | ||||||
|  |                 data, | ||||||
|  |             ) | ||||||
|  |             .await | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ pub trait DashboardMetadataInterface { | |||||||
|         &self, |         &self, | ||||||
|         metadata: storage::DashboardMetadataNew, |         metadata: storage::DashboardMetadataNew, | ||||||
|     ) -> CustomResult<storage::DashboardMetadata, errors::StorageError>; |     ) -> CustomResult<storage::DashboardMetadata, errors::StorageError>; | ||||||
|  |  | ||||||
|     async fn update_metadata( |     async fn update_metadata( | ||||||
|         &self, |         &self, | ||||||
|         user_id: Option<String>, |         user_id: Option<String>, | ||||||
| @ -30,6 +31,7 @@ pub trait DashboardMetadataInterface { | |||||||
|         org_id: &str, |         org_id: &str, | ||||||
|         data_keys: Vec<enums::DashboardMetadata>, |         data_keys: Vec<enums::DashboardMetadata>, | ||||||
|     ) -> CustomResult<Vec<storage::DashboardMetadata>, errors::StorageError>; |     ) -> CustomResult<Vec<storage::DashboardMetadata>, errors::StorageError>; | ||||||
|  |  | ||||||
|     async fn find_merchant_scoped_dashboard_metadata( |     async fn find_merchant_scoped_dashboard_metadata( | ||||||
|         &self, |         &self, | ||||||
|         merchant_id: &str, |         merchant_id: &str, | ||||||
| @ -37,11 +39,18 @@ pub trait DashboardMetadataInterface { | |||||||
|         data_keys: Vec<enums::DashboardMetadata>, |         data_keys: Vec<enums::DashboardMetadata>, | ||||||
|     ) -> CustomResult<Vec<storage::DashboardMetadata>, errors::StorageError>; |     ) -> CustomResult<Vec<storage::DashboardMetadata>, errors::StorageError>; | ||||||
|  |  | ||||||
|     async fn delete_user_scoped_dashboard_metadata_by_merchant_id( |     async fn delete_all_user_scoped_dashboard_metadata_by_merchant_id( | ||||||
|         &self, |         &self, | ||||||
|         user_id: &str, |         user_id: &str, | ||||||
|         merchant_id: &str, |         merchant_id: &str, | ||||||
|     ) -> CustomResult<bool, errors::StorageError>; |     ) -> CustomResult<bool, errors::StorageError>; | ||||||
|  |  | ||||||
|  |     async fn delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |         &self, | ||||||
|  |         user_id: &str, | ||||||
|  |         merchant_id: &str, | ||||||
|  |         data_key: enums::DashboardMetadata, | ||||||
|  |     ) -> CustomResult<storage::DashboardMetadata, errors::StorageError>; | ||||||
| } | } | ||||||
|  |  | ||||||
| #[async_trait::async_trait] | #[async_trait::async_trait] | ||||||
| @ -117,13 +126,13 @@ impl DashboardMetadataInterface for Store { | |||||||
|         .map_err(Into::into) |         .map_err(Into::into) | ||||||
|         .into_report() |         .into_report() | ||||||
|     } |     } | ||||||
|     async fn delete_user_scoped_dashboard_metadata_by_merchant_id( |     async fn delete_all_user_scoped_dashboard_metadata_by_merchant_id( | ||||||
|         &self, |         &self, | ||||||
|         user_id: &str, |         user_id: &str, | ||||||
|         merchant_id: &str, |         merchant_id: &str, | ||||||
|     ) -> CustomResult<bool, errors::StorageError> { |     ) -> CustomResult<bool, errors::StorageError> { | ||||||
|         let conn = connection::pg_connection_write(self).await?; |         let conn = connection::pg_connection_write(self).await?; | ||||||
|         storage::DashboardMetadata::delete_user_scoped_dashboard_metadata_by_merchant_id( |         storage::DashboardMetadata::delete_all_user_scoped_dashboard_metadata_by_merchant_id( | ||||||
|             &conn, |             &conn, | ||||||
|             user_id.to_owned(), |             user_id.to_owned(), | ||||||
|             merchant_id.to_owned(), |             merchant_id.to_owned(), | ||||||
| @ -132,6 +141,24 @@ impl DashboardMetadataInterface for Store { | |||||||
|         .map_err(Into::into) |         .map_err(Into::into) | ||||||
|         .into_report() |         .into_report() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async fn delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |         &self, | ||||||
|  |         user_id: &str, | ||||||
|  |         merchant_id: &str, | ||||||
|  |         data_key: enums::DashboardMetadata, | ||||||
|  |     ) -> CustomResult<storage::DashboardMetadata, errors::StorageError> { | ||||||
|  |         let conn = connection::pg_connection_write(self).await?; | ||||||
|  |         storage::DashboardMetadata::delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |             &conn, | ||||||
|  |             user_id.to_owned(), | ||||||
|  |             merchant_id.to_owned(), | ||||||
|  |             data_key, | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .map_err(Into::into) | ||||||
|  |         .into_report() | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[async_trait::async_trait] | #[async_trait::async_trait] | ||||||
| @ -267,7 +294,7 @@ impl DashboardMetadataInterface for MockDb { | |||||||
|         } |         } | ||||||
|         Ok(query_result) |         Ok(query_result) | ||||||
|     } |     } | ||||||
|     async fn delete_user_scoped_dashboard_metadata_by_merchant_id( |     async fn delete_all_user_scoped_dashboard_metadata_by_merchant_id( | ||||||
|         &self, |         &self, | ||||||
|         user_id: &str, |         user_id: &str, | ||||||
|         merchant_id: &str, |         merchant_id: &str, | ||||||
| @ -294,4 +321,31 @@ impl DashboardMetadataInterface for MockDb { | |||||||
|  |  | ||||||
|         Ok(true) |         Ok(true) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async fn delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |         &self, | ||||||
|  |         user_id: &str, | ||||||
|  |         merchant_id: &str, | ||||||
|  |         data_key: enums::DashboardMetadata, | ||||||
|  |     ) -> CustomResult<storage::DashboardMetadata, errors::StorageError> { | ||||||
|  |         let mut dashboard_metadata = self.dashboard_metadata.lock().await; | ||||||
|  |  | ||||||
|  |         let index_to_remove = dashboard_metadata | ||||||
|  |             .iter() | ||||||
|  |             .position(|metadata_inner| { | ||||||
|  |                 metadata_inner | ||||||
|  |                     .user_id | ||||||
|  |                     .as_deref() | ||||||
|  |                     .map_or(false, |user_id_inner| user_id_inner == user_id) | ||||||
|  |                     && metadata_inner.merchant_id == merchant_id | ||||||
|  |                     && metadata_inner.data_key == data_key | ||||||
|  |             }) | ||||||
|  |             .ok_or(errors::StorageError::ValueNotFound( | ||||||
|  |                 "No data found".to_string(), | ||||||
|  |             ))?; | ||||||
|  |  | ||||||
|  |         let deleted_value = dashboard_metadata.swap_remove(index_to_remove); | ||||||
|  |  | ||||||
|  |         Ok(deleted_value) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1964,6 +1964,7 @@ impl UserRoleInterface for KafkaStore { | |||||||
|             .update_user_role_by_user_id_merchant_id(user_id, merchant_id, update) |             .update_user_role_by_user_id_merchant_id(user_id, merchant_id, update) | ||||||
|             .await |             .await | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async fn delete_user_role_by_user_id_merchant_id( |     async fn delete_user_role_by_user_id_merchant_id( | ||||||
|         &self, |         &self, | ||||||
|         user_id: &str, |         user_id: &str, | ||||||
| @ -2021,6 +2022,7 @@ impl DashboardMetadataInterface for KafkaStore { | |||||||
|             .find_user_scoped_dashboard_metadata(user_id, merchant_id, org_id, data_keys) |             .find_user_scoped_dashboard_metadata(user_id, merchant_id, org_id, data_keys) | ||||||
|             .await |             .await | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async fn find_merchant_scoped_dashboard_metadata( |     async fn find_merchant_scoped_dashboard_metadata( | ||||||
|         &self, |         &self, | ||||||
|         merchant_id: &str, |         merchant_id: &str, | ||||||
| @ -2032,13 +2034,28 @@ impl DashboardMetadataInterface for KafkaStore { | |||||||
|             .await |             .await | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async fn delete_user_scoped_dashboard_metadata_by_merchant_id( |     async fn delete_all_user_scoped_dashboard_metadata_by_merchant_id( | ||||||
|         &self, |         &self, | ||||||
|         user_id: &str, |         user_id: &str, | ||||||
|         merchant_id: &str, |         merchant_id: &str, | ||||||
|     ) -> CustomResult<bool, errors::StorageError> { |     ) -> CustomResult<bool, errors::StorageError> { | ||||||
|         self.diesel_store |         self.diesel_store | ||||||
|             .delete_user_scoped_dashboard_metadata_by_merchant_id(user_id, merchant_id) |             .delete_all_user_scoped_dashboard_metadata_by_merchant_id(user_id, merchant_id) | ||||||
|  |             .await | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async fn delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |         &self, | ||||||
|  |         user_id: &str, | ||||||
|  |         merchant_id: &str, | ||||||
|  |         data_key: enums::DashboardMetadata, | ||||||
|  |     ) -> CustomResult<storage::DashboardMetadata, errors::StorageError> { | ||||||
|  |         self.diesel_store | ||||||
|  |             .delete_user_scoped_dashboard_metadata_by_merchant_id_data_key( | ||||||
|  |                 user_id, | ||||||
|  |                 merchant_id, | ||||||
|  |                 data_key, | ||||||
|  |             ) | ||||||
|             .await |             .await | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -25,6 +25,7 @@ pub enum MetaData { | |||||||
|     ConfigureWoocom(bool), |     ConfigureWoocom(bool), | ||||||
|     SetupWoocomWebhook(bool), |     SetupWoocomWebhook(bool), | ||||||
|     IsMultipleConfiguration(bool), |     IsMultipleConfiguration(bool), | ||||||
|  |     IsChangePasswordRequired(bool), | ||||||
| } | } | ||||||
|  |  | ||||||
| impl From<&MetaData> for DBEnum { | impl From<&MetaData> for DBEnum { | ||||||
| @ -51,6 +52,7 @@ impl From<&MetaData> for DBEnum { | |||||||
|             MetaData::ConfigureWoocom(_) => Self::ConfigureWoocom, |             MetaData::ConfigureWoocom(_) => Self::ConfigureWoocom, | ||||||
|             MetaData::SetupWoocomWebhook(_) => Self::SetupWoocomWebhook, |             MetaData::SetupWoocomWebhook(_) => Self::SetupWoocomWebhook, | ||||||
|             MetaData::IsMultipleConfiguration(_) => Self::IsMultipleConfiguration, |             MetaData::IsMultipleConfiguration(_) => Self::IsMultipleConfiguration, | ||||||
|  |             MetaData::IsChangePasswordRequired(_) => Self::IsChangePasswordRequired, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -219,7 +219,9 @@ pub fn separate_metadata_type_based_on_scope( | |||||||
|             | DBEnum::ConfigureWoocom |             | DBEnum::ConfigureWoocom | ||||||
|             | DBEnum::SetupWoocomWebhook |             | DBEnum::SetupWoocomWebhook | ||||||
|             | DBEnum::IsMultipleConfiguration => merchant_scoped.push(key), |             | DBEnum::IsMultipleConfiguration => merchant_scoped.push(key), | ||||||
|             DBEnum::Feedback | DBEnum::ProdIntent => user_scoped.push(key), |             DBEnum::Feedback | DBEnum::ProdIntent | DBEnum::IsChangePasswordRequired => { | ||||||
|  |                 user_scoped.push(key) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     (merchant_scoped, user_scoped) |     (merchant_scoped, user_scoped) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Apoorv Dixit
					Apoorv Dixit