1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::collections::HashMap;
use reqwest::Method;
use crate::{
client::TidalClient,
error::TidalError,
requests::{self, TidalRequest},
responses::RefreshTokenResponse,
};
impl TidalClient {
/// Refreshes the access token using the refresh token
///
/// Returns `true` if the token was refreshed, `false` if it was still valid.
///
/// # Arguments
///
/// * `force` - If true, refreshes even if the current token hasn't expired
///
/// # Example
///
/// ```no_run
/// # use tidlers::{TidalClient, auth::init::TidalAuth};
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// # let auth = TidalAuth::with_oauth();
/// # let mut client = TidalClient::new(&auth);
/// // Refresh if expired
/// if client.refresh_access_token(false).await? {
/// println!("Token refreshed");
/// }
/// # Ok(())
/// # }
/// ```
pub async fn refresh_access_token(&mut self, force: bool) -> Result<bool, TidalError> {
if self.session.auth.refresh_token.is_none() {
return Err(TidalError::Other(
"No refresh token available, cannot refresh access token.".to_string(),
));
}
if force || self.session.auth.is_token_expired() {
let mut form = HashMap::new();
form.insert("grant_type".to_string(), "refresh_token".to_string());
form.insert(
"refresh_token".to_string(),
self.session.auth.refresh_token.clone().unwrap(),
);
let mut req = TidalRequest::new(Method::POST, "/token".to_string());
req.form = Some(vec![form]);
req.basic_auth = Some(requests::BasicAuth::new(
self.session.auth.client_id.clone(),
self.session.auth.client_secret.clone(),
));
req.base_url = Some("https://auth.tidal.com/v1/oauth2".to_string());
let res = self.rq.request(req).await?;
let body = res.text().await?;
let json: RefreshTokenResponse = serde_json::from_str(&body)?;
// update the access token and refresh token
self.session.auth.access_token = Some(json.access_token.clone());
self.session.auth.refresh_expiry = Some(json.expires_in as u64);
self.session.auth.last_refresh_time = Some(
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)?
.as_secs(),
);
return Ok(true);
}
Ok(false)
}
}