From e11c4e1448c73f4adfa42eb2965e85227f2c6938 Mon Sep 17 00:00:00 2001 From: DecDuck Date: Wed, 9 Oct 2024 00:37:27 +1100 Subject: [PATCH 1/4] compliant with new APIs --- .env | 1 - app.vue | 3 + components/Header.vue | 6 +- components/InitiateAuthModule.vue | 93 ++++++++++++++++++++++++++ components/WindowControl.vue | 27 +------- nvidia-prop-dev.sh | 1 + pages/auth/index.vue | 104 +++--------------------------- pages/auth/signedout.vue | 18 ++++++ src-tauri/Cargo.lock | 20 +++++- src-tauri/Cargo.toml | 13 +++- src-tauri/src/auth.rs | 76 +++++++++++++++++++--- src-tauri/src/data.rs | 7 +- src-tauri/src/lib.rs | 4 +- 13 files changed, 234 insertions(+), 139 deletions(-) delete mode 100644 .env create mode 100644 components/InitiateAuthModule.vue create mode 100755 nvidia-prop-dev.sh create mode 100644 pages/auth/signedout.vue diff --git a/.env b/.env deleted file mode 100644 index d21acab..0000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ -WEBKIT_DISABLE_DMABUF_RENDERER=1 \ No newline at end of file diff --git a/app.vue b/app.vue index 4b92728..c5500da 100644 --- a/app.vue +++ b/app.vue @@ -23,6 +23,9 @@ switch (state.status) { case AppStatus.SignedOut: router.push("/auth"); break; + case AppStatus.SignedInNeedsReauth: + router.push("/auth/signedout"); + break; } listen("auth/processing", () => { diff --git a/components/Header.vue b/components/Header.vue index 2b16acf..dfe8d0b 100644 --- a/components/Header.vue +++ b/components/Header.vue @@ -1,9 +1,9 @@ diff --git a/components/InitiateAuthModule.vue b/components/InitiateAuthModule.vue new file mode 100644 index 0000000..00627e4 --- /dev/null +++ b/components/InitiateAuthModule.vue @@ -0,0 +1,93 @@ + + + diff --git a/components/WindowControl.vue b/components/WindowControl.vue index 3610162..f777504 100644 --- a/components/WindowControl.vue +++ b/components/WindowControl.vue @@ -1,28 +1,7 @@ diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 2083da5..474c913 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -931,7 +931,9 @@ version = "0.1.0" dependencies = [ "ciborium", "directories", + "hex", "log", + "openssl", "os_info", "rayon", "reqwest", @@ -945,6 +947,7 @@ dependencies = [ "tauri-plugin-shell", "tauri-plugin-single-instance", "url", + "uuid", "webbrowser", "zstd", ] @@ -3203,9 +3206,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.13" +version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" dependencies = [ "once_cell", "rustls-pki-types", @@ -4613,7 +4616,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom 0.2.15", + "rand 0.8.5", "serde", + "uuid-macro-internal", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee1cd046f83ea2c4e920d6ee9f7c3537ef928d75dce5d84a87c2c5d6b3999a3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a26e11a..1e2d353 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -35,6 +35,18 @@ os_info = "3.8.2" tauri-plugin-deep-link = "2" log = "0.4.22" structured-logger = "1.0.3" +hex = "0.4.3" + +[dependencies.uuid] +version = "1.10.0" +features = [ + "v4", # Lets you generate random UUIDs + "fast-rng", # Use a faster (but still sufficiently random) RNG + "macro-diagnostics", # Enable better diagnostics for compile-time UUIDs +] + +[dependencies.openssl] +version = "0.10.66" [dependencies.rustbreak] version = "2" @@ -43,4 +55,3 @@ features = ["bin_enc"] # You can also use "yaml_enc" or "bin_enc" [dependencies.reqwest] version = "0.12" features = ["json", "blocking"] - diff --git a/src-tauri/src/auth.rs b/src-tauri/src/auth.rs index 1c7403b..d0ff6f8 100644 --- a/src-tauri/src/auth.rs +++ b/src-tauri/src/auth.rs @@ -1,14 +1,22 @@ use std::{ borrow::{Borrow, BorrowMut}, + fmt::format, sync::Mutex, }; use log::info; +use openssl::{ + ec::EcKey, + hash::MessageDigest, + pkey::PKey, + sign::{self, Signer}, +}; use serde::{Deserialize, Serialize}; use tauri::{App, AppHandle, Emitter, Error, EventLoopMessage, Manager, Wry}; use url::Url; +use uuid::Uuid; -use crate::{data::DatabaseCerts, AppState, AppStatus, User, DB}; +use crate::{data::DatabaseAuth, AppState, AppStatus, User, DB}; #[derive(Serialize)] struct InitiateRequestBody { @@ -41,6 +49,52 @@ macro_rules! unwrap_or_return { }; } +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); + + return Ok(hex_signature); +} + +pub fn generate_authorization_header() -> String { + let certs = { + let db = DB.borrow_data().unwrap(); + db.auth.clone().unwrap() + }; + + let nonce = Uuid::new_v4().to_string(); + let signature = sign_nonce(certs.private, nonce.clone()).unwrap(); + + return format!("Nonce {} {} {}", certs.clientId, nonce, signature); +} + +pub fn fetch_user() -> Result { + let base_url = { + let handle = DB.borrow_data().unwrap(); + Url::parse(&handle.base_url).unwrap() + }; + + let endpoint = base_url.join("/api/v1/client/user").unwrap(); + let header = generate_authorization_header(); + + let client = reqwest::blocking::Client::new(); + let response = client + .get(endpoint.to_string()) + .header("Authorization", header) + .send() + .unwrap(); + + let user = response.json::().unwrap(); + + return Ok(user); +} + pub fn recieve_handshake(app: AppHandle, path: String) { // Tell the app we're processing app.emit("auth/processing", ()).unwrap(); @@ -63,7 +117,7 @@ pub fn recieve_handshake(app: AppHandle, path: String) { token: token.to_string(), }; - let endpoint = unwrap_or_return!(base_url.join("/api/v1/client/handshake"), app); + let endpoint = unwrap_or_return!(base_url.join("/api/v1/client/auth/handshake"), app); let client = reqwest::blocking::Client::new(); let response = unwrap_or_return!(client.post(endpoint).json(&body).send(), app); info!("server responded with {}", response.status()); @@ -71,9 +125,10 @@ pub fn recieve_handshake(app: AppHandle, path: String) { { let mut handle = DB.borrow_data_mut().unwrap(); - handle.certs = Some(DatabaseCerts { + handle.auth = Some(DatabaseAuth { private: response_struct.private, cert: response_struct.certificate, + clientId: response_struct.id, }); drop(handle); DB.save().unwrap(); @@ -86,6 +141,8 @@ pub fn recieve_handshake(app: AppHandle, path: String) { } app.emit("auth/finished", ()).unwrap(); + + fetch_user().unwrap(); } #[tauri::command] @@ -97,7 +154,7 @@ pub async fn auth_initiate<'a>() -> Result<(), String> { let current_os_info = os_info::get(); - let endpoint = base_url.join("/api/v1/client/initiate").unwrap(); + let endpoint = base_url.join("/api/v1/client/auth/initiate").unwrap(); let body = InitiateRequestBody { name: format!("Drop Desktop Client"), platform: current_os_info.os_type().to_string(), @@ -124,10 +181,13 @@ pub fn setup() -> Result<(AppStatus, Option), Error> { let data = DB.borrow_data().unwrap(); // If we have certs, exit for now - if data.certs.is_some() { - // TODO: check if it's still valid, and fetch user information - info!("have existing certs, assuming logged in..."); - return Ok((AppStatus::SignedInNeedsReauth, None)); + if data.auth.is_some() { + let user_result = fetch_user(); + if user_result.is_err() { + return Ok((AppStatus::SignedInNeedsReauth, None)); + + } + return Ok((AppStatus::SignedIn, Some(user_result.unwrap()))) } drop(data); diff --git a/src-tauri/src/data.rs b/src-tauri/src/data.rs index 4e52be4..2dd9ebd 100644 --- a/src-tauri/src/data.rs +++ b/src-tauri/src/data.rs @@ -7,14 +7,15 @@ use serde::Deserialize; use crate::DB; #[derive(serde::Serialize, Clone, Deserialize)] -pub struct DatabaseCerts { +pub struct DatabaseAuth { pub private: String, pub cert: String, + pub clientId: String, } #[derive(serde::Serialize, Clone, Deserialize)] pub struct Database { - pub certs: Option, + pub auth: Option, pub base_url: String, } @@ -24,7 +25,7 @@ pub type DatabaseInterface = pub fn setup() -> DatabaseInterface { let db_path = BaseDirs::new().unwrap().data_dir().join("drop"); let default = Database { - certs: None, + auth: None, base_url: "".to_string(), }; let db = match fs::exists(db_path.clone()).unwrap() { diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 4f7d644..fadfc0c 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -13,7 +13,7 @@ use auth::{auth_initiate, recieve_handshake}; use data::DatabaseInterface; use log::info; use remote::use_remote; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use structured_logger::{json::new_writer, Builder}; use tauri_plugin_deep_link::DeepLinkExt; @@ -24,7 +24,7 @@ pub enum AppStatus { SignedIn, SignedInNeedsReauth, } -#[derive(Clone, Copy, Serialize)] +#[derive(Clone, Copy, Serialize, Deserialize)] pub struct User {} #[derive(Clone, Copy, Serialize)] From c846f1c94f4bfad4d1dc3c33940ac0ad04e7a044 Mon Sep 17 00:00:00 2001 From: DecDuck Date: Wed, 9 Oct 2024 03:39:05 +1100 Subject: [PATCH 2/4] ci/cd and patches for windows builds --- .gitlab-ci-local/.gitignore | 2 ++ .gitlab-ci.yml | 28 ++++++++++++++++++++++++++ src-tauri/Cargo.lock | 40 ------------------------------------- src-tauri/Cargo.toml | 1 - src-tauri/src/unpacker.rs | 5 +++-- src-tauri/tauri.conf.json | 15 ++++++++++++-- 6 files changed, 46 insertions(+), 45 deletions(-) create mode 100644 .gitlab-ci-local/.gitignore create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci-local/.gitignore b/.gitlab-ci-local/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/.gitlab-ci-local/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..e53ed5f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,28 @@ +stages: + - build + +build-linux: + stage: build + image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/rust:1.81.0-bookworm + script: + - apt-get update -y + - apt-get install yarnpkg libsoup-3.0-0 libsoup-3.0-dev libatk-adaptor libgtk-3-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev -y + - yarnpkg + - yarnpkg tauri build + - cp src-tauri/target/release/bundle/deb/*.deb . + - cp src-tauri/target/release/bundle/rpm/*.rpm . + artifacts: + paths: + - "*.{deb,rpm}" + +build-windows: + stage: build + tags: + - windows + script: + - yarn + - yarn tauri build + - cp src-tauri/target/release/bundle/nsis/*.exe . + artifacts: + paths: + - "*.exe" diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 474c913..1192b43 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -455,8 +455,6 @@ version = "1.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8d9e0b4957f635b8d3da819d0db5603620467ecf1f692d22a8c2717ce27e6d8" dependencies = [ - "jobserver", - "libc", "shlex", ] @@ -949,7 +947,6 @@ dependencies = [ "url", "uuid", "webbrowser", - "zstd", ] [[package]] @@ -1962,15 +1959,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" version = "0.3.70" @@ -5478,34 +5466,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -[[package]] -name = "zstd" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "zvariant" version = "4.0.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 1e2d353..c7591c3 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -26,7 +26,6 @@ tauri-plugin-shell = "2.0.0" serde = { version = "1", features = ["derive"] } serde_json = "1" ciborium = "0.2.2" -zstd = "0.13.2" rayon = "1.10.0" directories = "5.0.1" webbrowser = "1.0.2" diff --git a/src-tauri/src/unpacker.rs b/src-tauri/src/unpacker.rs index a85bb89..58676e1 100644 --- a/src-tauri/src/unpacker.rs +++ b/src-tauri/src/unpacker.rs @@ -5,10 +5,11 @@ use std::{ collections::HashMap, fs::{create_dir_all, File}, io::{self, BufReader, Error, Seek, Write}, - os::unix::fs::PermissionsExt, path::Path, }; -use tauri::Runtime; + +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; #[derive(Deserialize)] struct ManifestChunk { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f6cd689..c7c4954 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -2,7 +2,7 @@ "$schema": "https://schema.tauri.app/config/2.0.0", "productName": "drop", "version": "0.1.0", - "identifier": "dev.drop.drop", + "identifier": "dev.drop.app", "build": { "beforeDevCommand": "yarn dev --port 1432", "devUrl": "http://localhost:1432", @@ -12,7 +12,7 @@ "app": { "windows": [ { - "title": "drop-app", + "title": "Drop", "width": 1536, "height": 864, "minWidth": 820, @@ -33,6 +33,17 @@ }, "bundle": { "active": true, + "targets": ["nsis", "deb", "rpm", "dmg"], + "windows": { + "nsis": { + "installMode": "both" + }, + "webviewInstallMode": { + "silent": true, + "type": "embedBootstrapper" + }, + "wix": null + }, "icon": [ "icons/32x32.png", "icons/128x128.png", From f8d3a5ad973bb9d4deef1d720f56c679b83562f2 Mon Sep 17 00:00:00 2001 From: Alessio D'Ambrosio <69647028+alessiodam@users.noreply.github.com> Date: Tue, 8 Oct 2024 20:27:38 +0200 Subject: [PATCH 3/4] Update .gitlab-ci.yml --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e53ed5f..32f747a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,7 @@ build-linux: script: - apt-get update -y - apt-get install yarnpkg libsoup-3.0-0 libsoup-3.0-dev libatk-adaptor libgtk-3-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev -y + - export RUSTFLAGS='-C target-feature=+crt-static' - yarnpkg - yarnpkg tauri build - cp src-tauri/target/release/bundle/deb/*.deb . @@ -20,6 +21,7 @@ build-windows: tags: - windows script: + - set RUSTFLAGS=-C target-feature=+crt-static - yarn - yarn tauri build - cp src-tauri/target/release/bundle/nsis/*.exe . From dc7a82247aca9f8297dd6d5ae633d7eb44637ced Mon Sep 17 00:00:00 2001 From: Alessio D'Ambrosio <69647028+alessiodam@users.noreply.github.com> Date: Tue, 8 Oct 2024 20:28:45 +0200 Subject: [PATCH 4/4] Update Cargo.toml --- src-tauri/Cargo.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index c7591c3..bbec9f4 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -54,3 +54,8 @@ features = ["bin_enc"] # You can also use "yaml_enc" or "bin_enc" [dependencies.reqwest] version = "0.12" features = ["json", "blocking"] + +[profile.release] +lto = true +codegen-units = 1 +panic = 'abort'