From cd637fbb6bc220be3bede9dd8e1caec4e995061d Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 25 Jul 2024 13:17:59 +0100 Subject: [PATCH] feat: add endpoints for Verify MFA Login and Send MFA SMS --- src/api/auth/login.rs | 61 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 57c03b7..e57474e 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -11,7 +11,9 @@ use crate::errors::ChorusResult; use crate::gateway::Gateway; use crate::instance::{ChorusUser, Instance}; use crate::ratelimiter::ChorusRequest; -use crate::types::{GatewayIdentifyPayload, LimitType, LoginResult, LoginSchema, User}; +use crate::types::{ + AuthenticatorType, GatewayIdentifyPayload, LimitType, LoginResult, LoginSchema, SendMfaSmsResponse, SendMfaSmsSchema, User, VerifyMFALoginResponse, VerifyMFALoginSchema +}; impl Instance { /// Logs into an existing account on the spacebar server. @@ -32,7 +34,7 @@ impl Instance { // instances' limits to pass them on as user_rate_limits later. let mut user = ChorusUser::shell(Arc::new(RwLock::new(self.clone())), "None".to_string()).await; - + let login_result = chorus_request .deserialize_response::(&mut user) .await?; @@ -48,4 +50,59 @@ impl Instance { Ok(user) } + + /// Verifies a multi-factor authentication login + /// + /// # Reference + /// See + pub async fn verify_mfa_login( + &mut self, + authenticator: AuthenticatorType, + schema: VerifyMFALoginSchema, + ) -> ChorusResult { + let endpoint_url = self.urls.api.clone() + &authenticator.to_string(); + + let chorus_request = ChorusRequest { + request: Client::new() + .post(endpoint_url) + .header("Content-Type", "application/json") + .json(&schema), + limit_type: LimitType::AuthLogin, + }; + + let mut user = + ChorusUser::shell(Arc::new(RwLock::new(self.clone())), "None".to_string()).await; + + match chorus_request.deserialize_response::(&mut user).await? { + VerifyMFALoginResponse::Success { token, user_settings: _ } => user.set_token(token), + VerifyMFALoginResponse::UserSuspended { suspended_user_token } => return Err(crate::errors::ChorusError::SuspendUser { token: suspended_user_token }), + } + + let mut identify = GatewayIdentifyPayload::common(); + identify.token = user.token(); + user.gateway.send_identify(identify).await; + + Ok(user) + } + + /// Sends a multi-factor authentication code to the user's phone number + /// + /// # Reference + /// See + pub async fn send_mfa_sms(&mut self, schema: SendMfaSmsSchema) -> ChorusResult { + let endpoint_url = self.urls.api.clone() + "/auth/mfa/sms/send"; + let chorus_request = ChorusRequest { + request: Client::new() + .post(endpoint_url) + .header("Content-Type", "application/json") + .json(&schema), + limit_type: LimitType::Ip + }; + + let mut chorus_user = ChorusUser::shell(Arc::new(RwLock::new(self.clone())), "None".to_string()).await; + + let send_mfa_sms_response = chorus_request.deserialize_response::(&mut chorus_user).await?; + + Ok(send_mfa_sms_response) + } }