mediaDrop/src/lib/media-types.ts
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

58 lines
1.6 KiB
TypeScript

/**
* Liste blanche des types de médias acceptés et correspondance type MIME -> extension.
*
* Note : le type MIME utilisé ici est celui *annoncé par le client*. Il n'est pas
* vérifié via les octets de signature du fichier (voir README, section durcissement).
*/
/** Types MIME autorisés par défaut lorsque `ALLOWED_MIME_TYPES` n'est pas défini. */
export const DEFAULT_ALLOWED_MIME: readonly string[] = [
'image/jpeg',
'image/png',
'image/gif',
'image/webp',
'image/avif',
'video/mp4',
'video/webm',
'video/quicktime',
'audio/mpeg',
'audio/ogg',
'audio/wav',
'audio/flac',
'audio/mp4',
];
const MIME_TO_EXTENSION: Readonly<Record<string, string>> = {
'image/jpeg': '.jpg',
'image/png': '.png',
'image/gif': '.gif',
'image/webp': '.webp',
'image/avif': '.avif',
'video/mp4': '.mp4',
'video/webm': '.webm',
'video/quicktime': '.mov',
'audio/mpeg': '.mp3',
'audio/ogg': '.ogg',
'audio/wav': '.wav',
'audio/flac': '.flac',
'audio/mp4': '.m4a',
};
/** Politique de filtrage : une liste blanche explicite, ou `'all'` pour tout accepter. */
export type MimePolicy = readonly string[] | 'all';
/** Indique si un type MIME est accepté selon la politique fournie. */
export function isAllowedMedia(mimeType: string, policy: MimePolicy): boolean {
if (policy === 'all') {
return true;
}
return policy.includes(mimeType);
}
/**
* Extension de fichier sûre pour un type MIME connu.
* Renvoie `null` si le type n'est pas répertorié (l'appelant choisit un repli).
*/
export function extensionForMime(mimeType: string): string | null {
return MIME_TO_EXTENSION[mimeType] ?? null;
}