Web workers
This commit is contained in:
parent
600d04eba9
commit
9004c4ed29
11 changed files with 811 additions and 643 deletions
196
Cargo.lock
generated
196
Cargo.lock
generated
|
@ -361,6 +361,22 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -419,6 +435,15 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
@ -453,6 +478,21 @@ version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foreign-types"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||||
|
dependencies = [
|
||||||
|
"foreign-types-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foreign-types-shared"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -766,6 +806,19 @@ dependencies = [
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-tls"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"hyper",
|
||||||
|
"native-tls",
|
||||||
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -787,6 +840,15 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "instant"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnet"
|
name = "ipnet"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
|
@ -941,6 +1003,24 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native-tls"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"openssl",
|
||||||
|
"openssl-probe",
|
||||||
|
"openssl-sys",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
|
"security-framework-sys",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.1"
|
version = "7.1.1"
|
||||||
|
@ -1053,7 +1133,7 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"omegaupload-common",
|
"omegaupload-common",
|
||||||
"reqwasm",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"tar",
|
"tar",
|
||||||
"tree_magic_mini",
|
"tree_magic_mini",
|
||||||
|
@ -1075,6 +1155,51 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl"
|
||||||
|
version = "0.10.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"foreign-types",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"openssl-macros",
|
||||||
|
"openssl-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-probe"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-sys"
|
||||||
|
version = "0.9.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
version = "6.2.0"
|
version = "6.2.0"
|
||||||
|
@ -1265,6 +1390,15 @@ version = "0.6.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "remove_dir_all"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwasm"
|
name = "reqwasm"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -1290,11 +1424,13 @@ dependencies = [
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-rustls",
|
"hyper-rustls",
|
||||||
|
"hyper-tls",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
|
"native-tls",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
@ -1303,6 +1439,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
|
@ -1381,6 +1518,16 @@ version = "1.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "schannel"
|
||||||
|
version = "0.1.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sct"
|
name = "sct"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -1400,6 +1547,29 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "security-framework"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"core-foundation",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
"security-framework-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "security-framework-sys"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.140"
|
version = "1.0.140"
|
||||||
|
@ -1571,6 +1741,20 @@ dependencies = [
|
||||||
"xattr",
|
"xattr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"fastrand",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"remove_dir_all",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -1671,6 +1855,16 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-native-tls"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
||||||
|
dependencies = [
|
||||||
|
"native-tls",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.23.4"
|
version = "0.23.4"
|
||||||
|
|
|
@ -294,18 +294,18 @@ impl From<Expiration> for HeaderValue {
|
||||||
|
|
||||||
pub struct ParseHeaderValueError;
|
pub struct ParseHeaderValueError;
|
||||||
|
|
||||||
#[cfg(feature = "wasm")]
|
// #[cfg(feature = "wasm")]
|
||||||
impl TryFrom<reqwasm::http::Headers> for Expiration {
|
// impl TryFrom<reqwest::header::HeaderMap<&str>> for Expiration {
|
||||||
type Error = ParseHeaderValueError;
|
// type Error = ParseHeaderValueError;
|
||||||
|
|
||||||
fn try_from(headers: reqwasm::http::Headers) -> Result<Self, Self::Error> {
|
// fn try_from(headers: reqwest::header::HeaderMap) -> Result<Self, Self::Error> {
|
||||||
headers
|
// headers
|
||||||
.get(http::header::EXPIRES.as_str())
|
// .get(http::header::EXPIRES.as_str())
|
||||||
.as_deref()
|
// .as_deref()
|
||||||
.and_then(|v| Self::try_from(v).ok())
|
// .and_then(|v| Self::try_from(v).ok())
|
||||||
.ok_or(ParseHeaderValueError)
|
// .ok_or(ParseHeaderValueError)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl TryFrom<HeaderValue> for Expiration {
|
impl TryFrom<HeaderValue> for Expiration {
|
||||||
type Error = ParseHeaderValueError;
|
type Error = ParseHeaderValueError;
|
||||||
|
|
|
@ -19,7 +19,6 @@ gloo-console = "0.2.1"
|
||||||
http = "0.2.8"
|
http = "0.2.8"
|
||||||
js-sys = "0.3.59"
|
js-sys = "0.3.59"
|
||||||
mime_guess = "2.0.4"
|
mime_guess = "2.0.4"
|
||||||
reqwasm = "0.5.0"
|
|
||||||
tree_magic_mini = { version = "3.0.3", features = ["with-gpl-data"] }
|
tree_magic_mini = { version = "3.0.3", features = ["with-gpl-data"] }
|
||||||
serde = { version = "1.0.140", features = ["derive"] }
|
serde = { version = "1.0.140", features = ["derive"] }
|
||||||
wasm-bindgen = { version = "0.2.82", features = ["serde-serialize"] }
|
wasm-bindgen = { version = "0.2.82", features = ["serde-serialize"] }
|
||||||
|
@ -27,6 +26,7 @@ wasm-bindgen-futures = "0.4.32"
|
||||||
zip = { version = "0.6.2", default-features = false, features = ["deflate"] }
|
zip = { version = "0.6.2", default-features = false, features = ["deflate"] }
|
||||||
flate2 = "1.0.24"
|
flate2 = "1.0.24"
|
||||||
tar = "0.4.38"
|
tar = "0.4.38"
|
||||||
|
reqwest = "0.11"
|
||||||
|
|
||||||
[dependencies.web-sys]
|
[dependencies.web-sys]
|
||||||
version = "0.3.59"
|
version = "0.3.59"
|
||||||
|
|
33
web/src/bg_encrypt.ts
Normal file
33
web/src/bg_encrypt.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// OmegaUpload Web Frontend
|
||||||
|
// Copyright (C) 2021 Edward Shen
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { encrypt_array_buffer } from '../pkg';
|
||||||
|
|
||||||
|
interface BgData {
|
||||||
|
location: string,
|
||||||
|
data: any
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener('message', (event: MessageEvent<BgData>) => {
|
||||||
|
let { location, data } = event.data;
|
||||||
|
console.log('[js-worker] Sending data to rust in a worker thread...');
|
||||||
|
encrypt_array_buffer(location, data).then(url => {
|
||||||
|
console.log("done buffer");
|
||||||
|
postMessage(url);
|
||||||
|
}).catch(e => console.error(e));
|
||||||
|
})
|
||||||
|
|
||||||
|
postMessage("init");
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
use std::{hint::unreachable_unchecked, marker::PhantomData};
|
use std::{hint::unreachable_unchecked, marker::PhantomData};
|
||||||
|
|
||||||
|
use gloo_console::log;
|
||||||
use js_sys::{Array, JsString, Object};
|
use js_sys::{Array, JsString, Object};
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
|
|
||||||
|
@ -37,7 +38,10 @@ 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() },
|
_ => {
|
||||||
|
log!("IdbObject invariant violated?!");
|
||||||
|
unsafe { unreachable_unchecked() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
import { start } from '../pkg';
|
import { start } from '../pkg';
|
||||||
|
import './main.scss';
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
|
||||||
|
window.addEventListener("hashchange", () => location.reload());
|
||||||
|
|
|
@ -24,17 +24,16 @@ use decrypt::{DecryptedData, MimeType};
|
||||||
use gloo_console::{error, log};
|
use gloo_console::{error, log};
|
||||||
use http::uri::PathAndQuery;
|
use http::uri::PathAndQuery;
|
||||||
use http::{StatusCode, Uri};
|
use http::{StatusCode, Uri};
|
||||||
use js_sys::{Array, JsString, Object, Uint8Array};
|
use js_sys::{Array, JsString, Object};
|
||||||
use omegaupload_common::base64;
|
use omegaupload_common::base64;
|
||||||
use omegaupload_common::crypto::seal_in_place;
|
use omegaupload_common::crypto::seal_in_place;
|
||||||
use omegaupload_common::crypto::{Error as CryptoError, Key};
|
use omegaupload_common::crypto::{Error as CryptoError, Key};
|
||||||
use omegaupload_common::fragment::Builder;
|
use omegaupload_common::fragment::Builder;
|
||||||
use omegaupload_common::secrecy::{ExposeSecret, Secret, SecretString, SecretVec};
|
use omegaupload_common::secrecy::{ExposeSecret, Secret, SecretString, SecretVec};
|
||||||
use omegaupload_common::{Expiration, PartialParsedUrl, Url};
|
use omegaupload_common::{Expiration, PartialParsedUrl, Url};
|
||||||
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};
|
||||||
use wasm_bindgen_futures::{spawn_local, JsFuture};
|
use wasm_bindgen_futures::spawn_local;
|
||||||
use web_sys::{Event, IdbObjectStore, IdbOpenDbRequest, IdbTransactionMode, Location, Window};
|
use web_sys::{Event, IdbObjectStore, IdbOpenDbRequest, IdbTransactionMode, Location, Window};
|
||||||
|
|
||||||
use crate::decrypt::decrypt;
|
use crate::decrypt::decrypt;
|
||||||
|
@ -173,51 +172,36 @@ pub fn start() {
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
#[allow(clippy::future_not_send)]
|
#[allow(clippy::future_not_send)]
|
||||||
pub fn encrypt_string(data: String) {
|
pub async fn encrypt_array_buffer(location: String, data: Vec<u8>) -> Result<JsString, JsString> {
|
||||||
spawn_local(async move {
|
do_encrypt(location, data).await.map_err(|e| {
|
||||||
if let Err(e) = do_encrypt(data.into_bytes()).await {
|
log!(format!("[rs] Error encrypting array buffer: {}", e));
|
||||||
log!(format!("[rs] Error encrypting string: {}", e));
|
JsString::from(e.to_string())
|
||||||
}
|
})
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
#[allow(clippy::future_not_send)]
|
|
||||||
pub fn encrypt_array_buffer(data: Vec<u8>) {
|
|
||||||
spawn_local(async move {
|
|
||||||
if let Err(e) = do_encrypt(data).await {
|
|
||||||
log!(format!("[rs] Error encrypting array buffer: {}", e));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::future_not_send)]
|
#[allow(clippy::future_not_send)]
|
||||||
async fn do_encrypt(mut data: Vec<u8>) -> Result<()> {
|
async fn do_encrypt(location: String, mut data: Vec<u8>) -> Result<JsString> {
|
||||||
let (data, key) = {
|
let (data, key) = {
|
||||||
let enc_key = seal_in_place(&mut data, None)?;
|
let enc_key = seal_in_place(&mut data, None)?;
|
||||||
let key = SecretString::new(base64::encode(&enc_key.expose_secret().as_ref()));
|
let key = SecretString::new(base64::encode(&enc_key.expose_secret().as_ref()));
|
||||||
(data, key)
|
(data, key)
|
||||||
};
|
};
|
||||||
|
|
||||||
let s: String = location().to_string().into();
|
let mut url = Url::from_str(&location)?;
|
||||||
let mut url = Url::from_str(&s)?;
|
|
||||||
let fragment = Builder::new(key);
|
let fragment = Builder::new(key);
|
||||||
|
|
||||||
let js_data = Uint8Array::new_with_length(u32::try_from(data.len()).expect("Data too large"));
|
let short_code = reqwest::Client::new()
|
||||||
js_data.copy_from(&data);
|
.post(url.as_ref())
|
||||||
|
.body(data)
|
||||||
let short_code = Request::post(url.as_ref())
|
|
||||||
.body(js_data)
|
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await?
|
||||||
.text()
|
.text()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
url.set_path(&short_code);
|
url.set_path(&short_code);
|
||||||
url.set_fragment(Some(fragment.build().expose_secret()));
|
url.set_fragment(Some(fragment.build().expose_secret()));
|
||||||
location()
|
|
||||||
.set_href(url.as_ref())
|
Ok(JsString::from(url.as_ref()))
|
||||||
.expect("Unable to navigate to encrypted upload");
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::future_not_send)]
|
#[allow(clippy::future_not_send)]
|
||||||
|
@ -228,31 +212,26 @@ async fn fetch_resources(
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
language: Option<String>,
|
language: Option<String>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match Request::get(&request_uri.to_string()).send().await {
|
match reqwest::Client::new()
|
||||||
|
.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 = resp
|
||||||
|_| "This item does not expire.".to_string(),
|
.headers()
|
||||||
|expires| expires.to_string(),
|
.get(http::header::EXPIRES)
|
||||||
);
|
.and_then(|header| Expiration::try_from(header).ok())
|
||||||
|
.map_or_else(
|
||||||
|
|| "This item does not expire.".to_string(),
|
||||||
|
|expires| expires.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
let data = {
|
let data = resp
|
||||||
let data_fut = resp
|
.bytes()
|
||||||
.as_raw()
|
.await
|
||||||
.array_buffer()
|
.expect("to get raw bytes from a response")
|
||||||
.expect("to get raw bytes from a response");
|
.to_vec();
|
||||||
let data = match JsFuture::from(data_fut).await {
|
|
||||||
Ok(data) => data,
|
|
||||||
Err(e) => {
|
|
||||||
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()
|
|
||||||
};
|
|
||||||
|
|
||||||
if data.len() as u128 > DOWNLOAD_SIZE_LIMIT {
|
if data.len() as u128 > DOWNLOAD_SIZE_LIMIT {
|
||||||
render_message("The paste is too large to decrypt from the web browser. You must use the CLI tool to download this paste.".into());
|
render_message("The paste is too large to decrypt from the web browser. You must use the CLI tool to download this paste.".into());
|
||||||
|
@ -300,7 +279,7 @@ async fn fetch_resources(
|
||||||
render_message("Invalid paste URL.".into());
|
render_message("Invalid paste URL.".into());
|
||||||
}
|
}
|
||||||
Ok(err) => {
|
Ok(err) => {
|
||||||
render_message(err.status_text().into());
|
render_message(err.status().as_str().into());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
render_message(format!("{err}").into());
|
render_message(format!("{err}").into());
|
||||||
|
|
|
@ -40,6 +40,7 @@ hr {
|
||||||
main {
|
main {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,11 +122,9 @@ textarea {
|
||||||
.button {
|
.button {
|
||||||
@extend .hljs;
|
@extend .hljs;
|
||||||
|
|
||||||
border: 1px solid white;
|
|
||||||
border-radius: $padding;
|
|
||||||
padding: $padding;
|
|
||||||
margin: $padding;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
text-decoration: underline;
|
||||||
|
border: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -14,28 +14,29 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import './main.scss';
|
|
||||||
import ReactDom from 'react-dom';
|
import ReactDom from 'react-dom';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { encrypt_string, encrypt_array_buffer } from '../pkg';
|
|
||||||
|
|
||||||
import hljs from 'highlight.js'
|
let hljs;
|
||||||
(window as any).hljs = hljs;
|
if (typeof WorkerGlobalScope === 'undefined' || !(self instanceof WorkerGlobalScope)) {
|
||||||
require('highlightjs-line-numbers.js');
|
hljs = require('highlight.js');
|
||||||
|
(window as any).hljs = hljs;
|
||||||
|
require('highlightjs-line-numbers.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const FileForm = () => {
|
const FileForm = () => {
|
||||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
let file = event.target.files![0];
|
let file = event.target.files![0];
|
||||||
const fr = new FileReader();
|
const fr = new FileReader();
|
||||||
fr.onload = (_e) => {
|
fr.onload = (_e) => {
|
||||||
let data = new Uint8Array(fr.result as ArrayBuffer);
|
encryptMessage(new Uint8Array(fr.result as ArrayBuffer));
|
||||||
encrypt_array_buffer(data);
|
|
||||||
}
|
}
|
||||||
fr.readAsArrayBuffer(file);
|
fr.readAsArrayBuffer(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<label className="file-upload" >
|
<label className="file-upload hljs-meta" >
|
||||||
Select a file
|
Select a file
|
||||||
<input type="file" onChange={handleChange} />
|
<input type="file" onChange={handleChange} />
|
||||||
</label>
|
</label>
|
||||||
|
@ -43,12 +44,14 @@ const FileForm = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const PasteForm = () => {
|
const PasteForm = () => {
|
||||||
const [value, setValue] = useState("");
|
const [data, setValue] = useState("");
|
||||||
|
|
||||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (value.trim() !== "") {
|
if (data.trim() !== "") {
|
||||||
encrypt_string(value);
|
encryptMessage(new TextEncoder().encode(data));
|
||||||
|
} else {
|
||||||
|
console.log("[js] Not sending string because it was empty.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,14 +59,28 @@ const PasteForm = () => {
|
||||||
<form className='hljs centered' onSubmit={handleSubmit}>
|
<form className='hljs centered' onSubmit={handleSubmit}>
|
||||||
<textarea
|
<textarea
|
||||||
placeholder="すいちゃんは~ 今日もかわい~!!"
|
placeholder="すいちゃんは~ 今日もかわい~!!"
|
||||||
value={value}
|
value={data}
|
||||||
onChange={(e) => setValue(e.target.value)}
|
onChange={(e) => setValue(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<input className="text-upload" type="submit" value="submit" />
|
<input className="text-upload hljs-meta" type="submit" value="Submit" />
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function encryptMessage(data: Uint8Array) {
|
||||||
|
const worker = new Worker(new URL('./bg_encrypt.ts', import.meta.url));
|
||||||
|
worker.onmessage = (event: MessageEvent<string>) => {
|
||||||
|
console.log(event);
|
||||||
|
if (event.data === 'init') {
|
||||||
|
console.log("[js] Sending data to worker");
|
||||||
|
const message = { data, location: window.location.toString() };
|
||||||
|
worker.postMessage(message, [message.data.buffer]);
|
||||||
|
} else {
|
||||||
|
window.location.assign(event.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createUploadUi() {
|
function createUploadUi() {
|
||||||
const html = <main className='hljs centered fullscreen'>
|
const html = <main className='hljs centered fullscreen'>
|
||||||
<FileForm />
|
<FileForm />
|
||||||
|
@ -149,7 +166,7 @@ function loadFromDb(mimeType: string, name?: string, language?: string) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createStringPasteUi(data, mimeType: string, name: string, lang?: string) {
|
function createStringPasteUi(data, mimeType: string, name: string, lang?: string, skipSyntaxHighlight?: boolean) {
|
||||||
const html = <main>
|
const html = <main>
|
||||||
<pre className='paste'>
|
<pre className='paste'>
|
||||||
<p className='unselectable centered'>{data.expiration}</p>
|
<p className='unselectable centered'>{data.expiration}</p>
|
||||||
|
@ -165,6 +182,10 @@ function createStringPasteUi(data, mimeType: string, name: string, lang?: string
|
||||||
|
|
||||||
ReactDom.render(html, document.body);
|
ReactDom.render(html, document.body);
|
||||||
|
|
||||||
|
if (skipSyntaxHighlight) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let languages = undefined;
|
let languages = undefined;
|
||||||
|
|
||||||
if (!hljs.getLanguage(lang)) {
|
if (!hljs.getLanguage(lang)) {
|
||||||
|
@ -203,6 +224,7 @@ function createStringPasteUi(data, mimeType: string, name: string, lang?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we still haven't set languages here, then we're leaving it up to the
|
// If we still haven't set languages here, then we're leaving it up to the
|
||||||
|
// library
|
||||||
if (!languages) {
|
if (!languages) {
|
||||||
console.log("[js] Deferring to hljs inference for syntax highlighting.");
|
console.log("[js] Deferring to hljs inference for syntax highlighting.");
|
||||||
} else {
|
} else {
|
||||||
|
@ -226,7 +248,7 @@ function createBlobPasteUi(data, name: string) {
|
||||||
<p className='display-anyways hljs-comment' onClick={() => {
|
<p className='display-anyways hljs-comment' onClick={() => {
|
||||||
data.data.text().then(text => {
|
data.data.text().then(text => {
|
||||||
data.data = text;
|
data.data = text;
|
||||||
createStringPasteUi(data, "application/octet-stream", name);
|
createStringPasteUi(data, "application/octet-stream", name, undefined, true);
|
||||||
})
|
})
|
||||||
}}>Display anyways?</p>
|
}}>Display anyways?</p>
|
||||||
</main>;
|
</main>;
|
||||||
|
@ -337,6 +359,5 @@ function getObjectUrl(data, mimeType?: string) {
|
||||||
return URL.createObjectURL(new Blob([data], { type: mimeType }));
|
return URL.createObjectURL(new Blob([data], { type: mimeType }));
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("hashchange", () => location.reload());
|
|
||||||
|
|
||||||
export { renderMessage, createUploadUi, loadFromDb };
|
export { renderMessage, createUploadUi, loadFromDb };
|
||||||
|
|
2
web/vendor/MPLUS_FONTS
vendored
2
web/vendor/MPLUS_FONTS
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 8690be3625964d9992e7be4bc3e1a61a80161cc6
|
Subproject commit a1268635894c5ee23dfdece570418ca07b66c3fc
|
Loading…
Reference in a new issue