import path from 'path' /** * Validiert und normalisiert einen Dateinamen, um Path-Traversal zu verhindern * @param {string} filename - Der zu validierende Dateiname * @param {string[]} allowedExtensions - Erlaubte Dateiendungen (z.B. ['.jpg', '.png']) * @returns {string} - Der validierte Dateiname * @throws {Error} - Wenn der Dateiname ungültig ist */ export function sanitizeFilename(filename, allowedExtensions = []) { if (!filename || typeof filename !== 'string') { throw new Error('Ungültiger Dateiname') } // Entferne Path-Traversal-Versuche const normalized = path.normalize(filename) // Prüfe auf Path-Traversal (.., /, \) if (normalized.includes('..') || normalized.startsWith('/') || normalized.startsWith('\\')) { throw new Error('Ungültiger Dateiname: Path-Traversal erkannt') } // Extrahiere nur den Dateinamen (ohne Pfad) const basename = path.basename(normalized) // Prüfe auf leeren Dateinamen if (!basename || basename === '.' || basename === '..') { throw new Error('Ungültiger Dateiname') } // Prüfe Dateiendung falls angegeben if (allowedExtensions.length > 0) { const ext = path.extname(basename).toLowerCase() if (!allowedExtensions.includes(ext)) { throw new Error(`Ungültige Dateiendung. Erlaubt: ${allowedExtensions.join(', ')}`) } } return basename } /** * Validiert eine UUID * @param {string} id - Die zu validierende ID * @returns {boolean} - True wenn gültige UUID */ export function isValidUUID(id) { if (!id || typeof id !== 'string') { return false } const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i return uuidRegex.test(id) } /** * Validiert einen Dateinamen mit UUID-Präfix * @param {string} filename - Der zu validierende Dateiname * @param {string[]} allowedExtensions - Erlaubte Dateiendungen * @returns {boolean} - True wenn gültig */ export function isValidUUIDFilename(filename, allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp']) { if (!filename || typeof filename !== 'string') { return false } const ext = path.extname(filename).toLowerCase() if (allowedExtensions.length > 0 && !allowedExtensions.includes(ext)) { return false } const basename = path.basename(filename, ext) const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i return uuidRegex.test(basename) }