You've already forked AstralRinth
forked from didirus/AstralRinth
@@ -20,7 +20,8 @@ pub async fn authenticate_begin_flow() -> crate::Result<url::Url> {
|
||||
/// This completes the authentication flow quasi-synchronously, returning the credentials
|
||||
/// This can be used in conjunction with 'authenticate_begin_flow'
|
||||
/// to call authenticate and call the flow from the frontend.
|
||||
pub async fn authenticate_await_complete_flow() -> crate::Result<Credentials> {
|
||||
pub async fn authenticate_await_complete_flow(
|
||||
) -> crate::Result<(Credentials, Option<String>)> {
|
||||
let credentials = AuthTask::await_auth_completion().await?;
|
||||
Ok(credentials)
|
||||
}
|
||||
@@ -38,7 +39,7 @@ pub async fn cancel_flow() -> crate::Result<()> {
|
||||
#[theseus_macros::debug_pin]
|
||||
pub async fn authenticate(
|
||||
browser_url: oneshot::Sender<url::Url>,
|
||||
) -> crate::Result<Credentials> {
|
||||
) -> crate::Result<(Credentials, Option<String>)> {
|
||||
let mut flow = inner::HydraAuthFlow::new().await?;
|
||||
let state = State::get().await?;
|
||||
|
||||
@@ -52,12 +53,12 @@ pub async fn authenticate(
|
||||
let credentials = flow.extract_credentials(&state.fetch_semaphore).await?;
|
||||
{
|
||||
let mut users = state.users.write().await;
|
||||
users.insert(&credentials).await?;
|
||||
users.insert(&credentials.0).await?;
|
||||
}
|
||||
|
||||
if state.settings.read().await.default_user.is_none() {
|
||||
let mut settings = state.settings.write().await;
|
||||
settings.default_user = Some(credentials.id);
|
||||
settings.default_user = Some(credentials.0.id);
|
||||
}
|
||||
|
||||
Ok(credentials)
|
||||
@@ -79,8 +80,17 @@ pub async fn refresh(user: uuid::Uuid) -> crate::Result<Credentials> {
|
||||
})?;
|
||||
|
||||
let fetch_semaphore = &state.fetch_semaphore;
|
||||
if Utc::now() > credentials.expires {
|
||||
inner::refresh_credentials(&mut credentials, fetch_semaphore).await?;
|
||||
if Utc::now() > credentials.expires
|
||||
&& inner::refresh_credentials(&mut credentials, fetch_semaphore)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
users.remove(credentials.id).await?;
|
||||
|
||||
return Err(crate::ErrorKind::OtherError(
|
||||
"Please re-authenticate with your Minecraft account!".to_string(),
|
||||
)
|
||||
.as_error());
|
||||
}
|
||||
users.insert(&credentials).await?;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ use serde::Deserialize;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::event::emit::{emit_loading, init_loading};
|
||||
use crate::state::CredentialsStore;
|
||||
use crate::util::fetch::{fetch_advanced, fetch_json};
|
||||
use crate::util::io;
|
||||
use crate::util::jre::extract_java_majorminor_version;
|
||||
@@ -97,6 +98,7 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
||||
None,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
&CredentialsStore(None),
|
||||
).await?;
|
||||
emit_loading(&loading_bar, 10.0, Some("Downloading java version")).await?;
|
||||
|
||||
@@ -109,6 +111,7 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
||||
None,
|
||||
Some((&loading_bar, 80.0)),
|
||||
&state.fetch_semaphore,
|
||||
&CredentialsStore(None),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ pub mod handler;
|
||||
pub mod jre;
|
||||
pub mod logs;
|
||||
pub mod metadata;
|
||||
pub mod mr_auth;
|
||||
pub mod pack;
|
||||
pub mod process;
|
||||
pub mod profile;
|
||||
@@ -14,9 +15,9 @@ pub mod tags;
|
||||
pub mod data {
|
||||
pub use crate::state::{
|
||||
DirectoryInfo, Hooks, JavaSettings, LinkedData, MemorySettings,
|
||||
ModLoader, ModrinthProject, ModrinthTeamMember, ModrinthUser,
|
||||
ModrinthVersion, ProfileMetadata, ProjectMetadata, Settings, Theme,
|
||||
WindowSize,
|
||||
ModLoader, ModrinthCredentials, ModrinthCredentialsResult,
|
||||
ModrinthProject, ModrinthTeamMember, ModrinthUser, ModrinthVersion,
|
||||
ProfileMetadata, ProjectMetadata, Settings, Theme, WindowSize,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
157
theseus/src/api/mr_auth.rs
Normal file
157
theseus/src/api/mr_auth.rs
Normal file
@@ -0,0 +1,157 @@
|
||||
use crate::state::{
|
||||
ModrinthAuthFlow, ModrinthCredentials, ModrinthCredentialsResult,
|
||||
};
|
||||
use crate::ErrorKind;
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn authenticate_begin_flow(provider: &str) -> crate::Result<String> {
|
||||
let state = crate::State::get().await?;
|
||||
|
||||
let mut flow = ModrinthAuthFlow::new(provider).await?;
|
||||
let url = flow.prepare_login_url().await?;
|
||||
|
||||
let mut write = state.modrinth_auth_flow.write().await;
|
||||
*write = Some(flow);
|
||||
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn authenticate_await_complete_flow(
|
||||
) -> crate::Result<ModrinthCredentialsResult> {
|
||||
let state = crate::State::get().await?;
|
||||
|
||||
let mut write = state.modrinth_auth_flow.write().await;
|
||||
if let Some(ref mut flow) = *write {
|
||||
let creds = flow.extract_credentials(&state.fetch_semaphore).await?;
|
||||
|
||||
if let ModrinthCredentialsResult::Credentials(creds) = &creds {
|
||||
let mut write = state.credentials.write().await;
|
||||
write.login(creds.clone()).await?;
|
||||
}
|
||||
|
||||
Ok(creds)
|
||||
} else {
|
||||
Err(ErrorKind::OtherError(
|
||||
"No active Modrinth authenication flow!".to_string(),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn cancel_flow() -> crate::Result<()> {
|
||||
let state = crate::State::get().await?;
|
||||
let mut write = state.modrinth_auth_flow.write().await;
|
||||
if let Some(ref mut flow) = *write {
|
||||
flow.close().await?;
|
||||
}
|
||||
*write = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn login_password(
|
||||
username: &str,
|
||||
password: &str,
|
||||
challenge: &str,
|
||||
) -> crate::Result<ModrinthCredentialsResult> {
|
||||
let state = crate::State::get().await?;
|
||||
let creds = crate::state::login_password(
|
||||
username,
|
||||
password,
|
||||
challenge,
|
||||
&state.fetch_semaphore,
|
||||
)
|
||||
.await?;
|
||||
|
||||
if let ModrinthCredentialsResult::Credentials(creds) = &creds {
|
||||
let mut write = state.credentials.write().await;
|
||||
write.login(creds.clone()).await?;
|
||||
}
|
||||
|
||||
Ok(creds)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn login_2fa(
|
||||
code: &str,
|
||||
flow: &str,
|
||||
) -> crate::Result<ModrinthCredentials> {
|
||||
let state = crate::State::get().await?;
|
||||
let creds =
|
||||
crate::state::login_2fa(code, flow, &state.fetch_semaphore).await?;
|
||||
|
||||
let mut write = state.credentials.write().await;
|
||||
write.login(creds.clone()).await?;
|
||||
|
||||
Ok(creds)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn login_minecraft(
|
||||
flow: &str,
|
||||
) -> crate::Result<ModrinthCredentialsResult> {
|
||||
let state = crate::State::get().await?;
|
||||
let creds =
|
||||
crate::state::login_minecraft(flow, &state.fetch_semaphore).await?;
|
||||
|
||||
if let ModrinthCredentialsResult::Credentials(creds) = &creds {
|
||||
let mut write = state.credentials.write().await;
|
||||
write.login(creds.clone()).await?;
|
||||
}
|
||||
|
||||
Ok(creds)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn create_account(
|
||||
username: &str,
|
||||
email: &str,
|
||||
password: &str,
|
||||
challenge: &str,
|
||||
sign_up_newsletter: bool,
|
||||
) -> crate::Result<ModrinthCredentials> {
|
||||
let state = crate::State::get().await?;
|
||||
let creds = crate::state::create_account(
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
challenge,
|
||||
sign_up_newsletter,
|
||||
&state.fetch_semaphore,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut write = state.credentials.write().await;
|
||||
write.login(creds.clone()).await?;
|
||||
|
||||
Ok(creds)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn refresh() -> crate::Result<()> {
|
||||
let state = crate::State::get().await?;
|
||||
|
||||
let mut write = state.credentials.write().await;
|
||||
crate::state::refresh_credentials(&mut write, &state.fetch_semaphore)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn logout() -> crate::Result<()> {
|
||||
let state = crate::State::get().await?;
|
||||
let mut write = state.credentials.write().await;
|
||||
write.logout().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn get_credentials() -> crate::Result<Option<ModrinthCredentials>> {
|
||||
let state = crate::State::get().await?;
|
||||
let read = state.credentials.read().await;
|
||||
|
||||
Ok(read.0.clone())
|
||||
}
|
||||
@@ -2,6 +2,7 @@ use std::path::PathBuf;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::state::CredentialsStore;
|
||||
use crate::{
|
||||
prelude::{ModLoader, ProfilePathId},
|
||||
state::ProfileInstallStage,
|
||||
@@ -90,8 +91,13 @@ pub async fn import_curseforge(
|
||||
thumbnail_url: Some(thumbnail_url),
|
||||
}) = minecraft_instance.installed_modpack.clone()
|
||||
{
|
||||
let icon_bytes =
|
||||
fetch(&thumbnail_url, None, &state.fetch_semaphore).await?;
|
||||
let icon_bytes = fetch(
|
||||
&thumbnail_url,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
&CredentialsStore(None),
|
||||
)
|
||||
.await?;
|
||||
let filename = thumbnail_url.rsplit('/').last();
|
||||
if let Some(filename) = filename {
|
||||
icon = Some(
|
||||
|
||||
@@ -192,12 +192,14 @@ pub async fn generate_pack_from_version_id(
|
||||
.await?;
|
||||
|
||||
emit_loading(&loading_bar, 0.0, Some("Fetching version")).await?;
|
||||
let creds = state.credentials.read().await;
|
||||
let version: ModrinthVersion = fetch_json(
|
||||
Method::GET,
|
||||
&format!("{}version/{}", MODRINTH_API_URL, version_id),
|
||||
None,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
&creds,
|
||||
)
|
||||
.await?;
|
||||
emit_loading(&loading_bar, 10.0, None).await?;
|
||||
@@ -225,6 +227,7 @@ pub async fn generate_pack_from_version_id(
|
||||
None,
|
||||
Some((&loading_bar, 70.0)),
|
||||
&state.fetch_semaphore,
|
||||
&creds,
|
||||
)
|
||||
.await?;
|
||||
emit_loading(&loading_bar, 0.0, Some("Fetching project metadata")).await?;
|
||||
@@ -235,13 +238,16 @@ pub async fn generate_pack_from_version_id(
|
||||
None,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
&creds,
|
||||
)
|
||||
.await?;
|
||||
|
||||
emit_loading(&loading_bar, 10.0, Some("Retrieving icon")).await?;
|
||||
let icon = if let Some(icon_url) = project.icon_url {
|
||||
let state = State::get().await?;
|
||||
let icon_bytes = fetch(&icon_url, None, &state.fetch_semaphore).await?;
|
||||
let icon_bytes =
|
||||
fetch(&icon_url, None, &state.fetch_semaphore, &creds).await?;
|
||||
drop(creds);
|
||||
|
||||
let filename = icon_url.rsplit('/').next();
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ pub async fn install_zipped_mrpack_files(
|
||||
}
|
||||
}
|
||||
|
||||
let creds = state.credentials.read().await;
|
||||
let file = fetch_mirrors(
|
||||
&project
|
||||
.downloads
|
||||
@@ -176,8 +177,10 @@ pub async fn install_zipped_mrpack_files(
|
||||
.collect::<Vec<&str>>(),
|
||||
project.hashes.get(&PackFileHash::Sha1).map(|x| &**x),
|
||||
&state.fetch_semaphore,
|
||||
&creds,
|
||||
)
|
||||
.await?;
|
||||
drop(creds);
|
||||
|
||||
let path =
|
||||
std::path::Path::new(&project.path).components().next();
|
||||
|
||||
Reference in New Issue
Block a user