Skip to content

feat: Add 'Store for Later' async file transfer mode - #45

Open
lucamartinetti wants to merge 1 commit into
mainfrom
feat/store-mode
Open

feat: Add 'Store for Later' async file transfer mode#45
lucamartinetti wants to merge 1 commit into
mainfrom
feat/store-mode

Conversation

@lucamartinetti

Copy link
Copy Markdown
Owner

Summary

Adds a new "Store for Later" mode for async file transfers. Senders can upload E2E encrypted files to S3-compatible storage and share them via passphrase or QR code link. Recipients can download anytime within 24 hours.

Changes

Backend (Rust/Axum):

  • New S3-compatible storage integration (aws-sdk-s3)
  • Endpoints: POST /api/store/{blob_id}, GET /api/store/{blob_id}, GET /api/store/{blob_id}/meta
  • Sliding window rate limiting: 10 uploads/hour, 60 reads/hour per IP
  • Hourly cleanup task for expired blobs (24h TTL)
  • Configurable via env vars: S3_ENDPOINT, S3_BUCKET, S3_REGION, STORE_MAX_SIZE, STORE_TTL_HOURS

Frontend (Vanilla JS):

  • New "Store for Later" tab in UI
  • Browser-side encryption using age-encryption
  • 4-word diceware passphrase generation (EFF wordlist)
  • QR code generation for shareable links
  • Blob ID derivation via SHA-256(passphrase)

Configuration

Requires S3-compatible storage:

S3_ENDPOINT=https://...
S3_BUCKET=...
S3_REGION=auto
STORE_MAX_SIZE=104857600  # 100MB default
STORE_TTL_HOURS=24

Known Issues

  • Rate limiter uses in-memory HashMap (won't work across multiple Fly.io instances). Will need Redis for distributed deployments.

Testing

Manual testing recommended:

  1. Upload a file via Store mode
  2. Share passphrase or QR link
  3. Verify download works
  4. Verify 24h expiry

- Backend: S3-compatible storage with aws-sdk-s3
- Endpoints: POST/GET /api/store/{blob_id}, GET /api/store/{blob_id}/meta
- Rate limiting: 10 uploads/hour, 60 reads/hour per IP (in-memory)
- Hourly cleanup task for expired blobs (24h TTL)
- Frontend: New 'Store for Later' tab with age-encryption
- 4-word diceware passphrase generation (EFF wordlist)
- QR code generation for shareable links
- Blob ID derived via SHA-256(passphrase)

Config: S3_ENDPOINT, S3_BUCKET, S3_REGION, STORE_MAX_SIZE, STORE_TTL_HOURS

Known: Rate limiter is in-memory (needs Redis for multi-instance)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant