1
0
mirror of https://github.com/Foltik/Shimapan synced 2024-11-15 01:06:32 -05:00
shimapan/app/routes/upload.js

104 lines
3.1 KiB
JavaScript
Raw Normal View History

const express = require('express');
const router = express.Router();
const config = require('config');
2017-10-09 22:01:02 -04:00
2018-07-28 12:19:38 -04:00
const fsPromises = require('fs').promises;
2018-07-26 19:01:16 -04:00
const ModelPath = '../models/';
const User = require(ModelPath + 'User.js');
const Upload = require(ModelPath + 'Upload.js');
const Key = require(ModelPath + 'Key.js');
2017-10-11 10:15:19 -04:00
2018-07-28 12:19:38 -04:00
const verifyScope = require('../util/verifyScope.js');
const multer = require('multer');
const fileUpload = multer({dest: config.get('Upload.path')}).single('file');
2017-10-09 22:01:02 -04:00
2018-07-26 21:52:47 -04:00
const wrap = require('../util/wrap.js');
2018-07-26 13:17:37 -04:00
const generatedIdExists = async id =>
await Upload.countDocuments({id: id}) === 1;
2017-10-22 12:19:51 -04:00
2018-07-28 12:19:38 -04:00
const generateId = async() => {
const charset = config.get('Upload.charset');
const len = config.get('Upload.idLength');
2018-07-26 13:17:37 -04:00
const id = [...Array(len)]
.map(() => charset.charAt(Math.floor(Math.random() * charset.length)))
.join('');
return await generatedIdExists(id)
? generateId()
: id;
2017-10-22 12:19:51 -04:00
};
2017-10-14 15:13:50 -04:00
2018-07-26 13:17:37 -04:00
const updateStats = async req =>
Promise.all([
User.updateOne({username: req.username}, {$inc: {uploadCount: 1, uploadSize: req.file.size}}),
req.key
? Key.updateOne({key: req.key}, {$inc: {uploadCount: 1, uploadSize: req.file.size}})
2018-07-26 13:17:37 -04:00
: Promise.resolve()
]);
2018-07-28 12:19:38 -04:00
router.post('/', fileUpload, wrap(async(req, res) => {
// We need to authenticate in place because the form data needs to be processed by multer first
const deleteAndError = async (code, message) => {
if (req.file)
await fsPromises.unlink(req.file.path);
res.status(code).json({message: message});
};
if (req.isAuthenticated()) {
if (verifyScope(req.session.passport.scope, 'file.upload')) {
req.username = req.session.passport.user;
req.displayname = req.session.passport.displayname;
req.scope = req.session.passport.scope;
req.key = null;
} else {
return await deleteAndError(403, 'Forbidden.');
}
} else if (req.body.key) {
const key = await Key.findOne({key: req.body.key});
if (verifyScope(key.scope, 'file.upload')) {
req.username = key.issuer;
req.displayname = key.issuer;
req.scope = key.scope;
req.key = key.key;
} else {
return await deleteAndError(403, 'Forbidden.');
}
} else {
return await deleteAndError(401, 'Unauthorized.');
}
2017-10-22 12:19:51 -04:00
if (!req.file)
2018-07-26 13:17:37 -04:00
return res.status(400).json({message: 'No file specified.'});
if (req.file.size > config.get('Upload.maxSize')) {
await fsPromises.unlink(req.file.path);
2018-07-26 13:17:37 -04:00
return res.status(413).json({message: 'File too large.'});
}
2018-07-26 13:17:37 -04:00
const upload = {
id: await generateId(),
uploader: req.username,
uploaderKey: req.key,
2018-07-26 13:17:37 -04:00
date: Date.now(),
file: req.file
};
await Promise.all([
Upload.create(upload),
updateStats(req)
]);
res.status(200).json({
2018-07-27 14:26:55 -04:00
message: 'File uploaded.',
2018-07-26 13:17:37 -04:00
id: upload.id,
url: config.get('Server.hostname') + '/v/' + upload.id
2017-10-09 22:01:02 -04:00
});
2018-07-26 13:17:37 -04:00
}));
2017-10-09 22:01:02 -04:00
module.exports = router;