{ "$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." }, "allowDirectories": { "type": "boolean", "default": false, "description": "Autoriser le dépôt de dossiers (arborescence recréée sous dir)." }, "allowedMimeTypes": { "description": "Types MIME acceptés par cette cible. Absent => hérite du allowedMimeTypes global. Mêmes formes : \"all\", ou liste de types exacts et/ou jokers (\"image/*\", \"*/*\", \"*\").", "oneOf": [ { "const": "all" }, { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^(\\*|\\*/\\*|[^/*\\s]+/(\\*|[^/*\\s]+))$" } } ] }, "permissions":{ "type":"string", "default":"0666", "description": "Mode d'écriture sur le disque" } } } }, "maxFileSizeMb": { "type": "integer", "minimum": 1, "default": 512 }, "logLevel": { "enum": ["fatal", "error", "warn", "info", "debug", "trace", "silent"], "default": "info" }, "chunkPoolSize": { "type": "integer", "minimum": 1, "maximum": 256, "default": 30, "description": "Nombre max de requêtes de morceaux en vol, réparti par le navigateur entre les fichiers fragmentés actifs (1 fichier => tout le pool, N fichiers => une part chacun). Efficace surtout en HTTP/2." }, "webhooks": { "type": "array", "description": "Points de terminaison POST notifiés à chaque upload finalisé et/ou chaque échec d'upload.", "items": { "type": "object", "additionalProperties": false, "required": ["url"], "properties": { "url": { "type": "string", "format": "uri", "description": "URL HTTP(S) appelée en POST (corps JSON)." }, "events": { "type": "array", "items": { "enum": ["upload", "error"] }, "uniqueItems": true, "default": ["upload", "error"], "description": "Événements souscrits. Défaut : les deux." }, "headers": { "type": "object", "additionalProperties": { "type": "string" }, "description": "En-têtes ajoutés à chaque requête (auth du récepteur, etc.)." }, "secret": { "type": "string", "description": "Si présent : en-tête X-MediaDrop-Signature = sha256=HMAC-SHA256(corps brut)." }, "timeoutMs": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 5000, "description": "Délai d'attente par tentative." } } } }, "allowedMimeTypes": { "description": "\"all\", ou liste de types exacts et/ou jokers de préfixe (\"video/*\", \"*/*\", \"*\"). Absent => liste média par défaut.", "oneOf": [ { "const": "all" }, { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^(\\*|\\*/\\*|[^/*\\s]+/(\\*|[^/*\\s]+))$" } } ] }, "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 /.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"] } } } } }