const express = require('express'); const fs = require('fs'); const path = require('path'); const multiparty = require('multiparty'); const router = express.Router(); const bcrypt = require('bcrypt'); // Limite de taille de fichier à 10 Go const MAX_FILE_SIZE = 10 * 1024 * 1024 * 1024; // 10 Go // Crée le dossier temporaire à la racine s'il n'existe pas const tempDir = path.join(process.cwd(), 'temp'); if (!fs.existsSync(tempDir)) { fs.mkdirSync(tempDir, { recursive: true }); } router.post('/', (req, res) => { const form = new multiparty.Form({ uploadDir: tempDir, maxFilesSize: MAX_FILE_SIZE, }); form.parse(req, async (err, fields, files) => { if (err) { console.error('Error parsing the file:', err); return res.status(400).send('Error during the file upload'); } if (!files.file || files.file.length === 0) { return res.status(400).send('No file uploaded'); } const file = files.file[0]; const targetFolder = fields.targetFolder ? fields.targetFolder[0] : ''; const isSharedFolder = fields.isSharedFolder ? fields.isSharedFolder[0] === 'true' : false; const ownerName = fields.ownerName ? fields.ownerName[0] : ''; // Construction du chemin cible avec le dossier spécifié let userName = req.user.name; // Si c'est un dossier partagé, utiliser le nom du propriétaire if (isSharedFolder && ownerName) { // Vérifier les permissions de collaboration const collaborationFilePath = path.join(__dirname, '../../../data', 'collaboration.json'); try { const collaborationData = JSON.parse(await fs.promises.readFile(collaborationFilePath, 'utf8')); const itemId = `folder-${targetFolder}`; const folderInfo = collaborationData.activeFiles[itemId]; // Vérifier si l'utilisateur a accès au dossier partagé if (!folderInfo || !folderInfo.isCollaborative || !folderInfo.activeUsers.some(u => u.id === req.user.id)) { return res.status(403).send('Accès refusé au dossier partagé'); } userName = ownerName; } catch (error) { console.error('Error checking collaboration permissions:', error); return res.status(500).send('Erreur lors de la vérification des permissions'); } } let userDir = path.join(process.cwd(), 'cdn-files', userName); if (targetFolder) { userDir = path.join(userDir, targetFolder); } const filename = fields.filename ? fields.filename[0] : file.originalFilename; const filePath = path.join(userDir, filename); // Récupérer les champs supplémentaires const expiryDate = fields.expiryDate ? fields.expiryDate[0] : ''; const password = fields.password ? fields.password[0] : ''; // Hasher le mot de passe si présent const saltRounds = 10; let hashedPassword = ''; if (password) { hashedPassword = await bcrypt.hash(password, saltRounds); } // Crée le répertoire s'il n'existe pas if (!fs.existsSync(userDir)) { fs.mkdirSync(userDir, { recursive: true }); } // Lecture en chunks pour plus de performances const readStream = fs.createReadStream(file.path, { highWaterMark: 1024 * 1024 }); const writeStream = fs.createWriteStream(filePath, { flags: 'a' }); readStream.pipe(writeStream); readStream.on('end', async () => { // Supprimer le fichier temporaire fs.unlinkSync(file.path); // Vérifier que le nom du fichier suit bien le format attendu const fileNamePattern = /^\d{8}_[A-Z0-9]{6}_.*$/; if (!fileNamePattern.test(filename)) { console.warn('Le fichier uploadé ne suit pas le format de nom sécurisé attendu:', filename); } // Mettre à jour file_info.json si password ou expiryDate présent if (expiryDate || password) { const fileInfo = { fileName: filename, expiryDate: expiryDate, password: hashedPassword, Id: req.user.id, path: filePath }; try { let data = []; const fileInfoPath = path.join(__dirname, '../../../data', 'file_info.json'); if (fs.existsSync(fileInfoPath)) { const existingData = await fs.promises.readFile(fileInfoPath, 'utf8'); data = JSON.parse(existingData); if (!Array.isArray(data)) { data = []; } } data.push(fileInfo); await fs.promises.writeFile(fileInfoPath, JSON.stringify(data, null, 2)); } catch (error) { console.error('Error updating file_info.json:', error); } } res.status(200).send({ message: 'File uploaded successfully.', filename: filename }); }); readStream.on('error', (err) => { console.error('Error reading the file:', err); // Nettoyer le fichier temporaire en cas d'erreur if (fs.existsSync(file.path)) { fs.unlinkSync(file.path); } res.status(500).send({ message: 'Error uploading file.' }); }); writeStream.on('error', (err) => { console.error('Error writing the file:', err); // Nettoyer le fichier temporaire en cas d'erreur if (fs.existsSync(file.path)) { fs.unlinkSync(file.path); } res.status(500).send({ message: 'Error uploading file.' }); }); }); }); module.exports = router;