const config = require('./config'); const express = require('express'); const fileUpload = require('express-fileupload'); const path = require('path'); const fs = require('fs'); const mime = require('mime-types') const app = express(); app.use(fileUpload()); app.set('view engine', 'ejs') app.get('/', (req, res) => { res.render('upload'); }); const isPathValid = (filename, filePath) => { if (!filename) { return false; } if (filename.indexOf('\0') !== -1 || filename.indexOf('%') !== -1 || filename.indexOf('/') !== -1 || filename.indexOf('..') !== -1) { return false; } if (filePath.indexOf(config.storagePath) !== 0) { return false; } return true; }; const getFileType = (filename) => { const extension = path.extname(filename).substring(1); let type = config.files.embed[extension]; if (!type) { type = config.files.other; } return type; }; app.get('/file/:filename', (req, res) => { const filename = req.params.filename; const filePath = path.join(config.storagePath, filename); const isValid = isPathValid(filename, filePath); if (!isValid) { res.status(400).send('Invalid input.'); return; } fs.access(filePath, fs.F_OK, (err) => { if (err) { res.status(404).send('File not found or is invalid.'); return; } const type = getFileType(filePath); const mimeType = mime.lookup(filePath); if (type === config.files.other) { res.contentType('text/plain'); res.sendFile(filePath); return; } else { res.render('file', { filename, fileType: type, fileUrl: `${config.url}/file/raw/${filename}`, mimeType }); return; } }); }); app.get('/file/raw/:filename', (req, res) => { const filename = req.params.filename; const filePath = path.join(config.storagePath, filename); const isValid = isPathValid(filename, filePath); if (!isValid) { res.status(400).send('Invalid input.'); return; } fs.access(filePath, fs.F_OK, (err) => { if (err) { res.status(404).send('File not found or is invalid.'); return; } const type = getFileType(filePath); const mimeType = mime.lookup(filePath); if (type === config.files.other) { res.contentType('text/plain'); } else { res.contentType(mimeType); } res.sendFile(filePath); }); }); app.post('/api/upload', (req, res) => { if (!req.files || Object.keys(req.files).length === 0) { return res.status(400).send('No files were uploaded.'); } const file = req.files.file; file.mv(`${config.storagePath}/${file.name}`, function(err) { if (err) return res.status(500).send(err); res.send('File uploaded!'); }); }); app.listen(config.server.port);