Files
NodeBB/src/controllers/uploads.js
Julian Lam 051a8e22df Removed allowedFileExtensions meta config
Now, when NodeBB needs to determine file compatibility, jimp
will attempt to open the file for reading. If it fails, file is
considered to be of an invalid type.
2015-11-09 14:39:00 -05:00

157 lines
3.8 KiB
JavaScript

"use strict";
var uploadsController = {},
fs = require('fs'),
path = require('path'),
async = require('async'),
nconf = require('nconf'),
validator = require('validator'),
meta = require('../meta'),
file = require('../file'),
plugins = require('../plugins'),
utils = require('../../public/src/utils'),
image = require('../image');
uploadsController.upload = function(req, res, filesIterator, next) {
var files = req.files.files;
if (!req.user) {
deleteTempFiles(files);
return res.status(403).json('not allowed');
}
if (!Array.isArray(files)) {
return res.status(500).json('invalid files');
}
if (Array.isArray(files[0])) {
files = files[0];
}
async.map(files, filesIterator, function(err, images) {
deleteTempFiles(files);
if (err) {
return res.status(500).send(err.message);
}
// IE8 - send it as text/html so browser won't trigger a file download for the json response
// malsup.com/jquery/form/#file-upload
res.status(200).send(req.xhr ? images : JSON.stringify(images));
});
};
uploadsController.uploadPost = function(req, res, next) {
uploadsController.upload(req, res, function(uploadedFile, next) {
file.isFileTypeAllowed(uploadedFile.path, function(err) {
if (err) {
return next(err);
}
if (uploadedFile.type.match(/image./)) {
uploadImage(req.user.uid, uploadedFile, next);
} else {
uploadFile(req.user.uid, uploadedFile, next);
}
});
}, next);
};
uploadsController.uploadThumb = function(req, res, next) {
if (parseInt(meta.config.allowTopicsThumbnail, 10) !== 1) {
deleteTempFiles(req.files.files);
return next(new Error('[[error:topic-thumbnails-are-disabled]]'));
}
uploadsController.upload(req, res, function(uploadedFile, next) {
file.isFileTypeAllowed(uploadedFile.path, function(err) {
if (err) {
return next(err);
}
if (uploadedFile.type.match(/image./)) {
var size = meta.config.topicThumbSize || 120;
image.resizeImage({
path: uploadedFile.path,
extension: path.extname(uploadedFile.name),
width: size,
height: size
}, function(err) {
if (err) {
return next(err);
}
uploadImage(req.user.uid, uploadedFile, next);
});
} else {
next(new Error('[[error:invalid-file]]'));
}
});
}, next);
};
uploadsController.uploadGroupCover = function(data, next) {
uploadImage(0, data, next);
};
function uploadImage(uid, image, callback) {
if (plugins.hasListeners('filter:uploadImage')) {
return plugins.fireHook('filter:uploadImage', {image: image, uid: uid}, callback);
}
if (parseInt(meta.config.allowFileUploads, 10)) {
uploadFile(uid, image, callback);
} else {
callback(new Error('[[error:uploads-are-disabled]]'));
}
}
function uploadFile(uid, uploadedFile, callback) {
if (plugins.hasListeners('filter:uploadFile')) {
return plugins.fireHook('filter:uploadFile', {file: uploadedFile, uid: uid}, callback);
}
if (parseInt(meta.config.allowFileUploads, 10) !== 1) {
return callback(new Error('[[error:uploads-are-disabled]]'));
}
if (!uploadedFile) {
return callback(new Error('[[error:invalid-file]]'));
}
if (uploadedFile.size > parseInt(meta.config.maximumFileSize, 10) * 1024) {
return callback(new Error('[[error:file-too-big, ' + meta.config.maximumFileSize + ']]'));
}
var filename = uploadedFile.name || 'upload';
filename = Date.now() + '-' + validator.escape(filename).substr(0, 255);
file.saveFileToLocal(filename, 'files', uploadedFile.path, function(err, upload) {
if (err) {
return callback(err);
}
callback(null, {
url: nconf.get('relative_path') + upload.url,
name: uploadedFile.name
});
});
}
function deleteTempFiles(files) {
async.each(files, function(file, next) {
fs.unlink(file.path, function(err) {
if (err) {
winston.error(err);
}
next();
});
});
}
module.exports = uploadsController;