const express = require('express'); const fs = require('fs'); const path = require('path'); const router = express.Router(); const fileUpload = require('express-fileupload'); const authMiddleware = require('../../../Middlewares/authMiddleware'); const { loggers } = require('winston'); const ncp = require('ncp'); const util = require('util'); const ncpAsync = util.promisify(ncp.ncp); const configFile = fs.readFileSync(path.join(__dirname, '../../../data', 'setup.json'), 'utf-8') const config = JSON.parse(configFile); const bodyParser = require('body-parser'); const crypto = require('crypto'); const os = require('os'); const { getUserData, getSetupData } = require('../../../Middlewares/watcherMiddleware'); const { logger, logRequestInfo, ErrorLogger, authLogger } = require('../../../config/logs'); let setupData = getSetupData(); let userData = getUserData(); router.use(bodyParser.json()); /** * @swagger * /dashboard/movefile?token={token}: * post: * security: * - bearerAuth: [] * tags: * - File * summary: Move file to a different folder * description: This route allows you to move a file to a different folder. It requires a valid JWT token in the Authorization header. * requestBody: * required: true * content: * application/json: * schema: * type: object * properties: * fileName: * type: string * description: The name of the file to be moved * folderName: * type: string * description: The name of the destination folder * parameters: * - in: header * name: Authorization * required: true * schema: * type: string * description: The JWT token of your account to have access * responses: * 200: * description: Success * content: * application/json: * schema: * type: object * properties: * message: * type: string * 400: * description: Bad Request * content: * application/json: * schema: * type: object * properties: * error: * type: string * 401: * description: Unauthorized * content: * application/json: * schema: * type: object * properties: * message: * type: string * 403: * description: Unauthorized directory access attempt * content: * application/json: * schema: * type: object * properties: * error: * type: string * 500: * description: Error moving the file * content: * application/json: * schema: * type: object * properties: * error: * type: string */ function authenticateToken(req, res, next) { let token = null; const authHeader = req.headers['authorization']; if (authHeader) { token = authHeader.split(' ')[1]; } else if (req.query.token) { token = req.query.token; } if (token == null) { if (req.user) { return next(); } else { return res.status(401).json({ message: 'Unauthorized' }); } } fs.readFile(path.join(__dirname, '../../../data', 'user.json'), 'utf8', (err, data) => { if (err) { console.error('Error reading user.js:', err); return res.status(401).json({ message: 'Unauthorized' }); } const users = JSON.parse(data); const user = users.find(u => u.token === token); if (user) { req.user = user; req.userData = user; next(); } else { return res.status(401).json({ message: 'Unauthorized' }); } }); } router.get('/', (req, res) => { res.status(400).json({ error: 'Bad Request. The request cannot be fulfilled due to bad syntax or missing parameters.' }); }); router.post('/', authenticateToken, async (req, res) => { console.log('MoveFile API - Raw request body:', req.body); console.log('MoveFile API - Request body keys:', Object.keys(req.body)); const fileName = req.body.fileName; const folderName = req.body.folderName; console.log('MoveFile API - Received data:', { fileName: fileName, folderName: folderName, typeOfFileName: typeof fileName, typeOfFolderName: typeof folderName, fileNameStringified: JSON.stringify(fileName), folderNameStringified: JSON.stringify(folderName), fullBody: req.body }); // Forcer la conversion en string si ce sont des objets let finalFileName = fileName; let finalFolderName = folderName; if (typeof fileName === 'object' && fileName !== null) { console.log('fileName is an object, attempting conversion:', fileName); finalFileName = String(fileName); console.log('Converted fileName to:', finalFileName, typeof finalFileName); } if (typeof folderName === 'object' && folderName !== null) { console.log('folderName is an object, attempting conversion:', folderName); finalFolderName = String(folderName); console.log('Converted folderName to:', finalFolderName, typeof finalFolderName); } if (!finalFileName || (typeof finalFileName === 'string' && finalFileName.trim() === '')) { return res.status(400).json({ error: 'No file selected for moving.' }); } // Vérifier que folderName est une chaîne de caractères if (finalFolderName && typeof finalFolderName !== 'string') { console.error('folderName is not a string after conversion:', finalFolderName, typeof finalFolderName); return res.status(400).json({ error: 'Invalid folder name format.' }); } try { const data = await fs.promises.readFile(path.join(__dirname, '../../../data', 'user.json'), 'utf-8'); const users = JSON.parse(data); const user = users.find(user => user.id === req.user.id); if (!user) { console.error('User not found in user.json'); return res.status(500).json({ error: 'Error moving the file.' }); } const userId = user.name; if (!finalFileName || !userId) { console.error('finalFileName or userId is undefined'); return res.status(500).json({ error: 'Error moving the file.' }); } const sourcePath = path.join('cdn-files', userId, finalFileName); let destinationDir; if (finalFolderName && finalFolderName.trim() !== '') { destinationDir = path.join('cdn-files', userId, finalFolderName); } else { destinationDir = path.join('cdn-files', userId); } const destinationPath = path.join(destinationDir, finalFileName); if (!destinationPath.startsWith(path.join('cdn-files', userId))) { return res.status(403).json({ error: 'Unauthorized: Cannot move file outside of user directory.' }); } const normalizedSourcePath = path.normalize(sourcePath); if (fs.existsSync(normalizedSourcePath)) { await fs.promises.access(destinationDir); await ncpAsync(normalizedSourcePath, destinationPath); await fs.promises.unlink(normalizedSourcePath); } else { return res.status(404).json({ error: 'File not found.' }); } res.status(200).json({ message: 'File moved successfully' }); } catch (err) { console.error(err); return res.status(500).json({ error: 'Error moving the file.' }); } }); router.post('/:folderName', authenticateToken, async (req, res) => { const fileName = req.body.fileName; let newFolderName = req.body.newFolderName; const oldFolderName = req.params.folderName; const userName = req.body.userName; if (newFolderName === 'root') { newFolderName = ''; } if (fileName === undefined || userName === undefined || oldFolderName === undefined || newFolderName === undefined) { console.error('fileName, userName, oldFolderName, or newFolderName is undefined'); return res.status(500).json({ error: 'Error moving the file.' }); } if (userName !== req.user.name) { return res.status(403).json({ error: 'Unauthorized: Cannot move files for other users.' }); } const userDir = path.join(process.cwd(), 'cdn-files', userName); const sourcePath = path.join(userDir, oldFolderName, fileName); const destinationDir = path.join(userDir, newFolderName); const destinationPath = path.join(destinationDir, fileName); if (!sourcePath.startsWith(userDir) || !destinationPath.startsWith(userDir)) { ErrorLogger.error('Unauthorized directory access attempt'); return res.status(403).json({ error: 'Unauthorized directory access attempt' }); } try { const normalizedSourcePath = path.normalize(sourcePath); if (fs.existsSync(normalizedSourcePath)) { await fs.promises.access(destinationDir, fs.constants.W_OK); await fs.promises.rename(normalizedSourcePath, destinationPath); } else { return res.status(404).json({ error: 'File not found.' }); } res.status(200).json({ message: 'File moved successfully', redirectTo: '/dpanel/dashboard' }); } catch (err) { console.error(err); return res.status(500).json({ error: 'Error moving the file.' }); } }); module.exports = router;