diff --git a/app/src-tauri/src/commands/auth.rs b/app/src-tauri/src/commands/auth.rs index 58f3435..85f914b 100644 --- a/app/src-tauri/src/commands/auth.rs +++ b/app/src-tauri/src/commands/auth.rs @@ -113,6 +113,36 @@ pub async fn cmd_connect( Ok(true) } +#[tauri::command] +pub async fn cmd_auth_restore_session( + app_handle: tauri::AppHandle, + state: State<'_, TelegramState>, + api_id: i32, +) -> Result { + *state.api_id.lock().await = Some(api_id); + let client = ensure_client_initialized(&app_handle, &state, api_id).await?; + + match client.is_authorized().await { + Ok(true) => { + log::info!("Restored authorized Telegram session."); + Ok(AuthResult { + success: true, + next_step: Some("dashboard".to_string()), + error: None, + }) + } + Ok(false) => { + log::info!("Saved Telegram session is not authorized."); + Ok(AuthResult { + success: false, + next_step: Some("phone".to_string()), + error: None, + }) + } + Err(e) => Err(format!("Failed to restore Telegram session: {}", e)), + } +} + #[tauri::command] pub async fn cmd_check_connection( app_handle: tauri::AppHandle, diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index a476644..e1e1f1a 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -79,6 +79,7 @@ pub fn run() { }) .invoke_handler(tauri::generate_handler![ commands::cmd_auth_request_code, + commands::cmd_auth_restore_session, commands::cmd_auth_sign_in, commands::cmd_auth_check_password, commands::cmd_get_files, diff --git a/app/src/components/AuthWizard.tsx b/app/src/components/AuthWizard.tsx index 043ed58..3a9cb91 100644 --- a/app/src/components/AuthWizard.tsx +++ b/app/src/components/AuthWizard.tsx @@ -6,7 +6,7 @@ import { load } from '@tauri-apps/plugin-store'; import { useTheme } from '../context/ThemeContext'; import { open } from '@tauri-apps/plugin-shell'; -type Step = "setup" | "phone" | "code" | "password"; +type Step = "checking" | "setup" | "phone" | "code" | "password"; function AuthThemeToggle() { const { theme, toggleTheme } = useTheme(); @@ -45,11 +45,12 @@ export function AuthWizard({ onLogin }: { onLogin: () => void }) { ) } - const [step, setStep] = useState("setup"); + const [step, setStep] = useState("checking"); const [loading, setLoading] = useState(false); const [apiId, setApiId] = useState(""); const [apiHash, setApiHash] = useState(""); + const [rememberLogin, setRememberLogin] = useState(true); const [phone, setPhone] = useState(""); const [code, setCode] = useState(""); @@ -77,23 +78,49 @@ export function AuthWizard({ onLogin }: { onLogin: () => void }) { const store = await load('config.json'); const savedId = await store.get('api_id'); const savedHash = await store.get('api_hash'); + const savedRemember = await store.get('remember_login'); + const shouldRemember = savedRemember !== false; + setRememberLogin(shouldRemember); - if (savedId && savedHash) { + if (savedId) { setApiId(savedId); - setApiHash(savedHash); + if (savedHash) setApiHash(savedHash); + if (shouldRemember) { + const idInt = parseInt(savedId, 10); + if (!isNaN(idInt)) { + try { + const res = await invoke<{ success: boolean; next_step?: string }>("cmd_auth_restore_session", { apiId: idInt }); + if (res.success) { + onLogin(); + return; + } + } catch (err) { + setError(`Could not restore saved Telegram session: ${String(err)}`); + } + } + } + setStep(savedHash ? "phone" : "setup"); + return; } + + setStep("setup"); } catch { - // config not found, starting fresh + setStep("setup"); } }; initStore(); - }, []); + }, [onLogin]); const saveCredentials = async () => { try { const store = await load('config.json'); - await store.set('api_id', apiId); - await store.set('api_hash', apiHash); + await store.set('remember_login', rememberLogin); + if (rememberLogin) { + await store.set('api_id', apiId); + } else { + await store.delete('api_id'); + } + await store.delete('api_hash'); await store.save(); } catch { // store write failure, non-critical @@ -122,6 +149,7 @@ export function AuthWizard({ onLogin }: { onLogin: () => void }) { setLoading(true); setError(null); try { + await saveCredentials(); const idInt = parseInt(apiId, 10); if (isNaN(idInt)) throw new Error("API ID must be a number"); @@ -156,6 +184,7 @@ export function AuthWizard({ onLogin }: { onLogin: () => void }) { try { const res = await invoke<{ success: boolean; next_step?: string }>("cmd_auth_sign_in", { code }); if (res.success) { + await saveCredentials(); onLogin(); } else if (res.next_step === "password") { setStep("password"); @@ -176,6 +205,7 @@ export function AuthWizard({ onLogin }: { onLogin: () => void }) { try { const res = await invoke<{ success: boolean; next_step?: string }>("cmd_auth_check_password", { password }); if (res.success) { + await saveCredentials(); onLogin(); } else { setError("Password verification failed."); @@ -231,6 +261,23 @@ export function AuthWizard({ onLogin }: { onLogin: () => void }) { ) : ( <> + {step === "checking" && ( + +
+
+
+
+

Checking Saved Session

+

Looking for an existing Telegram login on this computer.

+
+ + )} {step === "setup" && ( @@ -269,6 +316,17 @@ export function AuthWizard({ onLogin }: { onLogin: () => void }) { />
+