Auto-claim on receive so /settings shows transfers others sent you.
Filename decryption stays client-side using the key stored in localStorage
when the share link is opened.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Home is now two sections, no clutter:
- Nearby — tap a device on the same Wi-Fi and the composer takes its
place (drop files, optionally write a note, send). Pair-across-networks
and public-room panels moved off the main page into the footer as a
single discrete link (/pair).
- Share a link — inline WeTransfer-style card. Pick a file, optionally
expand email / password / expiry, upload. Result shows QR + copy link
+ the password to share out-of-band.
The password gate is a server-side access control layer on top of the
existing E2E encryption: scrypt-hashed on create, verified on consume.
The encryption key still lives only in the URL fragment; the password
does not participate in the crypto.
- server: password_hash column (migration 0002), scrypt+timingSafeEqual
verify on /consume, requiresPassword surfaced on the HEAD response.
- web: Composer merges drop zone + text note into one surface; Receive
shows a password prompt when requiresPassword is true and recovers in
place on a wrong attempt.
- responsive: mobile-first paddings, DeviceChip shrinks on narrow widths,
no 2-col grids on the main page.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a "Via AnyDrop" flow for senders who need to reach someone not
present on the mesh. The file is sealed client-side (XChaCha20-Poly1305),
uploaded directly to an in-cluster MinIO bucket via a presigned PUT, and
handed off to the recipient as a URL whose fragment carries the key.
The server only ever sees ciphertext, opaque metadata blobs, and sizes.
- server: transfers table (drizzle migration), /api/transfers CRUD +
consume endpoint, presigned PUT/GET via @aws-sdk/client-s3, cleanup
loop that purges expired + exhausted blobs.
- web: @noble/ciphers sealFile/openFile, high-level sendCloud/receive
helpers, CloudSharePanel on Home, /r/:id receive page, /inbox page
for signed-in users (sent + received tabs).
- k8s: MinIO StatefulSet with bucket-init initContainer, S3 env vars
on the server Deployment (credentials pulled from minio-credentials
Secret).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>