Add explicit login functionality

This commit is contained in:
2026-09-13 00:50:15 +02:00
parent 74bfdbfd8a
commit 1b77cdd165
14 changed files with 629 additions and 258 deletions
+6 -54
View File
@@ -40,7 +40,6 @@
if (!form) return;
var fileInput = document.getElementById('file');
var tokenInput = document.getElementById('token');
var drop = document.getElementById('drop');
var dropHint = document.getElementById('drop-hint');
var progress = document.getElementById('progress');
@@ -49,8 +48,9 @@
var submit = document.getElementById('submit');
var errorBox = document.getElementById('error');
// Limits as rendered for an anonymous caller; refreshed when a token is typed.
var limits = { max_size: null, allow_vanity: false };
// The session's limits are rendered by the server, so this script never has
// to ask who the visitor is. Zero means unlimited.
var maxSize = parseInt(form.dataset.maxSize, 10) || 0;
function formatSize(n) {
if (n === null || n === undefined) return 'unlimited';
@@ -64,54 +64,6 @@
errorBox.hidden = !msg;
}
// --- credentials --------------------------------------------------------
// A token is remembered in an HttpOnly cookie the server sets, not here:
// this script cannot read it back, so an injected script cannot steal it
// either. The page is told who it is by the server when it renders, and the
// limits panel is refreshed from /api/limits, which reads the same cookie.
function refreshLimits() {
var token = tokenInput ? tokenInput.value.trim() : '';
var xhr = new XMLHttpRequest();
xhr.open('GET', base + 'api/limits');
xhr.setRequestHeader('Accept', 'application/json');
// Sent only when the field holds something; otherwise the cookie answers.
if (token) xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.onload = function () {
if (xhr.status !== 200) {
if (xhr.status === 401 && token) showError('That token is not recognised.');
return;
}
showError('');
var l;
try { l = JSON.parse(xhr.responseText); } catch (e) { return; }
limits = l;
set('limit-size', l.max_size === null ? 'unlimited' : formatSize(l.max_size));
set('limit-expiry', l.max_expiry || 'never');
set('limit-default', l.default_expiry || 'never');
set('limit-vanity', l.allow_vanity ? 'allowed' : 'requires a token');
var vanity = document.getElementById('vanity');
if (vanity) vanity.disabled = !l.allow_vanity;
var expiry = document.getElementById('expiry');
if (expiry) expiry.placeholder = l.default_expiry || 'never';
};
xhr.send();
}
function set(id, text) {
var el = document.getElementById(id);
if (el) el.textContent = text;
}
if (tokenInput) {
var debounce;
tokenInput.addEventListener('input', function () {
clearTimeout(debounce);
debounce = setTimeout(refreshLimits, 400);
});
}
refreshLimits();
// --- drag and drop ------------------------------------------------------
function describeSelection() {
var f = fileInput.files[0];
@@ -144,10 +96,10 @@
var file = fileInput.files[0];
if (!file) return; // let the browser's own validation speak
if (limits.max_size && file.size > limits.max_size) {
if (maxSize && file.size > maxSize) {
e.preventDefault();
showError('That file is ' + formatSize(file.size) + '; the limit is ' +
formatSize(limits.max_size) + '.');
showError('That file is ' + formatSize(file.size) + '; your limit is ' +
formatSize(maxSize) + '.');
return;
}