feat: hacky tauri login
parent
80c0e26b3e
commit
7da5de6c1e
|
|
@ -2005,6 +2005,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ tauri-build = { version = "1.2", features = [] }
|
||||||
tauri = { version = "1.2", features = ["shell-execute", "shell-open", "shell-sidecar", "window-all"] }
|
tauri = { version = "1.2", features = ["shell-execute", "shell-open", "shell-sidecar", "window-all"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
tokio = { version = "1.0", features = ["time"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,81 @@
|
||||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
use std::{
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
use tauri::{window::WindowBuilder, WindowEvent};
|
||||||
|
use tokio::time::sleep;
|
||||||
|
|
||||||
|
const INIT_SCRIPT: &str = r#"
|
||||||
|
function onSelectUserClick(e) {
|
||||||
|
const element = document.getElementById('authorize-switch-approval-link');
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// very hacky way...
|
||||||
|
window.ipc.postMessage(JSON.stringify({
|
||||||
|
"cmd":"tauri",
|
||||||
|
"callback":0,
|
||||||
|
"error":0,
|
||||||
|
"__tauriModule":"Event",
|
||||||
|
"message":{"cmd":"emit","event":"login","payload":element.href}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
function detectAndInject() {
|
||||||
|
const element = document.getElementById('authorize-switch-approval-link');
|
||||||
|
if (!element) {
|
||||||
|
window.setTimeout(detectAndInject, 100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
element.addEventListener('click', onSelectUserClick);
|
||||||
|
}
|
||||||
|
detectAndInject();
|
||||||
|
"#;
|
||||||
|
|
||||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn greet(name: &str) -> String {
|
async fn open_login_window(app: tauri::AppHandle, url: String) -> Option<String> {
|
||||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
let window = WindowBuilder::new(&app, "login", tauri::WindowUrl::App("/".into()))
|
||||||
|
.title("Login")
|
||||||
|
.initialization_script(INIT_SCRIPT)
|
||||||
|
.build()
|
||||||
|
.ok()?;
|
||||||
|
let result: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));
|
||||||
|
let r2 = result.clone();
|
||||||
|
let r3 = result.clone();
|
||||||
|
|
||||||
|
window.listen("login", move |e| {
|
||||||
|
let mut result = r2.lock().unwrap();
|
||||||
|
*result = e.payload().map(ToString::to_string);
|
||||||
|
});
|
||||||
|
window.on_window_event(move |e| {
|
||||||
|
if let WindowEvent::Destroyed = e {
|
||||||
|
let mut result = r3.lock().unwrap();
|
||||||
|
if result.is_none() {
|
||||||
|
*result = Some("".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
window
|
||||||
|
.eval(&format!("window.location.href = '{}'", url))
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
sleep(Duration::from_millis(100)).await;
|
||||||
|
let result = result.lock().unwrap();
|
||||||
|
if result.is_some() {
|
||||||
|
window.close().ok();
|
||||||
|
return result.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.invoke_handler(tauri::generate_handler![greet])
|
.invoke_handler(tauri::generate_handler![open_login_window])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import React from 'react'
|
||||||
import { WebviewWindow } from '@tauri-apps/api/window'
|
import { WebviewWindow } from '@tauri-apps/api/window'
|
||||||
import { Loading } from 'components/Loading'
|
import { Loading } from 'components/Loading'
|
||||||
import { JSONRPCClient, S3SIService, StdioTransport } from 'jsonrpc';
|
import { JSONRPCClient, S3SIService, StdioTransport } from 'jsonrpc';
|
||||||
|
import { invoke } from '@tauri-apps/api';
|
||||||
|
import { emit } from '@tauri-apps/api/event';
|
||||||
|
|
||||||
const client = new JSONRPCClient<S3SIService>({
|
const client = new JSONRPCClient<S3SIService>({
|
||||||
transport: new StdioTransport()
|
transport: new StdioTransport()
|
||||||
|
|
@ -14,12 +16,11 @@ export const Home: React.FC = ({ }) => {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
throw new Error(result.error.message);
|
throw new Error(result.error.message);
|
||||||
}
|
}
|
||||||
const webview = new WebviewWindow('login', {
|
|
||||||
url: 'https://accounts.nintendo.com/',
|
|
||||||
resizable: true,
|
|
||||||
focus: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
const sessionToken = await invoke('open_login_window', {
|
||||||
|
url: result.result.url
|
||||||
|
})
|
||||||
|
console.log(sessionToken)
|
||||||
}
|
}
|
||||||
return <>
|
return <>
|
||||||
Hello world! <Loading />
|
Hello world! <Loading />
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,11 @@ export type Transport = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RPCResult<Result, Error extends ResponseError = ResponseError> = {
|
export type RPCResult<Result, Error extends ResponseError = ResponseError> = {
|
||||||
result?: Result;
|
result: Result;
|
||||||
error?: Error;
|
error?: undefined;
|
||||||
|
} | {
|
||||||
|
result?: undefined;
|
||||||
|
error: Error;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Service = {
|
export type Service = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue