mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 03:55:55 +01:00
one final push, cleanup + organize + lint; made feeds/meta/plugins routes follow same pattern as other route files
This commit is contained in:
@@ -16,9 +16,7 @@ var templates = require('./../../public/src/templates'),
|
|||||||
|
|
||||||
var middleware = {};
|
var middleware = {};
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper functions
|
|
||||||
*/
|
|
||||||
function routeThemeScreenshots(app, themes) {
|
function routeThemeScreenshots(app, themes) {
|
||||||
var screenshotPath;
|
var screenshotPath;
|
||||||
|
|
||||||
@@ -170,6 +168,9 @@ function catch404(req, res, next) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = function(app, data) {
|
module.exports = function(app, data) {
|
||||||
middleware = require('./middleware')(app);
|
middleware = require('./middleware')(app);
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ var nconf = require('nconf'),
|
|||||||
utils = require('./../../public/src/utils'),
|
utils = require('./../../public/src/utils'),
|
||||||
templates = require('./../../public/src/templates');
|
templates = require('./../../public/src/templates');
|
||||||
|
|
||||||
var Admin = {};
|
|
||||||
|
|
||||||
function uploadImage(filename, req, res) {
|
function uploadImage(filename, req, res) {
|
||||||
function done(err, image) {
|
function done(err, image) {
|
||||||
@@ -45,6 +44,89 @@ function uploadImage(filename, req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function uploadCategoryPicture(req, res, next) {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.redirect('/403');
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'],
|
||||||
|
params = null, er;
|
||||||
|
try {
|
||||||
|
params = JSON.parse(req.body.params);
|
||||||
|
} catch (e) {
|
||||||
|
er = {
|
||||||
|
error: 'Error uploading file! Error :' + e.message
|
||||||
|
};
|
||||||
|
return res.send(req.xhr ? er : JSON.stringify(er));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
|
||||||
|
er = {
|
||||||
|
error: 'Allowed image types are png, jpg and gif!'
|
||||||
|
};
|
||||||
|
res.send(req.xhr ? er : JSON.stringify(er));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename = 'category-' + params.cid + path.extname(req.files.userPhoto.name);
|
||||||
|
|
||||||
|
uploadImage(filename, req, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadFavicon(req, res, next) {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.redirect('/403');
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowedTypes = ['image/x-icon', 'image/vnd.microsoft.icon'],
|
||||||
|
er;
|
||||||
|
|
||||||
|
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
|
||||||
|
er = {error: 'You can only upload icon file type!'};
|
||||||
|
res.send(req.xhr ? er : JSON.stringify(er));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.saveFileToLocal('favicon.ico', req.files.userPhoto.path, function(err, image) {
|
||||||
|
fs.unlink(req.files.userPhoto.path);
|
||||||
|
|
||||||
|
if(err) {
|
||||||
|
er = {error: err.message};
|
||||||
|
return res.send(req.xhr ? er : JSON.stringify(er));
|
||||||
|
}
|
||||||
|
|
||||||
|
var rs = {path: image.url};
|
||||||
|
res.send(req.xhr ? rs : JSON.stringify(rs));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadLogo(req, res, next) {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.redirect('/403');
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowedTypes = ['image/png', 'image/jpeg', 'image/pjpeg', 'image/jpg', 'image/gif'],
|
||||||
|
er;
|
||||||
|
|
||||||
|
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
|
||||||
|
er = {error: 'Allowed image types are png, jpg and gif!'};
|
||||||
|
res.send(req.xhr ? er : JSON.stringify(er));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename = 'site-logo' + path.extname(req.files.userPhoto.name);
|
||||||
|
|
||||||
|
uploadImage(filename, req, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUsersCSV(req, res, next) {
|
||||||
|
user.getUsersCSV(function(err, data) {
|
||||||
|
res.attachment('users.csv');
|
||||||
|
res.setHeader('Content-Type', 'text/csv');
|
||||||
|
res.end(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function(app, middleware, controllers) {
|
module.exports = function(app, middleware, controllers) {
|
||||||
app.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI);
|
app.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI);
|
||||||
app.all('/admin/*', middleware.admin.isAdmin);
|
app.all('/admin/*', middleware.admin.isAdmin);
|
||||||
@@ -104,129 +186,11 @@ module.exports = function(app, middleware, controllers) {
|
|||||||
app.get('/api/admin/groups', controllers.admin.groups.get);
|
app.get('/api/admin/groups', controllers.admin.groups.get);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
app.namespace('/admin', function () {
|
app.namespace('/admin', function () {
|
||||||
app.post('/category/uploadpicture', function(req, res) {
|
app.get('/users/csv', getUsersCSV);
|
||||||
if (!req.user) {
|
|
||||||
return res.redirect('/403');
|
|
||||||
}
|
|
||||||
|
|
||||||
var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'],
|
app.post('/category/uploadpicture', uploadCategoryPicture);
|
||||||
params = null, er;
|
app.post('/uploadfavicon', uploadFavicon);
|
||||||
try {
|
app.post('/uploadlogo', uploadLogo);
|
||||||
params = JSON.parse(req.body.params);
|
|
||||||
} catch (e) {
|
|
||||||
er = {
|
|
||||||
error: 'Error uploading file! Error :' + e.message
|
|
||||||
};
|
|
||||||
return res.send(req.xhr ? er : JSON.stringify(er));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
|
|
||||||
er = {
|
|
||||||
error: 'Allowed image types are png, jpg and gif!'
|
|
||||||
};
|
|
||||||
res.send(req.xhr ? er : JSON.stringify(er));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var filename = 'category-' + params.cid + path.extname(req.files.userPhoto.name);
|
|
||||||
|
|
||||||
uploadImage(filename, req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/uploadfavicon', function(req, res) {
|
|
||||||
if (!req.user) {
|
|
||||||
return res.redirect('/403');
|
|
||||||
}
|
|
||||||
|
|
||||||
var allowedTypes = ['image/x-icon', 'image/vnd.microsoft.icon'],
|
|
||||||
er;
|
|
||||||
|
|
||||||
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
|
|
||||||
er = {error: 'You can only upload icon file type!'};
|
|
||||||
res.send(req.xhr ? er : JSON.stringify(er));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.saveFileToLocal('favicon.ico', req.files.userPhoto.path, function(err, image) {
|
|
||||||
fs.unlink(req.files.userPhoto.path);
|
|
||||||
|
|
||||||
if(err) {
|
|
||||||
er = {error: err.message};
|
|
||||||
return res.send(req.xhr ? er : JSON.stringify(er));
|
|
||||||
}
|
|
||||||
|
|
||||||
var rs = {path: image.url};
|
|
||||||
res.send(req.xhr ? rs : JSON.stringify(rs));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/uploadlogo', function(req, res) {
|
|
||||||
|
|
||||||
if (!req.user) {
|
|
||||||
return res.redirect('/403');
|
|
||||||
}
|
|
||||||
|
|
||||||
var allowedTypes = ['image/png', 'image/jpeg', 'image/pjpeg', 'image/jpg', 'image/gif'],
|
|
||||||
er;
|
|
||||||
|
|
||||||
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
|
|
||||||
er = {error: 'Allowed image types are png, jpg and gif!'};
|
|
||||||
res.send(req.xhr ? er : JSON.stringify(er));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var filename = 'site-logo' + path.extname(req.files.userPhoto.name);
|
|
||||||
|
|
||||||
uploadImage(filename, req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/users/csv', function(req, res) {
|
|
||||||
user.getUsersCSV(function(err, data) {
|
|
||||||
res.attachment('users.csv');
|
|
||||||
res.setHeader('Content-Type', 'text/csv');
|
|
||||||
res.end(data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var custom_routes = {
|
|
||||||
'routes': [],
|
|
||||||
'api': []
|
|
||||||
};
|
|
||||||
|
|
||||||
plugins.ready(function() {
|
|
||||||
plugins.fireHook('filter:admin.create_routes', custom_routes, function(err, custom_routes) {
|
|
||||||
var route, routes = custom_routes.routes;
|
|
||||||
|
|
||||||
for (route in routes) {
|
|
||||||
if (routes.hasOwnProperty(route)) {
|
|
||||||
(function(route) {
|
|
||||||
app[routes[route].method || 'get']('/admin' + routes[route].route, function(req, res) {
|
|
||||||
routes[route].options(req, res, function(options) {
|
|
||||||
Admin.buildHeader(req, res, function (err, header) {
|
|
||||||
res.send(header + options.content + templates['admin/footer']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}(route));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var apiRoutes = custom_routes.api;
|
|
||||||
for (route in apiRoutes) {
|
|
||||||
if (apiRoutes.hasOwnProperty(route)) {
|
|
||||||
(function(route) {
|
|
||||||
app[apiRoutes[route].method || 'get']('/api/admin' + apiRoutes[route].route, function(req, res) {
|
|
||||||
apiRoutes[route].callback(req, res, function(data) {
|
|
||||||
res.json(data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}(route));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,152 +13,156 @@ var path = require('path'),
|
|||||||
meta = require('./../meta'),
|
meta = require('./../meta'),
|
||||||
plugins = require('./../plugins'),
|
plugins = require('./../plugins'),
|
||||||
utils = require('./../../public/src/utils'),
|
utils = require('./../../public/src/utils'),
|
||||||
pkg = require('./../../package.json');
|
pkg = require('./../../package.json'),
|
||||||
|
|
||||||
|
customTemplates = [];
|
||||||
|
|
||||||
|
|
||||||
|
function searchTerm(req, res, next) {
|
||||||
|
if (!plugins.hasListeners('filter:search.query')) {
|
||||||
|
return res.redirect('/404');
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchPosts(callback) {
|
||||||
|
plugins.fireHook('filter:search.query', {
|
||||||
|
index: 'post',
|
||||||
|
query: req.params.term
|
||||||
|
}, function(err, pids) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
posts.getPostSummaryByPids(pids, false, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchTopics(callback) {
|
||||||
|
plugins.fireHook('filter:search.query', {
|
||||||
|
index: 'topic',
|
||||||
|
query: req.params.term
|
||||||
|
}, function(err, tids) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
topics.getTopicsByTids(tids, 0, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((req.user && req.user.uid) || meta.config.allowGuestSearching === '1') {
|
||||||
|
async.parallel([searchPosts, searchTopics], function (err, results) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!results) {
|
||||||
|
results = [];
|
||||||
|
results[0] = results[1] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json({
|
||||||
|
show_no_topics: results[1].length ? 'hide' : '',
|
||||||
|
show_no_posts: results[0].length ? 'hide' : '',
|
||||||
|
show_results: '',
|
||||||
|
search_query: req.params.term,
|
||||||
|
posts: results[0],
|
||||||
|
topics: results[1],
|
||||||
|
post_matches : results[0].length,
|
||||||
|
topic_matches : results[1].length
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.send(403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload(req, res, filesIterator, next) {
|
||||||
|
if(!req.user) {
|
||||||
|
return res.json(403, {message:'not allowed'});
|
||||||
|
}
|
||||||
|
var files = req.files.files;
|
||||||
|
|
||||||
|
if(!Array.isArray(files)) {
|
||||||
|
return res.json(500, {message: 'invalid files'});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Array.isArray(files[0])) {
|
||||||
|
files = files[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTempFiles() {
|
||||||
|
for(var i=0; i<files.length; ++i) {
|
||||||
|
fs.unlink(files[i].path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async.map(files, filesIterator, function(err, images) {
|
||||||
|
deleteTempFiles();
|
||||||
|
|
||||||
|
if(err) {
|
||||||
|
return res.send(500, 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.send(200, req.xhr ? images : JSON.stringify(images));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadPost(req, res, next) {
|
||||||
|
upload(req, res, function(file, next) {
|
||||||
|
if(file.type.match(/image./)) {
|
||||||
|
posts.uploadPostImage(file, next);
|
||||||
|
} else {
|
||||||
|
posts.uploadPostFile(file, next);
|
||||||
|
}
|
||||||
|
}, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadThumb(req, res, next) {
|
||||||
|
upload(req, res, function(file, next) {
|
||||||
|
if(file.type.match(/image./)) {
|
||||||
|
topics.uploadTopicThumb(file, next);
|
||||||
|
} else {
|
||||||
|
res.json(500, {message: 'Invalid File'});
|
||||||
|
}
|
||||||
|
}, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getModerators(req, res, next) {
|
||||||
|
categories.getModerators(req.params.cid, function(err, moderators) {
|
||||||
|
res.json({moderators: moderators});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTemplatesListing(req, res, next) {
|
||||||
|
utils.walk(nconf.get('views_dir'), function (err, data) {
|
||||||
|
data = data.concat(customTemplates)
|
||||||
|
.filter(function(value, index, self) {
|
||||||
|
return self.indexOf(value) === index;
|
||||||
|
}).map(function(el) {
|
||||||
|
return el.replace(nconf.get('views_dir') + '/', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function(app, middleware, controllers) {
|
module.exports = function(app, middleware, controllers) {
|
||||||
app.namespace('/api', function () {
|
app.namespace('/api', function () {
|
||||||
app.all('*', middleware.updateLastOnlineTime, middleware.prepareAPI);
|
app.all('*', middleware.updateLastOnlineTime, middleware.prepareAPI);
|
||||||
|
|
||||||
app.get('/user/uid/:uid', middleware.checkGlobalPrivacySettings, controllers.accounts.getUserByUID);
|
customTemplates = app.get_custom_templates();
|
||||||
|
|
||||||
app.get('/get_templates_listing', function (req, res) {
|
|
||||||
utils.walk(nconf.get('views_dir'), function (err, data) {
|
|
||||||
data = data.concat(app.get_custom_templates())
|
|
||||||
.filter(function(value, index, self) {
|
|
||||||
return self.indexOf(value) === index;
|
|
||||||
}).map(function(el) {
|
|
||||||
return el.replace(nconf.get('views_dir') + '/', '');
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json(data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/config', controllers.api.getConfig);
|
app.get('/config', controllers.api.getConfig);
|
||||||
|
|
||||||
app.get('/search/:term', function (req, res, next) {
|
app.get('/user/uid/:uid', middleware.checkGlobalPrivacySettings, controllers.accounts.getUserByUID);
|
||||||
if (!plugins.hasListeners('filter:search.query')) {
|
app.get('/get_templates_listing', getTemplatesListing);
|
||||||
return res.redirect('/404');
|
app.get('/search/:term', searchTerm);
|
||||||
}
|
app.get('/categories/:cid/moderators', getModerators);
|
||||||
|
|
||||||
function searchPosts(callback) {
|
app.post('/post/upload', uploadPost);
|
||||||
plugins.fireHook('filter:search.query', {
|
app.post('/topic/thumb/upload', uploadThumb);
|
||||||
index: 'post',
|
|
||||||
query: req.params.term
|
|
||||||
}, function(err, pids) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
posts.getPostSummaryByPids(pids, false, callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function searchTopics(callback) {
|
|
||||||
plugins.fireHook('filter:search.query', {
|
|
||||||
index: 'topic',
|
|
||||||
query: req.params.term
|
|
||||||
}, function(err, tids) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
topics.getTopicsByTids(tids, 0, callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((req.user && req.user.uid) || meta.config.allowGuestSearching === '1') {
|
|
||||||
async.parallel([searchPosts, searchTopics], function (err, results) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!results) {
|
|
||||||
results = [];
|
|
||||||
results[0] = results[1] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.json({
|
|
||||||
show_no_topics: results[1].length ? 'hide' : '',
|
|
||||||
show_no_posts: results[0].length ? 'hide' : '',
|
|
||||||
show_results: '',
|
|
||||||
search_query: req.params.term,
|
|
||||||
posts: results[0],
|
|
||||||
topics: results[1],
|
|
||||||
post_matches : results[0].length,
|
|
||||||
topic_matches : results[1].length
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.send(403);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function upload(req, res, filesIterator, next) {
|
|
||||||
if(!req.user) {
|
|
||||||
return res.json(403, {message:'not allowed'});
|
|
||||||
}
|
|
||||||
var files = req.files.files;
|
|
||||||
|
|
||||||
if(!Array.isArray(files)) {
|
|
||||||
return res.json(500, {message: 'invalid files'});
|
|
||||||
}
|
|
||||||
|
|
||||||
// multiple files
|
|
||||||
if(Array.isArray(files[0])) {
|
|
||||||
files = files[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteTempFiles() {
|
|
||||||
for(var i=0; i<files.length; ++i) {
|
|
||||||
fs.unlink(files[i].path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async.map(files, filesIterator, function(err, images) {
|
|
||||||
deleteTempFiles();
|
|
||||||
|
|
||||||
if(err) {
|
|
||||||
return res.send(500, err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this was not a XMLHttpRequest (hence the req.xhr check http://expressjs.com/api.html#req.xhr)
|
|
||||||
// then most likely it's submit via the iFrame workaround, via the jquery.form plugin's ajaxSubmit()
|
|
||||||
// we need to send it as text/html so IE8 won't trigger a file download for the json response
|
|
||||||
// malsup.com/jquery/form/#file-upload
|
|
||||||
|
|
||||||
// Also, req.send is safe for both types, if the response was an object, res.send will automatically submit as application/json
|
|
||||||
// expressjs.com/api.html#res.send
|
|
||||||
res.send(200, req.xhr ? images : JSON.stringify(images));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
app.post('/post/upload', function(req, res, next) {
|
|
||||||
upload(req, res, function(file, next) {
|
|
||||||
if(file.type.match(/image./)) {
|
|
||||||
posts.uploadPostImage(file, next);
|
|
||||||
} else {
|
|
||||||
posts.uploadPostFile(file, next);
|
|
||||||
}
|
|
||||||
}, next);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/topic/thumb/upload', function(req, res, next) {
|
|
||||||
upload(req, res, function(file, next) {
|
|
||||||
if(file.type.match(/image./)) {
|
|
||||||
topics.uploadTopicThumb(file, next);
|
|
||||||
} else {
|
|
||||||
res.json(500, {message: 'Invalid File'});
|
|
||||||
}
|
|
||||||
}, next);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/categories/:cid/moderators', function(req, res) {
|
|
||||||
categories.getModerators(req.params.cid, function(err, moderators) {
|
|
||||||
res.json({moderators: moderators});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// this should be in the API namespace
|
// this should be in the API namespace
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
var user = require('./../user'),
|
var user = require('./../user'),
|
||||||
categories = require('./../categories'),
|
categories = require('./../categories'),
|
||||||
topics = require('./../topics'),
|
topics = require('./../topics'),
|
||||||
posts = require('./../posts');
|
posts = require('./../posts');
|
||||||
|
|
||||||
var DebugRoute = function(app) {
|
module.exports = function(app, middleware, controllers) {
|
||||||
|
|
||||||
app.namespace('/debug', function() {
|
app.namespace('/debug', function() {
|
||||||
|
|
||||||
app.get('/uid/:uid', function (req, res) {
|
app.get('/uid/:uid', function (req, res) {
|
||||||
|
if (!req.params.uid) {
|
||||||
if (!req.params.uid)
|
|
||||||
return res.redirect('/404');
|
return res.redirect('/404');
|
||||||
|
}
|
||||||
|
|
||||||
user.getUserData(req.params.uid, function (err, data) {
|
user.getUserData(req.params.uid, function (err, data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
@@ -53,12 +52,5 @@ var DebugRoute = function(app) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/test', function(req, res) {
|
|
||||||
res.send(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = DebugRoute;
|
|
||||||
@@ -1,201 +1,202 @@
|
|||||||
(function (Feeds) {
|
"use strict";
|
||||||
var posts = require('../posts'),
|
|
||||||
topics = require('../topics'),
|
|
||||||
categories = require('../categories'),
|
|
||||||
|
|
||||||
rss = require('rss'),
|
var posts = require('../posts'),
|
||||||
nconf = require('nconf'),
|
topics = require('../topics'),
|
||||||
|
categories = require('../categories'),
|
||||||
|
|
||||||
ThreadTools = require('../threadTools'),
|
rss = require('rss'),
|
||||||
CategoryTools = require('../categoryTools');
|
nconf = require('nconf'),
|
||||||
|
|
||||||
Feeds.createRoutes = function(app){
|
ThreadTools = require('../threadTools'),
|
||||||
app.get('/topic/:topic_id.rss', hasTopicPrivileges, generateForTopic);
|
CategoryTools = require('../categoryTools');
|
||||||
app.get('/category/:category_id.rss', hasCategoryPrivileges, generateForCategory);
|
|
||||||
app.get('/recent.rss', generateForRecent);
|
function hasTopicPrivileges(req, res, next) {
|
||||||
app.get('/popular.rss', generateForPopular);
|
var tid = req.params.topic_id;
|
||||||
};
|
var uid = req.user ? req.user.uid || 0 : 0;
|
||||||
|
|
||||||
|
ThreadTools.privileges(tid, uid, function(err, privileges) {
|
||||||
|
if(err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!privileges.read) {
|
||||||
|
return res.redirect('403');
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasCategoryPrivileges(req, res, next) {
|
||||||
|
var cid = req.params.category_id;
|
||||||
|
var uid = req.user ? req.user.uid || 0 : 0;
|
||||||
|
|
||||||
|
CategoryTools.privileges(cid, uid, function(err, privileges) {
|
||||||
|
if(err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!privileges.read) {
|
||||||
|
return res.redirect('403');
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function hasTopicPrivileges(req, res, next) {
|
function generateForTopic(req, res, next) {
|
||||||
var tid = req.params.topic_id;
|
var tid = req.params.topic_id;
|
||||||
var uid = req.user ? req.user.uid || 0 : 0;
|
|
||||||
|
|
||||||
ThreadTools.privileges(tid, uid, function(err, privileges) {
|
topics.getTopicWithPosts(tid, 0, 0, 25, function (err, topicData) {
|
||||||
if(err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!privileges.read) {
|
var description = topicData.posts.length ? topicData.posts[0].content : '';
|
||||||
return res.redirect('403');
|
var image_url = topicData.posts.length ? topicData.posts[0].picture : '';
|
||||||
}
|
var author = topicData.posts.length ? topicData.posts[0].username : '';
|
||||||
|
|
||||||
return next();
|
var feed = new rss({
|
||||||
});
|
title: topicData.title,
|
||||||
}
|
description: description,
|
||||||
|
feed_url: nconf.get('url') + '/topic/' + tid + '.rss',
|
||||||
|
site_url: nconf.get('url') + '/topic/' + topicData.slug,
|
||||||
|
image_url: image_url,
|
||||||
|
author: author,
|
||||||
|
ttl: 60
|
||||||
|
}),
|
||||||
|
dateStamp;
|
||||||
|
|
||||||
function hasCategoryPrivileges(req, res, next) {
|
// Add pubDate if topic contains posts
|
||||||
var cid = req.params.category_id;
|
if (topicData.posts.length > 0) {
|
||||||
var uid = req.user ? req.user.uid || 0 : 0;
|
feed.pubDate = new Date(parseInt(topicData.posts[0].timestamp, 10)).toUTCString();
|
||||||
|
}
|
||||||
|
|
||||||
CategoryTools.privileges(cid, uid, function(err, privileges) {
|
topicData.posts.forEach(function(postData) {
|
||||||
if(err) {
|
if (parseInt(postData.deleted, 10) === 0) {
|
||||||
return next(err);
|
dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString();
|
||||||
}
|
|
||||||
|
|
||||||
if(!privileges.read) {
|
|
||||||
return res.redirect('403');
|
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function generateForTopic(req, res, next) {
|
|
||||||
var tid = req.params.topic_id;
|
|
||||||
|
|
||||||
topics.getTopicWithPosts(tid, 0, 0, 25, function (err, topicData) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var description = topicData.posts.length ? topicData.posts[0].content : '';
|
|
||||||
var image_url = topicData.posts.length ? topicData.posts[0].picture : '';
|
|
||||||
var author = topicData.posts.length ? topicData.posts[0].username : '';
|
|
||||||
|
|
||||||
var feed = new rss({
|
|
||||||
title: topicData.title,
|
|
||||||
description: description,
|
|
||||||
feed_url: nconf.get('url') + '/topic/' + tid + '.rss',
|
|
||||||
site_url: nconf.get('url') + '/topic/' + topicData.slug,
|
|
||||||
image_url: image_url,
|
|
||||||
author: author,
|
|
||||||
ttl: 60
|
|
||||||
}),
|
|
||||||
dateStamp;
|
|
||||||
|
|
||||||
// Add pubDate if topic contains posts
|
|
||||||
if (topicData.posts.length > 0) {
|
|
||||||
feed.pubDate = new Date(parseInt(topicData.posts[0].timestamp, 10)).toUTCString();
|
|
||||||
}
|
|
||||||
|
|
||||||
topicData.posts.forEach(function(postData) {
|
|
||||||
if (parseInt(postData.deleted, 10) === 0) {
|
|
||||||
dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString();
|
|
||||||
|
|
||||||
feed.item({
|
|
||||||
title: 'Reply to ' + topicData.title + ' on ' + dateStamp,
|
|
||||||
description: postData.content,
|
|
||||||
url: nconf.get('url') + '/topic/' + topicData.slug + '#' + postData.pid,
|
|
||||||
author: postData.username,
|
|
||||||
date: dateStamp
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var xml = feed.xml();
|
|
||||||
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
function generateForCategory(req, res, next) {
|
|
||||||
var cid = req.params.category_id;
|
|
||||||
|
|
||||||
categories.getCategoryById(cid, 0, 25, 0, function (err, categoryData) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var feed = new rss({
|
|
||||||
title: categoryData.name,
|
|
||||||
description: categoryData.description,
|
|
||||||
feed_url: nconf.get('url') + '/category/' + cid + '.rss',
|
|
||||||
site_url: nconf.get('url') + '/category/' + categoryData.cid,
|
|
||||||
ttl: 60
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add pubDate if category has topics
|
|
||||||
if (categoryData.topics.length > 0) feed.pubDate = new Date(parseInt(categoryData.topics[0].lastposttime, 10)).toUTCString();
|
|
||||||
|
|
||||||
categoryData.topics.forEach(function(topicData) {
|
|
||||||
feed.item({
|
feed.item({
|
||||||
title: topicData.title,
|
title: 'Reply to ' + topicData.title + ' on ' + dateStamp,
|
||||||
url: nconf.get('url') + '/topic/' + topicData.slug,
|
description: postData.content,
|
||||||
author: topicData.username,
|
url: nconf.get('url') + '/topic/' + topicData.slug + '#' + postData.pid,
|
||||||
date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
|
author: postData.username,
|
||||||
|
date: dateStamp
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var xml = feed.xml();
|
||||||
|
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateForCategory(req, res, next) {
|
||||||
|
var cid = req.params.category_id;
|
||||||
|
|
||||||
|
categories.getCategoryById(cid, 0, 25, 0, function (err, categoryData) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var feed = new rss({
|
||||||
|
title: categoryData.name,
|
||||||
|
description: categoryData.description,
|
||||||
|
feed_url: nconf.get('url') + '/category/' + cid + '.rss',
|
||||||
|
site_url: nconf.get('url') + '/category/' + categoryData.cid,
|
||||||
|
ttl: 60
|
||||||
});
|
});
|
||||||
|
|
||||||
var xml = feed.xml();
|
// Add pubDate if category has topics
|
||||||
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
if (categoryData.topics.length > 0) {
|
||||||
|
feed.pubDate = new Date(parseInt(categoryData.topics[0].lastposttime, 10)).toUTCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryData.topics.forEach(function(topicData) {
|
||||||
|
feed.item({
|
||||||
|
title: topicData.title,
|
||||||
|
url: nconf.get('url') + '/topic/' + topicData.slug,
|
||||||
|
author: topicData.username,
|
||||||
|
date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
function generateForRecent(req, res, next) {
|
var xml = feed.xml();
|
||||||
topics.getLatestTopics(0, 0, 19, 'month', function (err, recentData) {
|
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
||||||
if(err){
|
});
|
||||||
return next(err);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var feed = new rss({
|
function generateForRecent(req, res, next) {
|
||||||
title: 'Recently Active Topics',
|
topics.getLatestTopics(0, 0, 19, 'month', function (err, recentData) {
|
||||||
description: 'A list of topics that have been active within the past 24 hours',
|
if(err){
|
||||||
feed_url: nconf.get('url') + '/recent.rss',
|
return next(err);
|
||||||
site_url: nconf.get('url') + '/recent',
|
}
|
||||||
ttl: 60
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add pubDate if recent topics list contains topics
|
var feed = new rss({
|
||||||
if (recentData.topics.length > 0) {
|
title: 'Recently Active Topics',
|
||||||
feed.pubDate = new Date(parseInt(recentData.topics[0].lastposttime, 10)).toUTCString();
|
description: 'A list of topics that have been active within the past 24 hours',
|
||||||
}
|
feed_url: nconf.get('url') + '/recent.rss',
|
||||||
|
site_url: nconf.get('url') + '/recent',
|
||||||
recentData.topics.forEach(function(topicData) {
|
ttl: 60
|
||||||
feed.item({
|
|
||||||
title: topicData.title,
|
|
||||||
url: nconf.get('url') + '/topic/' + topicData.slug,
|
|
||||||
author: topicData.username,
|
|
||||||
date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var xml = feed.xml();
|
// Add pubDate if recent topics list contains topics
|
||||||
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
if (recentData.topics.length > 0) {
|
||||||
|
feed.pubDate = new Date(parseInt(recentData.topics[0].lastposttime, 10)).toUTCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
recentData.topics.forEach(function(topicData) {
|
||||||
|
feed.item({
|
||||||
|
title: topicData.title,
|
||||||
|
url: nconf.get('url') + '/topic/' + topicData.slug,
|
||||||
|
author: topicData.username,
|
||||||
|
date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
function generateForPopular(req, res, next) {
|
var xml = feed.xml();
|
||||||
topics.getTopicsFromSet(0, 'topics:posts', 0, 19, function (err, popularData) {
|
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
||||||
if(err){
|
});
|
||||||
return next(err);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var feed = new rss({
|
function generateForPopular(req, res, next) {
|
||||||
title: 'Popular Topics',
|
topics.getTopicsFromSet(0, 'topics:posts', 0, 19, function (err, popularData) {
|
||||||
description: 'A list of topics that are sorted by post count',
|
if(err){
|
||||||
feed_url: nconf.get('url') + '/popular.rss',
|
return next(err);
|
||||||
site_url: nconf.get('url') + '/popular',
|
}
|
||||||
ttl: 60
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add pubDate if recent topics list contains topics
|
var feed = new rss({
|
||||||
if (popularData.topics.length > 0) {
|
title: 'Popular Topics',
|
||||||
feed.pubDate = new Date(parseInt(popularData.topics[0].lastposttime, 10)).toUTCString();
|
description: 'A list of topics that are sorted by post count',
|
||||||
}
|
feed_url: nconf.get('url') + '/popular.rss',
|
||||||
|
site_url: nconf.get('url') + '/popular',
|
||||||
popularData.topics.forEach(function(topicData) {
|
ttl: 60
|
||||||
feed.item({
|
|
||||||
title: topicData.title,
|
|
||||||
url: nconf.get('url') + '/topic/' + topicData.slug,
|
|
||||||
author: topicData.username,
|
|
||||||
date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var xml = feed.xml();
|
// Add pubDate if recent topics list contains topics
|
||||||
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
if (popularData.topics.length > 0) {
|
||||||
|
feed.pubDate = new Date(parseInt(popularData.topics[0].lastposttime, 10)).toUTCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
popularData.topics.forEach(function(topicData) {
|
||||||
|
feed.item({
|
||||||
|
title: topicData.title,
|
||||||
|
url: nconf.get('url') + '/topic/' + topicData.slug,
|
||||||
|
author: topicData.username,
|
||||||
|
date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
}(exports));
|
var xml = feed.xml();
|
||||||
|
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(app, middleware, controllers){
|
||||||
|
app.get('/topic/:topic_id.rss', hasTopicPrivileges, generateForTopic);
|
||||||
|
app.get('/category/:category_id.rss', hasCategoryPrivileges, generateForCategory);
|
||||||
|
app.get('/recent.rss', generateForRecent);
|
||||||
|
app.get('/popular.rss', generateForPopular);
|
||||||
|
};
|
||||||
@@ -5,20 +5,19 @@ var nconf = require('nconf'),
|
|||||||
meta = require('./../meta'),
|
meta = require('./../meta'),
|
||||||
|
|
||||||
plugins = require('./../plugins'),
|
plugins = require('./../plugins'),
|
||||||
metaRoute = require('./meta'),
|
metaRoutes = require('./meta'),
|
||||||
apiRoute = require('./api'),
|
apiRoutes = require('./api'),
|
||||||
admin = require('./admin'),
|
adminRoutes = require('./admin'),
|
||||||
feedsRoute = require('./feeds');
|
feedRoutes = require('./feeds'),
|
||||||
|
pluginRoutes = require('./plugins');
|
||||||
|
|
||||||
|
|
||||||
module.exports = function(app, middleware) {
|
module.exports = function(app, middleware) {
|
||||||
app.namespace(nconf.get('relative_path'), function() {
|
app.namespace(nconf.get('relative_path'), function() {
|
||||||
//temp
|
adminRoutes(app, middleware, controllers);
|
||||||
metaRoute.createRoutes(app);
|
metaRoutes(app, middleware, controllers);
|
||||||
feedsRoute.createRoutes(app);
|
apiRoutes(app, middleware, controllers);
|
||||||
|
feedRoutes(app, middleware, controllers);
|
||||||
admin(app, middleware, controllers);
|
|
||||||
apiRoute(app, middleware, controllers);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every view has an associated API route.
|
* Every view has an associated API route.
|
||||||
@@ -122,83 +121,10 @@ module.exports = function(app, middleware) {
|
|||||||
app.get('/users/search', middleware.buildHeader, middleware.checkGlobalPrivacySettings, controllers.users.getUsersForSearch);
|
app.get('/users/search', middleware.buildHeader, middleware.checkGlobalPrivacySettings, controllers.users.getUsersForSearch);
|
||||||
app.get('/api/users/search', middleware.checkGlobalPrivacySettings, controllers.users.getUsersForSearch);
|
app.get('/api/users/search', middleware.checkGlobalPrivacySettings, controllers.users.getUsersForSearch);
|
||||||
|
|
||||||
/* Misc */
|
pluginRoutes(app, middleware, controllers);
|
||||||
app.get('/sitemap.xml', controllers.sitemap);
|
|
||||||
app.get('/robots.txt', controllers.robots);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Other routes
|
|
||||||
require('./plugins')(app);
|
|
||||||
|
|
||||||
// Debug routes
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
require('./debug')(app);
|
require('./debug')(app, middleware, controllers);
|
||||||
}
|
}
|
||||||
|
|
||||||
var custom_routes = {
|
|
||||||
'routes': [],
|
|
||||||
'api': [],
|
|
||||||
'templates': []
|
|
||||||
};
|
|
||||||
|
|
||||||
app.get_custom_templates = function() {
|
|
||||||
return custom_routes.templates.map(function(tpl) {
|
|
||||||
return tpl.template;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
plugins.ready(function() {
|
|
||||||
/*
|
|
||||||
* TO BE DEPRECATED post 0.4x
|
|
||||||
*/
|
|
||||||
plugins.fireHook('filter:server.create_routes', custom_routes, function(err, custom_routes) {
|
|
||||||
var route,
|
|
||||||
routes = custom_routes.routes;
|
|
||||||
|
|
||||||
for (route in routes) {
|
|
||||||
if (routes.hasOwnProperty(route)) {
|
|
||||||
(function(route) {
|
|
||||||
app[routes[route].method || 'get'](routes[route].route, function(req, res) {
|
|
||||||
routes[route].options(req, res, function(options) {
|
|
||||||
app.build_header({
|
|
||||||
req: options.req || req,
|
|
||||||
res: options.res || res
|
|
||||||
}, function (err, header) {
|
|
||||||
//res.send(header + options.content + templates.footer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}(route));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var apiRoutes = custom_routes.api;
|
|
||||||
for (route in apiRoutes) {
|
|
||||||
if (apiRoutes.hasOwnProperty(route)) {
|
|
||||||
(function(route) {
|
|
||||||
app[apiRoutes[route].method || 'get']('/api' + apiRoutes[route].route, function(req, res) {
|
|
||||||
apiRoutes[route].callback(req, res, function(data) {
|
|
||||||
res.json(data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}(route));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var templateRoutes = custom_routes.templates;
|
|
||||||
for (route in templateRoutes) {
|
|
||||||
if (templateRoutes.hasOwnProperty(route)) {
|
|
||||||
(function(route) {
|
|
||||||
app.get('/templates/' + templateRoutes[route].template, function(req, res) {
|
|
||||||
res.send(templateRoutes[route].content);
|
|
||||||
});
|
|
||||||
}(route));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1,67 +1,78 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
var path = require('path'),
|
var path = require('path'),
|
||||||
nconf = require('nconf'),
|
nconf = require('nconf'),
|
||||||
less = require('less'),
|
less = require('less'),
|
||||||
|
|
||||||
meta = require('../meta'),
|
meta = require('../meta'),
|
||||||
db = require('../database'),
|
db = require('../database'),
|
||||||
plugins = require('../plugins');
|
plugins = require('../plugins'),
|
||||||
|
|
||||||
(function (Meta) {
|
minificationEnabled = false;
|
||||||
Meta.createRoutes = function(app) {
|
|
||||||
app.get('/stylesheet.css', function(req, res) {
|
|
||||||
if (meta.css.cache) {
|
function sendMinifiedJS(req, res, next) {
|
||||||
res.type('text/css').send(200, meta.css.cache);
|
function sendCached() {
|
||||||
|
return res.type('text/javascript').send(meta.js.cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meta.js.cache) {
|
||||||
|
sendCached();
|
||||||
|
} else {
|
||||||
|
if (minificationEnabled) {
|
||||||
|
meta.js.minify(function() {
|
||||||
|
sendCached();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Compress only
|
||||||
|
meta.js.concatenate(function() {
|
||||||
|
sendCached();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendStylesheet(req, res, next) {
|
||||||
|
if (meta.css.cache) {
|
||||||
|
res.type('text/css').send(200, meta.css.cache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.getObjectFields('config', ['theme:type', 'theme:id'], function(err, themeData) {
|
||||||
|
var themeId = (themeData['theme:id'] || 'nodebb-theme-vanilla'),
|
||||||
|
baseThemePath = path.join(nconf.get('themes_path'), (themeData['theme:type'] && themeData['theme:type'] === 'local' ? themeId : 'nodebb-theme-vanilla')),
|
||||||
|
paths = [baseThemePath, path.join(__dirname, '../../node_modules')],
|
||||||
|
source = '@import "./theme";',
|
||||||
|
x, numLESS;
|
||||||
|
|
||||||
|
// Add the imports for each LESS file
|
||||||
|
for(x=0,numLESS=plugins.lessFiles.length;x<numLESS;x++) {
|
||||||
|
source += '\n@import "./' + plugins.lessFiles[x] + '";';
|
||||||
|
}
|
||||||
|
|
||||||
|
var parser = new (less.Parser)({
|
||||||
|
paths: paths
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.parse(source, function(err, tree) {
|
||||||
|
if (err) {
|
||||||
|
res.send(500, err.message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.getObjectFields('config', ['theme:type', 'theme:id'], function(err, themeData) {
|
meta.css.cache = tree.toCSS({
|
||||||
var themeId = (themeData['theme:id'] || 'nodebb-theme-vanilla'),
|
compress: true
|
||||||
baseThemePath = path.join(nconf.get('themes_path'), (themeData['theme:type'] && themeData['theme:type'] === 'local' ? themeId : 'nodebb-theme-vanilla')),
|
|
||||||
paths = [baseThemePath, path.join(__dirname, '../../node_modules')],
|
|
||||||
source = '@import "./theme";',
|
|
||||||
x, numLESS;
|
|
||||||
|
|
||||||
// Add the imports for each LESS file
|
|
||||||
for(x=0,numLESS=plugins.lessFiles.length;x<numLESS;x++) {
|
|
||||||
source += '\n@import "./' + plugins.lessFiles[x] + '";';
|
|
||||||
}
|
|
||||||
|
|
||||||
var parser = new (less.Parser)({
|
|
||||||
paths: paths
|
|
||||||
});
|
|
||||||
|
|
||||||
parser.parse(source, function(err, tree) {
|
|
||||||
if (err) {
|
|
||||||
res.send(500, err.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta.css.cache = tree.toCSS({
|
|
||||||
compress: true
|
|
||||||
});
|
|
||||||
res.type('text/css').send(200, meta.css.cache);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
res.type('text/css').send(200, meta.css.cache);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
app.get('/nodebb.min.js', function(req, res) {
|
module.exports = function(app, middleware, controllers) {
|
||||||
var sendCached = function() {
|
minificationEnabled = app.enabled('minification');
|
||||||
return res.type('text/javascript').send(meta.js.cache);
|
|
||||||
}
|
app.get('/stylesheet.css', sendStylesheet);
|
||||||
if (meta.js.cache) {
|
app.get('/nodebb.min.js', sendMinifiedJS);
|
||||||
sendCached();
|
app.get('/sitemap.xml', controllers.sitemap);
|
||||||
} else {
|
app.get('/robots.txt', controllers.robots);
|
||||||
if (app.enabled('minification')) {
|
};
|
||||||
meta.js.minify(function() {
|
|
||||||
sendCached();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Compress only
|
|
||||||
meta.js.concatenate(function() {
|
|
||||||
sendCached();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
})(exports);
|
|
||||||
@@ -6,73 +6,184 @@ var nconf = require('nconf'),
|
|||||||
validator = require('validator'),
|
validator = require('validator'),
|
||||||
_ = require('underscore'),
|
_ = require('underscore'),
|
||||||
async = require('async'),
|
async = require('async'),
|
||||||
plugins = require('../plugins'),
|
|
||||||
|
|
||||||
PluginRoutes = function(app) {
|
plugins = require('../plugins');
|
||||||
/**
|
|
||||||
* GET/PUT /plugins/fireHook to be deprecated after 0.4.x
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
app.get('/plugins/fireHook', function(req, res) {
|
|
||||||
// GET = filter
|
|
||||||
plugins.fireHook('filter:' + req.query.hook, req.query.args, function(err, returnData) {
|
|
||||||
if (typeof returnData === 'object') {
|
|
||||||
res.json(200, returnData);
|
|
||||||
} else {
|
|
||||||
res.send(200, validator.escape(returnData));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/plugins/fireHook', function(req, res) {
|
function setupPluginRoutes(app) {
|
||||||
// PUT = action
|
var custom_routes = {
|
||||||
var hook = 'action:' + req.body.hook;
|
'routes': [],
|
||||||
if (plugins.hasListeners(hook)) {
|
'api': [],
|
||||||
// Hook executes
|
'templates': []
|
||||||
plugins.fireHook(hook, req.body.args);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
res.send(200);
|
app.get_custom_templates = function() {
|
||||||
});
|
return custom_routes.templates.map(function(tpl) {
|
||||||
|
return tpl.template;
|
||||||
// Static Assets
|
|
||||||
app.get('/plugins/:id/*', function(req, res) {
|
|
||||||
var relPath = req._parsedUrl.pathname.replace(nconf.get('relative_path') + '/plugins/', ''),
|
|
||||||
matches = _.map(plugins.staticDirs, function(realPath, mappedPath) {
|
|
||||||
if (relPath.match(mappedPath)) {
|
|
||||||
return mappedPath;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).filter(function(a) { return a; });
|
|
||||||
|
|
||||||
if (matches) {
|
|
||||||
async.map(matches, function(mappedPath, next) {
|
|
||||||
var filePath = path.join(plugins.staticDirs[mappedPath], decodeURIComponent(relPath.slice(mappedPath.length)));
|
|
||||||
|
|
||||||
fs.exists(filePath, function(exists) {
|
|
||||||
if (exists) {
|
|
||||||
next(null, filePath);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, function(err, matches) {
|
|
||||||
// Filter out the nulls
|
|
||||||
matches = matches.filter(function(a) {
|
|
||||||
return a;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (matches.length) {
|
|
||||||
res.sendfile(matches[0]);
|
|
||||||
} else {
|
|
||||||
res.redirect('/404');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.redirect('/404');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = PluginRoutes;
|
plugins.ready(function() {
|
||||||
|
/*
|
||||||
|
* TO BE DEPRECATED post 0.4x and replaced with something that isn't as complicated as this...
|
||||||
|
*/
|
||||||
|
plugins.fireHook('filter:server.create_routes', custom_routes, function(err, custom_routes) {
|
||||||
|
var route,
|
||||||
|
routes = custom_routes.routes;
|
||||||
|
|
||||||
|
for (route in routes) {
|
||||||
|
if (routes.hasOwnProperty(route)) {
|
||||||
|
(function(route) {
|
||||||
|
app[routes[route].method || 'get'](routes[route].route, function(req, res) {
|
||||||
|
routes[route].options(req, res, function(options) {
|
||||||
|
app.build_header({
|
||||||
|
req: options.req || req,
|
||||||
|
res: options.res || res
|
||||||
|
}, function (err, header) {
|
||||||
|
//res.send(header + options.content + templates.footer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}(route));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiRoutes = custom_routes.api;
|
||||||
|
for (route in apiRoutes) {
|
||||||
|
if (apiRoutes.hasOwnProperty(route)) {
|
||||||
|
(function(route) {
|
||||||
|
app[apiRoutes[route].method || 'get']('/api' + apiRoutes[route].route, function(req, res) {
|
||||||
|
apiRoutes[route].callback(req, res, function(data) {
|
||||||
|
res.json(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}(route));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var templateRoutes = custom_routes.templates;
|
||||||
|
for (route in templateRoutes) {
|
||||||
|
if (templateRoutes.hasOwnProperty(route)) {
|
||||||
|
(function(route) {
|
||||||
|
app.get('/templates/' + templateRoutes[route].template, function(req, res) {
|
||||||
|
res.send(templateRoutes[route].content);
|
||||||
|
});
|
||||||
|
}(route));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupPluginAdminRoutes(app) {
|
||||||
|
var custom_routes = {
|
||||||
|
'routes': [],
|
||||||
|
'api': []
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins.ready(function() {
|
||||||
|
/*
|
||||||
|
* TO BE DEPRECATED post 0.4x and replaced with something that isn't as complicated as this...
|
||||||
|
*/
|
||||||
|
plugins.fireHook('filter:admin.create_routes', custom_routes, function(err, custom_routes) {
|
||||||
|
var route, routes = custom_routes.routes;
|
||||||
|
|
||||||
|
for (route in routes) {
|
||||||
|
if (routes.hasOwnProperty(route)) {
|
||||||
|
(function(route) {
|
||||||
|
app[routes[route].method || 'get']('/admin' + routes[route].route, function(req, res) {
|
||||||
|
routes[route].options(req, res, function(options) {
|
||||||
|
Admin.buildHeader(req, res, function (err, header) {
|
||||||
|
//res.send(header + options.content + templates['admin/footer']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}(route));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiRoutes = custom_routes.api;
|
||||||
|
for (route in apiRoutes) {
|
||||||
|
if (apiRoutes.hasOwnProperty(route)) {
|
||||||
|
(function(route) {
|
||||||
|
app[apiRoutes[route].method || 'get']('/api/admin' + apiRoutes[route].route, function(req, res) {
|
||||||
|
apiRoutes[route].callback(req, res, function(data) {
|
||||||
|
res.json(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}(route));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(app, middleware, controllers) {
|
||||||
|
/**
|
||||||
|
* GET/PUT /plugins/fireHook to be deprecated after 0.4.x
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
app.get('/plugins/fireHook', function(req, res) {
|
||||||
|
// GET = filter
|
||||||
|
plugins.fireHook('filter:' + req.query.hook, req.query.args, function(err, returnData) {
|
||||||
|
if (typeof returnData === 'object') {
|
||||||
|
res.json(200, returnData);
|
||||||
|
} else {
|
||||||
|
res.send(200, validator.escape(returnData));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.put('/plugins/fireHook', function(req, res) {
|
||||||
|
// PUT = action
|
||||||
|
var hook = 'action:' + req.body.hook;
|
||||||
|
if (plugins.hasListeners(hook)) {
|
||||||
|
// Hook executes
|
||||||
|
plugins.fireHook(hook, req.body.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Static Assets
|
||||||
|
app.get('/plugins/:id/*', function(req, res) {
|
||||||
|
var relPath = req._parsedUrl.pathname.replace(nconf.get('relative_path') + '/plugins/', ''),
|
||||||
|
matches = _.map(plugins.staticDirs, function(realPath, mappedPath) {
|
||||||
|
if (relPath.match(mappedPath)) {
|
||||||
|
return mappedPath;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).filter(function(a) { return a; });
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
async.map(matches, function(mappedPath, next) {
|
||||||
|
var filePath = path.join(plugins.staticDirs[mappedPath], decodeURIComponent(relPath.slice(mappedPath.length)));
|
||||||
|
|
||||||
|
fs.exists(filePath, function(exists) {
|
||||||
|
if (exists) {
|
||||||
|
next(null, filePath);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function(err, matches) {
|
||||||
|
// Filter out the nulls
|
||||||
|
matches = matches.filter(function(a) {
|
||||||
|
return a;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matches.length) {
|
||||||
|
res.sendfile(matches[0]);
|
||||||
|
} else {
|
||||||
|
res.redirect('/404');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.redirect('/404');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setupPluginRoutes(app);
|
||||||
|
setupPluginAdminRoutes(app);
|
||||||
|
};
|
||||||
@@ -14,12 +14,7 @@ var path = require('path'),
|
|||||||
plugins = require('./plugins'),
|
plugins = require('./plugins'),
|
||||||
logger = require('./logger'),
|
logger = require('./logger'),
|
||||||
middleware = require('./middleware'),
|
middleware = require('./middleware'),
|
||||||
routes = require('./routes'),
|
routes = require('./routes');
|
||||||
|
|
||||||
admin = require('./routes/admin'),
|
|
||||||
apiRoute = require('./routes/api'),
|
|
||||||
feedsRoute = require('./routes/feeds'),
|
|
||||||
metaRoute = require('./routes/meta');
|
|
||||||
|
|
||||||
if(nconf.get('ssl')) {
|
if(nconf.get('ssl')) {
|
||||||
server = require('https').createServer({
|
server = require('https').createServer({
|
||||||
|
|||||||
Reference in New Issue
Block a user