use data::{AppState, State}; use error::Result; use reqwest_cookie_store::CookieStoreMutex; use std::sync::Arc; use tauri::{async_runtime::Mutex, Manager}; mod data; mod error; #[macro_use] extern crate tauri; const DEFAULT_ECHO360: &str = "https://echo360.org.uk"; /// Check if the user is authenticated with echo360 #[command(rename_all = "snake_case")] async fn is_authenticated(state: State<'_>) -> Result { // get client let state = state.lock().await; // fetch courses page let html = state .client .get(format!("{}/courses", DEFAULT_ECHO360)) .send() .await? .text() .await?; // the courses page redirects to a sign in page if the user is not authenticated // if we can find the user's first name somewhere in the html, then the user must be authenticated let authenticated = regex::Regex::new(r#"\\"firstName\\":\\"(\w+)\\""#)? .captures(&html) .is_some(); Ok(authenticated) } #[cfg_attr(mobile, mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .invoke_handler(tauri::generate_handler![is_authenticated]) .setup(|app| { // todo: load profile file, or create if it does not exist // create reqwest client with cookie jar // todo: load cookies into cookie jar //? https://docs.rs/tauri/1.8.1/tauri/api/path/fn.app_config_dir.html let jar = Arc::new(CookieStoreMutex::default()); let client = reqwest::Client::builder() .cookie_provider(jar.clone()) .build()?; // store app state app.manage(Mutex::new(AppState { client })); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }