use serde::{Serialize, Deserialize}; use sqlx::types::Uuid; use tauri::{AppHandle, State}; use crate::config::AppConfig; use crate::credentials::{ AppSession, CredentialRecord, SshKey, }; use crate::errors::*; use crate::clientinfo::Client; use crate::state::AppState; use crate::terminal; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AwsRequestNotification { pub id: u64, pub client: Client, pub base: bool, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SshRequestNotification { pub id: u64, pub client: Client, pub key_name: String, } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(tag = "type")] pub enum RequestNotification { Aws(AwsRequestNotification), Ssh(SshRequestNotification), } impl RequestNotification { pub fn new_aws(id: u64, client: Client, base: bool) -> Self { Self::Aws(AwsRequestNotification {id, client, base}) } pub fn new_ssh(id: u64, client: Client, key_name: String) -> Self { Self::Ssh(SshRequestNotification {id, client, key_name}) } } #[derive(Debug, Serialize, Deserialize)] pub struct RequestResponse { pub id: u64, pub approval: Approval, pub base: bool, } #[derive(Debug, Serialize, Deserialize)] pub enum Approval { Approved, Denied, } #[tauri::command] pub async fn respond(response: RequestResponse, app_state: State<'_, AppState>) -> Result<(), SendResponseError> { app_state.send_response(response).await } #[tauri::command] pub async fn unlock(passphrase: String, app_state: State<'_, AppState>) -> Result<(), UnlockError> { app_state.unlock(&passphrase).await } #[tauri::command] pub async fn lock(app_state: State<'_, AppState>) -> Result<(), LockError> { app_state.lock().await } #[tauri::command] pub async fn reset_session(app_state: State<'_, AppState>) -> Result<(), SaveCredentialsError> { app_state.reset_session().await } #[tauri::command] pub async fn set_passphrase(passphrase: &str, app_state: State<'_, AppState>) -> Result<(), SaveCredentialsError> { app_state.set_passphrase(passphrase).await } #[tauri::command] pub async fn get_session_status(app_state: State<'_, AppState>) -> Result { let session = app_state.app_session.read().await; let status = match *session { AppSession::Locked{..} => "locked".into(), AppSession::Unlocked{..} => "unlocked".into(), AppSession::Empty => "empty".into(), }; Ok(status) } #[tauri::command] pub async fn signal_activity(app_state: State<'_, AppState>) -> Result<(), ()> { app_state.signal_activity().await; Ok(()) } #[tauri::command] pub async fn save_credential( record: CredentialRecord, app_state: State<'_, AppState> ) -> Result<(), SaveCredentialsError> { app_state.save_credential(record).await } #[tauri::command] pub async fn delete_credential(id: &str, app_state: State<'_, AppState>) -> Result<(), SaveCredentialsError> { let id = Uuid::try_parse(id) .map_err(|_| LoadCredentialsError::NoCredentials)?; app_state.delete_credential(&id).await } #[tauri::command] pub async fn list_credentials(app_state: State<'_, AppState>) -> Result, GetCredentialsError> { app_state.list_credentials().await } #[tauri::command] pub async fn sshkey_from_file(path: &str, passphrase: &str) -> Result { SshKey::from_file(path, passphrase) } #[tauri::command] pub async fn get_config(app_state: State<'_, AppState>) -> Result { let config = app_state.config.read().await; Ok(config.clone()) } #[tauri::command] pub async fn save_config(config: AppConfig, app_state: State<'_, AppState>) -> Result<(), String> { app_state.update_config(config) .await .map_err(|e| format!("Error saving config: {e}"))?; Ok(()) } #[tauri::command] pub async fn launch_terminal(base: bool) -> Result<(), LaunchTerminalError> { let res = terminal::launch(base).await; res } #[tauri::command] pub async fn get_setup_errors(app_state: State<'_, AppState>) -> Result, ()> { Ok(app_state.setup_errors.clone()) } #[tauri::command] pub fn exit(app_handle: AppHandle) { app_handle.exit(0) }