Fix auth device token (#1152)

This commit is contained in:
Geometrically
2024-04-25 11:45:52 -07:00
committed by GitHub
parent 4de64d9a43
commit 89c7adfbcd

View File

@@ -11,7 +11,7 @@ use p256::pkcs8::{DecodePrivateKey, EncodePrivateKey, LineEnding};
use rand::rngs::OsRng; use rand::rngs::OsRng;
use rand::Rng; use rand::Rng;
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
use reqwest::Response; use reqwest::{Error, Response};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
@@ -46,13 +46,14 @@ pub enum MinecraftAuthenticationError {
source: serde_json::Error, source: serde_json::Error,
}, },
#[error( #[error(
"Failed to deserialize response to JSON during step {step:?}: {source}" "Failed to deserialize response to JSON during step {step:?}: {source}. Status Code: {status_code} Body: {raw}"
)] )]
DeserializeResponse { DeserializeResponse {
step: MinecraftAuthStep, step: MinecraftAuthStep,
raw: String, raw: String,
#[source] #[source]
source: serde_json::Error, source: serde_json::Error,
status_code: reqwest::StatusCode,
}, },
#[error("Request failed during step {step:?}: {source}")] #[error("Request failed during step {step:?}: {source}")]
Request { Request {
@@ -81,6 +82,8 @@ pub struct SaveDeviceToken {
pub x: String, pub x: String,
pub y: String, pub y: String,
pub token: DeviceToken, pub token: DeviceToken,
#[serde(default)]
modern: bool,
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@@ -151,6 +154,7 @@ impl MinecraftAuthStore {
x: key.x.clone(), x: key.x.clone(),
y: key.y.clone(), y: key.y.clone(),
token: token.clone(), token: token.clone(),
modern: true,
}); });
self.save().await?; self.save().await?;
@@ -160,13 +164,7 @@ impl MinecraftAuthStore {
let (key, token) = if let Some(ref token) = self.token { let (key, token) = if let Some(ref token) = self.token {
// reset device token for legacy launcher versions with broken values // reset device token for legacy launcher versions with broken values
if self.users.is_empty() if self.users.is_empty() && !token.modern {
&& token.token.issue_instant
< DateTime::parse_from_rfc3339(
"2024-04-25T23:59:59.999999999Z",
)
.unwrap()
{
return Ok(generate_key!( return Ok(generate_key!(
self, self,
generate_key, generate_key,
@@ -487,6 +485,7 @@ async fn oauth_token(
step: MinecraftAuthStep::GetOAuthToken, step: MinecraftAuthStep::GetOAuthToken,
})?; })?;
let status = res.status();
let text = res.text().await.map_err(|source| { let text = res.text().await.map_err(|source| {
MinecraftAuthenticationError::Request { MinecraftAuthenticationError::Request {
source, source,
@@ -499,6 +498,7 @@ async fn oauth_token(
source, source,
raw: text, raw: text,
step: MinecraftAuthStep::GetOAuthToken, step: MinecraftAuthStep::GetOAuthToken,
status_code: status,
} }
}) })
} }
@@ -527,6 +527,7 @@ async fn oauth_refresh(
step: MinecraftAuthStep::RefreshOAuthToken, step: MinecraftAuthStep::RefreshOAuthToken,
})?; })?;
let status = res.status();
let text = res.text().await.map_err(|source| { let text = res.text().await.map_err(|source| {
MinecraftAuthenticationError::Request { MinecraftAuthenticationError::Request {
source, source,
@@ -539,6 +540,7 @@ async fn oauth_refresh(
source, source,
raw: text, raw: text,
step: MinecraftAuthStep::RefreshOAuthToken, step: MinecraftAuthStep::RefreshOAuthToken,
status_code: status,
} }
}) })
} }
@@ -655,6 +657,7 @@ async fn minecraft_token(
step: MinecraftAuthStep::MinecraftToken, step: MinecraftAuthStep::MinecraftToken,
})?; })?;
let status = res.status();
let text = res.text().await.map_err(|source| { let text = res.text().await.map_err(|source| {
MinecraftAuthenticationError::Request { MinecraftAuthenticationError::Request {
source, source,
@@ -667,6 +670,7 @@ async fn minecraft_token(
source, source,
raw: text, raw: text,
step: MinecraftAuthStep::MinecraftToken, step: MinecraftAuthStep::MinecraftToken,
status_code: status,
} }
}) })
} }
@@ -694,6 +698,7 @@ async fn minecraft_profile(
step: MinecraftAuthStep::MinecraftProfile, step: MinecraftAuthStep::MinecraftProfile,
})?; })?;
let status = res.status();
let text = res.text().await.map_err(|source| { let text = res.text().await.map_err(|source| {
MinecraftAuthenticationError::Request { MinecraftAuthenticationError::Request {
source, source,
@@ -706,6 +711,7 @@ async fn minecraft_profile(
source, source,
raw: text, raw: text,
step: MinecraftAuthStep::MinecraftProfile, step: MinecraftAuthStep::MinecraftProfile,
status_code: status,
} }
}) })
} }
@@ -727,6 +733,7 @@ async fn minecraft_entitlements(
}) })
.await.map_err(|source| MinecraftAuthenticationError::Request { source, step: MinecraftAuthStep::MinecraftEntitlements })?; .await.map_err(|source| MinecraftAuthenticationError::Request { source, step: MinecraftAuthStep::MinecraftEntitlements })?;
let status = res.status();
let text = res.text().await.map_err(|source| { let text = res.text().await.map_err(|source| {
MinecraftAuthenticationError::Request { MinecraftAuthenticationError::Request {
source, source,
@@ -739,6 +746,7 @@ async fn minecraft_entitlements(
source, source,
raw: text, raw: text,
step: MinecraftAuthStep::MinecraftEntitlements, step: MinecraftAuthStep::MinecraftEntitlements,
status_code: status,
} }
}) })
} }
@@ -751,25 +759,33 @@ async fn auth_retry<F>(
where where
F: Future<Output = Result<Response, reqwest::Error>>, F: Future<Output = Result<Response, reqwest::Error>>,
{ {
const RETRY_COUNT: usize = 9; // Does command 9 times const RETRY_COUNT: usize = 5; // Does command 9 times
const RETRY_WAIT: std::time::Duration = const RETRY_WAIT: std::time::Duration =
std::time::Duration::from_millis(250); std::time::Duration::from_millis(250);
let mut resp = reqwest_request().await?; let mut resp = reqwest_request().await;
for i in 0..RETRY_COUNT { for i in 0..RETRY_COUNT {
if resp.status().is_success() { match &resp {
break; Ok(_) => {
break;
}
Err(err) => {
if err.is_connect() || err.is_timeout() {
if i < RETRY_COUNT - 1 {
tracing::debug!(
"Request failed with connect error, retrying...",
);
tokio::time::sleep(RETRY_WAIT).await;
resp = reqwest_request().await;
} else {
break;
}
}
}
} }
tracing::debug!(
"Request failed with status code {}, retrying...",
resp.status()
);
if i < RETRY_COUNT - 1 {
tokio::time::sleep(RETRY_WAIT).await;
}
resp = reqwest_request().await?;
} }
Ok(resp)
resp
} }
pub struct DeviceTokenKey { pub struct DeviceTokenKey {
@@ -896,16 +912,18 @@ async fn send_signed_request<T: DeserializeOwned>(
.await .await
.map_err(|source| MinecraftAuthenticationError::Request { source, step })?; .map_err(|source| MinecraftAuthenticationError::Request { source, step })?;
let status = res.status();
let headers = res.headers().clone(); let headers = res.headers().clone();
let res = res.text().await.map_err(|source| { let body = res.text().await.map_err(|source| {
MinecraftAuthenticationError::Request { source, step } MinecraftAuthenticationError::Request { source, step }
})?; })?;
let body = serde_json::from_str(&res).map_err(|source| { let body = serde_json::from_str(&body).map_err(|source| {
MinecraftAuthenticationError::DeserializeResponse { MinecraftAuthenticationError::DeserializeResponse {
source, source,
raw: res, raw: body,
step, step,
status_code: status,
} }
})?; })?;
Ok((headers, body)) Ok((headers, body))