mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 02:41:50 +03:00
829e8ed010
- Having these as destructured from the same package is hindering refactoring now - Events should really only ever be used server-side - i18n should be a shared module for now so it can be used everywhere until we figure out something better - Having them seperate also allows us to lint them properly
102 lines
3.0 KiB
JavaScript
102 lines
3.0 KiB
JavaScript
const path = require('path');
|
|
const os = require('os');
|
|
const multer = require('multer');
|
|
const fs = require('fs-extra');
|
|
const errors = require('@tryghost/errors');
|
|
const config = require('../../../../shared/config');
|
|
const i18n = require('../../../lib/common/i18n');
|
|
const logging = require('../../../../shared/logging');
|
|
|
|
const upload = {
|
|
enabledClear: config.get('uploadClear') || true,
|
|
multer: multer({dest: os.tmpdir()})
|
|
};
|
|
|
|
const deleteSingleFile = file => fs.unlink(file.path).catch(err => logging.error(err));
|
|
|
|
const single = name => (req, res, next) => {
|
|
const singleUpload = upload.multer.single(name);
|
|
singleUpload(req, res, (err) => {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
if (upload.enabledClear) {
|
|
const deleteFiles = () => {
|
|
res.removeListener('finish', deleteFiles);
|
|
res.removeListener('close', deleteFiles);
|
|
if (!req.disableUploadClear) {
|
|
if (req.files) {
|
|
return req.files.forEach(deleteSingleFile);
|
|
}
|
|
|
|
if (req.file) {
|
|
return deleteSingleFile(req.file);
|
|
}
|
|
}
|
|
};
|
|
if (!req.disableUploadClear) {
|
|
res.on('finish', deleteFiles);
|
|
res.on('close', deleteFiles);
|
|
}
|
|
}
|
|
next();
|
|
});
|
|
};
|
|
|
|
const checkFileExists = (fileData) => {
|
|
return !!(fileData.mimetype && fileData.path);
|
|
};
|
|
|
|
const checkFileIsValid = (fileData, types, extensions) => {
|
|
const type = fileData.mimetype;
|
|
|
|
if (types.includes(type) && extensions.includes(fileData.ext)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
const validation = function (options) {
|
|
const type = options.type;
|
|
|
|
// if we finish the data/importer logic, we forward the request to the specified importer
|
|
return function uploadValidation(req, res, next) {
|
|
const extensions = (config.get('uploads')[type] && config.get('uploads')[type].extensions) || [];
|
|
const contentTypes = (config.get('uploads')[type] && config.get('uploads')[type].contentTypes) || [];
|
|
|
|
req.file = req.file || {};
|
|
req.file.name = req.file.originalname;
|
|
req.file.type = req.file.mimetype;
|
|
|
|
// Check if a file was provided
|
|
if (!checkFileExists(req.file)) {
|
|
return next(new errors.ValidationError({
|
|
message: i18n.t(`errors.api.${type}.missingFile`)
|
|
}));
|
|
}
|
|
|
|
req.file.ext = path.extname(req.file.name).toLowerCase();
|
|
|
|
// Check if the file is valid
|
|
if (!checkFileIsValid(req.file, contentTypes, extensions)) {
|
|
return next(new errors.UnsupportedMediaTypeError({
|
|
message: i18n.t(`errors.api.${type}.invalidFile`, {extensions: extensions})
|
|
}));
|
|
}
|
|
|
|
next();
|
|
};
|
|
};
|
|
|
|
module.exports = {
|
|
single,
|
|
validation
|
|
};
|
|
|
|
// Exports for testing only
|
|
module.exports._test = {
|
|
checkFileExists,
|
|
checkFileIsValid
|
|
};
|