End-to-end encrypted file sharing with burn-after-reading downloads. Pick a file, get a link — the recipient downloads it once and it's gone forever. Zero-knowledge architecture ensures the server never sees your plaintext or encryption keys.
Authenticated users can save capability URLs to their collection — links are automatically saved after upload and browsable in a paginated list view.
Read more on our Zero-Knowledge Encryption page.
Browser (encrypt) ──► Backend (presigned URLs) ──► Cloudflare R2 (encrypted bytes)
Browser (decrypt) ◄── Backend (fetch & delete) ◄── Cloudflare R2 (encrypted bytes)
Browser (save url) ──► Backend (Bearer auth) ──► MongoDB (saved_urls)
| Sub-project | Path | Language | Description |
|---|---|---|---|
| Backend API | backend/ |
Rust (Axum) | Presigned URL generation, multipart upload, burn-after-read download, health endpoint, user auth (JWT + bcrypt + MongoDB), saved URLs with Bearer token middleware |
| Frontend | frontend/ |
TypeScript (SvelteKit) | Upload UI, client-side encryption/decryption, capability URLs, zero-knowledge page, login/register with JWT auth, auto-save and paginated list view for saved URLs |
| Cleanup Worker | worker/cleanup-orphaned-uploads/ |
Rust (standalone) | Background job that aborts orphaned multipart uploads older than 6 hours, runs via Supercronic on a schedule |
Create a .env file in the project root (used by both backend and worker):
R2_ACCOUNT_ID=<cloudflare account id>
R2_ACCESS_KEY_ID=<r2 access key>
R2_SECRET_ACCESS_KEY=<r2 secret key>
R2_BUCKET=<bucket name>
Optionally set RUST_LOG=info for verbose logging.
For user account and saved URL features, also set:
MONGODB_URI=mongodb://localhost:27017
JWT_SECRET=<a random secret string for signing JWT tokens>
JWT_EXPIRY_MINS=5
Create a frontend/.env file:
PUBLIC_API_PREFIX=http://localhost:8000/v1
PUBLIC_PREFIX=http://localhost:5173
Terminal 1 — Backend:
cd backend
cargo run
# → http://0.0.0.0:8000
Terminal 2 — Frontend:
cd frontend
deno install
deno task dev
# → http://localhost:5173
Terminal 3 — Cleanup worker (run periodically):
cd worker/cleanup-orphaned-uploads
cargo run
# Scans R2, aborts orphaned uploads, then exits
| Service | Development URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend | http://localhost:8000 |
| Method | Path | Purpose |
|---|---|---|
| GET | /health |
Health check — returns {"status":"ok"} |
| POST | /v1/create-upload |
Initiate a multipart upload |
| POST | /v1/sign-parts |
Generate presigned URLs for part numbers (valid 1 hour) |
| POST | /v1/complete-upload |
Finalise multipart upload with ETags |
| POST | /v1/abort-upload |
Cancel an in-progress multipart upload |
| GET | /v1/f/:id |
Download encrypted blob and delete from R2 |
| PUT | /v1/check-file |
Check if a file still exists in storage (head_object) |
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/auth/register |
Create user account (returns JWT) |
| POST | /v1/auth/login |
Authenticate user (returns JWT) |
| Method | Path | Purpose | Auth |
|---|---|---|---|
| POST | /v1/urls |
Save a capability URL to the user's collection | Authorization: Bearer <token> |
| GET | /v1/urls |
List saved URLs with pagination (?page=&per_page=) |
Authorization: Bearer <token> |
| DELETE | /v1/delete |
Delete authenticated user's account | Authorization: Bearer <token> |
Protected endpoints use the require_auth middleware which validates the JWT before the request reaches the handler. Unauthenticated requests receive 401 Unauthorized.
For full request/response schemas and curl examples, see backend/README.md.
filez.zone supports optional user accounts for managing shared files. Accounts are protected with:
JWT_EXPIRY_MINS, default 5 minutes) for session managementThe backend serves auth endpoints at /v1/auth/register and /v1/auth/login. Account deletion is handled at DELETE /v1/delete with Bearer token authentication. The frontend provides login and registration pages at /login and /register.
Authenticated users automatically get their capability URLs saved after upload. Saved URLs can be browsed at /urls with pagination, copy-to-clipboard, and direct-open actions. Each saved URL is checked against storage to show an "Already used" badge when the file has been consumed by a burn-after-read download.
The project uses two authentication patterns:
| Route group | Paths | Auth pattern |
|---|---|---|
auth_routes |
/v1/auth/* |
Token in request body |
protected_routes |
/v1/urls |
Authorization: Bearer <token> header, validated by middleware |
The frontend auth store (src/lib/auth.svelte.ts) persists JWT tokens in localStorage with automatic expiry detection and reactive state via Svelte 5 runes. Protected API calls in src/lib/savedUrls.ts send the token via the Authorization: Bearer <token> header.
{base}/f/{uuid}#{url-safe-base64(key)}Learn more on the Zero-Knowledge Encryption page.
The project is designed for deployment on Koyeb. Each sub-project has its own Dockerfile:
| Component | Dockerfile | Koyeb Service Type | Notes |
|---|---|---|---|
| Backend | backend/Dockerfile |
Web Service | Uses tini as init, reads PORT from Koyeb, has /health endpoint |
| Frontend | frontend/Dockerfile |
Web Service | Uses tini as init, adapter-node bundles everything into build/, has /health endpoint |
| Cleanup Worker | worker/cleanup-orphaned-uploads/Dockerfile |
Worker | Uses Supercronic for in-container cron scheduling (*/30 * * * *) |
Key Koyeb environment variables for the frontend: ORIGIN=https://your-domain.com (to prevent host-header spoofing). Build args: PUBLIC_API_PREFIX=https://api.your-domain.com/v1.
We use OpenPanel, a self-hosted, cookieless analytics tool, to collect anonymous page view data. No cookies are set, no personal identifiers are collected, and users cannot be tracked across sessions. See our Privacy Policy for details.
# Backend (cargo-nextest) — 106 tests pass
cd backend && cargo nextest run
# Frontend (Vitest)
cd frontend && deno task test
# Cleanup Worker (cargo-nextest)
cd worker/cleanup-orphaned-uploads && cargo nextest run
MIT