This commit is contained in:
@@ -6,10 +6,13 @@ const fsStandard = require('fs');
|
||||
const mime = require('mime-types');
|
||||
const { logger, ErrorLogger } = require('../config/logs');
|
||||
const bcrypt = require('bcrypt');
|
||||
const saltRounds = 10;
|
||||
|
||||
const compression = require('compression');
|
||||
const { pipeline } = require('stream/promises'); // Utilisation du pipeline moderne
|
||||
const baseDir = 'cdn-files';
|
||||
|
||||
// Middleware de compression gzip
|
||||
router.use(compression());
|
||||
|
||||
async function getSamAccountNameFromUserId(userId) {
|
||||
const data = await fs.readFile(path.join(__dirname, '../data', 'user.json'), 'utf8');
|
||||
const users = JSON.parse(data);
|
||||
@@ -60,27 +63,14 @@ router.get('/:userId/:filename', async (req, res) => {
|
||||
|
||||
try {
|
||||
const filePath = await findFileInUserDir(userId, filename);
|
||||
|
||||
if (!filePath) {
|
||||
return res.render('file-not-found');
|
||||
}
|
||||
|
||||
const data = await fs.readFile(path.join(__dirname, '../data', 'file_info.json'), 'utf8');
|
||||
let fileInfoArray;
|
||||
try {
|
||||
fileInfoArray = JSON.parse(data);
|
||||
} catch (error) {
|
||||
console.error('Error parsing file_info.json:', error);
|
||||
return res.status(500).send('Error reading file info.');
|
||||
}
|
||||
|
||||
if (!Array.isArray(fileInfoArray)) {
|
||||
console.error('fileInfoArray is not an array');
|
||||
return res.status(500).send('Invalid file info format.');
|
||||
}
|
||||
const fileInfoArray = JSON.parse(data);
|
||||
|
||||
const fileInfo = fileInfoArray.find(info => info.fileName === filename && info.Id === userId);
|
||||
|
||||
if (fileInfo) {
|
||||
const expiryDate = new Date(fileInfo.expiryDate);
|
||||
const now = new Date();
|
||||
@@ -95,18 +85,41 @@ router.get('/:userId/:filename', async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
const readStream = fsStandard.createReadStream(filePath);
|
||||
let mimeType = mime.lookup(filePath) || 'application/octet-stream';
|
||||
const mimeType = mime.lookup(filePath) || 'application/octet-stream';
|
||||
const range = req.headers.range;
|
||||
const stats = await fs.stat(filePath);
|
||||
const fileSize = stats.size;
|
||||
|
||||
res.setHeader('Content-Type', mimeType);
|
||||
readStream.pipe(res);
|
||||
if (range) {
|
||||
const [start, end] = range.replace(/bytes=/, '').split('-');
|
||||
const chunkStart = parseInt(start, 10);
|
||||
const chunkEnd = end ? parseInt(end, 10) : fileSize - 1;
|
||||
|
||||
if (fileInfo) {
|
||||
req.session.passwordVerified = false;
|
||||
if (chunkStart >= fileSize || chunkEnd >= fileSize) {
|
||||
res.setHeader('Content-Range', `bytes */${fileSize}`);
|
||||
return res.status(416).send('Requested Range Not Satisfiable');
|
||||
}
|
||||
|
||||
res.status(206);
|
||||
res.setHeader('Content-Range', `bytes ${chunkStart}-${chunkEnd}/${fileSize}`);
|
||||
res.setHeader('Accept-Ranges', 'bytes');
|
||||
res.setHeader('Content-Length', chunkEnd - chunkStart + 1);
|
||||
res.setHeader('Content-Type', mimeType);
|
||||
|
||||
const readStream = fsStandard.createReadStream(filePath, { start: chunkStart, end: chunkEnd });
|
||||
await pipeline(readStream, res); // Utilisation de pipeline avec await pour éviter les erreurs
|
||||
} else {
|
||||
res.setHeader('Content-Length', fileSize);
|
||||
res.setHeader('Content-Type', mimeType);
|
||||
|
||||
const readStream = fsStandard.createReadStream(filePath);
|
||||
await pipeline(readStream, res);
|
||||
}
|
||||
} catch (err) {
|
||||
ErrorLogger.error('Error reading file:', err);
|
||||
return res.status(500).send('Error reading file.');
|
||||
ErrorLogger.error('Error handling request:', err);
|
||||
if (!res.headersSent) {
|
||||
res.status(500).send('Error reading file.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -116,18 +129,7 @@ router.post('/:userId/:filename', async (req, res) => {
|
||||
|
||||
try {
|
||||
const data = await fs.readFile(path.join(__dirname, '../data', 'file_info.json'), 'utf8');
|
||||
let fileInfoArray;
|
||||
try {
|
||||
fileInfoArray = JSON.parse(data);
|
||||
} catch (error) {
|
||||
console.error('Error parsing file_info.json:', error);
|
||||
return res.status(500).send('Error reading file info.');
|
||||
}
|
||||
|
||||
if (!Array.isArray(fileInfoArray)) {
|
||||
console.error('fileInfoArray is not an array');
|
||||
return res.status(500).send('Invalid file info format.');
|
||||
}
|
||||
const fileInfoArray = JSON.parse(data);
|
||||
|
||||
const fileInfo = fileInfoArray.find(info => info.fileName === filename && info.Id === userId);
|
||||
|
||||
@@ -138,81 +140,26 @@ router.post('/:userId/:filename', async (req, res) => {
|
||||
const passwordMatch = await bcrypt.compare(enteredPassword, fileInfo.password);
|
||||
if (passwordMatch) {
|
||||
req.session.passwordVerified = true;
|
||||
|
||||
const filePath = await findFileInUserDir(userId, filename);
|
||||
const mimeType = mime.lookup(filePath) || 'application/octet-stream';
|
||||
const readStream = fsStandard.createReadStream(filePath);
|
||||
let mimeType = mime.lookup(filePath) || 'application/octet-stream';
|
||||
|
||||
let fileContent = '';
|
||||
readStream.on('data', chunk => {
|
||||
for await (const chunk of readStream) {
|
||||
fileContent += chunk.toString('base64');
|
||||
});
|
||||
}
|
||||
|
||||
readStream.on('end', () => {
|
||||
res.json({ success: true, fileContent, mimeType });
|
||||
});
|
||||
res.json({ success: true, fileContent, mimeType });
|
||||
} else {
|
||||
res.json({ success: false, message: 'Incorrect password' });
|
||||
}
|
||||
} catch (err) {
|
||||
ErrorLogger.error('Error reading file:', err);
|
||||
return res.status(500).send('Error reading file.');
|
||||
if (!res.headersSent) {
|
||||
res.status(500).send('Error reading file.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function deleteExpiredFiles() {
|
||||
let data;
|
||||
try {
|
||||
data = await fs.readFile(path.join(__dirname, '../data', 'file_info.json'), 'utf8');
|
||||
} catch (error) {
|
||||
console.error('Error reading file_info.json:', error);
|
||||
return;
|
||||
}
|
||||
|
||||
let fileInfoArray;
|
||||
try {
|
||||
fileInfoArray = JSON.parse(data);
|
||||
} catch (error) {
|
||||
console.error('Error parsing file_info.json:', error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(fileInfoArray)) {
|
||||
console.error('fileInfoArray is not an array');
|
||||
return;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
let newFileInfoArray = [];
|
||||
|
||||
for (const fileInfo of fileInfoArray) {
|
||||
let expiryDate;
|
||||
if (fileInfo.expiryDate && fileInfo.expiryDate.trim() !== '') {
|
||||
expiryDate = new Date(fileInfo.expiryDate);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (expiryDate < now) {
|
||||
try {
|
||||
const samaccountname = await getSamAccountNameFromUserId(fileInfo.userId);
|
||||
const userDir = path.join(baseDir, samaccountname);
|
||||
const filePath = path.join(userDir, fileInfo.fileName);
|
||||
await fs.unlink(filePath);
|
||||
} catch (err) {
|
||||
ErrorLogger.error('Error deleting file:', err);
|
||||
}
|
||||
} else {
|
||||
newFileInfoArray.push(fileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await fs.writeFile(path.join(__dirname, '../data', 'file_info.json'), JSON.stringify(newFileInfoArray, null, 2), 'utf8');
|
||||
} catch (err) {
|
||||
ErrorLogger.error('Error writing to file_info.json:', err);
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(deleteExpiredFiles, 24 * 60 * 60 * 1000);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user