mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 13:30:39 +08:00
feat(users): Create user_key_store table and begin_totp API (#4577)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,9 +1,13 @@
|
||||
use api_models::user::{self as user_api, InviteMultipleUserResponse};
|
||||
#[cfg(feature = "email")]
|
||||
use diesel_models::user_role::UserRoleUpdate;
|
||||
use diesel_models::{enums::UserStatus, user as storage_user, user_role::UserRoleNew};
|
||||
use diesel_models::{
|
||||
enums::{TotpStatus, UserStatus},
|
||||
user as storage_user,
|
||||
user_role::UserRoleNew,
|
||||
};
|
||||
use error_stack::{report, ResultExt};
|
||||
use masking::ExposeInterface;
|
||||
use masking::{ExposeInterface, PeekInterface};
|
||||
#[cfg(feature = "email")]
|
||||
use router_env::env;
|
||||
use router_env::logger;
|
||||
@ -1581,3 +1585,60 @@ pub async fn user_from_email(
|
||||
};
|
||||
auth::cookies::set_cookie_response(response, token)
|
||||
}
|
||||
|
||||
pub async fn begin_totp(
|
||||
state: AppState,
|
||||
user_token: auth::UserFromSinglePurposeToken,
|
||||
) -> UserResponse<user_api::BeginTotpResponse> {
|
||||
let user_from_db: domain::UserFromStorage = state
|
||||
.store
|
||||
.find_user_by_id(&user_token.user_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into();
|
||||
|
||||
if user_from_db.get_totp_status() == TotpStatus::Set {
|
||||
return Ok(ApplicationResponse::Json(user_api::BeginTotpResponse {
|
||||
secret: None,
|
||||
}));
|
||||
}
|
||||
|
||||
let totp = utils::user::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?;
|
||||
|
||||
state
|
||||
.store
|
||||
.update_user_by_user_id(
|
||||
user_from_db.get_user_id(),
|
||||
storage_user::UserUpdate::TotpUpdate {
|
||||
totp_status: Some(TotpStatus::InProgress),
|
||||
totp_secret: Some(
|
||||
// TODO: Impl conversion trait for User and move this there
|
||||
domain::types::encrypt::<String, masking::WithType>(
|
||||
totp.get_secret_base32().into(),
|
||||
key_store.key.peek(),
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into(),
|
||||
),
|
||||
totp_recovery_codes: Some(
|
||||
recovery_codes
|
||||
.get_hashed()
|
||||
.change_context(UserErrors::InternalServerError)?,
|
||||
),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
Ok(ApplicationResponse::Json(user_api::BeginTotpResponse {
|
||||
secret: Some(user_api::TotpSecret {
|
||||
secret: totp.get_secret_base32().into(),
|
||||
totp_url: totp.get_url().into(),
|
||||
recovery_codes: recovery_codes.into_inner(),
|
||||
}),
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user