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
+28 -32
View File
@@ -1,45 +1,39 @@
{{define "content"}}
{{if .Stale}}
<p class="notice">The token remembered on this device no longer exists. It has been forgotten.</p>
<p class="notice">Your login is no longer valid — that token has been removed. You have been logged out.</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" data-max-size="{{.MaxSizeBytes}}">
<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="{{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="drop" id="drop">
<input type="file" name="file" id="file" required>
<p class="hint" id="drop-hint">Choose a file, or drop one here.</p>
</div>
<div class="row">
<label class="field">
<span>Expires in</span>
<input type="text" name="expiry" id="expiry" placeholder="{{.DefaultExpiry}}" autocomplete="off">
</label>
<label class="field" id="vanity-field">
<span>Vanity name <em>token only</em></span>
<label class="field">
<span>Custom name <em>{{if .AllowVanity}}optional{{else}}needs a token{{end}}</em></span>
<input type="text" name="vanity" id="vanity" placeholder="auto" autocomplete="off"
pattern="[A-Za-z0-9][A-Za-z0-9._-]{1,63}"{{if not .AllowVanity}} disabled{{end}}>
</label>
</div>
<div class="drop" id="drop">
<input type="file" name="file" id="file" required>
<p class="hint" id="drop-hint">Choose a file, or drop one here.</p>
</div>
<details class="onceoff">
<summary>Use a different token for this upload</summary>
<p class="hint">
Applies to this upload only and does not log you in.
{{if not .User}}To keep a token for this browser, <a href="{{.Base}}login">log in</a> instead.{{end}}
</p>
<label class="field">
<span>Token</span>
<input type="password" name="token" autocomplete="off">
</label>
</details>
<div class="progress" id="progress" hidden>
<div class="bar"><div class="fill" id="bar-fill"></div></div>
@@ -51,13 +45,15 @@
</form>
<section class="limits">
<h2>Current limits</h2>
<dl id="limits">
<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">{{if .AllowVanity}}allowed{{else}}requires a token{{end}}</dd>
<h2>Your limits</h2>
<dl>
<dt>Uploading as</dt><dd>{{if .User}}{{.User}}{{else}}<em>anonymous</em>{{end}}</dd>
<dt>Maximum size</dt><dd>{{.MaxSize}}</dd>
<dt>Longest lifetime</dt><dd>{{.MaxExpiry}}</dd>
<dt>Default lifetime</dt><dd>{{.DefaultExpiry}}</dd>
<dt>Custom names</dt><dd>{{if .AllowVanity}}allowed{{else}}need a token{{end}}</dd>
</dl>
{{if not .User}}<p class="hint"><a href="{{.Base}}login">Log in</a> with a token to raise these.</p>{{end}}
</section>
<section class="cli">
+9 -1
View File
@@ -9,7 +9,15 @@
<body data-base="{{.Base}}">
<header>
<a class="brand" href="{{.Base}}">Uncensored&nbsp;Send</a>
{{if .Admin}}<nav><a href="{{.Base}}admin">Administration</a></nav>{{end}}
<nav>
{{if .User}}
{{if .Admin}}<a href="{{.Base}}admin">Administration</a>{{end}}
<span class="who">{{.User}}</span>
<form method="post" action="{{.Base}}logout"><button type="submit" class="link">Log out</button></form>
{{else}}
<a href="{{.Base}}login">Log in</a>
{{end}}
</nav>
</header>
<main>
{{template "content" .}}
+41
View File
@@ -0,0 +1,41 @@
{{define "content"}}
{{if .User}}
<section class="card">
<h1>Logged in</h1>
<p>You are logged in as <strong>{{.User}}</strong>.</p>
<dl>
<dt>Maximum size</dt><dd>{{.MaxSize}}</dd>
<dt>Longest lifetime</dt><dd>{{.MaxExpiry}}</dd>
<dt>Custom names</dt><dd>{{if .Vanity}}allowed{{else}}not allowed{{end}}</dd>
</dl>
<p class="actions">
<a class="button" href="{{.Base}}">Upload a file</a>
<form method="post" action="{{.Base}}logout"><button type="submit" class="link">Log out</button></form>
</p>
</section>
{{else}}
<section class="card">
<h1>Log in</h1>
<p class="hint">
A token raises your size and lifetime limits and lets you choose custom
names. Logging in keeps it for this browser, so you do not have to paste it
for every upload. Without one you can still upload anonymously.
</p>
{{if .Error}}<p class="error">{{.Error}}</p>{{end}}
<form method="post" action="{{.Base}}login">
<input type="hidden" name="next" value="{{.Next}}">
<label class="field">
<span>Token</span>
<input type="password" name="token" autocomplete="current-password" required autofocus>
</label>
<label class="check">
<input type="checkbox" name="persist" value="1" checked>
<span>Stay logged in on this device</span>
</label>
<button type="submit">Log in</button>
</form>
</section>
{{end}}
{{end}}