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

Commit 2a8af59

Browse files
committed
feat: oauth improvements, scope/refreshtoken options
1 parent 846e709 commit 2a8af59

6 files changed

Lines changed: 122 additions & 60 deletions

File tree

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ tauri = { version = "2.2.4" }
1313
serde = "1.0"
1414
thiserror = "2"
1515
minecraft-essentials = {git = "https://github.com/minecraft-essentials/minecraft-essentials", branch = "0.2.12"}
16+
tokio = { version = "1.45.1", features = ["sync"] }
17+
url = "2.5.4"
18+
open = {version = "5.3.2", optional = true }
1619

1720
[build-dependencies]
1821
tauri-plugin = { version = "2.0.3", features = ["build"] }
22+
23+
24+
[features]
25+
open = ["dep:open"]

build.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
const COMMANDS: &[&str] = &["ping"];
22

33
fn main() {
4-
tauri_plugin::Builder::new(COMMANDS)
5-
.build();
4+
tauri_plugin::Builder::new(COMMANDS).build();
5+
6+
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
7+
let mobile = target_os == "ios" || target_os == "android";
8+
alias("desktop", !mobile);
9+
alias("mobile", mobile);
10+
}
11+
12+
fn alias(alias: &str, has_feature: bool) {
13+
println!("cargo:rustc-check-cfg=cfg({alias})");
14+
if has_feature {
15+
println!("cargo:rustc-cfg={alias}");
16+
}
617
}

guest-js/index.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import { invoke } from '@tauri-apps/api/core'
22

