add 404 page for incorrect download codes
This commit is contained in:
parent
106c99d398
commit
9d87934cf4
27
src/main.rs
27
src/main.rs
|
@ -5,8 +5,10 @@ mod zip;
|
||||||
|
|
||||||
use std::{fmt::Debug, fs::File, path::PathBuf, str::FromStr};
|
use std::{fmt::Debug, fs::File, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
|
use actix_files::NamedFile;
|
||||||
use actix_web::{
|
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 actix_web_actors::ws;
|
||||||
use bytesize::ByteSize;
|
use bytesize::ByteSize;
|
||||||
|
@ -27,6 +29,7 @@ struct Config {
|
||||||
max_lifetime: u16,
|
max_lifetime: u16,
|
||||||
upload_password: String,
|
upload_password: String,
|
||||||
storage_dir: PathBuf,
|
storage_dir: PathBuf,
|
||||||
|
static_dir: PathBuf,
|
||||||
reverse_proxy: bool,
|
reverse_proxy: bool,
|
||||||
mnemonic_codes: bool,
|
mnemonic_codes: bool,
|
||||||
}
|
}
|
||||||
|
@ -57,14 +60,11 @@ async fn handle_download(
|
||||||
download: web::Query<DownloadRequest>,
|
download: web::Query<DownloadRequest>,
|
||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
) -> actix_web::Result<HttpResponse> {
|
) -> actix_web::Result<HttpResponse> {
|
||||||
let ip_addr = get_ip_addr(&req, data.config.reverse_proxy);
|
|
||||||
let code = &download.code;
|
let code = &download.code;
|
||||||
if !store::is_valid_storage_code(code) {
|
if !store::is_valid_storage_code(code) {
|
||||||
log_auth_failure(&ip_addr);
|
return download_not_found(req, data);
|
||||||
return Ok(HttpResponse::NotFound().finish());
|
|
||||||
}
|
}
|
||||||
let file_store = data.file_store.read().await;
|
let info = data.file_store.read().await.lookup_file(code);
|
||||||
let info = file_store.lookup_file(code);
|
|
||||||
if let Some(info) = info {
|
if let Some(info) = info {
|
||||||
let storage_path = data.config.storage_dir.join(code);
|
let storage_path = data.config.storage_dir.join(code);
|
||||||
let file = File::open(&storage_path)?;
|
let file = File::open(&storage_path)?;
|
||||||
|
@ -75,11 +75,21 @@ async fn handle_download(
|
||||||
}
|
}
|
||||||
.into_response(&req))
|
.into_response(&req))
|
||||||
} else {
|
} else {
|
||||||
log_auth_failure(&ip_addr);
|
download_not_found(req, data)
|
||||||
Ok(HttpResponse::NotFound().finish())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn download_not_found(
|
||||||
|
req: HttpRequest,
|
||||||
|
data: web::Data<AppState>,
|
||||||
|
) -> actix_web::Result<HttpResponse> {
|
||||||
|
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")]
|
#[get("/upload")]
|
||||||
async fn handle_upload(
|
async fn handle_upload(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
|
@ -183,6 +193,7 @@ async fn main() -> std::io::Result<()> {
|
||||||
max_lifetime,
|
max_lifetime,
|
||||||
upload_password,
|
upload_password,
|
||||||
storage_dir,
|
storage_dir,
|
||||||
|
static_dir: static_dir.clone(),
|
||||||
reverse_proxy,
|
reverse_proxy,
|
||||||
mnemonic_codes,
|
mnemonic_codes,
|
||||||
},
|
},
|
||||||
|
|
38
static/404.html
Normal file
38
static/404.html
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/transbeam.css"/>
|
||||||
|
<link rel="apple-touch-icon" href="images/site-icons/transbeam-apple.png"/>
|
||||||
|
<link rel="manifest" href="manifest.json"/>
|
||||||
|
<script src="js/download.js"></script>
|
||||||
|
<title>transbeam</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<a href="./">
|
||||||
|
<img src="images/site-icons/transbeam.svg" height="128">
|
||||||
|
<h1>transbeam</h1>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div id="download" class="section">
|
||||||
|
<h3>The download code you entered wasn't found. The download may have expired.</h3>
|
||||||
|
<form id="download_form" action="download" method="get">
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
<input type="text" id="download_code_input" name="code" placeholder="Download code"/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<input id="download_button" type="submit" value="Download"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="section">
|
||||||
|
<a href="./"><h3>< Back</h3></a>
|
||||||
|
</div>
|
||||||
|
<div id="footer">
|
||||||
|
<h5>(c) 2022 xenofem, MIT licensed</h5>
|
||||||
|
<h5><a target="_blank" href="https://git.xeno.science/xenofem/transbeam">source</a></h5>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -8,6 +8,11 @@ body {
|
||||||
|
|
||||||
#header h1 {
|
#header h1 {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header a {
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#message {
|
#message {
|
|
@ -3,12 +3,13 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<link rel="stylesheet" type="text/css" href="transbeam.css"/>
|
<link rel="stylesheet" type="text/css" href="css/transbeam.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="states.css"/>
|
<link rel="stylesheet" type="text/css" href="css/states.css"/>
|
||||||
<link rel="apple-touch-icon" href="images/site-icons/transbeam-apple.png"/>
|
<link rel="apple-touch-icon" href="images/site-icons/transbeam-apple.png"/>
|
||||||
<link rel="manifest" href="manifest.json"/>
|
<link rel="manifest" href="manifest.json"/>
|
||||||
<script src="util.js"></script>
|
<script src="js/util.js"></script>
|
||||||
<script src="transbeam.js"></script>
|
<script src="js/download.js"></script>
|
||||||
|
<script src="js/upload.js"></script>
|
||||||
<title>transbeam</title>
|
<title>transbeam</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="noscript landing">
|
<body class="noscript landing">
|
||||||
|
|
25
static/js/download.js
Normal file
25
static/js/download.js
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -71,30 +71,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
downloadCodeContainer.addEventListener('mouseleave', () => {
|
downloadCodeContainer.addEventListener('mouseleave', () => {
|
||||||
downloadCodeContainer.className = '';
|
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() {
|
function updateFiles() {
|
Loading…
Reference in a new issue