use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Icon, KeyLoggedInSession, RegisterCodeData}; use crate::shared::email::Email; use crate::shared::opaque::UserSecretKey; use anyhow::Result; use async_trait::async_trait; use nkode_rs::nkode_core::keypad::Keypad; use nkode_rs::nkode_core::policy::{NKodePolicy, DEFAULT_POLICY}; use crate::client::opaque::{OpaqueAuthData, OpaqueAuth, ServerConnectionLogin, ServerConnectionRegister}; use crate::shared::signed_session_data::SignedSessionData; use crate::shared::user_api::UserAPI; pub struct ClientAuth<'a, R, U> where R: ServerConnectionRegister + ServerConnectionLogin, U: UserAPI { opaque_key_register: OpaqueAuth<'a, R>, opaque_key_login: OpaqueAuth<'a, R>, opaque_code_register: OpaqueAuth<'a, R>, opaque_code_login: OpaqueAuth<'a, R>, user_api: U } #[async_trait] impl<'a, R, U> AuthAPI for ClientAuth<'a, R, U> where R: ServerConnectionRegister + ServerConnectionLogin, U: UserAPI, { async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String> { let auth_data = OpaqueAuthData::from_secret_key(email.as_str(), secret_key.as_slice()); self.opaque_key_register.register(&auth_data).await.map_err(|e| format!("error: {}", e)) } async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, register_code_data: RegisterCodeData) -> Result<(), String> { let auth_data = OpaqueAuthData::from_code(email.as_str(), passcode); self.opaque_code_register.register(&auth_data).await.map_err(|e| format!("error: {}", e))?; let signed_session = SignedSessionData::new( key_login_session.0.session_id, register_code_data, &key_login_session.0.session_key ).map_err(|e| format!("error: {e:?}"))?; self.user_api.set_code_login_data(signed_session).await } async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result { let auth_data = OpaqueAuthData::from_secret_key(&email.as_str(), secret_key.as_slice()); let session = self.opaque_key_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?; Ok(KeyLoggedInSession(session)) } async fn login_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, keypad: Keypad) -> Result { let auth_data = OpaqueAuthData::from_code(email.as_str(), passcode); let signed_session = SignedSessionData::new( key_login_session.0.session_id, keypad, &key_login_session.0.session_key ).map_err(|e| format!("error: {e:?}"))?; self.user_api.update_keypad(signed_session).await?; let session = self.opaque_code_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?; Ok(CodeLoggedInSession(session)) } async fn get_new_icons( &self, ) -> Result, String> { let total_props = self.get_policy().await?.keypad_dimension().total_props(); self.user_api.get_new_icons(total_props).await } async fn get_login_data( &self, key_login_session: &KeyLoggedInSession, ) -> Result { let session = SignedSessionData::new( key_login_session.0.session_id, key_login_session.0.email.clone(), &key_login_session.0.session_key ).map_err(|e| format!("error: {e:?}"))?; self.user_api.get_login_data(session).await } async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result { let session = SignedSessionData::new( key_login_session.0.session_id, key_login_session.0.email.clone(), &key_login_session.0.session_key ).map_err(|e| format!("error: {e:?}"))?; self.user_api.is_code_registered(session).await } async fn get_policy(&self) -> Result { Ok(DEFAULT_POLICY) } }