Dépôt de dossiers : - flag `allowDirectories` (défaut false) par cible dans config.json + schéma. - POST /upload accepte `?path=<chemin relatif>` : l'arborescence est recréée sous `dir`, nom d'origine conservé, fichier écrasé si présent. - src/lib/paths.ts : assainissement segment par segment (pas de `..`, pas de séparateur) + vérification de confinement dans storage.ts -> aucune sortie possible de la cible. Refus 400 si la cible n'autorise pas les dossiers. - GET /targets expose `allowDirectories`. - Page : glisser-déposer d'un dossier (parcours récursif webkitGetAsEntry) + bouton « parcourir un dossier », visibles selon la cible. Très gros fichiers (~10 Go) : - `requestTimeout: 0` / `connectionTimeout: 0` : aucun timeout serveur imposé. - écriture disque avec un tampon de 1 Mio. - doc : `maxFileSizeMb` à l'échelle Go, réglages reverse proxy. Tests : +paths.test.ts, +placement (storage), +dossier & gros fichier (upload) ; 60 tests. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
23 lines
761 B
JSON
23 lines
761 B
JSON
{
|
|
"$schema": "./config.schema.json",
|
|
"port": 3000,
|
|
"host": "0.0.0.0",
|
|
"publicUrl": "http://localhost:3000",
|
|
"targets": [
|
|
{ "name": "photos", "label": "Photos", "dir": "./uploads/photos" },
|
|
{ "name": "videos", "label": "Vidéos", "dir": "./uploads/videos", "allowDirectories": true }
|
|
],
|
|
"maxFileSizeMb": 512,
|
|
"logLevel": "info",
|
|
"allowedMimeTypes": ["image/jpeg", "image/png", "image/webp", "video/mp4", "audio/mpeg"],
|
|
"session": {
|
|
"key": "REMPLACER_PAR_32_OCTETS_BASE64_openssl_rand_base64_32",
|
|
"maxAgeHours": 12
|
|
},
|
|
"oidc": {
|
|
"issuer": "https://auth.exemple.fr/realms/mon-realm",
|
|
"clientId": "mediadrop",
|
|
"clientSecret": "REMPLACER_PAR_LE_SECRET_DU_CLIENT",
|
|
"scopes": ["openid", "profile", "email"]
|
|
}
|
|
}
|