v3.0.0/src/api/routes/uploads/uploadPOST.js

155 lines
4.5 KiB
JavaScript
Raw Normal View History

2019-10-01 19:11:16 +02:00
const Route = require('../../structures/Route');
const path = require('path');
const Util = require('../../utils/Util');
const jetpack = require('fs-jetpack');
const multer = require('multer');
2019-10-12 07:37:09 +02:00
const moment = require('moment');
2019-10-01 19:11:16 +02:00
const upload = multer({
storage: multer.memoryStorage(),
limits: {
fileSize: parseInt(process.env.MAX_SIZE, 10) * (1000 * 1000),
files: 1
},
fileFilter: (req, file, cb) => {
/*
if (options.blacklist.mimes.includes(file.mimetype)) {
return cb(new Error(`${file.mimetype} is a blacklisted filetype.`));
} else if (options.blacklist.extensions.some(ext => path.extname(file.originalname).toLowerCase() === ext)) {
return cb(new Error(`${path.extname(file.originalname).toLowerCase()} is a blacklisted extension.`));
}
*/
return cb(null, true);
}
}).array('files[]');
class uploadPOST extends Route {
constructor() {
super('/upload', 'post', { bypassAuth: true });
}
async run(req, res, db) {
const user = await Util.isAuthorized(req);
if (!user && process.env.PUBLIC_MODE == 'false') return res.status(401).json({ message: 'Not authorized to use this resource' });
2019-10-12 07:37:09 +02:00
2019-10-01 19:11:16 +02:00
return upload(req, res, async err => {
if (err) console.error(err.message);
2019-10-12 07:37:09 +02:00
const albumId = req.body.albumid || req.headers.albumid;
if (albumId && !user) return res.status(401).json({ message: 'Only registered users can upload files to an album' });
if (albumId && user) {
const album = await db.table('albums').where({ id: albumId, userId: user.id }).first();
if (!album) return res.status(401).json({ message: 'Album doesn\'t exist or it doesn\'t belong to the user' });
}
2019-10-01 19:11:16 +02:00
let uploadedFile = {};
2019-10-12 07:37:09 +02:00
let originalFile;
let insertedId;
const remappedKeys = this._remapKeys(req.body);
2019-10-01 19:11:16 +02:00
for (const file of req.files) {
2019-10-12 07:37:09 +02:00
originalFile = file;
2019-10-01 19:11:16 +02:00
const ext = path.extname(file.originalname);
const hash = Util.generateFileHash(file.buffer);
const filename = Util.getUniqueFilename(file.originalname);
if (remappedKeys && remappedKeys.uuid) {
const chunkOutput = path.join(__dirname,
'..',
'..',
'..',
'..',
process.env.UPLOAD_FOLDER,
'chunks',
remappedKeys.uuid,
`${remappedKeys.chunkindex.padStart(3, 0)}${ext || ''}`);
await jetpack.writeAsync(chunkOutput, file.buffer);
} else {
const output = path.join(__dirname,
'..',
'..',
'..',
'..',
process.env.UPLOAD_FOLDER,
filename);
await jetpack.writeAsync(output, file.buffer);
uploadedFile = {
name: filename,
hash,
size: file.buffer.length,
url: filename
};
}
}
2019-10-12 07:37:09 +02:00
if (!remappedKeys || !remappedKeys.uuid) {
Util.generateThumbnails(uploadedFile.name);
insertedId = await this.saveFileToDatabase(req, res, user, db, uploadedFile, originalFile);
if (!insertedId) return res.status(500).json({ message: 'There was an error saving the file.' });
uploadedFile.deleteUrl = `${process.env.DOMAIN}/api/file/${insertedId[0]}`;
}
2019-10-01 19:11:16 +02:00
2019-10-12 07:37:09 +02:00
return res.status(201).send({
2019-10-01 19:11:16 +02:00
message: 'Sucessfully uploaded the file.',
...uploadedFile
});
});
}
2019-10-12 07:37:09 +02:00
async saveFileToDatabase(req, res, user, db, file, originalFile) {
/*
Save the upload information to the database
*/
const now = moment.utc().toDate();
let insertedId = null;
try {
/*
This is so fucking dumb
*/
if (process.env.DB_CLIENT === 'sqlite3') {
insertedId = await db.table('files').insert({
userId: user ? user.id : null,
name: file.name,
original: originalFile.originalname,
type: originalFile.mimetype || '',
size: file.size,
hash: file.hash,
ip: req.ip,
createdAt: now,
editedAt: now
});
} else {
insertedId = await db.table('files').insert({
userId: user ? user.id : null,
name: file.name,
original: originalFile.originalname,
type: originalFile.mimetype || '',
size: file.size,
hash: file.hash,
ip: req.ip,
createdAt: now,
editedAt: now
}, 'id');
}
return insertedId;
} catch (error) {
console.error('There was an error saving the file to the database');
console.error(error);
return null;
// return res.status(500).json({ message: 'There was an error uploading the file.' });
}
}
2019-10-01 19:11:16 +02:00
_remapKeys(body) {
const keys = Object.keys(body);
if (keys.length) {
for (const key of keys) {
if (!/^dz/.test(key)) continue;
body[key.replace(/^dz/, '')] = body[key];
delete body[key];
}
return body;
}
}
}
module.exports = uploadPOST;