Merge pull request #5420 from NodeBB/assets-route

/assets/uploads
v1.18.x
Julian Lam 8 years ago committed by GitHub
commit 7ba111acdd

@ -99,6 +99,7 @@ function loadConfig(callback) {
nconf.defaults({ nconf.defaults({
base_dir: __dirname, base_dir: __dirname,
themes_path: path.join(__dirname, 'node_modules'), themes_path: path.join(__dirname, 'node_modules'),
upload_path: 'public/uploads',
views_dir: path.join(__dirname, 'build/public/templates'), views_dir: path.join(__dirname, 'build/public/templates'),
version: pkg.version version: pkg.version
}); });
@ -112,6 +113,8 @@ function loadConfig(callback) {
nconf.set('themes_path', path.resolve(__dirname, nconf.get('themes_path'))); nconf.set('themes_path', path.resolve(__dirname, nconf.get('themes_path')));
nconf.set('core_templates_path', path.join(__dirname, 'src/views')); nconf.set('core_templates_path', path.join(__dirname, 'src/views'));
nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates')); nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates'));
nconf.set('upload_path', path.resolve(nconf.get('base_dir'), nconf.get('upload_path')));
if (nconf.get('url')) { if (nconf.get('url')) {
nconf.set('url_parsed', url.parse(nconf.get('url'))); nconf.set('url_parsed', url.parse(nconf.get('url')));

@ -558,7 +558,7 @@ app.cacheBuster = null;
var scriptEl = document.createElement('script'); var scriptEl = document.createElement('script');
scriptEl.type = 'text/javascript'; scriptEl.type = 'text/javascript';
scriptEl.src = config.relative_path + '/vendor/jquery/js/jquery-ui.js' + '?' + config['cache-buster']; scriptEl.src = config.relative_path + '/assets/vendor/jquery/js/jquery-ui.js' + '?' + config['cache-buster'];
scriptEl.onload = callback; scriptEl.onload = callback;
document.head.appendChild(scriptEl); document.head.appendChild(scriptEl);
}; };