3-
interface CustomAuthData {
4-
access_token: string,
5-
uuid?: number,
6-
expires_in: string,
7-
xts_token?: string,
3+
interface OAuthParams {
4+
client_id: string;
5+
client_secret: string;
6+
bedrock_rel: boolean;
7+
refresh_token?: string;
8+
scope?: string;
9+
port?: number;
810
}
911

12+
interface CustomAuthData {
13+
access_token: string;
14+
uuid?: number;
15+
expires_in: string;
16+
xts_token?: string;
17+
}
1018

11-
export async function oauth(client_id: string, client_secret: string, bedrock_rel?: boolean, port?: number): Promise<CustomAuthData> {
12-
return await invoke<CustomAuthData>('plugin:minecraft-essentails|oauth', {
13-
client_id,
14-
client_secret,
15-
bedrock_rel,
16-
port
17-
}).then((r) => (r));
19+
export async function oauth(params: OAuthParams): Promise<CustomAuthData> {
20+
return await invoke<CustomAuthData>('plugin:minecraft-essentials|oauth', { ...params });
1821
}

src/commands.rs

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,87 @@
1+
use tauri::{command, AppHandle, Runtime};
12
use tauri::{Url, WebviewWindowBuilder};
2-
use tauri::{AppHandle, command, Runtime};
33

44
use minecraft_essentials::{AuthType, AuthenticationBuilder, CustomAuthData};
5+
#[cfg(feature = "open")]
6+
use open;
7+
58
use std::str::FromStr;
69

710
#[command]
8-
pub async fn oauth<R: Runtime>(app: AppHandle<R>, client_id: &str, client_secret: &str, bedrock_rel: bool, port: Option<u16>) -> Result<CustomAuthData, String> {
9-
let mut auth = AuthenticationBuilder::builder();
10-
auth.of_type(AuthType::Oauth).client_id(client_id).client_secret(client_secret).bedrockrel(bedrock_rel).port(port);
11-
12-
let get_info = auth.get_info().await.ouath_url.unwrap();
13-
let url = Url::from_str(&get_info).map_err(|e| e.to_string())?;
14-
let window = WebviewWindowBuilder::new(&app, "Minecraft Authentification", tauri::WebviewUrl::External(url)).closable(true).build().map_err(|e| e.to_string())?;
15-
16-
let auth_info: CustomAuthData = auth.launch().await.map_err(|e| e.to_string())?;
17-
18-
if auth_info.access_token.is_some() {
19-
let _ = window.close();
11+
#[cfg(desktop)]
12+
pub async fn oauth<R: Runtime>(
13+
app: AppHandle<R>,
14+
client_id: &str,
15+
client_secret: &str,
16+
bedrock_rel: bool,
17+
refresh_token: Option<String>,
18+
scope: Option<String>,
19+
port: Option<u16>,
20+
) -> Result<CustomAuthData, String> {
21+
let mut builder = AuthenticationBuilder::builder();
22+
23+
if let Some(token) = refresh_token {
24+
let _ = builder
25+
.of_type(AuthType::Refresh)
26+
.refresh_token(Some(token))
27+
.map_err(|e| e.to_string())?;
28+
} else {
29+
builder.of_type(AuthType::Oauth);
30+
}
31+
32+
if scope.is_some() {
33+
builder.scope(scope);
34+
};
35+
36+
builder
37+
.client_id(client_id)
38+
.client_secret(client_secret)
39+
.bedrockrel(bedrock_rel)
40+
.port(port);
41+
42+
let get_info = builder.get_info().await;
43+
let oauth_url_str = get_info.ouath_url.ok_or_else(|| {
44+
"Could not retrieve the OAuth URL from the authentication provider.".to_string()
45+
})?;
46+
47+
let webview_window_to_close: Option<tauri::WebviewWindow<R>> = {
48+
#[cfg(not(feature = "open"))]
49+
{
50+
let url = Url::from_str(&oauth_url_str).map_err(|e| e.to_string())?;
51+
52+
let window = WebviewWindowBuilder::new(
53+
&app,
54+
"minecraft-authentication",
55+
tauri::WebviewUrl::External(url),
56+
)
57+
.title("Minecraft Authentication")
58+
.closable(true)
59+
.inner_size(500.0, 650.0)
60+
.build()
61+
.map_err(|e| e.to_string())?;
62+
Some(window) // Return the created window
63+
}
64+
#[cfg(feature = "open")]
65+
{
66+
open::that(&oauth_url_str)
67+
.map_err(|e| format!("Failed to open URL in browser: {}", e))?;
68+
None
69+
}
2070
};
2171

72+
let auth_info =
73+
tauri::async_runtime::spawn(
74+
async move { builder.launch().await.map_err(|e| e.to_string()) },
75+
)
76+
.await
77+
.map_err(|e| e.to_string())?
78+
.map_err(|e| e.to_string())?;
79+
80+
if let Some(window) = webview_window_to_close {
81+
if auth_info.access_token.is_some() {
82+
let _ = window.close();
83+
}
84+
}
85+
2286
Ok(auth_info)
23-
}
87+
}

src/lib.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,28 @@
1-
use tauri::{
2-
plugin::{Builder, TauriPlugin},
3-
Manager, Runtime, AppHandle
4-
};
1+
pub use error::{Error, Result};
2+
use tauri::{plugin::TauriPlugin, AppHandle, Manager, Runtime};
53

64
pub use minecraft_essentials::CustomAuthData;
75

86
mod commands;
97
mod error;
10-
mod models;
11-
12-
pub use error::{Error, Result};
138

149
/// Access to the minecraft-essentails APIs.
1510
pub struct MinecraftEssentails<R: Runtime>(AppHandle<R>);
1611

1712
/// Extensions to [`tauri::App`], [`tauri::AppHandle`] and [`tauri::Window`] to access the minecraft-essentails APIs.
1813
pub trait MinecraftEssentailsExt<R: Runtime> {
19-
fn minecraft_essentails(&self) -> &MinecraftEssentails<R>;
14+
fn minecraft_essentails(&self) -> &MinecraftEssentails<R>;
2015
}
2116

2217
impl<R: Runtime, T: Manager<R>> crate::MinecraftEssentailsExt<R> for T {
23-
fn minecraft_essentails(&self) -> &MinecraftEssentails<R> {
24-
self.state::<MinecraftEssentails<R>>().inner()
25-
}
18+
fn minecraft_essentails(&self) -> &MinecraftEssentails<R> {
19+
self.state::<MinecraftEssentails<R>>().inner()
20+
}
2621
}
2722

2823
/// Initializes the plugin.
2924
pub fn init<R: Runtime>() -> TauriPlugin<R> {
30-
Builder::new("minecraft-essentails")
31-
.invoke_handler(tauri::generate_handler![commands::oauth])
32-
.setup(|app, _api| {
33-
#[cfg(desktop)]
34-
app.manage(MinecraftEssentails(app.clone()));
35-
Ok(())
36-
})
37-
.build()
25+
tauri::plugin::Builder::new("minecraft-essentails")
26+
.invoke_handler(tauri::generate_handler![commands::oauth])
27+
.build()
3828
}

src/models.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)