aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src-tauri
diff options
context:
space:
mode:
authorHsiangNianian <i@jyunko.cn>2026-01-13 18:46:17 +0800
committerHsiangNianian <i@jyunko.cn>2026-01-13 18:46:17 +0800
commit464fe3ba5242bcb16e5ae3d9941f52a3b9a5ee4b (patch)
treebea59a7919326ea2e7fde619f96f181658f976de /src-tauri
parentf49685f30fe93f105ad4bde61d639f6e0a5c2c0f (diff)
downloadDropOut-464fe3ba5242bcb16e5ae3d9941f52a3b9a5ee4b.tar.gz
DropOut-464fe3ba5242bcb16e5ae3d9941f52a3b9a5ee4b.zip
feat: update Microsoft account client ID and enhance error handling for authentication and profile fetch
Diffstat (limited to 'src-tauri')
-rw-r--r--src-tauri/src/core/auth.rs49
1 files changed, 44 insertions, 5 deletions
diff --git a/src-tauri/src/core/auth.rs b/src-tauri/src/core/auth.rs
index 18e51ee..eb4f3a0 100644
--- a/src-tauri/src/core/auth.rs
+++ b/src-tauri/src/core/auth.rs
@@ -73,8 +73,7 @@ pub fn generate_offline_uuid(username: &str) -> String {
// --- Microsoft Auth Logic ---
// Constants
-// Using a common public client ID for Minecraft Launchers
-const CLIENT_ID: &str = "00000000-402b-802d-0000-000000000000";
+const CLIENT_ID: &str = "fe165602-5410-4441-92f7-326e10a7cb82";
const SCOPE: &str = "XboxLive.Signin offline_access openid profile email";
#[derive(Debug, Serialize, Deserialize)]
@@ -215,7 +214,9 @@ pub async fn method_xbox_live(ms_access_token: &str) -> Result<(String, String),
.map_err(|e| e.to_string())?;
if !resp.status().is_success() {
- return Err(format!("Xbox Live auth failed: {}", resp.status()));
+ let status = resp.status();
+ let text = resp.text().await.unwrap_or_default();
+ return Err(format!("Xbox Live auth failed: {} - {}", status, text));
}
let xbl_resp: XboxLiveResponse = resp.json().await.map_err(|e| e.to_string())?;
@@ -277,7 +278,9 @@ pub async fn login_minecraft(xsts_token: &str, uhs: &str) -> Result<String, Stri
.map_err(|e| e.to_string())?;
if !resp.status().is_success() {
- return Err(format!("Minecraft auth failed: {}", resp.status()));
+ let status = resp.status();
+ let text = resp.text().await.unwrap_or_else(|_| "No body".to_string());
+ return Err(format!("Minecraft auth failed: {} - Body: {}", status, text));
}
let mc_resp: MinecraftAuthResponse = resp.json().await.map_err(|e| e.to_string())?;
@@ -296,9 +299,45 @@ pub async fn fetch_profile(mc_access_token: &str) -> Result<MinecraftProfile, St
.map_err(|e| e.to_string())?;
if !resp.status().is_success() {
- return Err(format!("Profile fetch failed: {}", resp.status()));
+ let status = resp.status();
+ let text = resp.text().await.unwrap_or_default();
+ return Err(format!("Profile fetch failed: {} - {}", status, text));
}
let profile: MinecraftProfile = resp.json().await.map_err(|e| e.to_string())?;
Ok(profile)
}
+
+// 7. Check Game Ownership
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Entitlement {
+ pub name: String,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct EntitlementsResponse {
+ pub items: Vec<Entitlement>,
+ pub signature: Option<String>,
+ pub keyId: Option<String>,
+}
+
+pub async fn check_ownership(mc_access_token: &str) -> Result<bool, String> {
+ let client = reqwest::Client::new();
+ let url = "https://api.minecraftservices.com/entitlements/mcstore";
+
+ let resp = client.get(url)
+ .bearer_auth(mc_access_token)
+ .send()
+ .await
+ .map_err(|e| e.to_string())?;
+
+ if !resp.status().is_success() {
+ let text = resp.text().await.unwrap_or_default();
+ return Err(format!("Entitlement check failed: {} - {}", resp.status(), text));
+ }
+
+ let body: EntitlementsResponse = resp.json().await.map_err(|e| e.to_string())?;
+ // We look for "product_minecraft" or "game_minecraft"
+ let owns_game = body.items.iter().any(|e| e.name == "product_minecraft" || e.name == "game_minecraft");
+ Ok(owns_game)
+}