Add --port

This commit is contained in:
2026-09-12 23:48:03 +02:00
parent a180fe4b52
commit da36645aaf
14 changed files with 677 additions and 40 deletions
+11 -13
View File
@@ -32,27 +32,25 @@
errorBox.hidden = !msg;
}
// --- token memory -------------------------------------------------------
// Kept in localStorage only so the field survives a reload; it is never sent
// anywhere but this origin's upload endpoint.
try {
var saved = localStorage.getItem('send.token');
if (saved && tokenInput) tokenInput.value = saved;
} catch (e) { /* private mode; not important */ }
// --- 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() : '';
try {
if (token) localStorage.setItem('send.token', token);
else localStorage.removeItem('send.token');
} catch (e) { /* ignore */ }
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) return;
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;
+24
View File
@@ -142,3 +142,27 @@ pre {
.warn p { margin: .25rem 0 .75rem; font-size: .875rem; }
.result .field { margin-top: 1rem; }
.check { display: flex; align-items: center; gap: .5rem; margin-bottom: 1rem; font-size: .875rem; }
.check input { margin: 0; }
.notice {
margin: 0 0 1rem;
padding: .625rem .875rem;
background: var(--card);
border: 1px solid var(--line);
border-left: 3px solid var(--accent);
border-radius: 6px;
font-size: .875rem;
}
.notice .forget-form, .notice form { display: inline; }
button.link {
padding: 0;
background: none;
border: 0;
color: var(--accent);
font: inherit;
text-decoration: underline;
cursor: pointer;
}
+20 -3
View File
@@ -1,10 +1,27 @@
{{define "content"}}
{{if .Stale}}
<p class="notice">The token remembered on this device no longer exists. It has been forgotten.</p>
{{end}}
{{if .TokenName}}
<div class="notice" id="identity">
Uploading as <strong>{{.TokenName}}</strong>.
<form method="post" action="{{.Base}}api/forget"><button type="submit" class="link">Forget</button></form>
</div>
{{end}}
<form id="upload" class="card" method="post" action="{{.Base}}api/upload" enctype="multipart/form-data">
<!-- Field order is load-bearing: the server streams this body and must know
the credentials and options before the file part arrives. -->
<label class="field">
<span>Token <em>optional</em></span>
<input type="password" name="token" id="token" autocomplete="off" placeholder="anonymous">
<input type="password" name="token" id="token" autocomplete="off"
placeholder="{{if .TokenName}}remembered — type to replace{{else}}anonymous{{end}}">
</label>
<label class="check">
<input type="checkbox" name="remember" id="remember" value="1" checked>
<span>Remember this token on this device</span>
</label>
<div class="row">
@@ -15,7 +32,7 @@
<label class="field" id="vanity-field">
<span>Vanity name <em>token only</em></span>
<input type="text" name="vanity" id="vanity" placeholder="auto" autocomplete="off"
pattern="[A-Za-z0-9][A-Za-z0-9._-]{1,63}">
pattern="[A-Za-z0-9][A-Za-z0-9._-]{1,63}"{{if not .AllowVanity}} disabled{{end}}>
</label>
</div>
@@ -39,7 +56,7 @@
<dt>Maximum size</dt><dd id="limit-size">{{.MaxSize}}</dd>
<dt>Longest lifetime</dt><dd id="limit-expiry">{{.MaxExpiry}}</dd>
<dt>Default lifetime</dt><dd id="limit-default">{{.DefaultExpiry}}</dd>
<dt>Vanity names</dt><dd id="limit-vanity">requires a token</dd>
<dt>Vanity names</dt><dd id="limit-vanity">{{if .AllowVanity}}allowed{{else}}requires a token{{end}}</dd>
</dl>
</section>