diff --git a/src/main.rs b/src/main.rs index 37aee64..e38e0b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,10 @@ mod zip; use std::{fmt::Debug, fs::File, path::PathBuf, str::FromStr}; +use actix_files::NamedFile; use actix_web::{ - get, middleware::Logger, post, web, App, HttpRequest, HttpResponse, HttpServer, Responder, + get, http::StatusCode, middleware::Logger, post, web, App, HttpRequest, HttpResponse, + HttpServer, Responder, }; use actix_web_actors::ws; use bytesize::ByteSize; @@ -27,6 +29,7 @@ struct Config { max_lifetime: u16, upload_password: String, storage_dir: PathBuf, + static_dir: PathBuf, reverse_proxy: bool, mnemonic_codes: bool, } @@ -57,14 +60,11 @@ async fn handle_download( download: web::Query, data: web::Data, ) -> actix_web::Result { - let ip_addr = get_ip_addr(&req, data.config.reverse_proxy); let code = &download.code; if !store::is_valid_storage_code(code) { - log_auth_failure(&ip_addr); - return Ok(HttpResponse::NotFound().finish()); + return download_not_found(req, data); } - let file_store = data.file_store.read().await; - let info = file_store.lookup_file(code); + let info = data.file_store.read().await.lookup_file(code); if let Some(info) = info { let storage_path = data.config.storage_dir.join(code); let file = File::open(&storage_path)?; @@ -75,11 +75,21 @@ async fn handle_download( } .into_response(&req)) } else { - log_auth_failure(&ip_addr); - Ok(HttpResponse::NotFound().finish()) + download_not_found(req, data) } } +fn download_not_found( + req: HttpRequest, + data: web::Data, +) -> actix_web::Result { + let ip_addr = get_ip_addr(&req, data.config.reverse_proxy); + log_auth_failure(&ip_addr); + Ok(NamedFile::open(data.config.static_dir.join("404.html"))? + .set_status_code(StatusCode::NOT_FOUND) + .into_response(&req)) +} + #[get("/upload")] async fn handle_upload( req: HttpRequest, @@ -183,6 +193,7 @@ async fn main() -> std::io::Result<()> { max_lifetime, upload_password, storage_dir, + static_dir: static_dir.clone(), reverse_proxy, mnemonic_codes, }, diff --git a/static/404.html b/static/404.html new file mode 100644 index 0000000..05bf6a2 --- /dev/null +++ b/static/404.html @@ -0,0 +1,38 @@ + + + + + + + + + + transbeam + + + +
+

The download code you entered wasn't found. The download may have expired.

+
+
+ +
+ +
+
+
+

< Back

+
+ + + diff --git a/static/states.css b/static/css/states.css similarity index 100% rename from static/states.css rename to static/css/states.css diff --git a/static/transbeam.css b/static/css/transbeam.css similarity index 97% rename from static/transbeam.css rename to static/css/transbeam.css index 98bdc20..8dab70e 100644 --- a/static/transbeam.css +++ b/static/css/transbeam.css @@ -8,6 +8,11 @@ body { #header h1 { margin-top: 5px; + color: black; +} + +#header a { + text-decoration: none; } #message { diff --git a/static/index.html b/static/index.html index 4423d66..ff438e6 100644 --- a/static/index.html +++ b/static/index.html @@ -3,12 +3,13 @@ - - + + - - + + + transbeam diff --git a/static/js/download.js b/static/js/download.js new file mode 100644 index 0000000..7b057df --- /dev/null +++ b/static/js/download.js @@ -0,0 +1,25 @@ +document.addEventListener('DOMContentLoaded', () => { + const downloadCodeInput = document.getElementById('download_code_input'); + const downloadButton = document.getElementById('download_button'); + const downloadForm = document.getElementById('download_form'); + downloadCodeInput.addEventListener('beforeinput', (e) => { + if (/^[a-zA-Z0-9-]+$/.test(e.data)) { return; } + e.preventDefault(); + if (e.data === ' ') { + downloadCodeInput.value += '-'; + } + }); + const disableEnableDownload = () => { downloadButton.disabled = (downloadCodeInput.value === ''); }; + disableEnableDownload(); + downloadCodeInput.addEventListener('input', disableEnableDownload); + downloadForm.addEventListener('submit', (e) => { + if (downloadCodeInput.value === '') { + e.preventDefault(); + } else { + setTimeout(() => { + downloadCodeInput.value = ''; + downloadButton.disabled = true; + }, 0); + } + }); +}); diff --git a/static/transbeam.js b/static/js/upload.js similarity index 90% rename from static/transbeam.js rename to static/js/upload.js index 42747e5..6cca00c 100644 --- a/static/transbeam.js +++ b/static/js/upload.js @@ -71,30 +71,6 @@ document.addEventListener('DOMContentLoaded', () => { downloadCodeContainer.addEventListener('mouseleave', () => { downloadCodeContainer.className = ''; }); - - const downloadCodeInput = document.getElementById('download_code_input'); - const downloadButton = document.getElementById('download_button'); - const downloadForm = document.getElementById('download_form'); - downloadCodeInput.addEventListener('beforeinput', (e) => { - if (/^[a-zA-Z0-9-]+$/.test(e.data)) { return; } - e.preventDefault(); - if (e.data === ' ') { - downloadCodeInput.value += '-'; - } - }); - const disableEnableDownload = () => { downloadButton.disabled = (downloadCodeInput.value === ''); }; - disableEnableDownload(); - downloadCodeInput.addEventListener('input', disableEnableDownload); - downloadForm.addEventListener('submit', (e) => { - if (downloadCodeInput.value === '') { - e.preventDefault(); - } else { - setTimeout(() => { - downloadCodeInput.value = ''; - downloadButton.disabled = true; - }, 0); - } - }); }); function updateFiles() { diff --git a/static/util.js b/static/js/util.js similarity index 100% rename from static/util.js rename to static/js/util.js