diff --git a/src-tauri/src/launcher/auth.rs b/src-tauri/src/launcher/auth.rs index 35e209e..ecc45fd 100644 --- a/src-tauri/src/launcher/auth.rs +++ b/src-tauri/src/launcher/auth.rs @@ -1,7 +1,7 @@ use std::{fs, path::PathBuf}; use reqwest::Client; -use tauri::{command, Url}; +use tauri::{command, AppHandle, Emitter, Manager, Url}; use lyceris::auth::microsoft::{authenticate, create_link, refresh, validate, MinecraftAccount}; @@ -34,21 +34,47 @@ fn save_accounts(accounts: &[MinecraftAccount]) -> Result<(), String> { fs::write(path, data).map_err(|e| e.to_string()) } +fn extract_code(url: &str) -> Option { + Url::parse(url) + .ok()? + .query_pairs() + .find(|(key, _)| key == "code") + .map(|(_, value)| value.to_string()) +} + #[command] -pub fn auth_create_link(app: tauri::AppHandle) -> Result { +pub fn auth_create_link(app: AppHandle) -> Result { let link = create_link().map_err(|e| e.to_string())?; - // Create auth window - tauri::WebviewWindowBuilder::new( - &app, - "auth", - tauri::WebviewUrl::External(link.parse::().map_err(|e| e.to_string())?), - ) - .title("Microsoft Login") - .inner_size(500.0, 700.0) - .resizable(false) - .build() - .map_err(|e| e.to_string())?; + let url = link.parse::().map_err(|e| e.to_string())?; + + let app_handle = app.clone(); + + tauri::WebviewWindowBuilder::new(&app, "auth", tauri::WebviewUrl::External(url)) + .title("Microsoft Login") + .inner_size(500.0, 700.0) + .resizable(false) + .on_navigation(move |nav_url| { + let url_str = nav_url.to_string(); + + // Check for auth code + if url_str.contains("code=") { + if let Some(code) = extract_code(&url_str) { + println!("Auth code received: {}", code); + + let _ = app_handle.emit("auth-code", code); + + if let Some(win) = app_handle.get_webview_window("auth") { + let _ = win.close(); + } + } + } + + // Always allow navigation + true + }) + .build() + .map_err(|e| e.to_string())?; Ok(link) } diff --git a/src/components/layout/AccountDropdown.tsx b/src/components/layout/AccountDropdown.tsx index 89eebe9..84b03e9 100644 --- a/src/components/layout/AccountDropdown.tsx +++ b/src/components/layout/AccountDropdown.tsx @@ -2,7 +2,8 @@ import { useEffect, useState } from "react"; import { User, LogOut } from "lucide-react"; import { cn } from "@/lib/utils"; import { Props } from "./props"; -import { authList, authRemove, authCreateLink } from "@/lib/auth"; +import { authList, authRemove, authCreateLink, authLogin } from "@/lib/auth"; +import { listen } from "@tauri-apps/api/event"; interface Account { uuid: string; @@ -81,6 +82,11 @@ export default function AccountDropdown({ async function addAccount() { const url = await authCreateLink(); console.log("Opening auth URL:", url); + listen("auth-code", async (event) => { + const code = event.payload; + await authLogin(code); + await loadAccounts(); + }); } const otherAccounts = accounts.filter((a) => a.uuid !== active?.uuid);