@ -70,7 +70,7 @@ uploadsController.uploadTouchIcon = function (req, res, next) {
async.series([ async.series([
async.apply(file.saveFileToLocal, 'touchicon-' + size + '.png', 'system', uploadedFile.path), async.apply(file.saveFileToLocal, 'touchicon-' + size + '.png', 'system', uploadedFile.path),
async.apply(image.resizeImage, { async.apply(image.resizeImage, {
path: path.join(nconf.get('base_dir'), nconf.get('upload_path'), 'system', 'touchicon-' + size + '.png'), path: path.join(nconf.get('upload_path'), 'system', 'touchicon-' + size + '.png'),
extension: 'png', extension: 'png',
width: size, width: size,
height: size height: size
@ -106,7 +106,7 @@ uploadsController.uploadSound = function (req, res, next) {
} }
var soundsPath = path.join(__dirname, '../../../build/public/sounds'), var soundsPath = path.join(__dirname, '../../../build/public/sounds'),
filePath = path.join(__dirname, '../../../public/uploads/sounds', uploadedFile.name); filePath = path.join(nconf.get('upload_path'), 'sounds', uploadedFile.name);
file.link(filePath, path.join(soundsPath, path.basename(filePath))); file.link(filePath, path.join(soundsPath, path.basename(filePath)));

@ -290,32 +290,32 @@ Controllers.manifest = function (req, res) {
if (meta.config['brand:touchIcon']) { if (meta.config['brand:touchIcon']) {
manifest.icons.push({ manifest.icons.push({
src: nconf.get('relative_path') + '/uploads/system/touchicon-36.png', src: nconf.get('relative_path') + '/assets/uploads/system/touchicon-36.png',
sizes: '36x36', sizes: '36x36',
type: 'image/png', type: 'image/png',
density: 0.75 density: 0.75
}, { }, {
src: nconf.get('relative_path') + '/uploads/system/touchicon-48.png', src: nconf.get('relative_path') + '/assets/uploads/system/touchicon-48.png',
sizes: '48x48', sizes: '48x48',
type: 'image/png', type: 'image/png',
density: 1.0 density: 1.0
}, { }, {
src: nconf.get('relative_path') + '/uploads/system/touchicon-72.png', src: nconf.get('relative_path') + '/assets/uploads/system/touchicon-72.png',
sizes: '72x72', sizes: '72x72',
type: 'image/png', type: 'image/png',
density: 1.5 density: 1.5
}, { }, {
src: nconf.get('relative_path') + '/uploads/system/touchicon-96.png', src: nconf.get('relative_path') + '/assets/uploads/system/touchicon-96.png',
sizes: '96x96', sizes: '96x96',
type: 'image/png', type: 'image/png',
density: 2.0 density: 2.0
}, { }, {
src: nconf.get('relative_path') + '/uploads/system/touchicon-144.png', src: nconf.get('relative_path') + '/assets/uploads/system/touchicon-144.png',
sizes: '144x144', sizes: '144x144',
type: 'image/png', type: 'image/png',
density: 3.0 density: 3.0
}, { }, {
src: nconf.get('relative_path') + '/uploads/system/touchicon-192.png', src: nconf.get('relative_path') + '/assets/uploads/system/touchicon-192.png',
sizes: '192x192', sizes: '192x192',
type: 'image/png', type: 'image/png',
density: 4.0 density: 4.0

@ -5,6 +5,7 @@ var nconf = require('nconf');
var path = require('path'); var path = require('path');
var winston = require('winston'); var winston = require('winston');
var jimp = require('jimp'); var jimp = require('jimp');
var mkdirp = require('mkdirp');
var utils = require('../public/src/utils'); var utils = require('../public/src/utils');
@ -20,27 +21,31 @@ file.saveFileToLocal = function (filename, folder, tempPath, callback) {
}); });
filename = filename.join('.'); filename = filename.join('.');
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), folder, filename); var uploadPath = path.join(nconf.get('upload_path'), folder, filename);
winston.verbose('Saving file ' + filename + ' to : ' + uploadPath); winston.verbose('Saving file ' + filename + ' to : ' + uploadPath);
mkdirp(path.dirname(uploadPath), function (err) {
if (err) {
callback(err);
}
var is = fs.createReadStream(tempPath); var is = fs.createReadStream(tempPath);
var os = fs.createWriteStream(uploadPath); var os = fs.createWriteStream(uploadPath);
is.on('end', function () { is.on('end', function () {
callback(null, { callback(null, {
url: nconf.get('upload_url') + '/' + folder + '/' + filename, url: '/assets/uploads/' + folder + '/' + filename,
path: uploadPath path: uploadPath
});
}); });
});
os.on('error', callback); os.on('error', callback);
is.pipe(os);
is.pipe(os); });
}; };
file.base64ToLocal = function (imageData, uploadPath, callback) { file.base64ToLocal = function (imageData, uploadPath, callback) {
var buffer = new Buffer(imageData.slice(imageData.indexOf('base64') + 7), 'base64'); var buffer = new Buffer(imageData.slice(imageData.indexOf('base64') + 7), 'base64');
uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), uploadPath); uploadPath = path.join(nconf.get('upload_path'), uploadPath);
fs.writeFile(uploadPath, buffer, { fs.writeFile(uploadPath, buffer, {
encoding: 'base64' encoding: 'base64'

@ -105,7 +105,7 @@ module.exports = function (Groups) {
md5sum = md5sum.digest('hex'); md5sum = md5sum.digest('hex');
// Save image // Save image
var tempPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), md5sum) + '.png'; var tempPath = path.join(nconf.get('upload_path'), md5sum + '.png');
var buffer = new Buffer(imageData.slice(imageData.indexOf('base64') + 7), 'base64'); var buffer = new Buffer(imageData.slice(imageData.indexOf('base64') + 7), 'base64');
fs.writeFile(tempPath, buffer, { fs.writeFile(tempPath, buffer, {

@ -32,11 +32,23 @@ module.exports = function (Meta) {
fs.readdir(path.join(__dirname, '../../build/public/sounds'), next); fs.readdir(path.join(__dirname, '../../build/public/sounds'), next);
}, },
function (sounds, next) { function (sounds, next) {
fs.readdir(path.join(__dirname, '../../public/uploads/sounds'), function (err, uploaded) { fs.readdir(path.join(nconf.get('upload_path'), 'sounds'), function (err, uploaded) {
next(err, sounds.concat(uploaded)); if (err) {
if (err.code === 'ENOENT') {
return next(null, sounds);
}
return next(err);
}
next(null, sounds.concat(uploaded));
}); });
} }
], function (err, files) { ], function (err, files) {
if (err) {
winston.error('Could not get local sound files:' + err.message);
console.log(err.stack);
return callback(null, []);
}
var localList = {}; var localList = {};
// Filter out hidden files // Filter out hidden files
@ -44,15 +56,9 @@ module.exports = function (Meta) {
return !filename.startsWith('.'); return !filename.startsWith('.');
}); });
if (err) {
winston.error('Could not get local sound files:' + err.message);
console.log(err.stack);
return callback(null, []);
}
// Return proper paths // Return proper paths
files.forEach(function (filename) { files.forEach(function (filename) {
localList[filename] = nconf.get('relative_path') + '/sounds/' + filename; localList[filename] = nconf.get('relative_path') + '/assets/sounds/' + filename;
}); });
callback(null, localList); callback(null, localList);
@ -93,13 +99,22 @@ module.exports = function (Meta) {
async.waterfall([ async.waterfall([
function (next) { function (next) {
fs.readdir(path.join(__dirname, '../../public/uploads/sounds'), next); fs.readdir(path.join(nconf.get('upload_path'), 'sounds'), function (err, files) {
if (err) {
if (err.code === 'ENOENT') {
return next(null, []);
}
return next(err);
}
next(null, files);
});
}, },
function (uploaded, next) { function (uploaded, next) {
uploaded = uploaded.filter(function (filename) { uploaded = uploaded.filter(function (filename) {
return !filename.startsWith('.'); return !filename.startsWith('.');
}).map(function (filename) { }).map(function (filename) {
return path.join(__dirname, '../../public/uploads/sounds', filename); return path.join(nconf.get('upload_path'), 'sounds', filename);
}); });
plugins.fireHook('filter:sounds.get', uploaded, function (err, filePaths) { plugins.fireHook('filter:sounds.get', uploaded, function (err, filePaths) {

@ -60,27 +60,27 @@ module.exports = function (Meta) {
}, { }, {
rel: 'icon', rel: 'icon',
sizes: '36x36', sizes: '36x36',
href: nconf.get('relative_path') + '/uploads/system/touchicon-36.png' href: nconf.get('relative_path') + '/assets/uploads/system/touchicon-36.png'
}, { }, {
rel: 'icon', rel: 'icon',
sizes: '48x48', sizes: '48x48',
href: nconf.get('relative_path') + '/uploads/system/touchicon-48.png' href: nconf.get('relative_path') + '/assets/uploads/system/touchicon-48.png'
}, { }, {
rel: 'icon', rel: 'icon',
sizes: '72x72', sizes: '72x72',
href: nconf.get('relative_path') + '/uploads/system/touchicon-72.png' href: nconf.get('relative_path') + '/assets/uploads/system/touchicon-72.png'
}, { }, {
rel: 'icon', rel: 'icon',
sizes: '96x96', sizes: '96x96',
href: nconf.get('relative_path') + '/uploads/system/touchicon-96.png' href: nconf.get('relative_path') + '/assets/uploads/system/touchicon-96.png'
}, { }, {
rel: 'icon', rel: 'icon',
sizes: '144x144', sizes: '144x144',
href: nconf.get('relative_path') + '/uploads/system/touchicon-144.png' href: nconf.get('relative_path') + '/assets/uploads/system/touchicon-144.png'
}, { }, {
rel: 'icon', rel: 'icon',
sizes: '192x192', sizes: '192x192',
href: nconf.get('relative_path') + '/uploads/system/touchicon-192.png' href: nconf.get('relative_path') + '/assets/uploads/system/touchicon-192.png'
}); });
} }
plugins.fireHook('filter:meta.getLinkTags', defaultLinks, next); plugins.fireHook('filter:meta.getLinkTags', defaultLinks, next);

@ -162,7 +162,7 @@ middleware.privateUploads = function (req, res, next) {
if (req.user || parseInt(meta.config.privateUploads, 10) !== 1) { if (req.user || parseInt(meta.config.privateUploads, 10) !== 1) {
return next(); return next();
} }
if (req.path.startsWith('/uploads/files')) { if (req.path.startsWith('/assets/uploads/files')) {
return res.status(403).json('not-allowed'); return res.status(403).json('not-allowed');
} }
next(); next();

@ -142,16 +142,25 @@ module.exports = function (app, middleware, hotswapIds) {
app.use(middleware.privateUploads); app.use(middleware.privateUploads);
app.use(relativePath + '/assets', express.static(path.join(__dirname, '../../build/public'), { var statics = [
maxAge: app.enabled('cache') ? 5184000000 : 0 { route: '/assets', path: path.join(__dirname, '../../build/public') },
})); { route: '/assets', path: path.join(__dirname, '../../public') },
app.use(relativePath + '/assets', express.static(path.join(__dirname, '../../public'), { { route: '/plugins', path: path.join(__dirname, '../../build/public/plugins') },
maxAge: app.enabled('cache') ? 5184000000 : 0 ];
})); var staticOptions = {
// TODO: deprecate? maxAge: app.enabled('cache') ? 5184000000 : 0,
app.use(relativePath + '/plugins', express.static(path.join(__dirname, '../../build/public/plugins'), { };
maxAge: app.enabled('cache') ? 5184000000 : 0
})); if (path.resolve(__dirname, '../../public/uploads') !== nconf.get('upload_path')) {
statics.unshift({ route: '/assets/uploads', path: nconf.get('upload_path') });
}
statics.forEach(function (obj) {
app.use(relativePath + obj.route, express.static(obj.path, staticOptions));
});
app.use(relativePath + '/uploads', function (req, res) {
res.redirect(relativePath + '/assets/uploads' + req.path + '?' + meta.config['cache-buster']);
});
// DEPRECATED // DEPRECATED
var deprecatedPaths = [ var deprecatedPaths = [
@ -163,7 +172,6 @@ module.exports = function (app, middleware, hotswapIds) {
'/logo.png', '/logo.png',
'/favicon.ico', '/favicon.ico',
'/vendor/', '/vendor/',
'/uploads/',
'/templates/', '/templates/',
'/src/', '/src/',
'/images/', '/images/',

@ -86,7 +86,7 @@ module.exports = function (SocketUser) {
function (userData, next) { function (userData, next) {
if (userData.uploadedpicture && !userData.uploadedpicture.startsWith('http')) { if (userData.uploadedpicture && !userData.uploadedpicture.startsWith('http')) {
var pathToFile = path.join(nconf.get('base_dir'), 'public', userData.uploadedpicture); var pathToFile = path.join(nconf.get('base_dir'), 'public', userData.uploadedpicture);
if (pathToFile.startsWith(path.join(nconf.get('base_dir'), nconf.get('upload_path')))) { if (pathToFile.startsWith(nconf.get('upload_path'))) {
require('fs').unlink(pathToFile, function (err) { require('fs').unlink(pathToFile, function (err) {
if (err) { if (err) {
winston.error(err); winston.error(err);

@ -88,9 +88,6 @@ start.start = function () {
function setupConfigs() { function setupConfigs() {
// nconf defaults, if not set in config // nconf defaults, if not set in config
if (!nconf.get('upload_path')) {
nconf.set('upload_path', '/public/uploads');
}
if (!nconf.get('sessionKey')) { if (!nconf.get('sessionKey')) {
nconf.set('sessionKey', 'express.sid'); nconf.set('sessionKey', 'express.sid');
} }
@ -102,7 +99,6 @@ function setupConfigs() {
nconf.set('use_port', !!urlObject.port); nconf.set('use_port', !!urlObject.port);
nconf.set('relative_path', relativePath); nconf.set('relative_path', relativePath);
nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567); nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567);
nconf.set('upload_url', nconf.get('upload_path').replace(/^\/public/, ''));
} }
function printStartupInfo() { function printStartupInfo() {

@ -41,7 +41,7 @@ module.exports = function (Topics) {
extension = '.' + mime.extension(type); extension = '.' + mime.extension(type);
} }
filename = Date.now() + '-topic-thumb' + extension; filename = Date.now() + '-topic-thumb' + extension;
pathToUpload = path.join(nconf.get('base_dir'), nconf.get('upload_path'), 'files', filename); pathToUpload = path.join(nconf.get('upload_path'), 'files', filename);
request(data.thumb).pipe(fs.createWriteStream(pathToUpload)).on('close', next); request(data.thumb).pipe(fs.createWriteStream(pathToUpload)).on('close', next);
}, },
@ -59,7 +59,7 @@ module.exports = function (Topics) {
}, },
function (next) { function (next) {
if (!plugins.hasListeners('filter:uploadImage')) { if (!plugins.hasListeners('filter:uploadImage')) {
data.thumb = path.join(nconf.get('upload_url'), 'files', filename); data.thumb = '/assets/uploads/files/' + filename;
return callback(); return callback();
} }

@ -19,7 +19,7 @@
nconf.defaults({ nconf.defaults({
base_dir: path.join(__dirname,'../..'), base_dir: path.join(__dirname,'../..'),
themes_path: path.join(__dirname, '../../node_modules'), themes_path: path.join(__dirname, '../../node_modules'),
upload_url: path.join(path.sep, '../../uploads', path.sep), upload_path: 'public/uploads',
views_dir: path.join(__dirname, '../../build/public/templates'), views_dir: path.join(__dirname, '../../build/public/templates'),
relative_path: '' relative_path: ''
}); });
@ -121,9 +121,6 @@
}, },
function (next) { function (next) {
// nconf defaults, if not set in config // nconf defaults, if not set in config
if (!nconf.get('upload_path')) {
nconf.set('upload_path', '/public/uploads');
}
if (!nconf.get('sessionKey')) { if (!nconf.get('sessionKey')) {
nconf.set('sessionKey', 'express.sid'); nconf.set('sessionKey', 'express.sid');
} }
@ -135,7 +132,7 @@
nconf.set('use_port', !!urlObject.port); nconf.set('use_port', !!urlObject.port);
nconf.set('relative_path', relativePath); nconf.set('relative_path', relativePath);
nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567); nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567);
nconf.set('upload_url', nconf.get('upload_path').replace(/^\/public/, '')); nconf.set('upload_path', path.join(nconf.get('base_dir'), nconf.get('upload_path')));
nconf.set('core_templates_path', path.join(__dirname, '../../src/views')); nconf.set('core_templates_path', path.join(__dirname, '../../src/views'));
nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates')); nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates'));

@ -72,7 +72,7 @@ describe('Upload Controllers', function () {
assert.equal(res.statusCode, 200); assert.equal(res.statusCode, 200);
assert(Array.isArray(body)); assert(Array.isArray(body));
assert.equal(body.length, 1); assert.equal(body.length, 1);
assert.equal(body[0].url, '/uploads/profile/' + regularUid + '-profileimg.png'); assert.equal(body[0].url, '/assets/uploads/profile/' + regularUid + '-profileimg.png');
done(); done();
}); });
}); });
@ -122,7 +122,7 @@ describe('Upload Controllers', function () {
assert.ifError(err); assert.ifError(err);
assert.equal(res.statusCode, 200); assert.equal(res.statusCode, 200);
assert(Array.isArray(body)); assert(Array.isArray(body));
assert.equal(body[0].url, '/uploads/system/site-logo.png'); assert.equal(body[0].url, '/assets/uploads/system/site-logo.png');
done(); done();
}); });
}); });
@ -132,7 +132,7 @@ describe('Upload Controllers', function () {
assert.ifError(err); assert.ifError(err);
assert.equal(res.statusCode, 200); assert.equal(res.statusCode, 200);
assert(Array.isArray(body)); assert(Array.isArray(body));
assert.equal(body[0].url, '/uploads/category/category-1.png'); assert.equal(body[0].url, '/assets/uploads/category/category-1.png');
done(); done();
}); });
}); });
@ -142,7 +142,7 @@ describe('Upload Controllers', function () {
assert.ifError(err); assert.ifError(err);
assert.equal(res.statusCode, 200); assert.equal(res.statusCode, 200);
assert(Array.isArray(body)); assert(Array.isArray(body));
assert.equal(body[0].url, '/uploads/system/favicon.ico'); assert.equal(body[0].url, '/assets/uploads/system/favicon.ico');
done(); done();
}); });
}); });
@ -152,7 +152,7 @@ describe('Upload Controllers', function () {
assert.ifError(err); assert.ifError(err);
assert.equal(res.statusCode, 200); assert.equal(res.statusCode, 200);
assert(Array.isArray(body)); assert(Array.isArray(body));
assert.equal(body[0].url, '/uploads/system/touchicon-orig.png'); assert.equal(body[0].url, '/assets/uploads/system/touchicon-orig.png');
done(); done();
}); });
}); });

@ -503,7 +503,7 @@ describe('User', function () {
}; };
User.uploadPicture(uid, picture, function (err, uploadedPicture) { User.uploadPicture(uid, picture, function (err, uploadedPicture) {
assert.ifError(err); assert.ifError(err);
assert.equal(uploadedPicture.url, '/uploads/profile/' + uid + '-profileimg.png'); assert.equal(uploadedPicture.url, '/assets/uploads/profile/' + uid + '-profileimg.png');
assert.equal(uploadedPicture.path, path.join(nconf.get('base_dir'), 'public', 'uploads', 'profile', uid + '-profileimg.png')); assert.equal(uploadedPicture.path, path.join(nconf.get('base_dir'), 'public', 'uploads', 'profile', uid + '-profileimg.png'));
done(); done();
}); });

Loading…
Cancel
Save