You've already forked AstralRinth
Hydra local (#594)
* initial commit * merge fixes * added sanitizing * linter * Improve sign in UI * simple simple! * bump version --------- Co-authored-by: CodexAdrian <83074853+CodexAdrian@users.noreply.github.com> Co-authored-by: Jai A <jaiagr+gpg@pm.me>
This commit is contained in:
85
theseus/src/api/hydra/complete.rs
Normal file
85
theseus/src/api/hydra/complete.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
//! Main authentication flow for Hydra
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::prelude::Credentials;
|
||||
|
||||
use super::stages::{
|
||||
bearer_token, player_info, poll_response, xbl_signin, xsts_token,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct OauthFailure {
|
||||
pub error: String,
|
||||
}
|
||||
|
||||
pub struct SuccessfulLogin {
|
||||
pub name: String,
|
||||
pub icon: String,
|
||||
pub token: String,
|
||||
pub refresh_token: String,
|
||||
pub expires_after: i64,
|
||||
}
|
||||
|
||||
pub async fn wait_finish(device_code: String) -> crate::Result<Credentials> {
|
||||
// Loop, polling for response from Microsoft
|
||||
let oauth = poll_response::poll_response(device_code).await?;
|
||||
|
||||
// Get xbl token from oauth token
|
||||
let xbl_token = xbl_signin::login_xbl(&oauth.access_token).await?;
|
||||
|
||||
// Get xsts token from xbl token
|
||||
let xsts_response = xsts_token::fetch_token(&xbl_token.token).await?;
|
||||
|
||||
match xsts_response {
|
||||
xsts_token::XSTSResponse::Unauthorized(err) => {
|
||||
Err(crate::ErrorKind::HydraError(format!(
|
||||
"Error getting XBox Live token: {}",
|
||||
err
|
||||
))
|
||||
.as_error())
|
||||
}
|
||||
xsts_token::XSTSResponse::Success { token: xsts_token } => {
|
||||
// Get xsts bearer token from xsts token
|
||||
let bearer_token =
|
||||
bearer_token::fetch_bearer(&xsts_token, &xbl_token.uhs)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
crate::ErrorKind::HydraError(format!(
|
||||
"Error getting bearer token: {}",
|
||||
err
|
||||
))
|
||||
})?;
|
||||
|
||||
// Get player info from bearer token
|
||||
let player_info = player_info::fetch_info(&bearer_token).await.map_err(|_err| {
|
||||
crate::ErrorKind::HydraError("No Minecraft account for profile. Make sure you own the game and have set a username through the official Minecraft launcher."
|
||||
.to_string())
|
||||
})?;
|
||||
|
||||
// Create credentials
|
||||
let credentials = Credentials::new(
|
||||
uuid::Uuid::parse_str(&player_info.id)?, // get uuid from player_info.id which is a String
|
||||
player_info.name,
|
||||
bearer_token,
|
||||
oauth.refresh_token,
|
||||
chrono::Utc::now()
|
||||
+ chrono::Duration::seconds(oauth.expires_in),
|
||||
);
|
||||
|
||||
// Put credentials into state
|
||||
let state = crate::State::get().await?;
|
||||
{
|
||||
let mut users = state.users.write().await;
|
||||
users.insert(&credentials).await?;
|
||||
}
|
||||
|
||||
if state.settings.read().await.default_user.is_none() {
|
||||
let mut settings = state.settings.write().await;
|
||||
settings.default_user = Some(credentials.id);
|
||||
}
|
||||
|
||||
Ok(credentials)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user