aboutsummaryrefslogtreecommitdiff
path: root/src/api/routes/uploads/chunksPOST.js
blob: 9cf7338040c6f8017351cd7e496171897da1b990 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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;