mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 05:17:02 +08:00
feat(users): Create generate recovery codes API (#4708)
This commit is contained in:
@ -66,10 +66,12 @@ pub enum UserErrors {
|
||||
RoleNameParsingError,
|
||||
#[error("RoleNameAlreadyExists")]
|
||||
RoleNameAlreadyExists,
|
||||
#[error("TOTPNotSetup")]
|
||||
#[error("TotpNotSetup")]
|
||||
TotpNotSetup,
|
||||
#[error("InvalidTOTP")]
|
||||
#[error("InvalidTotp")]
|
||||
InvalidTotp,
|
||||
#[error("TotpRequired")]
|
||||
TotpRequired,
|
||||
}
|
||||
|
||||
impl common_utils::errors::ErrorSwitch<api_models::errors::types::ApiErrorResponse> for UserErrors {
|
||||
@ -179,6 +181,9 @@ impl common_utils::errors::ErrorSwitch<api_models::errors::types::ApiErrorRespon
|
||||
Self::InvalidTotp => {
|
||||
AER::BadRequest(ApiError::new(sub_code, 37, self.get_error_message(), None))
|
||||
}
|
||||
Self::TotpRequired => {
|
||||
AER::BadRequest(ApiError::new(sub_code, 38, self.get_error_message(), None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,6 +222,7 @@ impl UserErrors {
|
||||
Self::RoleNameAlreadyExists => "Role name already exists",
|
||||
Self::TotpNotSetup => "TOTP not setup",
|
||||
Self::InvalidTotp => "Invalid TOTP",
|
||||
Self::TotpRequired => "TOTP required",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1631,7 +1631,7 @@ pub async fn begin_totp(
|
||||
}));
|
||||
}
|
||||
|
||||
let totp = utils::user::generate_default_totp(user_from_db.get_email(), None)?;
|
||||
let totp = utils::user::two_factor_auth::generate_default_totp(user_from_db.get_email(), None)?;
|
||||
let recovery_codes = domain::RecoveryCodes::generate_new();
|
||||
|
||||
let key_store = user_from_db.get_or_create_key_store(&state).await?;
|
||||
@ -1693,8 +1693,10 @@ pub async fn verify_totp(
|
||||
.await?
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
|
||||
let totp =
|
||||
utils::user::generate_default_totp(user_from_db.get_email(), Some(user_totp_secret))?;
|
||||
let totp = utils::user::two_factor_auth::generate_default_totp(
|
||||
user_from_db.get_email(),
|
||||
Some(user_totp_secret),
|
||||
)?;
|
||||
|
||||
if totp
|
||||
.generate_current()
|
||||
@ -1732,3 +1734,35 @@ pub async fn verify_totp(
|
||||
token,
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn generate_recovery_codes(
|
||||
state: AppState,
|
||||
user_token: auth::UserFromSinglePurposeToken,
|
||||
) -> UserResponse<user_api::RecoveryCodes> {
|
||||
if !utils::user::two_factor_auth::check_totp_in_redis(&state, &user_token.user_id).await? {
|
||||
return Err(UserErrors::TotpRequired.into());
|
||||
}
|
||||
|
||||
let recovery_codes = domain::RecoveryCodes::generate_new();
|
||||
|
||||
state
|
||||
.store
|
||||
.update_user_by_user_id(
|
||||
&user_token.user_id,
|
||||
storage_user::UserUpdate::TotpUpdate {
|
||||
totp_status: None,
|
||||
totp_secret: None,
|
||||
totp_recovery_codes: Some(
|
||||
recovery_codes
|
||||
.get_hashed()
|
||||
.change_context(UserErrors::InternalServerError)?,
|
||||
),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
Ok(ApplicationResponse::Json(user_api::RecoveryCodes {
|
||||
recovery_codes: recovery_codes.into_inner(),
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user