The upload password gate can now be skipped with a bookmarkable
#psst=<sha256-hash> fragment instead of typing the password each time.
The server accepts either the plaintext password (X-Upload-Password) or
its SHA-256 hash (X-Upload-Password-Hash), compared timing-safely. The
client computes the hash locally after a normal password entry, so the
bypass link never contains the real password — only a one-way digest of
it, kept out of the URL query string (and thus server logs) by living in
the fragment, same as the decryption key.
Client-side libsodium encryption with the key in the URL fragment, an
Express/SQLite server holding ciphertext until a confirm-token round trip
proves successful decrypt (avoiding the delete-on-first-byte race), TTL
sweep for unclaimed drops, and a password-gated upload UI styled to match
flit. Dockerized to match the project family's conventions, with a named
volume so the DB/blobs survive redeploys, and a Gitea Actions workflow to
build and push the image.
README covers the pitch and how this differs from flit (synchronous,
zero server storage) and zipline (persistent hosting). IMPLEMENTATION
covers the crypto scheme (key-in-fragment, same primitives as
flit/waste-go), storage shape, and the deletion-race problem —
delete-on-first-byte-served is the wrong default (see Firefox Send's
history with this exact bug); confirm-then-delete with a TTL backstop
is the fix.
No code yet — design stage.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>