Skip to content

Commit 6d9f145

Browse files
committed
✨ feature: add webview-based auth
1 parent a73f4b0 commit 6d9f145

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

apps/desktop/build.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ fn main() {
66
"onelauncher",
77
tauri_build::InlinedPlugin::new().commands(&[
88
// User
9-
"begin_msa",
10-
"finish_msa",
9+
"auth_login",
1110
"get_users",
1211
"get_user",
1312
"remove_user",

apps/desktop/permissions/onelauncher/default.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
description = "Default permissions for the plugin"
33
permissions = [
44
# User
5-
"allow-begin-msa",
6-
"allow-finish-msa",
5+
"allow-auth-login",
76
"allow-get-users",
87
"allow-get-user",
98
"allow-remove-user",

apps/desktop/src/api/commands.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ use interpulse::api::minecraft::Version;
44
use onelauncher::constants::{NATIVE_ARCH, TARGET_OS, VERSION};
55
use onelauncher::data::{Loader, ManagedPackage, MinecraftCredentials, PackageData, Settings};
66
use onelauncher::package::content;
7-
use onelauncher::store::{Cluster, ClusterPath, MinecraftLogin};
7+
use onelauncher::store::{Cluster, ClusterPath};
88
use onelauncher::{cluster, minecraft, processor, settings};
99
use serde::{Deserialize, Serialize};
1010
use specta::Type;
11+
use tauri::{AppHandle, Manager};
1112
use uuid::Uuid;
1213

1314
#[macro_export]
@@ -21,8 +22,7 @@ macro_rules! collect_commands {
2122
)
2223
.commands(tauri_specta::collect_commands![
2324
// User
24-
begin_msa,
25-
finish_msa,
25+
auth_login,
2626
get_users,
2727
get_user,
2828
remove_user,
@@ -214,14 +214,49 @@ pub async fn get_user(uuid: Uuid) -> Result<MinecraftCredentials, String> {
214214

215215
#[specta::specta]
216216
#[tauri::command]
217-
pub async fn begin_msa() -> Result<MinecraftLogin, String> {
218-
Ok(minecraft::begin().await?)
219-
}
217+
pub async fn auth_login(handle: AppHandle) -> Result<Option<MinecraftCredentials>, String> {
218+
let flow = minecraft::begin().await?;
219+
let now = chrono::Utc::now();
220220

221-
#[specta::specta]
222-
#[tauri::command]
223-
pub async fn finish_msa(code: String, login: MinecraftLogin) -> Result<MinecraftCredentials, String> {
224-
Ok(minecraft::finish(code.as_str(), login).await?)
221+
if let Some(win) = handle.get_webview_window("login") {
222+
win.close().map_err(|err| err.to_string())?;
223+
}
224+
225+
let win = tauri::WebviewWindowBuilder::new(
226+
&handle,
227+
"login",
228+
tauri::WebviewUrl::External(flow.redirect_uri.parse().map_err(|_|
229+
anyhow::anyhow!("failed to parse auth redirect url")
230+
).map_err(|err| err.to_string())?),
231+
)
232+
.title("Log into OneLauncher")
233+
.always_on_top(true)
234+
.center()
235+
.build()
236+
.map_err(|err| err.to_string())?;
237+
238+
win.request_user_attention(Some(tauri::UserAttentionType::Critical)).map_err(|err| err.to_string())?;
239+
240+
while (chrono::Utc::now() - now) < chrono::Duration::minutes(10) {
241+
if win.title().is_err() {
242+
return Ok(None);
243+
}
244+
245+
if win.url().map_err(|err| err.to_string())?.as_str().starts_with("https://login.live.com/oauth20_desktop.srf") {
246+
if let Some((_, code)) = win.url().map_err(|err| err.to_string())?.query_pairs().find(|x| x.0 == "code") {
247+
win.close().map_err(|err| err.to_string())?;
248+
let value = minecraft::finish(&code.clone(), flow).await?;
249+
250+
return Ok(Some(value));
251+
}
252+
}
253+
254+
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
255+
}
256+
257+
win.close().map_err(|err| err.to_string())?;
258+
259+
Ok(None)
225260
}
226261

227262
#[specta::specta]

0 commit comments

Comments
 (0)