import { buildStoragePath } from '@/lib/minio'; import { MIME_TO_EXT } from '@/lib/constants/file-validation'; export function generateStorageKey( portSlug: string, entity: string, entityId: string, mimeType: string, ): string { const fileId = crypto.randomUUID(); const extension = MIME_TO_EXT[mimeType] ?? 'bin'; return buildStoragePath(portSlug, entity, entityId, fileId, extension); } export function sanitizeFilename(name: string): string { return ( name .normalize('NFC') .replace(/[/\\:]/g, '') // strip path chars .replace(/\x00/g, '') // strip null bytes .replace(/[\x01-\x1f\x7f]/g, '') // strip control chars // asset-auditor M2: strip Unicode bidi-control + zero-width // characters that enable the classic Windows-icon spoof // (`invoice_‮fdp.exe` renders as `invoice_exe.pdf`) and folder- // listing collision spoofs (U+200B/U+FEFF). .replace(/[​-‏‪-‮⁦-⁩]/g, '') .trim() .slice(0, 255) ); }