From 774b13e46cf37f4dc269d25a26b9e891e38b117f Mon Sep 17 00:00:00 2001 From: Ninja3047 Date: Tue, 26 Jul 2022 22:03:50 -0400 Subject: [PATCH 1/8] add support for encrypting text files from web --- Cargo.lock | 53 +-- cli/Cargo.toml | 3 +- cli/src/main.rs | 5 +- {cli => common}/src/fragment.rs | 2 +- common/src/lib.rs | 1 + package.json | 3 +- web/src/lib.rs | 44 ++- web/src/main.scss | 10 +- web/src/render.tsx | 47 ++- webpack.config.js | 4 + yarn.lock | 587 ++++++++++++++++++-------------- 11 files changed, 438 insertions(+), 321 deletions(-) rename {cli => common}/src/fragment.rs (96%) diff --git a/Cargo.lock b/Cargo.lock index f5ba0da..962a3a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,17 +33,6 @@ version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" -[[package]] -name = "argon2" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25df3c03f1040d0069fcd3907e24e36d59f9b6fa07ba49be0eb25a794f036ba7" -dependencies = [ - "base64ct", - "blake2", - "password-hash 0.3.2", -] - [[package]] name = "argon2" version = "0.4.1" @@ -52,7 +41,7 @@ checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73" dependencies = [ "base64ct", "blake2", - "password-hash 0.4.2", + "password-hash", ] [[package]] @@ -998,7 +987,7 @@ dependencies = [ "anyhow", "atty", "clap", - "omegaupload-common 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "omegaupload-common", "reqwest", "rpassword", ] @@ -1007,7 +996,7 @@ dependencies = [ name = "omegaupload-common" version = "0.2.0" dependencies = [ - "argon2 0.4.1", + "argon2", "base64", "bytes", "chacha20poly1305", @@ -1025,27 +1014,6 @@ dependencies = [ "url", ] -[[package]] -name = "omegaupload-common" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0e6112dcb442b5d280f65cf14b9d6749f3585709d1ed2f1b8821f12c3b6c16" -dependencies = [ - "argon2 0.3.4", - "base64", - "bytes", - "chacha20poly1305", - "chrono", - "headers", - "lazy_static", - "rand", - "secrecy", - "serde", - "thiserror", - "typenum", - "url", -] - [[package]] name = "omegaupload-server" version = "0.1.0" @@ -1058,7 +1026,7 @@ dependencies = [ "futures", "headers", "lazy_static", - "omegaupload-common 0.2.0", + "omegaupload-common", "rand", "rocksdb", "serde", @@ -1084,7 +1052,7 @@ dependencies = [ "http", "js-sys", "mime_guess", - "omegaupload-common 0.2.0", + "omegaupload-common", "reqwasm", "serde", "tar", @@ -1113,17 +1081,6 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" -[[package]] -name = "password-hash" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - [[package]] name = "password-hash" version = "0.4.2" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d0b0a2c..869e0a1 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -9,8 +9,7 @@ license = "GPL-3.0-or-later" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -omegaupload-common = "0.2.0" - +omegaupload-common = { path = "../common" } anyhow = "1.0.58" atty = "0.2.14" clap = { version = "3.2.8", features = ["derive"] } diff --git a/cli/src/main.rs b/cli/src/main.rs index 1ac3907..8dc4342 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -25,6 +25,7 @@ use atty::Stream; use clap::Parser; use omegaupload_common::crypto::{open_in_place, seal_in_place}; use omegaupload_common::secrecy::{ExposeSecret, SecretString, SecretVec}; +use omegaupload_common::fragment::Builder; use omegaupload_common::{ base64, Expiration, ParsedUrl, Url, API_ENDPOINT, EXPIRATION_HEADER_NAME, }; @@ -33,10 +34,6 @@ use reqwest::header::EXPIRES; use reqwest::StatusCode; use rpassword::prompt_password; -use crate::fragment::Builder; - -mod fragment; - #[derive(Parser)] struct Opts { #[clap(subcommand)] diff --git a/cli/src/fragment.rs b/common/src/fragment.rs similarity index 96% rename from cli/src/fragment.rs rename to common/src/fragment.rs index 39ce094..e0134f3 100644 --- a/cli/src/fragment.rs +++ b/common/src/fragment.rs @@ -1,4 +1,4 @@ -use omegaupload_common::secrecy::{ExposeSecret, SecretString}; +use crate::secrecy::{ExposeSecret, SecretString}; pub struct Builder { decryption_key: SecretString, diff --git a/common/src/lib.rs b/common/src/lib.rs index 54af80b..c4383f7 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -41,6 +41,7 @@ use crate::crypto::Key; pub mod base64; pub mod crypto; +pub mod fragment; pub const API_ENDPOINT: &str = "/api"; diff --git a/package.json b/package.json index 04d5c5c..153a29d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "highlight.js": "^11.4.0", "highlightjs-line-numbers.js": "^2.8.0", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "source-map-loader": "^4.0.0" }, "scripts": { "build": "webpack --mode production", diff --git a/web/src/lib.rs b/web/src/lib.rs index f88bea2..569e828 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -26,8 +26,11 @@ use http::uri::PathAndQuery; use http::{StatusCode, Uri}; use js_sys::{Array, JsString, Object, Uint8Array}; use omegaupload_common::crypto::{Error as CryptoError, Key}; -use omegaupload_common::secrecy::{Secret, SecretVec}; -use omegaupload_common::{Expiration, PartialParsedUrl}; +use omegaupload_common::fragment::Builder; +use omegaupload_common::base64; +use omegaupload_common::crypto::seal_in_place; +use omegaupload_common::secrecy::{Secret, SecretVec, SecretString, ExposeSecret}; +use omegaupload_common::{Expiration, PartialParsedUrl, Url}; use reqwasm::http::Request; use wasm_bindgen::prelude::{wasm_bindgen, Closure}; use wasm_bindgen::{JsCast, JsValue}; @@ -50,6 +53,8 @@ extern "C" { pub fn load_from_db(mime_type: JsString, name: Option, language: Option); #[wasm_bindgen(js_name = renderMessage)] pub fn render_message(message: JsString); + #[wasm_bindgen(js_name = createUploadUi)] + pub fn create_upload_ui(); } fn window() -> Window { @@ -75,7 +80,7 @@ pub fn start() { std::panic::set_hook(Box::new(console_error_panic_hook::hook)); if location().pathname().unwrap() == "/" { - render_message("Go away".into()); + create_upload_ui(); return; } @@ -166,6 +171,39 @@ pub fn start() { }); } +#[wasm_bindgen] +#[allow(clippy::future_not_send)] +#[allow(clippy::missing_panics_doc)] +pub fn encrypt_string(data: String) { + spawn_local(async move { + if let Err(e) = do_encrypt(data.into_bytes()).await { + log!(e.to_string()); + } + }); +} + +#[allow(clippy::future_not_send)] +async fn do_encrypt(mut data: Vec) -> Result<()> { + let (data, key) = { + let enc_key = seal_in_place(&mut data, None)?; + let key = SecretString::new(base64::encode(&enc_key.expose_secret().as_ref())); + (data, key) + }; + + let s: String = location().to_string().into(); + let mut url = Url::from_str(&s)?; + let fragment = Builder::new(key); + + let js_data = Uint8Array::new_with_length(data.len() as u32); + js_data.copy_from(&data); + + let short_code = Request::post(url.as_ref()).body(js_data).send().await?.text().await?; + url.set_path(&short_code); + url.set_fragment(Some(fragment.build().expose_secret())); + location().set_href(url.as_ref()).expect("Unable to navigate to encrypted upload"); + Ok(()) +} + #[allow(clippy::future_not_send)] async fn fetch_resources( request_uri: Uri, diff --git a/web/src/main.scss b/web/src/main.scss index 695872e..bc5aeb5 100644 --- a/web/src/main.scss +++ b/web/src/main.scss @@ -95,6 +95,14 @@ img, audio, video { max-width: 75vw; } +textarea { + width: 100%; + height: 100%; + min-width: 75vw; + min-height: 75vh; + box-sizing: border-box; +} + .primary { @extend .hljs; } @@ -108,4 +116,4 @@ img, audio, video { @extend .align-right; padding-left: $padding; } -} \ No newline at end of file +} diff --git a/web/src/render.tsx b/web/src/render.tsx index 1d2fe24..f99ab6b 100644 --- a/web/src/render.tsx +++ b/web/src/render.tsx @@ -17,11 +17,56 @@ import './main.scss'; import ReactDom from 'react-dom'; import React from 'react'; +import { encrypt_string } from '../pkg'; const hljs = require('highlight.js'); (window as any).hljs = hljs; require('highlightjs-line-numbers.js'); +class PasteForm extends React.Component { + constructor(props) { + super(props) + this.state = { + value: "Sample text" + }; + this.handleChange = this.handleChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + + handleChange(event) { + this.setState({value: event.target.value}); + } + + handleSubmit(event) { + try { + encrypt_string(this.state.value); + } catch (e) { + console.error(e); + } + + event.preventDefault(); + } + + render() { + return ( +
+        
+