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

100 lines
2.9 KiB
JavaScript

const path = require('path');
const jetpack = require('fs-jetpack');
const randomstring = require('randomstring');
const Util = require('../../utils/Util');
const Route = require('../../structures/Route');
class uploadPOST extends Route {
constructor() {
super('/upload/chunks', 'post', {
bypassAuth: true,
canApiKey: 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' });
const filename = Util.getUniqueFilename(randomstring.generate(32));
// console.log('Files', req.body.files);
const info = {
size: req.body.files[0].size,
url: `${process.env.DOMAIN}/`
};
for (const chunk of req.body.files) {
const { uuid } = chunk;
// console.log('Chunk', chunk);
const chunkOutput = path.join(__dirname,
'../../../../',
process.env.UPLOAD_FOLDER,
'chunks',
uuid);
const chunkDir = await jetpack.list(chunkOutput);
const ext = path.extname(chunkDir[0]);
const output = path.join(__dirname,
'../../../../',
process.env.UPLOAD_FOLDER,
`${filename}${ext || ''}`);
chunkDir.sort();
// Save some data
info.name = `${filename}${ext || ''}`;
info.url += `${filename}${ext || ''}`;
info.data = chunk;
for (let i = 0; i < chunkDir.length; i++) {
const dir = path.join(__dirname,
'../../../../',
process.env.UPLOAD_FOLDER,
'chunks',
uuid,
chunkDir[i]);
const file = await jetpack.readAsync(dir, 'buffer');
await jetpack.appendAsync(output, file);
}
await jetpack.removeAsync(chunkOutput);
}
/*
If a file with the same hash and user is found, delete this
uploaded copy and return a link to the original
*/
info.hash = await Util.getFileHash(info.name);
let existingFile = await Util.checkIfFileExists(db, user, info.hash);
if (existingFile) {
existingFile = Util.constructFilePublicLink(existingFile);
res.json({
message: 'Successfully uploaded the file.',
name: existingFile.name,
hash: existingFile.hash,
size: existingFile.size,
url: `${process.env.DOMAIN}/${existingFile.name}`,
deleteUrl: `${process.env.DOMAIN}/api/file/${existingFile.id}`,
repeated: true
});
return Util.deleteFile(info.name);
}
// Otherwise generate thumbs and do the rest
Util.generateThumbnails(info.name);
const insertedId = await Util.saveFileToDatabase(req, res, user, db, info, {
originalname: info.data.original, mimetype: info.data.type
});
if (!insertedId) return res.status(500).json({ message: 'There was an error saving the file.' });
info.deleteUrl = `${process.env.DOMAIN}/api/file/${insertedId[0]}`;
Util.saveFileToAlbum(db, req.headers.albumid, insertedId);
delete info.chunk;
return res.status(201).send({
message: 'Sucessfully merged the chunk(s).',
...info
});
}
}
module.exports = uploadPOST;