mediaDrop/config.schema.json
Nicolas fe8bd26bb7 Initial commit: mediaDrop — serveur de dépôt de fichiers médias
Serveur TypeScript (Fastify 5) permettant de déposer des fichiers médias
dans des dossiers nommés, via une page web de glisser-déposer.

- Authentification OpenID Connect gérée côté serveur (Authorization Code +
  PKCE, client confidentiel, openid-client) ; session via cookie chiffré
  (@fastify/secure-session).
- Configuration dans un fichier JSON (schéma fourni) ; l'environnement ne
  porte que le pointeur MEDIADROP_CONFIG.
- Cibles de dépôt nommées : liste { name, label, dir }, sélection par
  ?target=, première cible par défaut.
- Upload multipart en streaming : nom de fichier dérivé côté serveur (pas
  de path traversal), liste blanche de types MIME, plafond de taille.
- TypeScript strict, ESLint + Prettier sans warning, 46 tests Vitest.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 23:06:53 +02:00

83 lines
2.8 KiB
JSON

{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://mediadrop.local/config.schema.json",
"title": "Configuration mediaDrop",
"type": "object",
"additionalProperties": false,
"required": ["publicUrl", "targets", "session", "oidc"],
"properties": {
"$schema": { "type": "string" },
"port": { "type": "integer", "minimum": 1, "maximum": 65535, "default": 3000 },
"host": { "type": "string", "default": "0.0.0.0" },
"publicUrl": {
"type": "string",
"format": "uri",
"description": "URL externe de base, ex. https://media.exemple.fr (sert à redirect_uri / post-logout)."
},
"targets": {
"type": "array",
"minItems": 1,
"description": "Dossiers nommés dans lesquels déposer. Le premier est la cible par défaut.",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name", "dir"],
"properties": {
"name": {
"type": "string",
"pattern": "^[A-Za-z0-9._-]+$",
"description": "Identifiant transmis par le client (?target=...)."
},
"label": { "type": "string", "description": "Libellé affiché (défaut : name)." },
"dir": { "type": "string", "description": "Chemin du dossier de destination." }
}
}
},
"maxFileSizeMb": { "type": "integer", "minimum": 1, "default": 512 },
"logLevel": {
"enum": ["fatal", "error", "warn", "info", "debug", "trace", "silent"],
"default": "info"
},
"allowedMimeTypes": {
"description": "Liste blanche de types MIME, ou \"all\". Absent => liste média par défaut.",
"oneOf": [
{ "const": "all" },
{ "type": "array", "items": { "type": "string" }, "minItems": 1 }
]
},
"session": {
"type": "object",
"additionalProperties": false,
"required": ["key"],
"properties": {
"key": {
"type": "string",
"description": "32 octets encodés en base64. Générer avec : openssl rand -base64 32"
},
"maxAgeHours": { "type": "number", "exclusiveMinimum": 0, "default": 12 }
}
},
"oidc": {
"type": "object",
"additionalProperties": false,
"required": ["issuer", "clientId", "clientSecret"],
"properties": {
"issuer": {
"type": "string",
"format": "uri",
"description": "Issuer OIDC (le serveur lit <issuer>/.well-known/openid-configuration)."
},
"clientId": { "type": "string" },
"clientSecret": {
"type": "string",
"description": "Secret du client confidentiel déclaré côté fournisseur."
},
"scopes": {
"type": "array",
"items": { "type": "string" },
"default": ["openid", "profile", "email"]
}
}
}
}
}