From 569ba4243c07b4eca58eedd627084143d8fe874b Mon Sep 17 00:00:00 2001 From: DecDuck Date: Wed, 2 Apr 2025 11:00:39 +1100 Subject: [PATCH] feat: add offline widget & remove openssl in favour of droplet-rs --- components/Header.vue | 10 +- components/OfflineHeaderWidget.vue | 17 ++ src-tauri/Cargo.lock | 303 ++++++++++++++++++++++++++--- src-tauri/Cargo.toml | 7 +- src-tauri/src/lib.rs | 17 +- src-tauri/src/remote/auth.rs | 34 ++-- 6 files changed, 329 insertions(+), 59 deletions(-) create mode 100644 components/OfflineHeaderWidget.vue diff --git a/components/Header.vue b/components/Header.vue index c8a82d3..aaa2ffd 100644 --- a/components/Header.vue +++ b/components/Header.vue @@ -28,9 +28,7 @@ />
    - +
  1. +
@@ -49,11 +48,12 @@ + + diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8c64452..cfcd79b 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -89,6 +89,73 @@ dependencies = [ "zbus", ] +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive 0.5.1", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" +dependencies = [ + "asn1-rs-derive 0.6.0", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 2.0.9", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", + "synstructure", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + [[package]] name = "async-broadcast" version = "0.7.2" @@ -651,9 +718,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.5" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "shlex", ] @@ -988,10 +1055,44 @@ dependencies = [ ] [[package]] -name = "deranged" -version = "0.3.11" +name = "data-encoding" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" + +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs 0.6.2", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs 0.7.1", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", "serde", @@ -1187,14 +1288,15 @@ dependencies = [ "boxcar", "cacache 13.1.0", "chrono", + "deranged", "directories", + "droplet-rs", "hex 0.4.3", "http 1.2.0", "http-serde 2.1.1", "log", "log4rs", "md5", - "openssl", "parking_lot 0.12.3", "rayon", "reqwest 0.12.9", @@ -1225,6 +1327,21 @@ dependencies = [ "webbrowser", ] +[[package]] +name = "droplet-rs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926e179267dfe9fd891d4141d65d71fba06b6b82cd6834916a6310794df7d739" +dependencies = [ + "hex 0.4.3", + "rcgen", + "ring", + "time", + "time-macros", + "webpki", + "x509-parser 0.17.0", +] + [[package]] name = "dtoa" version = "1.0.9" @@ -2834,6 +2951,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.2" @@ -2946,12 +3069,41 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -3219,6 +3371,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "oid-registry" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +dependencies = [ + "asn1-rs 0.6.2", +] + +[[package]] +name = "oid-registry" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" +dependencies = [ + "asn1-rs 0.7.1", +] + [[package]] name = "once_cell" version = "1.20.2" @@ -3280,15 +3450,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.4.1+3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.104" @@ -3297,7 +3458,6 @@ checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -3443,6 +3603,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pem" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +dependencies = [ + "base64 0.22.1", + "serde", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -3867,6 +4037,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "x509-parser 0.16.0", + "yasna", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -4096,15 +4280,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -4146,6 +4329,15 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustix" version = "0.38.42" @@ -4699,12 +4891,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "ssri" version = "7.0.0" @@ -5421,9 +5607,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa 1.0.14", @@ -5436,15 +5622,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -6142,6 +6328,16 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "webview2-com" version = "0.33.0" @@ -6791,6 +6987,42 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs 0.6.2", + "data-encoding", + "der-parser 9.0.0", + "lazy_static", + "nom", + "oid-registry 0.7.1", + "ring", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "x509-parser" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4569f339c0c402346d4a75a9e39cf8dad310e287eef1ff56d4c68e5067f53460" +dependencies = [ + "asn1-rs 0.7.1", + "data-encoding", + "der-parser 10.0.0", + "lazy_static", + "nom", + "oid-registry 0.8.1", + "ring", + "rusticata-macros", + "thiserror 2.0.9", + "time", +] + [[package]] name = "xdg-home" version = "1.3.0" @@ -6807,6 +7039,15 @@ version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + [[package]] name = "yoke" version = "0.7.5" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 41611c1..59d1bfa 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -55,12 +55,13 @@ bincode = "1.3.3" http-serde = "2.1.1" reqwest-middleware = "0.4.0" reqwest-middleware-cache = "0.1.1" +deranged = "=0.4.0" +droplet-rs = "0.7.3" [dependencies.tauri] version = "2.1.1" features = ["tray-icon"] - [dependencies.tokio] version = "1.40.0" features = ["rt", "tokio-macros", "signal"] @@ -81,10 +82,6 @@ features = [ "macro-diagnostics", # Enable better diagnostics for compile-time UUIDs ] -[dependencies.openssl] -version = "0.10.66" -features = ["vendored"] - [dependencies.rustbreak] version = "2" features = [] # You can also use "yaml_enc" or "bin_enc" diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5919ef6..f034305 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -25,7 +25,10 @@ use download_manager::commands::{ }; use download_manager::download_manager::DownloadManager; use download_manager::download_manager_builder::DownloadManagerBuilder; -use games::collections::commands::{add_game_to_collection, create_collection, delete_collection, delete_game_in_collection, fetch_collection, fetch_collections}; +use games::collections::commands::{ + add_game_to_collection, create_collection, delete_collection, delete_game_in_collection, + fetch_collection, fetch_collections, +}; use games::commands::{ fetch_game, fetch_game_status, fetch_game_verion_options, fetch_library, uninstall_game, }; @@ -43,7 +46,8 @@ use process::commands::{kill_game, launch_game}; use process::process_manager::ProcessManager; use remote::auth::{self, recieve_handshake}; use remote::commands::{ - auth_initiate, fetch_drop_object, gen_drop_url, manual_recieve_handshake, retry_connect, sign_out, use_remote + auth_initiate, fetch_drop_object, gen_drop_url, manual_recieve_handshake, retry_connect, + sign_out, use_remote, }; use remote::fetch_object::{fetch_object, fetch_object_offline}; use remote::requests::make_request; @@ -84,6 +88,7 @@ pub struct User { profile_picture: String, } + #[derive(Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct AppState<'a> { @@ -370,7 +375,13 @@ pub fn run() { }) .register_asynchronous_uri_scheme_protocol("object", move |ctx, request, responder| { let state: tauri::State<'_, Mutex> = ctx.app_handle().state(); - offline!(state, fetch_object, fetch_object_offline, request, responder); + offline!( + state, + fetch_object, + fetch_object_offline, + request, + responder + ); }) .on_window_event(|window, event| { if let WindowEvent::CloseRequested { api, .. } = event { diff --git a/src-tauri/src/remote/auth.rs b/src-tauri/src/remote/auth.rs index e87ab2b..28d8ac5 100644 --- a/src-tauri/src/remote/auth.rs +++ b/src-tauri/src/remote/auth.rs @@ -1,9 +1,10 @@ use std::{env, sync::Mutex}; use chrono::Utc; +use droplet_rs::ssl::sign_nonce; use log::{debug, error, warn}; -use openssl::{ec::EcKey, hash::MessageDigest, pkey::PKey, sign::Signer}; use serde::{Deserialize, Serialize}; +use serde_json::json; use tauri::{AppHandle, Emitter, Manager}; use url::Url; @@ -39,20 +40,6 @@ struct HandshakeResponse { id: String, } -// TODO: Change return value on Err -pub fn sign_nonce(private_key: String, nonce: String) -> Result { - let client_private_key = EcKey::private_key_from_pem(private_key.as_bytes()).unwrap(); - let pkey_private_key = PKey::from_ec_key(client_private_key).unwrap(); - - let mut signer = Signer::new(MessageDigest::sha256(), &pkey_private_key).unwrap(); - signer.update(nonce.as_bytes()).unwrap(); - let signature = signer.sign_to_vec().unwrap(); - - let hex_signature = hex::encode(signature); - - Ok(hex_signature) -} - pub fn generate_authorization_header() -> String { let certs = { let db = borrow_db_checked(); @@ -133,6 +120,23 @@ fn recieve_handshake_logic(app: &AppHandle, path: String) -> Result<(), RemoteAc let mut app_state_handle = app_state.lock().unwrap(); app_state_handle.status = AppStatus::SignedIn; app_state_handle.user = Some(fetch_user()?); + + // Setup capabilities + let endpoint = base_url.join("/api/v1/client/capability")?; + let header = generate_authorization_header(); + let body = json!({ + "capability": "cloudSaves", + "configuration": {} + }); + let response = client + .post(endpoint) + .header("Authorization", header) + .json(&body) + .send()?; + + if response.status().is_success() { + debug!("registered client for 'cloudSaves' capability") + } } Ok(())