diff --git a/src-tauri/src/launcher/auth.rs b/src-tauri/src/launcher/auth.rs new file mode 100644 index 0000000..45cd859 --- /dev/null +++ b/src-tauri/src/launcher/auth.rs @@ -0,0 +1,135 @@ +use std::{fs, path::PathBuf}; + +use reqwest::Client; +use tauri::command; + +use lyceris::auth::microsoft::{authenticate, create_link, refresh, validate, MinecraftAccount}; + +use crate::launcher::LAUNCHER_DIR; + +fn accounts_path() -> PathBuf { + LAUNCHER_DIR.data_dir().join("accounts.json") +} + +fn load_accounts() -> Vec { + let path = accounts_path(); + + if !path.exists() { + return vec![]; + } + + let data = fs::read_to_string(path).unwrap_or_default(); + serde_json::from_str(&data).unwrap_or_default() +} + +fn save_accounts(accounts: &[MinecraftAccount]) -> Result<(), String> { + let path = accounts_path(); + + if let Some(parent) = path.parent() { + fs::create_dir_all(parent).map_err(|e| e.to_string())?; + } + + let data = serde_json::to_string_pretty(accounts).map_err(|e| e.to_string())?; + + fs::write(path, data).map_err(|e| e.to_string()) +} + +#[command] +pub fn auth_create_link() -> Result { + create_link().map_err(|e| e.to_string()) +} + +#[command] +pub async fn auth_login(code: String) -> Result { + let client = Client::new(); + + let account = authenticate(code, &client) + .await + .map_err(|e| e.to_string())?; + + let mut accounts = load_accounts(); + + // Replace if same UUID exists + accounts.retain(|a| a.uuid != account.uuid); + accounts.push(account.clone()); + + save_accounts(&accounts)?; + + Ok(account) +} + +#[command] +pub async fn auth_refresh(uuid: String) -> Result { + let client = Client::new(); + let mut accounts = load_accounts(); + + let account = accounts + .iter() + .find(|a| a.uuid == uuid) + .cloned() + .ok_or("Account not found")?; + + let refreshed = refresh(account.refresh_token, &client) + .await + .map_err(|e| e.to_string())?; + + accounts.retain(|a| a.uuid != uuid); + accounts.push(refreshed.clone()); + + save_accounts(&accounts)?; + + Ok(refreshed) +} + +#[command] +pub fn auth_list() -> Result, String> { + Ok(load_accounts()) +} + +#[command] +pub fn auth_remove(uuid: String) -> Result<(), String> { + let mut accounts = load_accounts(); + + accounts.retain(|a| a.uuid != uuid); + + save_accounts(&accounts) +} + +#[command] +pub fn auth_validate(uuid: String) -> Result { + let accounts = load_accounts(); + + let account = accounts + .iter() + .find(|a| a.uuid == uuid) + .ok_or("Account not found")?; + + Ok(validate(account.exp)) +} + +#[command] +pub async fn auth_get_valid(uuid: String) -> Result { + let client = Client::new(); + let mut accounts = load_accounts(); + + let account = accounts + .iter() + .find(|a| a.uuid == uuid) + .cloned() + .ok_or("Account not found")?; + + if validate(account.exp) { + return Ok(account); + } + + let refreshed = refresh(account.refresh_token, &client) + .await + .map_err(|e| e.to_string())?; + + accounts.retain(|a| a.uuid != uuid); + accounts.push(refreshed.clone()); + + save_accounts(&accounts)?; + + Ok(refreshed) +} diff --git a/src-tauri/src/launcher/mod.rs b/src-tauri/src/launcher/mod.rs index 783e5ee..74a0df1 100644 --- a/src-tauri/src/launcher/mod.rs +++ b/src-tauri/src/launcher/mod.rs @@ -1,5 +1,6 @@ pub mod downloader; pub mod install; +pub mod auth; use directories::ProjectDirs; use lyceris::minecraft::{ diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index b7f84c1..c5559e8 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -10,12 +10,22 @@ fn main() { .plugin(tauri_plugin_opener::init()) .manage(Mutex::new(AppState::default())) .invoke_handler(tauri::generate_handler![ + // Saturn Launcher Commands get_installed_mods, toggle_mod, install_mod, get_settings, update_settings, - saturn_launcher_lib::launcher::launch_game + // Launcher Commands + saturn_launcher_lib::launcher::launch_game, + // Auth Commands + saturn_launcher_lib::launcher::auth::auth_create_link, + saturn_launcher_lib::launcher::auth::auth_login, + saturn_launcher_lib::launcher::auth::auth_refresh, + saturn_launcher_lib::launcher::auth::auth_list, + saturn_launcher_lib::launcher::auth::auth_remove, + saturn_launcher_lib::launcher::auth::auth_validate, + saturn_launcher_lib::launcher::auth::auth_get_valid ]) .run(tauri::generate_context!()) .expect("error while running tauri application");