All checks were successful
continuous-integration/drone/push Build is passing
We would like to apologize for the inconvenience caused and we would like to thank you for the quick report.
219 lines
6.8 KiB
JavaScript
219 lines
6.8 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const path = require('path');
|
|
const fs = require('fs').promises;
|
|
const fsStandard = require('fs');
|
|
const mime = require('mime-types');
|
|
const { logger, ErrorLogger } = require('../config/logs');
|
|
const bcrypt = require('bcrypt');
|
|
const saltRounds = 10;
|
|
|
|
const baseDir = 'cdn-files';
|
|
|
|
async function getSamAccountNameFromUserId(userId) {
|
|
const data = await fs.readFile(path.join(__dirname, '../data', 'user.json'), 'utf8');
|
|
const users = JSON.parse(data);
|
|
const user = users.find(user => user.id === userId);
|
|
if (user) {
|
|
return user.name;
|
|
} else {
|
|
throw new Error('User not found');
|
|
}
|
|
}
|
|
|
|
async function findFileInUserDir(userId, filename) {
|
|
const samaccountname = await getSamAccountNameFromUserId(userId);
|
|
const userDir = path.join(baseDir, samaccountname);
|
|
return findFileInDir(userDir, filename);
|
|
}
|
|
|
|
async function findFileInDir(dir, filename) {
|
|
let files;
|
|
try {
|
|
files = await fs.readdir(dir, { withFileTypes: true });
|
|
} catch (err) {
|
|
return null; // Directory does not exist
|
|
}
|
|
|
|
for (const file of files) {
|
|
const filePath = path.join(dir, file.name);
|
|
|
|
if (file.name === filename && file.isFile()) {
|
|
return filePath;
|
|
} else if (file.isDirectory()) {
|
|
const found = await findFileInDir(filePath, filename);
|
|
if (found) {
|
|
return found;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
router.get('/:userId', (req, res) => {
|
|
res.render('unauthorized');
|
|
});
|
|
|
|
router.get('/:userId/:filename', async (req, res) => {
|
|
const { userId, filename } = req.params;
|
|
|
|
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 fileInfo = fileInfoArray.find(info => info.fileName === filename && info.Id === userId);
|
|
|
|
if (fileInfo) {
|
|
const expiryDate = new Date(fileInfo.expiryDate);
|
|
const now = new Date();
|
|
|
|
if (expiryDate < now) {
|
|
await fs.unlink(filePath);
|
|
return res.render('file-expired');
|
|
}
|
|
|
|
if (fileInfo.password && !req.session.passwordVerified) {
|
|
return res.render('password-check', { userId, filename });
|
|
}
|
|
}
|
|
|
|
const readStream = fsStandard.createReadStream(filePath);
|
|
let mimeType = mime.lookup(filePath) || 'application/octet-stream';
|
|
|
|
res.setHeader('Content-Type', mimeType);
|
|
readStream.pipe(res);
|
|
|
|
if (fileInfo) {
|
|
req.session.passwordVerified = false;
|
|
}
|
|
} catch (err) {
|
|
ErrorLogger.error('Error reading file:', err);
|
|
return res.status(500).send('Error reading file.');
|
|
}
|
|
});
|
|
|
|
router.post('/:userId/:filename', async (req, res) => {
|
|
const { userId, filename } = req.params;
|
|
const enteredPassword = req.body.password;
|
|
|
|
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 fileInfo = fileInfoArray.find(info => info.fileName === filename && info.Id === userId);
|
|
|
|
if (!fileInfo) {
|
|
return res.json({ success: false, message: 'File not found' });
|
|
}
|
|
|
|
const passwordMatch = await bcrypt.compare(enteredPassword, fileInfo.password);
|
|
if (passwordMatch) {
|
|
req.session.passwordVerified = true;
|
|
const filePath = await findFileInUserDir(userId, filename);
|
|
const readStream = fsStandard.createReadStream(filePath);
|
|
let mimeType = mime.lookup(filePath) || 'application/octet-stream';
|
|
|
|
let fileContent = '';
|
|
readStream.on('data', chunk => {
|
|
fileContent += chunk.toString('base64');
|
|
});
|
|
|
|
readStream.on('end', () => {
|
|
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.');
|
|
}
|
|
});
|
|
|
|
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;
|