Compare commits

..

No commits in common. "f5e9b3abd2e258c4f4d4ec389248ab388e9ffdef" and "fe0c0c87370ff86e82b97dfca70a10a7247f69c1" have entirely different histories.

8 changed files with 311 additions and 149 deletions

261
Cargo.lock generated
View file

@ -2,6 +2,18 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler32"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]] [[package]]
name = "aead" name = "aead"
version = "0.4.3" version = "0.4.3"
@ -173,6 +185,18 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e"
[[package]]
name = "bytemuck"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.1.0" version = "1.1.0"
@ -297,14 +321,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "console_error_panic_hook" name = "color_quant"
version = "0.1.7" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
dependencies = [
"cfg-if",
"wasm-bindgen",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
@ -315,6 +335,69 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
dependencies = [
"cfg-if",
"crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]]
name = "deflate"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
dependencies = [
"adler32",
"byteorder",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.9.0" version = "0.9.0"
@ -324,6 +407,12 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.28" version = "0.8.28"
@ -478,6 +567,16 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "gif"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b"
dependencies = [
"color_quant",
"weezl",
]
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.3.0" version = "0.3.0"
@ -649,10 +748,23 @@ dependencies = [
] ]
[[package]] [[package]]
name = "imagesize" name = "image"
version = "0.9.0" version = "0.23.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b3b62f4e783e38afa07b51eaaa789be2fba03dbe29a05a1a906eb64feb987d" checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"gif",
"jpeg-decoder",
"num-iter",
"num-rational",
"num-traits",
"png",
"scoped_threadpool",
"tiff",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
@ -685,6 +797,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "jpeg-decoder"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
dependencies = [
"rayon",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.55" version = "0.3.55"
@ -764,6 +885,15 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.3.16" version = "0.3.16"
@ -776,6 +906,25 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677"
[[package]]
name = "miniz_oxide"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
dependencies = [
"adler32",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.7.13" version = "0.7.13"
@ -840,6 +989,28 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "num-iter"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.14" version = "0.2.14"
@ -899,6 +1070,7 @@ dependencies = [
"bincode", "bincode",
"bytes", "bytes",
"chrono", "chrono",
"futures",
"headers", "headers",
"omegaupload-common", "omegaupload-common",
"rand", "rand",
@ -916,11 +1088,10 @@ dependencies = [
"anyhow", "anyhow",
"byte-unit", "byte-unit",
"bytes", "bytes",
"console_error_panic_hook",
"getrandom", "getrandom",
"gloo-console", "gloo-console",
"http", "http",
"imagesize", "image",
"js-sys", "js-sys",
"omegaupload-common", "omegaupload-common",
"reqwasm", "reqwasm",
@ -1002,6 +1173,18 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "png"
version = "0.16.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
dependencies = [
"bitflags",
"crc32fast",
"deflate",
"miniz_oxide 0.3.7",
]
[[package]] [[package]]
name = "poly1305" name = "poly1305"
version = "0.7.2" version = "0.7.2"
@ -1119,6 +1302,31 @@ dependencies = [
"rand_core", "rand_core",
] ]
[[package]]
name = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.5.4" version = "1.5.4"
@ -1248,6 +1456,18 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "sct" name = "sct"
version = "0.6.1" version = "0.6.1"
@ -1462,6 +1682,17 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "tiff"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
dependencies = [
"jpeg-decoder",
"miniz_oxide 0.4.4",
"weezl",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.1.43" version = "0.1.43"
@ -1886,6 +2117,12 @@ dependencies = [
"webpki", "webpki",
] ]
[[package]]
name = "weezl"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View file

@ -14,6 +14,7 @@ bincode = "1"
# to enable the feature # to enable the feature
bytes = { version = "*", features = ["serde"] } bytes = { version = "*", features = ["serde"] }
chrono = { version = "0.4", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] }
futures = "0.3"
# We just need to pull in whatever axum is pulling in # We just need to pull in whatever axum is pulling in
headers = "*" headers = "*"
rand = "0.8" rand = "0.8"

View file

@ -13,11 +13,10 @@ getrandom = { version = "*", features = ["js"] }
anyhow = "1" anyhow = "1"
bytes = "1" bytes = "1"
byte-unit = "4" byte-unit = "4"
console_error_panic_hook = "0.1"
gloo-console = "0.1" gloo-console = "0.1"
http = "0.2" http = "0.2"
image = "0.23"
js-sys = "0.3" js-sys = "0.3"
imagesize = "0.9"
reqwasm = "0.2" reqwasm = "0.2"
tree_magic_mini = { version = "3", features = ["with-gpl-data"] } tree_magic_mini = { version = "3", features = ["with-gpl-data"] }
wasm-bindgen = "0.2" wasm-bindgen = "0.2"
@ -39,6 +38,5 @@ features = [
"Event", "Event",
"EventTarget", "EventTarget",
"Window", "Window",
"Performance",
"Location", "Location",
] ]

View file

@ -5,7 +5,6 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Omegaupload</title> <title>Omegaupload</title>
<link data-trunk rel="rust" data-wasm-opt="0" data-keep-debug="true" data-no-mangle="true" />
<link data-trunk rel="copy-file" href="vendor/MPLUS_FONTS/fonts/ttf/MplusCodeLatin[wdth,wght].ttf" dest="/" /> <link data-trunk rel="copy-file" href="vendor/MPLUS_FONTS/fonts/ttf/MplusCodeLatin[wdth,wght].ttf" dest="/" />
<link data-trunk rel="copy-file" href="vendor/highlight.min.js" dest="/" /> <link data-trunk rel="copy-file" href="vendor/highlight.min.js" dest="/" />
<link data-trunk rel="copy-file" href="vendor/highlightjs-line-numbers.js/dist/highlightjs-line-numbers.min.js" <link data-trunk rel="copy-file" href="vendor/highlightjs-line-numbers.js/dist/highlightjs-line-numbers.min.js"

View file

@ -2,6 +2,7 @@ use std::fmt::{Display, Formatter};
use std::sync::Arc; use std::sync::Arc;
use gloo_console::log; use gloo_console::log;
use image::GenericImageView;
use js_sys::{Array, Uint8Array}; use js_sys::{Array, Uint8Array};
use omegaupload_common::crypto::{open_in_place, Key, Nonce}; use omegaupload_common::crypto::{open_in_place, Key, Nonce};
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
@ -11,19 +12,11 @@ use web_sys::Blob;
pub enum DecryptedData { pub enum DecryptedData {
String(Arc<String>), String(Arc<String>),
Blob(Arc<Blob>), Blob(Arc<Blob>),
Image(Arc<Blob>, (usize, usize), usize), Image(Arc<Blob>, (u32, u32), usize),
Audio(Arc<Blob>), Audio(Arc<Blob>),
Video(Arc<Blob>), Video(Arc<Blob>),
} }
fn now() -> f64 {
web_sys::window()
.expect("should have a Window")
.performance()
.expect("should have a Performance")
.now()
}
pub fn decrypt( pub fn decrypt(
mut container: Vec<u8>, mut container: Vec<u8>,
key: Key, key: Key,
@ -31,34 +24,21 @@ pub fn decrypt(
maybe_password: Option<Key>, maybe_password: Option<Key>,
) -> Result<DecryptedData, PasteCompleteConstructionError> { ) -> Result<DecryptedData, PasteCompleteConstructionError> {
let container = &mut container; let container = &mut container;
log!("Stage 1 decryption started."); log!("stage 1 decryption start");
let start = now();
if let Some(password) = maybe_password { if let Some(password) = maybe_password {
crate::render_message("Decrypting Stage 1...".into()); open_in_place(container, &nonce.increment(), &password)
open_in_place(container, &nonce.increment(), &password).map_err(|_| { .map_err(|_| PasteCompleteConstructionError::StageOneFailure)?;
crate::render_message("Unable to decrypt paste with the provided password.".into());
PasteCompleteConstructionError::StageOneFailure
})?;
} }
log!(format!("Stage 1 completed in {}ms", now() - start));
log!("Stage 2 decryption started."); log!("stage 2 decryption start");
let start = now(); open_in_place(container, &nonce, &key)
crate::render_message("Decrypting Stage 2...".into()); .map_err(|_| PasteCompleteConstructionError::StageTwoFailure)?;
open_in_place(container, &nonce, &key).map_err(|_| {
crate::render_message(
"Unable to decrypt paste with the provided encryption key and nonce.".into(),
);
PasteCompleteConstructionError::StageTwoFailure
})?;
log!(format!("Stage 2 completed in {}ms", now() - start));
log!("stage 2 decryption end");
if let Ok(decrypted) = std::str::from_utf8(container) { if let Ok(decrypted) = std::str::from_utf8(container) {
Ok(DecryptedData::String(Arc::new(decrypted.to_owned()))) Ok(DecryptedData::String(Arc::new(decrypted.to_owned())))
} else { } else {
log!("Blob conversion started."); log!("blob conversion start");
let start = now();
let blob_chunks = Array::new_with_length(container.chunks(65536).len().try_into().unwrap()); let blob_chunks = Array::new_with_length(container.chunks(65536).len().try_into().unwrap());
for (i, chunk) in container.chunks(65536).enumerate() { for (i, chunk) in container.chunks(65536).enumerate() {
let array = Uint8Array::new_with_length(chunk.len().try_into().unwrap()); let array = Uint8Array::new_with_length(chunk.len().try_into().unwrap());
@ -67,20 +47,12 @@ pub fn decrypt(
} }
let blob = let blob =
Arc::new(Blob::new_with_u8_array_sequence(blob_chunks.dyn_ref().unwrap()).unwrap()); Arc::new(Blob::new_with_u8_array_sequence(blob_chunks.dyn_ref().unwrap()).unwrap());
log!(format!("Blob conversion completed in {}ms", now() - start)); log!("blob conversion end");
log!("Image introspection started"); if let Ok(image) = image::load_from_memory(container) {
let start = now();
let dimensions = imagesize::blob_size(&container).ok();
log!(format!(
"Image introspection completed in {}ms",
now() - start
));
if let Some(dimensions) = dimensions {
Ok(DecryptedData::Image( Ok(DecryptedData::Image(
blob, blob,
(dimensions.width, dimensions.height), image.dimensions(),
container.len(), container.len(),
)) ))
} else { } else {

View file

@ -21,7 +21,7 @@ impl From<IdbObject<Ready>> for Object {
Ok(o) => o, Ok(o) => o,
// SAFETY: IdbObject maintains the invariant that it can eventually // SAFETY: IdbObject maintains the invariant that it can eventually
// be constructed into a JS object. // be constructed into a JS object.
_ => unsafe { unreachable_unchecked() }, _ => unsafe { panic!() },
} }
} }
} }

View file

@ -2,15 +2,14 @@
use std::str::FromStr; use std::str::FromStr;
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, Context, Result};
use byte_unit::{n_mib_bytes, Byte}; use byte_unit::Byte;
use decrypt::DecryptedData; use decrypt::DecryptedData;
use gloo_console::{error, log}; use gloo_console::log;
use http::uri::PathAndQuery; use http::uri::PathAndQuery;
use http::{StatusCode, Uri}; use http::{StatusCode, Uri};
use js_sys::{JsString, Object, Uint8Array}; use js_sys::{JsString, Object, Uint8Array};
use omegaupload_common::crypto::{Key, Nonce}; use omegaupload_common::{Expiration, PartialParsedUrl};
use omegaupload_common::{hash, Expiration, PartialParsedUrl};
use reqwasm::http::Request; use reqwasm::http::Request;
use wasm_bindgen::prelude::{wasm_bindgen, Closure}; use wasm_bindgen::prelude::{wasm_bindgen, Closure};
use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen::{JsCast, JsValue};
@ -25,14 +24,12 @@ mod decrypt;
mod idb_object; mod idb_object;
mod util; mod util;
const DOWNLOAD_SIZE_LIMIT: u128 = n_mib_bytes!(500);
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
#[wasm_bindgen(js_name = loadFromDb)] #[wasm_bindgen(js_name = loadFromDb)]
pub fn load_from_db(); fn load_from_db();
#[wasm_bindgen(js_name = renderMessage)] #[wasm_bindgen(js_name = createNotFoundUi)]
pub fn render_message(message: JsString); fn create_not_found_ui();
} }
fn window() -> Window { fn window() -> Window {
@ -53,10 +50,6 @@ fn open_idb() -> Result<IdbOpenDbRequest> {
} }
fn main() { fn main() {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
render_message("Loading paste...".into());
let url = String::from(location().to_string()); let url = String::from(location().to_string());
let request_uri = { let request_uri = {
let mut uri_parts = url.parse::<Uri>().unwrap().into_parts(); let mut uri_parts = url.parse::<Uri>().unwrap().into_parts();
@ -69,48 +62,10 @@ fn main() {
log!(&url); log!(&url);
log!(&request_uri.to_string()); log!(&request_uri.to_string());
log!(&location().pathname().unwrap()); log!(&location().pathname().unwrap());
let (key, nonce, needs_pw) = {
let partial_parsed_url = url
.split_once('#')
.map(|(_, fragment)| PartialParsedUrl::from(fragment))
.unwrap_or_default();
let key = match partial_parsed_url.decryption_key {
Some(key) => key,
None => {
error!("Key is missing in url; bailing.");
render_message("Invalid paste link: Missing decryption key.".into());
return;
}
};
let nonce = match partial_parsed_url.nonce {
Some(nonce) => nonce,
None => {
error!("Nonce is missing in url; bailing.");
render_message("Invalid paste link: Missing nonce.".into());
return;
}
};
(key, nonce, partial_parsed_url.needs_password)
};
let password = if needs_pw {
loop {
let pw = window().prompt_with_message("A password is required to decrypt this paste:");
if let Ok(Some(password)) = pw {
if !password.is_empty() {
break Some(hash(password));
}
}
}
} else {
None
};
if location().pathname().unwrap() == "/" { if location().pathname().unwrap() == "/" {
} else { } else {
spawn_local(async move { spawn_local(async {
if let Err(e) = fetch_resources(request_uri, key, nonce, password).await { if let Err(e) = fetch_resources(request_uri, url).await {
log!(e.to_string()); log!(e.to_string());
} }
}); });
@ -118,12 +73,7 @@ fn main() {
} }
#[allow(clippy::future_not_send)] #[allow(clippy::future_not_send)]
async fn fetch_resources( async fn fetch_resources(request_uri: Uri, url: String) -> Result<()> {
request_uri: Uri,
key: Key,
nonce: Nonce,
password: Option<Key>,
) -> Result<()> {
match Request::get(&request_uri.to_string()).send().await { match Request::get(&request_uri.to_string()).send().await {
Ok(resp) if resp.status() == StatusCode::OK => { Ok(resp) if resp.status() == StatusCode::OK => {
let expires = Expiration::try_from(resp.headers()).map_or_else( let expires = Expiration::try_from(resp.headers()).map_or_else(
@ -135,28 +85,28 @@ async fn fetch_resources(
let data_fut = resp let data_fut = resp
.as_raw() .as_raw()
.array_buffer() .array_buffer()
.expect("to get raw bytes from a response"); .expect("Failed to get raw bytes from response");
let data = match JsFuture::from(data_fut).await { let data = JsFuture::from(data_fut)
Ok(data) => data, .await
Err(e) => { .expect("Failed to result array buffer future");
render_message(
"Network failure: Failed to completely read encryption paste.".into(),
);
bail!(format!(
"JsFuture returned an error while fetching resp buffer: {:?}",
e
));
}
};
Uint8Array::new(&data).to_vec() Uint8Array::new(&data).to_vec()
}; };
if data.len() as u128 > DOWNLOAD_SIZE_LIMIT { let (key, nonce) = {
render_message("The paste is too large to decrypt from the web browser. You must use the CLI tool to download this paste.".into()); let partial_parsed_url = url
return Ok(()); .split_once('#')
} .map(|(_, fragment)| PartialParsedUrl::from(fragment))
.unwrap_or_default();
let key = partial_parsed_url
.decryption_key
.context("missing key should be handled in the future")?;
let nonce = partial_parsed_url
.nonce
.context("missing nonce be handled in the future")?;
(key, nonce)
};
let decrypted = decrypt(data, key, nonce, password)?; let decrypted = decrypt(data, key, nonce, None)?;
let db_open_req = open_idb()?; let db_open_req = open_idb()?;
// On success callback // On success callback
@ -238,17 +188,11 @@ async fn fetch_resources(
db_open_req.set_onupgradeneeded(Some(on_upgrade.into_js_value().unchecked_ref())); db_open_req.set_onupgradeneeded(Some(on_upgrade.into_js_value().unchecked_ref()));
} }
Ok(resp) if resp.status() == StatusCode::NOT_FOUND => { Ok(resp) if resp.status() == StatusCode::NOT_FOUND => {
render_message("Either the paste was burned or it never existed.".into()); create_not_found_ui();
}
Ok(resp) if resp.status() == StatusCode::BAD_REQUEST => {
render_message("Invalid paste URL.".into());
}
Ok(err) => {
render_message(format!("{}", err.status_text()).into());
}
Err(err) => {
render_message(format!("{}", err).into());
} }
Ok(resp) if resp.status() == StatusCode::BAD_REQUEST => {}
Ok(err) => {}
Err(err) => {}
} }
Ok(()) Ok(())

View file

@ -26,7 +26,7 @@ function loadFromDb() {
createVideoPasteUi(data); createVideoPasteUi(data);
break; break;
default: default:
renderMessage("Something went wrong. Try clearing local data."); createBrokenStateUi();
break; break;
} }
@ -159,15 +159,26 @@ function createMultiMediaPasteUi(tag, expiration, data, downloadMessage) {
bodyEle.appendChild(mainEle); bodyEle.appendChild(mainEle);
} }
function renderMessage(message) { // Exported to main.rs
function createNotFoundUi() {
let body = document.getElementsByTagName("body")[0]; let body = document.getElementsByTagName("body")[0];
body.textContent = ''; body.textContent = '';
body.appendChild(createGenericError("Either the paste has been burned or one never existed."));
}
function createBrokenStateUi() {
let body = document.getElementsByTagName("body")[0];
body.textContent = '';
body.appendChild(createGenericError("Something went wrong. Try clearing local data."));
}
function createGenericError(message) {
let mainEle = document.createElement("main"); let mainEle = document.createElement("main");
mainEle.classList.add("hljs"); mainEle.classList.add("hljs");
mainEle.classList.add("centered"); mainEle.classList.add("centered");
mainEle.classList.add("fullscreen"); mainEle.classList.add("fullscreen");
mainEle.textContent = message; mainEle.textContent = message;
body.appendChild(mainEle); return mainEle;
} }
window.addEventListener("hashchange", () => location.reload()); window.addEventListener("hashchange", () => location.reload());