Skip to content
This repository was archived by the owner on Mar 14, 2026. It is now read-only.

Commit e68b3cd

Browse files
committed
feat: minecraft-auth partial support
fixup: form string
1 parent 9845ba8 commit e68b3cd

4 files changed

Lines changed: 157 additions & 76 deletions

File tree

crates/core/src/auth/microsoft.rs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![forbid(unsafe_code)]
22
#![warn(clippy::pedantic)]
33

4+
use std::collections::HashMap;
5+
46
use crate::{errors::AuthErrors, trait_alias::*};
57
use reqwest::Client;
68
use serde::{Deserialize, Serialize};
@@ -154,10 +156,7 @@ fn parse_oauth(data: &[u8]) -> Result<OuathInfo, AuthErrors> {
154156
/// OAuth Auth Token Infomation.
155157
#[derive(Deserialize, Debug)]
156158
pub struct OuathToken {
157-
pub token_type: String,
158-
pub scope: String,
159-
pub expires_in: u16,
160-
pub ext_expires_in: u16,
159+
pub expires_in: u64,
161160
pub access_token: String,
162161
pub refresh_token: String,
163162
}
@@ -168,34 +167,38 @@ pub fn ouath_token(
168167
code: Option<&str>,
169168
client_id: &str,
170169
scope: &str,
171-
port: u16,
172-
client_secret: &str,
170+
redirect_uri: String,
171+
client_secret: Option<&str>,
173172
) -> impl AsyncSendSync<Result<OuathToken, AuthErrors>> {
174-
let url = format!("https://login.microsoftonline.com/consumers/oauth2/v2.0/token");
175-
let mut body = format!(
176-
"client_id={}&scope={}&client_secret={}",
177-
client_id, scope, client_secret
178-
);
173+
let url = if redirect_uri == "https://login.live.com/oauth20_desktop.srf" {
174+
"https://login.live.com/oauth20_token.srf"
175+
} else {
176+
"https://login.microsoftonline.com/consumers/oauth2/v2.0/token"
177+
};
178+
179+
// Use owned Strings for both keys and values
180+
let mut form = HashMap::new();
181+
form.insert("client_id".to_string(), client_id.to_string());
182+
form.insert("scope".to_string(), scope.to_string());
183+
184+
if let Some(secret) = client_secret {
185+
form.insert("client_secret".to_string(), secret.to_string());
186+
}
179187

180188
if let Some(token) = refresh_token {
181-
body.push_str(&format!(
182-
"&grant_type=refresh_token&refresh_token={}",
183-
token
184-
));
189+
form.insert("grant_type".to_string(), "refresh_token".to_string());
190+
form.insert("refresh_token".to_string(), token); // token is already a String
185191
} else if let Some(auth_code) = code {
186-
let redirect_uri = format!("http://localhost:{}", port);
187-
body.push_str(&format!(
188-
"&grant_type=authorization_code&code={}&redirect_uri={}",
189-
auth_code, redirect_uri
190-
));
191-
};
192+
form.insert("grant_type".to_string(), "authorization_code".to_string());
193+
form.insert("code".to_string(), auth_code.to_string());
194+
form.insert("redirect_uri".to_string(), redirect_uri);
195+
}
192196

193197
async move {
194198
'out: {
195-
let result = client.post(url).body(body).send().await;
199+
let result = client.post(url).form(&form).send().await;
196200

197201
let std::result::Result::Ok(response) = result else {
198-
println!("Part 1");
199202
break 'out Err(AuthErrors::ResponseError(
200203
"Failed to send request".to_string(),
201204
));
@@ -205,7 +208,8 @@ pub fn ouath_token(
205208
.text()
206209
.await
207210
.map_err(|_| AuthErrors::ResponseError("Failed to send request".to_string()))?;
208-
let std::result::Result::Ok(token) = serde_json::from_str::<OuathToken>(&text) else {
211+
212+
let std::result::Result::Ok(token) = serde_json::from_str(&text) else {
209213
break 'out Err(AuthErrors::ResponseError(
210214
"Failed to send request, Check your Client Secret.".to_string(),
211215
));

crates/core/src/auth/xbox.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
use crate::trait_alias::*;
55
use reqwest::Client;
66

7-
use reqwest::header::{self, HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE};
7+
use reqwest::header::{self, ACCEPT, CONTENT_TYPE, HeaderMap, HeaderValue};
88
use serde::Deserialize;
9-
use serde_json::{json, Value};
9+
use serde_json::{Value, json};
1010

1111
use crate::errors::AuthErrors;
1212
#[derive(Deserialize, Debug)]
@@ -33,7 +33,6 @@ pub fn xbl(client: Client, token: &str) -> impl AsyncSendSync<Result<XblOutput,
3333
let url = format!("https://user.auth.xboxlive.com/user/authenticate");
3434
let rps_ticket = format!("d={}", token);
3535
let mut headers = HeaderMap::new();
36-
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
3736
headers.insert(ACCEPT, HeaderValue::from_static("application/json"));
3837

3938
let body = json!({
@@ -73,6 +72,8 @@ async fn xbl_internal(
7372
.await
7473
.map_err(|_| AuthErrors::ParseError("Failed to pass text from xbox".to_string()))?;
7574

75+
println!("Text: {}", text);
76+
7677
let std::result::Result::Ok(token) = serde_json::from_str::<XblOutput>(&text) else {
7778
return Err(AuthErrors::ParseError(
7879
"Failed to pass text to json".to_string(),

0 commit comments

Comments
 (0)