refactor config variables, add upload password

This commit is contained in:
xenofem 2022-05-03 16:28:43 -04:00
parent bfe7fcde99
commit eb53030043
13 changed files with 456 additions and 182 deletions

View file

@ -11,55 +11,73 @@
<script src="transbeam.js"></script>
<title>transbeam</title>
</head>
<body class="no_files selecting">
<body class="noscript landing">
<div id="header">
<img src="images/site-icons/transbeam.svg" height="128">
<h1>transbeam</h1>
</div>
<div id="message"></div>
<div id="upload_controls">
<div>
<button id="upload">Upload</button>
</div>
<div id="lifetime_container">
<label>
Keep files for:
<select id="lifetime">
<option value="1">1 day</option>
<option value="7">1 week</option>
<option value="14" selected>2 weeks</option>
<option value="30">1 month</option>
</select>
</label>
</div>
</div>
<div id="download_code_container">
<div id="download_code_main">
<div>Download code: <span id="download_code"></span></div><div class="copy_button"></div>
</div>
<div id="copied_message">Link copied!</div>
</div>
<div id="progress_container">
<div id="progress"></div>
<div id="progress_bar"></div>
</div>
<table id="file_list">
</table>
<label id="file_input_container">
<input type="file" multiple id="file_input"/>
<span class="fake_button" id="file_input_message">Select files to upload...</span>
</label>
<div id="download">
<div id="download" class="section">
<h3 class="section_heading">Download</h3>
<form id="download_form" action="download" method="get">
<div>
<label>
<h4>Or enter a code to download files:</h4>
<input type="text" id="download_code_input" name="code" placeholder="Download code"/>
</label>
</div>
<input id="download_button" type="submit" value="Download"/>
</form>
</div>
<noscript>Javascript is required to upload files :(</noscript>
<div id="upload" class="section">
<h3 class="section_heading">Upload</h3>
<div id="message"></div>
<div>
<form id="upload_password_form">
<div>
<label>
<input id="upload_password" type="password" placeholder="Password"/>
</label>
</div>
<div>
<input type="submit" id="submit_upload_password" value="Submit" />
</div>
</form>
</div>
<div id="upload_controls">
<div id="upload_settings">
<div>
<button id="upload_button">Upload</button>
</div>
<div id="lifetime_container">
<label>
Keep files for:
<select id="lifetime">
<option value="1">1 day</option>
<option value="7">1 week</option>
<option value="14" selected>2 weeks</option>
<option value="30">1 month</option>
</select>
</label>
</div>
</div>
<div id="download_code_container">
<div id="download_code_main">
<div>Download code: <span id="download_code"></span></div><div class="copy_button"></div>
</div>
<div id="copied_message">Link copied!</div>
</div>
<div id="progress_container">
<div id="progress"></div>
<div id="progress_bar"></div>
</div>
<table id="file_list">
</table>
<label id="file_input_container">
<input type="file" multiple id="file_input"/>
<span class="fake_button" id="file_input_message">Select files to upload...</span>
</label>
</div>
</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>

View file

@ -1,6 +1,7 @@
/**
* List of classes the body can have:
*
* landing: haven't entered upload password yet
* no_files: no files are selected
* selecting: upload hasn't started yet
* uploading: upload is in progress
@ -8,6 +9,14 @@
* error: an error has occurred
*/
.section_heading { display: none; }
body.landing .section_heading { display: revert; }
#download { display: none; }
body.landing #download { display: revert; }
body.noscript #upload { display: none; }
#message { display: none; }
body.completed #message {
display: revert;
@ -20,9 +29,14 @@ body.error #message {
border-color: #f24;
}
#upload_controls { display: none; }
body.selecting #upload_controls { display: revert; }
body.no_files #upload_controls { display: none; }
#upload_password_form { display: none; }
body.landing #upload_password_form { display: revert; }
body.landing #upload_controls { display: none; }
#upload_settings { display: none; }
body.selecting #upload_settings { display: revert; }
body.no_files #upload_settings { display: none; }
body.selecting #download_code_container { display: none; }
@ -37,6 +51,3 @@ body.selecting .delete_button { display: revert; }
#file_input_container { display: none; }
body.selecting #file_input_container { display: revert; }
#download { display: none; }
body.no_files #download { display: revert; }

View file

@ -153,17 +153,13 @@ button:disabled, input:disabled + .fake_button, input[type="submit"]:disabled {
margin-top: 10px;
}
#download {
margin-top: 40px;
}
#download_code_input {
input[type="text"], input[type="password"] {
font-size: 18px;
margin-bottom: 10px;
}
#footer {
margin-top: 30px;
.section {
margin: 30px auto;
}
#footer h5 {

View file

@ -11,6 +11,8 @@ let totalBytes = 0;
let maxSize = null;
let uploadPassword;
let messageBox;
let fileInput;
let fileList;
@ -21,15 +23,37 @@ let progress;
let progressBar;
document.addEventListener('DOMContentLoaded', () => {
document.body.className = "landing";
messageBox = document.getElementById('message');
fileInput = document.getElementById('file_input');
fileList = document.getElementById('file_list');
uploadButton = document.getElementById('upload');
uploadButton = document.getElementById('upload_button');
lifetimeInput = document.getElementById('lifetime');
downloadCode = document.getElementById('download_code');
progress = document.getElementById('progress');
progressBar = document.getElementById('progress_bar');
const uploadPasswordInput = document.getElementById('upload_password');
const uploadPasswordForm = document.getElementById('upload_password_form');
uploadPasswordForm.addEventListener('submit', (e) => {
e.preventDefault();
uploadPassword = uploadPasswordInput.value;
fetch('/upload/check_password', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ password: uploadPassword }),
}).then((res) => {
if (res.ok) {
updateFiles();
} else {
messageBox.textContent = (res.status === 403) ? 'Incorrect password' : 'An error occurred';
uploadPasswordInput.value = '';
document.body.className = 'error landing';
}
});
});
fileInput.addEventListener('input', () => {
for (const file of fileInput.files) { addFile(file); }
updateFiles();
@ -71,8 +95,6 @@ document.addEventListener('DOMContentLoaded', () => {
}, 0);
}
});
updateFiles();
});
function updateFiles() {
@ -162,7 +184,11 @@ function sendManifest() {
size: file.size,
modtime: file.lastModified,
}));
socket.send(JSON.stringify({ lifetime, files: fileMetadata }));
socket.send(JSON.stringify({
files: fileMetadata,
lifetime,
password: uploadPassword,
}));
}
function handleMessage(msg) {
@ -202,6 +228,9 @@ function handleMessage(msg) {
}
}
displayError(`The maximum retention time for uploads is ${reply.max_days} days`);
} else if (reply.type === 'incorrect_password') {
messageBox.textContent = ('Incorrect password');
document.body.className = 'error landing';
} else if (reply.type === 'error') {
displayError(reply.details);
}

View file

@ -1,7 +1,7 @@
const UNITS = [
{ name: 'GB', size: Math.pow(2, 30) },
{ name: 'MB', size: Math.pow(2, 20) },
{ name: 'KB', size: Math.pow(2, 10) },
{ name: 'GB', size: Math.pow(10, 9) },
{ name: 'MB', size: Math.pow(10, 6) },
{ name: 'KB', size: Math.pow(10, 3) },
];
function displaySize(bytes) {