/** * Utilitaire pour scanner les fichiers avec ClamAV */ import { logger } from './logger.js'; const CLAMAV_API_URL = process.env.CLAMAV_API_URL || 'http://localhost:3023'; /** * Scanne un buffer avec ClamAV * @param {Buffer} buffer - Le buffer à scanner * @param {string} filename - Le nom du fichier (optionnel) * @returns {Promise<{clean: boolean, infected: boolean, viruses: string[]}>} */ export async function scanBuffer(buffer, filename = 'unknown') { try { const base64Data = buffer.toString('base64'); const response = await fetch(`${CLAMAV_API_URL}/api/scan/buffer`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ data: base64Data, filename: filename, }), }); if (!response.ok) { if (response.status === 503) { // ClamAV non disponible, on log mais on continue (mode dégradé) logger.warn('ClamAV service unavailable, skipping scan', { status: response.status, filename: filename, }); return { clean: true, infected: false, viruses: [] }; } const error = await response.json().catch(() => ({ message: 'Unknown error' })); throw new Error(`ClamAV scan failed: ${error.message || response.statusText}`); } const result = await response.json(); if (result.infected) { logger.warn('File infected by virus', { filename: filename, viruses: result.viruses, }); } return result; } catch (error) { // Si ClamAV n'est pas disponible, on log mais on continue (mode dégradé) if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch failed')) { logger.warn('ClamAV service unavailable, skipping scan', { error: error.message, filename: filename, }); return { clean: true, infected: false, viruses: [] }; } logger.error('ClamAV scan error', { error: error.message, filename: filename, }); throw error; } }