diff --git a/src/auth.rs b/src/auth.rs index 12f6710..0f29182 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -31,7 +31,8 @@ impl SpotifyAuth { .append_pair("response_type", "code") .append_pair("client_id", &self.config.client_id) .append_pair("scope", &self.config.scopes.join(" ")) - .append_pair("redirect_uri", &self.config.redirect_uri); + .append_pair("redirect_uri", &self.config.redirect_uri) + .append_pair("show_dialog", "true"); if let Some(state) = state { url.query_pairs_mut().append_pair("state", state); diff --git a/src/client.rs b/src/client.rs index eda77c7..9b1da69 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,4 +1,5 @@ use crate::auth::SpotifyAuth; +use crate::config::ConfigManager; use crate::error::{Result, SpotifyError}; use crate::models::{CurrentTrack, SimplifiedCurrentTrack, SpotifyConfig, TokenInfo}; use chrono::Utc; @@ -12,10 +13,11 @@ pub struct SpotifyClient { client: Client, auth: SpotifyAuth, token_info: Arc>>, + config_manager: ConfigManager, } impl SpotifyClient { - pub fn new(config: SpotifyConfig) -> Self { + pub fn new(config: SpotifyConfig, config_manager: ConfigManager) -> Self { let client = Client::builder() .user_agent("SpotifyTracker/1.0") .timeout(std::time::Duration::from_secs(30)) @@ -29,6 +31,7 @@ impl SpotifyClient { client, auth, token_info, + config_manager, } } @@ -140,9 +143,9 @@ impl SpotifyClient { let token_guard = self.token_info.read().await; if let Some(token_info) = token_guard.as_ref() { - // Check if token expires in the next 5 minutes - let expires_soon = token_info.expires_at - chrono::Duration::minutes(5); - Utc::now() < expires_soon + // Check if token expires in the next 5 minutes - refresh if within 5 min of expiry + let expires_with_buffer = token_info.expires_at - chrono::Duration::minutes(5); + Utc::now() < expires_with_buffer } else { false } @@ -170,13 +173,18 @@ impl SpotifyClient { log::info!("Refreshing expired token..."); match self.auth.refresh_token(refresh_token).await { Ok(new_token) => { + // Save token to disk + if let Err(e) = self.config_manager.save_token(&new_token) { + log::error!("Failed to save refreshed token to disk: {}", e); + } *token_guard = Some(new_token); log::info!("Token refreshed successfully"); return Ok(()); } Err(e) => { log::error!("Failed to refresh token: {}", e); - *token_guard = None; + // Keep the existing token rather than clearing it entirely + // This allows manual re-auth instead of losing the token completely return Err(e); } } @@ -207,7 +215,8 @@ mod tests { #[tokio::test] async fn test_client_creation() { let config = SpotifyConfig::default(); - let client = SpotifyClient::new(config); + let config_manager = ConfigManager::new().unwrap(); + let client = SpotifyClient::new(config, config_manager); assert!(!client.is_token_valid().await); } @@ -215,7 +224,8 @@ mod tests { #[test] fn test_authorization_url() { let config = SpotifyConfig::default(); - let client = SpotifyClient::new(config); + let config_manager = ConfigManager::new().unwrap(); + let client = SpotifyClient::new(config, config_manager); let url = client.get_authorization_url(Some("test_state")); assert!(url.contains("spotify.com"));