diff --git a/Cargo.lock b/Cargo.lock index 2b37cac..be8903f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aead" version = "0.4.3" @@ -154,9 +160,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" [[package]] name = "byte-unit" @@ -173,6 +179,12 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.1.0" @@ -267,9 +279,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.0.0-beta.4" +version = "3.0.0-beta.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" +checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63" dependencies = [ "atty", "bitflags", @@ -280,14 +292,14 @@ dependencies = [ "strsim", "termcolor", "textwrap", - "vec_map", + "unicase", ] [[package]] name = "clap_derive" -version = "3.0.0-beta.4" +version = "3.0.0-beta.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" +checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3" dependencies = [ "heck", "proc-macro-error", @@ -315,6 +327,15 @@ dependencies = [ "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 = "digest" version = "0.9.0" @@ -326,9 +347,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.28" +version = "0.8.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" dependencies = [ "cfg-if", ] @@ -339,6 +360,18 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e" +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -498,9 +531,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c06815895acec637cd6ed6e9662c935b866d20a106f8361892893a7d9234964" +checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" dependencies = [ "bytes", "fnv", @@ -523,18 +556,18 @@ checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "headers" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855" +checksum = "a4c4eb0471fcb85846d8b0690695ef354f9afb11cb03cac2e1d7c9253351afb0" dependencies = [ "base64", "bitflags", "bytes", "headers-core", "http", + "httpdate", "mime", "sha-1", - "time", ] [[package]] @@ -577,9 +610,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ "bytes", "http", @@ -600,9 +633,9 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" [[package]] name = "hyper" -version = "0.14.13" +version = "0.14.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593" +checksum = "2b91bb1f221b6ea1f1e4371216b70f40748774c2fb5971b450c07773fb92d26b" dependencies = [ "bytes", "futures-channel", @@ -702,9 +735,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.103" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" +checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" [[package]] name = "libloading" @@ -771,10 +804,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" [[package]] -name = "mio" -version = "0.7.13" +name = "miniz_oxide" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -917,10 +960,12 @@ dependencies = [ "js-sys", "omegaupload-common", "reqwasm", + "serde", "tree_magic_mini", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "zip", ] [[package]] @@ -937,9 +982,12 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "os_str_bytes" -version = "3.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" +checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799" +dependencies = [ + "memchr", +] [[package]] name = "peeking_take_while" @@ -1008,9 +1056,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" [[package]] name = "proc-macro-error" @@ -1157,9 +1205,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51c732d463dd300362ffb44b7b125f299c23d2990411a4253824630ebc7467fb" +checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280" dependencies = [ "base64", "bytes", @@ -1535,9 +1583,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15a6b60cdff0cb039d81d3b37f8bc3d7e53dca09069aae3ef2502ca4834fe30" +checksum = "c00e500fff5fa1131c866b246041a6bf96da9c965f8fe4128cb1421f23e93c00" dependencies = [ "futures-core", "futures-util", @@ -1687,6 +1735,15 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.7" @@ -1754,12 +1811,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cf7d77f457ef8dfa11e4cd5933c5ddb5dc52a94664071951219a97710f0a32b" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.3" @@ -1930,3 +1981,15 @@ name = "zeroize" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "crc32fast", + "flate2", + "thiserror", +] diff --git a/web/Cargo.toml b/web/Cargo.toml index 36f2c6a..dc90c66 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -19,8 +19,11 @@ http = "0.2" js-sys = "0.3" reqwasm = "0.2" tree_magic_mini = { version = "3", features = ["with-gpl-data"] } -wasm-bindgen = "0.2" +serde = { version = "1.0", featurse = ["derive"] } +wasm-bindgen = { version = "0.2", features = ["serde-serialize"]} wasm-bindgen-futures = "0.4" +zip = { version = "0.5", default-features = false, features = ["deflate"] } +#tar = { version = "0.4", default-features = false } [dependencies.web-sys] version = "0.3" @@ -40,4 +43,4 @@ features = [ "Window", "Performance", "Location", -] \ No newline at end of file +] diff --git a/web/src/decrypt.rs b/web/src/decrypt.rs index 689bd86..50921b8 100644 --- a/web/src/decrypt.rs +++ b/web/src/decrypt.rs @@ -1,4 +1,5 @@ use std::fmt::{Display, Formatter}; +use std::io::Cursor; use std::sync::Arc; use gloo_console::log; @@ -6,6 +7,13 @@ use js_sys::{Array, Uint8Array}; use omegaupload_common::crypto::{open_in_place, Key, Nonce}; use wasm_bindgen::JsCast; use web_sys::Blob; +use serde::Serialize; + +#[derive(Clone, Serialize)] +pub struct ArchiveMeta { + name: String, + file_size: usize, +} #[derive(Clone)] pub enum DecryptedData { @@ -14,6 +22,7 @@ pub enum DecryptedData { Image(Arc, usize), Audio(Arc), Video(Arc), + Archive(Arc, Vec), } fn now() -> f64 { @@ -70,6 +79,7 @@ pub fn decrypt( log!(format!("Blob conversion completed in {}ms", now() - start)); let mime_type = tree_magic_mini::from_u8(container); + log!("Mimetype: ", mime_type); if mime_type.starts_with("image/") || mime_type == "application/x-riff" { Ok(DecryptedData::Image(blob, container.len())) @@ -77,6 +87,28 @@ pub fn decrypt( Ok(DecryptedData::Audio(blob)) } else if mime_type.starts_with("video/") || mime_type == "application/x-matroska" { Ok(DecryptedData::Video(blob)) + } else if mime_type == "application/zip" { + let mut entries = vec![]; + let cursor = Cursor::new(container); + if let Ok(mut zip) = zip::ZipArchive::new(cursor) { + for i in 0..zip.len() { + match zip.by_index(i) { + Ok(file) => { + entries.push(ArchiveMeta{name: file.name().to_string(), file_size: file.size() as usize}) + }, + Err(err) => { + match err { + zip::result::ZipError::UnsupportedArchive(s) => { log!("Unsupported: ", s.to_string()); } + _ => { log!(format!("Error: {}", err)); } + } + } + } + } + } + Ok(DecryptedData::Archive(blob, entries)) + } else if mime_type == "application/gzip" { + let entries = vec![]; + Ok(DecryptedData::Archive(blob, entries)) } else { Ok(DecryptedData::Blob(blob)) } diff --git a/web/src/idb_object.rs b/web/src/idb_object.rs index f853c2e..37a55e0 100644 --- a/web/src/idb_object.rs +++ b/web/src/idb_object.rs @@ -31,6 +31,10 @@ impl IdbObject { Self(Array::new(), PhantomData) } + pub fn archive(self) -> IdbObject { + self.add_tuple("type", &JsString::from("archive")) + } + pub fn video(self) -> IdbObject { self.add_tuple("type", &JsString::from("video")) } diff --git a/web/src/main.rs b/web/src/main.rs index eabc5ab..bba5b8c 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -8,7 +8,7 @@ use decrypt::DecryptedData; use gloo_console::{error, log}; use http::uri::PathAndQuery; use http::{StatusCode, Uri}; -use js_sys::{JsString, Object, Uint8Array}; +use js_sys::{JsString, Object, Uint8Array, Array}; use omegaupload_common::crypto::{Key, Nonce}; use omegaupload_common::{hash, Expiration, PartialParsedUrl}; use reqwasm::http::Request; @@ -191,6 +191,16 @@ async fn fetch_resources( .video() .expiration_text(&expires) .data(blob), + DecryptedData::Archive(blob, entries) => IdbObject::new() + .archive() + .expiration_text(&expires) + .data(blob) + .extra( + "entries", + JsValue::from(entries.into_iter() + .filter_map(|x| JsValue::from_serde(x).ok()) + .collect::()) + ), }; let put_action = transaction diff --git a/web/src/main.ts b/web/src/main.ts index bda6b7e..a8efe9d 100644 --- a/web/src/main.ts +++ b/web/src/main.ts @@ -25,6 +25,9 @@ function loadFromDb() { case "video": createVideoPasteUi(data); break; + case "archive": + createArchivePasteUi(data); + break; default: renderMessage("Something went wrong. Try clearing local data."); break; @@ -133,6 +136,48 @@ function createVideoPasteUi({ expiration, data }) { createMultiMediaPasteUi("video", expiration, data, "Download"); } +function createArchivePasteUi({ expiration, data, entries }) { + let bodyEle = document.getElementsByTagName("body")[0]; + bodyEle.textContent = ''; + + let mainEle = document.createElement("main"); + mainEle.classList.add("hljs"); + mainEle.classList.add("centered"); + mainEle.classList.add("fullscreen"); + + const downloadLink = URL.createObjectURL(data); + + let expirationEle = document.createElement("p"); + expirationEle.textContent = expiration; + mainEle.appendChild(expirationEle); + + let mediaEle = document.createElement("table"); + mediaEle.style.width = "50%"; + const tr = mediaEle.insertRow(); + const tdName = tr.insertCell(); + tdName.appendChild(document.createTextNode("Name")); + const tdSize = tr.insertCell(); + tdSize.appendChild(document.createTextNode("File Size")); + for (const entry of entries) { + const tr = mediaEle.insertRow(); + const tdName = tr.insertCell(); + tdName.appendChild(document.createTextNode(entry.name)); + const tdSize = tr.insertCell(); + tdSize.appendChild(document.createTextNode(entry.file_size)); + } + mainEle.appendChild(mediaEle); + + let downloadEle = document.createElement("a"); + downloadEle.href = downloadLink; + downloadEle.download = window.location.pathname; + downloadEle.classList.add("hljs-meta"); + mainEle.appendChild(downloadEle); + + bodyEle.appendChild(mainEle); + + downloadEle.textContent = "Download"; +} + function createMultiMediaPasteUi(tag, expiration, data, on_create?) { let bodyEle = document.getElementsByTagName("body")[0]; bodyEle.textContent = ''; @@ -179,4 +224,4 @@ function renderMessage(message) { body.appendChild(mainEle); } -window.addEventListener("hashchange", () => location.reload()); \ No newline at end of file +window.addEventListener("hashchange", () => location.reload());