From 1b3b45b348179e36d8e0b376d241953bdbe1bcee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=C3=AFs=20Saraiva?= <53227802+Kisakay@users.noreply.github.com> Date: Tue, 25 Aug 2026 12:32:54 +0200 Subject: [PATCH] fix --- README.md | 81 +++++++++++----------- backend/src/routes/auth.rs | 14 ++-- frontend/index.html | 11 ++- frontend/src/App.svelte | 61 +++++++++++++--- frontend/src/app.css | 34 ++++++++- frontend/src/components/Dropzone.svelte | 6 +- frontend/src/components/FileList.svelte | 16 ++--- frontend/src/components/FileRow.svelte | 8 +-- frontend/src/components/ResultPanel.svelte | 2 +- frontend/src/lib/theme.js | 20 ++++++ frontend/tailwind.config.js | 21 +++--- scripts/build.sh | 14 ++-- 12 files changed, 193 insertions(+), 95 deletions(-) create mode 100644 frontend/src/lib/theme.js diff --git a/README.md b/README.md index 574ad5c..b7155e6 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,83 @@ # File Drop -Un hébergeur de fichiers privé, auto-hébergé et minimal. On dépose un fichier, -on reçoit un lien secret et intraçable. Les images, vidéos et sons s'affichent -directement dans le navigateur ; les autres fichiers se téléchargent. +A minimal, self-hosted private file host. Drop a file, get a secret, +unguessable link. Images, videos and audio render directly in the browser; +everything else downloads. - **Backend** — Rust (Axum + Tokio) - **Frontend** — Svelte (Vite + Tailwind) -- **Stockage** — système de fichiers local, sans base de données +- **Storage** — local filesystem, no database -## Démarrage rapide +## Quick start ```bash -# 1. Construire le frontend (produit frontend/dist) +# 1. Build the frontend (outputs frontend/dist) cd frontend npm install npm run build cd .. -# 2. Lancer le serveur (depuis la racine du projet) +# 2. Run the server (from the project root) cargo run --release --manifest-path backend/Cargo.toml ``` -Ouvrir ensuite http://localhost:3000. +Then open http://localhost:3000. -> Les chemins `STORAGE_DIR` et `STATIC_DIR` sont relatifs au dossier de -> lancement. Lance donc le serveur depuis la racine du projet (ou règle ces -> variables en absolu dans `.env`). +> `STORAGE_DIR` and `STATIC_DIR` are relative to where you run the server. +> Run it from the project root, or set absolute paths in `.env`. ## Configuration -Copier `backend/.env.example` vers `.env` puis l'adapter. +Copy `backend/.env.example` to `.env` and edit it. -| Variable | Défaut | Rôle | -| ---------------------- | ----------------- | ----------------------------------------- | -| `HOST` / `PORT` | `0.0.0.0` / `3000`| Adresse d'écoute. | -| `STORAGE_DIR` | `./storage` | Dossier des fichiers et métadonnées. | -| `STATIC_DIR` | `./frontend/dist` | Dossier du frontend construit. | -| `MAX_FILE_SIZE` | `10GB` | Taille maximale d'envoi. | -| `FILE_TTL_MS` | `172800000` | Durée de vie d'un fichier (48 h max). | -| `KEY_LENGTH` | `8` | Longueur de la clé de partage (`a-z0-9`). | -| `PUBLIC_BASE_URL` | — | URL publique pour les liens absolus. | -| `RATE_LIMIT_ENABLED` | `1` | Limite de requêtes par IP. | -| `RATE_LIMIT_MAX` | `300` | Requêtes max par fenêtre. | -| `RATE_LIMIT_WINDOW_MS` | `60000` | Fenêtre en millisecondes. | -| `TRUST_PROXY` | `0` | Activer derrière un proxy (`X-Forwarded-For`). | +| Variable | Default | Description | +| ---------------------- | ----------------- | ---------------------------------------------- | +| `HOST` / `PORT` | `0.0.0.0` / `3000`| Bind address. | +| `STORAGE_DIR` | `./storage` | Files and metadata directory. | +| `STATIC_DIR` | `./frontend/dist` | Built frontend directory. | +| `MAX_FILE_SIZE` | `10GB` | Maximum upload size. | +| `FILE_TTL_MS` | `172800000` | File lifetime (48 h max). | +| `KEY_LENGTH` | `8` | Share key length (`a-z0-9`). | +| `PUBLIC_BASE_URL` | — | Public URL for absolute links. | +| `RATE_LIMIT_ENABLED` | `1` | Per-IP rate limiting. | +| `RATE_LIMIT_MAX` | `300` | Max requests per window. | +| `RATE_LIMIT_WINDOW_MS` | `60000` | Window in milliseconds. | +| `TRUST_PROXY` | `0` | Enable behind a proxy (`X-Forwarded-For`). | ## API -| Méthode | Route | Rôle | -| --------- | -------------------- | ------------------------------------------- | -| `POST` | `/api/upload` | Envoi d'un fichier (`multipart/form-data`). | -| `GET` | `/:key` | Téléchargement (inline pour les médias). | -| `POST` | `/api/auth/:key` | Mot de passe d'un fichier protégé. | -| `DELETE` | `/api/files/:id` | Suppression (en-tête `X-Delete-Key`). | -| `GET` | `/api/health` | État du service. | +| Method | Route | Description | +| -------- | ------------------ | --------------------------------------------- | +| `POST` | `/api/upload` | Upload a file (`multipart/form-data`). | +| `GET` | `/:key` | Download (inline for media). | +| `POST` | `/api/auth/:key` | Submit the password for a protected file. | +| `DELETE` | `/api/files/:id` | Delete a file (`X-Delete-Key` header). | +| `GET` | `/api/health` | Service status. | -Exemple : +Example: ```bash curl -F "file=@photo.png" http://localhost:3000/api/upload ``` -Le lien renvoyé est de la forme `http://localhost:3000/.png`. Ajouter -`?dl=1` force le téléchargement au lieu de l'affichage. +The returned link looks like `http://localhost:3000/.png`. Append `?dl=1` +to force a download instead of inline display. ## Structure ``` -backend/ serveur Rust (Axum) -frontend/ interface Svelte (Vite + Tailwind) +backend/ Rust server (Axum) +frontend/ Svelte interface (Vite + Tailwind) scripts/ tests -storage/ données (généré au premier lancement) +storage/ data (created on first run) ``` ## Tests ```bash -cargo build # dans backend/ +cargo build # in backend/ bash scripts/e2e-test.sh ``` -Le test couvre l'envoi, le téléchargement, l'authentification par mot de passe, -les clés invalides, la sanitisation des noms et la suppression. +The test covers upload, download, password auth, invalid keys, name +sanitization and deletion. diff --git a/backend/src/routes/auth.rs b/backend/src/routes/auth.rs index 7b27177..d3491bb 100644 --- a/backend/src/routes/auth.rs +++ b/backend/src/routes/auth.rs @@ -106,19 +106,19 @@ pub async fn auth( pub fn render_password_form(key: &str, filename: &str, error: bool) -> Response { let message = if error { - "

Mot de passe incorrect. Réessayez.

" + "

Incorrect password. Please try again.

" } else { "" }; let safe_filename = escape_html(filename); let html = format!( r#" - + - Fichier protégé + Protected file