jellytau_lib/auth/
session_verifier.rs1use serde::Serialize;
2use std::sync::atomic::{AtomicBool, Ordering};
3use std::sync::Arc;
4use std::time::Duration;
5use tauri::{AppHandle, Emitter};
6
7use super::{AuthManager, User};
8
9const VERIFICATION_INTERVAL_MS: u64 = 300000;
11
12#[derive(Debug, Clone, Serialize)]
14#[serde(rename_all = "camelCase", tag = "type")]
15pub enum SessionVerificationEvent {
16 Verified { user: User },
17 NeedsReauth { reason: String },
18 NetworkError { message: String },
19}
20
21pub struct SessionVerifier {
23 auth_manager: Arc<AuthManager>,
24 is_running: Arc<AtomicBool>,
25 device_id: String,
26 app_handle: Option<AppHandle>,
27}
28
29impl SessionVerifier {
30 pub fn new(auth_manager: Arc<AuthManager>, device_id: String) -> Self {
32 Self {
33 auth_manager,
34 is_running: Arc::new(AtomicBool::new(false)),
35 device_id,
36 app_handle: None,
37 }
38 }
39
40 pub fn set_app_handle(&mut self, app_handle: AppHandle) {
42 self.app_handle = Some(app_handle);
43 }
44
45 pub async fn start(&self) {
47 if self.is_running.swap(true, Ordering::SeqCst) {
48 log::info!("[SessionVerifier] Already running");
49 return;
50 }
51
52 log::info!("[SessionVerifier] Starting background verification");
53
54 let auth_manager = Arc::clone(&self.auth_manager);
55 let is_running = Arc::clone(&self.is_running);
56 let device_id = self.device_id.clone();
57 let app_handle = self.app_handle.clone();
58
59 tokio::spawn(async move {
60 tokio::time::sleep(Duration::from_millis(2000)).await;
62
63 while is_running.load(Ordering::SeqCst) {
64 let session = auth_manager.get_session().await;
66
67 if let Some(session) = session {
68 log::debug!(
69 "[SessionVerifier] Verifying session for: {}",
70 session.username
71 );
72
73 match auth_manager
75 .verify_session(
76 &session.server_url,
77 &session.user_id,
78 &session.access_token,
79 &device_id,
80 )
81 .await
82 {
83 Ok(user) => {
84 log::info!("[SessionVerifier] Session verified successfully");
85
86 if let Some(app) = &app_handle {
88 let event = SessionVerificationEvent::Verified { user };
89 if let Err(e) = app.emit("auth:session-verified", event) {
90 log::error!("[SessionVerifier] Failed to emit event: {}", e);
91 }
92 }
93
94 let mut updated_session = session;
96 updated_session.verified = true;
97 updated_session.needs_reauth = false;
98 auth_manager.set_session(Some(updated_session)).await;
99 }
100 Err(e) => {
101 log::warn!("[SessionVerifier] Verification failed: {}", e);
102
103 let is_auth_error = e.contains("401") || e.contains("403");
105 let is_network_error = e.contains("network")
106 || e.contains("timeout")
107 || e.contains("connection")
108 || e.contains("DNS");
109
110 if is_auth_error {
111 log::warn!("[SessionVerifier] Session requires re-authentication");
113
114 if let Some(app) = &app_handle {
115 let event = SessionVerificationEvent::NeedsReauth {
116 reason: "Session expired".to_string(),
117 };
118 if let Err(e) = app.emit("auth:needs-reauth", event) {
119 log::error!(
120 "[SessionVerifier] Failed to emit event: {}",
121 e
122 );
123 }
124 }
125
126 let mut updated_session = session;
128 updated_session.verified = false;
129 updated_session.needs_reauth = true;
130 auth_manager.set_session(Some(updated_session)).await;
131 } else if is_network_error {
132 log::info!("[SessionVerifier] Network error during verification, keeping cached session");
134
135 if let Some(app) = &app_handle {
136 let event = SessionVerificationEvent::NetworkError {
137 message: e.clone(),
138 };
139 if let Err(e) = app.emit("auth:network-error", event) {
140 log::error!(
141 "[SessionVerifier] Failed to emit event: {}",
142 e
143 );
144 }
145 }
146 } else {
147 log::error!(
149 "[SessionVerifier] Unknown error during verification: {}",
150 e
151 );
152 }
153 }
154 }
155 }
156
157 tokio::time::sleep(Duration::from_millis(VERIFICATION_INTERVAL_MS)).await;
159 }
160
161 log::info!("[SessionVerifier] Stopped");
162 });
163 }
164
165 pub fn stop(&self) {
167 log::info!("[SessionVerifier] Stopping background verification");
168 self.is_running.store(false, Ordering::SeqCst);
169 }
170}