diff --git a/desktop-client/src-tauri/src/lib.rs b/desktop-client/src-tauri/src/lib.rs index 210b266..a7e6fd2 100644 --- a/desktop-client/src-tauri/src/lib.rs +++ b/desktop-client/src-tauri/src/lib.rs @@ -75,6 +75,11 @@ struct LoginRequest<'a> { password: &'a str, } +#[derive(Debug, Serialize)] +struct RefreshRequest<'a> { + refresh_token: &'a str, +} + #[derive(Debug, Deserialize)] struct LoginResponse { #[serde(rename = "access_token")] @@ -406,7 +411,7 @@ fn current_metrics(app: &AppHandle) -> Result { } async fn sync_current_session(app: &AppHandle) -> Result { - let existing = { + let mut existing = { let state = app.state::(); let session = state.session.lock().map_err(|_| "Unable to read client state".to_string())?; session.clone().ok_or_else(|| "No enrolled profile is available yet".to_string())? @@ -417,13 +422,49 @@ async fn sync_current_session(app: &AppHandle) -> Result { .build() .map_err(|err| err.to_string())?; - let response = client - .get(format!("{}/api/v1/me/profile", existing.server_url.trim_end_matches('/'))) + let profile_url = format!("{}/api/v1/me/profile", existing.server_url.trim_end_matches('/')); + let mut response = client + .get(&profile_url) .bearer_auth(&existing.access_token) .send() .await .map_err(|err| format!("Profile sync failed: {}", err))?; + if response.status().as_u16() == 401 { + let refresh = client + .post(format!("{}/api/v1/auth/refresh", existing.server_url.trim_end_matches('/'))) + .json(&RefreshRequest { + refresh_token: &existing.refresh_token, + }) + .send() + .await + .map_err(|err| format!("Session refresh failed: {}", err))?; + + if !refresh.status().is_success() { + let status = refresh.status(); + let body = refresh + .text() + .await + .unwrap_or_else(|_| "".into()); + return Err(format!("Session refresh failed with status {}: {}", status, body)); + } + + let refreshed = refresh + .json::() + .await + .map_err(|err| format!("Unable to decode refresh response: {}", err))?; + + existing.access_token = refreshed.access_token; + existing.refresh_token = refreshed.refresh_token; + + response = client + .get(&profile_url) + .bearer_auth(&existing.access_token) + .send() + .await + .map_err(|err| format!("Profile sync failed: {}", err))?; + } + if !response.status().is_success() { let status = response.status(); let body = response