mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-11-03 20:45:58 +01:00 
			
		
		
		
	refactor: async/await, remove dupe code for homepage routes
This commit is contained in:
		@@ -10,8 +10,6 @@ const user = require('../../user');
 | 
				
			|||||||
const languages = require('../../languages');
 | 
					const languages = require('../../languages');
 | 
				
			||||||
const meta = require('../../meta');
 | 
					const meta = require('../../meta');
 | 
				
			||||||
const plugins = require('../../plugins');
 | 
					const plugins = require('../../plugins');
 | 
				
			||||||
const privileges = require('../../privileges');
 | 
					 | 
				
			||||||
const categories = require('../../categories');
 | 
					 | 
				
			||||||
const notifications = require('../../notifications');
 | 
					const notifications = require('../../notifications');
 | 
				
			||||||
const db = require('../../database');
 | 
					const db = require('../../database');
 | 
				
			||||||
const helpers = require('../helpers');
 | 
					const helpers = require('../helpers');
 | 
				
			||||||
@@ -241,49 +239,12 @@ async function getNotificationSettings(userData) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getHomePageRoutes(userData) {
 | 
					async function getHomePageRoutes(userData) {
 | 
				
			||||||
	let cids = await categories.getAllCidsFromSet('cid:0:children');
 | 
						let routes = await helpers.getHomePageRoutes(userData.uid);
 | 
				
			||||||
	cids = await privileges.categories.filterCids('find', cids, userData.uid);
 | 
					 | 
				
			||||||
	let categoryData = await categories.getCategoriesFields(cids, ['name', 'slug']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	categoryData = categoryData.map(function (category) {
 | 
					 | 
				
			||||||
		return {
 | 
					 | 
				
			||||||
			route: 'category/' + category.slug,
 | 
					 | 
				
			||||||
			name: 'Category: ' + category.name,
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const data = await plugins.fireHook('filter:homepage.get', { routes: [
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			route: 'categories',
 | 
					 | 
				
			||||||
			name: 'Categories',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			route: 'unread',
 | 
					 | 
				
			||||||
			name: 'Unread',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			route: 'recent',
 | 
					 | 
				
			||||||
			name: 'Recent',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			route: 'top',
 | 
					 | 
				
			||||||
			name: 'Top',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			route: 'popular',
 | 
					 | 
				
			||||||
			name: 'Popular',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	].concat(categoryData, [
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			route: 'custom',
 | 
					 | 
				
			||||||
			name: 'Custom',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	]) });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Set selected for each route
 | 
						// Set selected for each route
 | 
				
			||||||
	var customIdx;
 | 
						var customIdx;
 | 
				
			||||||
	var hasSelected = false;
 | 
						var hasSelected = false;
 | 
				
			||||||
	data.routes = data.routes.map(function (route, idx) {
 | 
						routes = routes.map(function (route, idx) {
 | 
				
			||||||
		if (route.route === userData.settings.homePageRoute) {
 | 
							if (route.route === userData.settings.homePageRoute) {
 | 
				
			||||||
			route.selected = true;
 | 
								route.selected = true;
 | 
				
			||||||
			hasSelected = true;
 | 
								hasSelected = true;
 | 
				
			||||||
@@ -299,8 +260,8 @@ async function getHomePageRoutes(userData) {
 | 
				
			|||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!hasSelected && customIdx && userData.settings.homePageRoute !== 'none') {
 | 
						if (!hasSelected && customIdx && userData.settings.homePageRoute !== 'none') {
 | 
				
			||||||
		data.routes[customIdx].selected = true;
 | 
							routes[customIdx].selected = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data.routes;
 | 
						return routes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +1,28 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const json2csv = require('json-2-csv').json2csv;
 | 
				
			||||||
var json2csv = require('json-2-csv').json2csv;
 | 
					const util = require('util');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var meta = require('../../meta');
 | 
					const meta = require('../../meta');
 | 
				
			||||||
var analytics = require('../../analytics');
 | 
					const analytics = require('../../analytics');
 | 
				
			||||||
 | 
					const utils = require('../../utils');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var errorsController = module.exports;
 | 
					const errorsController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
errorsController.get = function (req, res, next) {
 | 
					errorsController.get = async function (req, res) {
 | 
				
			||||||
	async.waterfall([
 | 
						const data = await utils.promiseParallel({
 | 
				
			||||||
		function (next) {
 | 
							'not-found': meta.errors.get(true),
 | 
				
			||||||
			async.parallel({
 | 
							analytics: analytics.getErrorAnalytics(),
 | 
				
			||||||
				'not-found': async.apply(meta.errors.get, true),
 | 
						});
 | 
				
			||||||
				analytics: async.apply(analytics.getErrorAnalytics),
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (data) {
 | 
					 | 
				
			||||||
	res.render('admin/advanced/errors', data);
 | 
						res.render('admin/advanced/errors', data);
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
errorsController.export = function (req, res, next) {
 | 
					const json2csvAsync = util.promisify(function (data, callback) {
 | 
				
			||||||
	async.waterfall([
 | 
						json2csv(data, (err, output) => callback(err, output));
 | 
				
			||||||
		async.apply(meta.errors.get, false),
 | 
					});
 | 
				
			||||||
		async.apply(json2csv),
 | 
					
 | 
				
			||||||
		function (csv) {
 | 
					errorsController.export = async function (req, res) {
 | 
				
			||||||
 | 
						const data = await meta.errors.get(false);
 | 
				
			||||||
 | 
						const csv = await json2csvAsync(data);
 | 
				
			||||||
	res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="404.csv"').send(csv);
 | 
						res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="404.csv"').send(csv);
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,40 +1,31 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const db = require('../../database');
 | 
				
			||||||
 | 
					const events = require('../../events');
 | 
				
			||||||
 | 
					const pagination = require('../../pagination');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var db = require('../../database');
 | 
					const eventsController = module.exports;
 | 
				
			||||||
var events = require('../../events');
 | 
					 | 
				
			||||||
var pagination = require('../../pagination');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var eventsController = module.exports;
 | 
					eventsController.get = async function (req, res) {
 | 
				
			||||||
 | 
						const page = parseInt(req.query.page, 10) || 1;
 | 
				
			||||||
eventsController.get = function (req, res, next) {
 | 
						const itemsPerPage = parseInt(req.query.perPage, 10) || 20;
 | 
				
			||||||
	var page = parseInt(req.query.page, 10) || 1;
 | 
						const start = (page - 1) * itemsPerPage;
 | 
				
			||||||
	var itemsPerPage = parseInt(req.query.perPage, 10) || 20;
 | 
						const stop = start + itemsPerPage - 1;
 | 
				
			||||||
	var start = (page - 1) * itemsPerPage;
 | 
					 | 
				
			||||||
	var stop = start + itemsPerPage - 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Limit by date
 | 
						// Limit by date
 | 
				
			||||||
	var from = req.query.start ? new Date(req.query.start) || undefined : undefined;
 | 
						let from = req.query.start ? new Date(req.query.start) || undefined : undefined;
 | 
				
			||||||
	var to = req.query.end ? new Date(req.query.end) || undefined : new Date();
 | 
						let to = req.query.end ? new Date(req.query.end) || undefined : new Date();
 | 
				
			||||||
	from = from && from.setHours(0, 0, 0, 0);	// setHours returns a unix timestamp (Number, not Date)
 | 
						from = from && from.setHours(0, 0, 0, 0);	// setHours returns a unix timestamp (Number, not Date)
 | 
				
			||||||
	to = to && to.setHours(23, 59, 59, 999);	// setHours returns a unix timestamp (Number, not Date)
 | 
						to = to && to.setHours(23, 59, 59, 999);	// setHours returns a unix timestamp (Number, not Date)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var currentFilter = req.query.type || '';
 | 
						const currentFilter = req.query.type || '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async.waterfall([
 | 
						const [eventCount, eventData] = await Promise.all([
 | 
				
			||||||
		function (next) {
 | 
							db.sortedSetCount('events:time' + (currentFilter ? ':' + currentFilter : ''), from || '-inf', to),
 | 
				
			||||||
			async.parallel({
 | 
							events.getEvents(currentFilter, start, stop, from || '-inf', to),
 | 
				
			||||||
				eventCount: function (next) {
 | 
						]);
 | 
				
			||||||
					db.sortedSetCount('events:time' + (currentFilter ? ':' + currentFilter : ''), from || '-inf', to, next);
 | 
					
 | 
				
			||||||
				},
 | 
						const types = [''].concat(events.types).map(function (type) {
 | 
				
			||||||
				events: function (next) {
 | 
					 | 
				
			||||||
					events.getEvents(currentFilter, start, stop, from || '-inf', to, next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (results) {
 | 
					 | 
				
			||||||
			var types = [''].concat(events.types).map(function (type) {
 | 
					 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			value: type,
 | 
								value: type,
 | 
				
			||||||
			name: type || 'all',
 | 
								name: type || 'all',
 | 
				
			||||||
@@ -42,14 +33,12 @@ eventsController.get = function (req, res, next) {
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var pageCount = Math.max(1, Math.ceil(results.eventCount / itemsPerPage));
 | 
						const pageCount = Math.max(1, Math.ceil(eventCount / itemsPerPage));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.render('admin/advanced/events', {
 | 
						res.render('admin/advanced/events', {
 | 
				
			||||||
				events: results.events,
 | 
							events: eventData,
 | 
				
			||||||
		pagination: pagination.create(page, pageCount, req.query),
 | 
							pagination: pagination.create(page, pageCount, req.query),
 | 
				
			||||||
		types: types,
 | 
							types: types,
 | 
				
			||||||
		query: req.query,
 | 
							query: req.query,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,63 +1,45 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const validator = require('validator');
 | 
				
			||||||
var validator = require('validator');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var db = require('../../database');
 | 
					const db = require('../../database');
 | 
				
			||||||
var groups = require('../../groups');
 | 
					const groups = require('../../groups');
 | 
				
			||||||
var meta = require('../../meta');
 | 
					const meta = require('../../meta');
 | 
				
			||||||
var pagination = require('../../pagination');
 | 
					const pagination = require('../../pagination');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var groupsController = module.exports;
 | 
					const groupsController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
groupsController.list = function (req, res, next) {
 | 
					groupsController.list = async function (req, res) {
 | 
				
			||||||
	var page = parseInt(req.query.page, 10) || 1;
 | 
						const page = parseInt(req.query.page, 10) || 1;
 | 
				
			||||||
	var groupsPerPage = 20;
 | 
						const groupsPerPage = 20;
 | 
				
			||||||
	var pageCount = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async.waterfall([
 | 
						let groupNames = await getGroupNames();
 | 
				
			||||||
		function (next) {
 | 
						const pageCount = Math.ceil(groupNames.length / groupsPerPage);
 | 
				
			||||||
			getGroupNames(next);
 | 
						const start = (page - 1) * groupsPerPage;
 | 
				
			||||||
		},
 | 
						const stop = start + groupsPerPage - 1;
 | 
				
			||||||
		function (groupNames, next) {
 | 
					 | 
				
			||||||
			pageCount = Math.ceil(groupNames.length / groupsPerPage);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var start = (page - 1) * groupsPerPage;
 | 
					 | 
				
			||||||
			var stop = start + groupsPerPage - 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	groupNames = groupNames.slice(start, stop + 1);
 | 
						groupNames = groupNames.slice(start, stop + 1);
 | 
				
			||||||
			groups.getGroupsData(groupNames, next);
 | 
						const groupData = await groups.getGroupsData(groupNames);
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (groupData) {
 | 
					 | 
				
			||||||
	res.render('admin/manage/groups', {
 | 
						res.render('admin/manage/groups', {
 | 
				
			||||||
		groups: groupData,
 | 
							groups: groupData,
 | 
				
			||||||
		pagination: pagination.create(page, pageCount),
 | 
							pagination: pagination.create(page, pageCount),
 | 
				
			||||||
		yourid: req.uid,
 | 
							yourid: req.uid,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
groupsController.get = function (req, res, callback) {
 | 
					groupsController.get = async function (req, res, next) {
 | 
				
			||||||
	var groupName = req.params.name;
 | 
						const groupName = req.params.name;
 | 
				
			||||||
	async.waterfall([
 | 
						const [groupNames, group] = await Promise.all([
 | 
				
			||||||
		function (next) {
 | 
							getGroupNames(),
 | 
				
			||||||
			async.parallel({
 | 
							groups.get(groupName, { uid: req.uid, truncateUserList: true, userListCount: 20 }),
 | 
				
			||||||
				groupNames: function (next) {
 | 
						]);
 | 
				
			||||||
					getGroupNames(next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				group: function (next) {
 | 
					 | 
				
			||||||
					groups.get(groupName, { uid: req.uid, truncateUserList: true, userListCount: 20 }, next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (result) {
 | 
					 | 
				
			||||||
			if (!result.group) {
 | 
					 | 
				
			||||||
				return callback();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			result.group.isOwner = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			result.groupNames = result.groupNames.map(function (name) {
 | 
						if (!group) {
 | 
				
			||||||
 | 
							return next();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						group.isOwner = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const groupNameData = groupNames.map(function (name) {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			encodedName: encodeURIComponent(name),
 | 
								encodedName: encodeURIComponent(name),
 | 
				
			||||||
			displayName: validator.escape(String(name)),
 | 
								displayName: validator.escape(String(name)),
 | 
				
			||||||
@@ -66,26 +48,15 @@ groupsController.get = function (req, res, callback) {
 | 
				
			|||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.render('admin/manage/group', {
 | 
						res.render('admin/manage/group', {
 | 
				
			||||||
				group: result.group,
 | 
							group: group,
 | 
				
			||||||
				groupNames: result.groupNames,
 | 
							groupNames: groupNameData,
 | 
				
			||||||
		allowPrivateGroups: meta.config.allowPrivateGroups,
 | 
							allowPrivateGroups: meta.config.allowPrivateGroups,
 | 
				
			||||||
		maximumGroupNameLength: meta.config.maximumGroupNameLength,
 | 
							maximumGroupNameLength: meta.config.maximumGroupNameLength,
 | 
				
			||||||
		maximumGroupTitleLength: meta.config.maximumGroupTitleLength,
 | 
							maximumGroupTitleLength: meta.config.maximumGroupTitleLength,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], callback);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getGroupNames(callback) {
 | 
					async function getGroupNames() {
 | 
				
			||||||
	async.waterfall([
 | 
						const groupNames = await db.getSortedSetRange('groups:createtime', 0, -1);
 | 
				
			||||||
		function (next) {
 | 
						return groupNames.filter(name => name !== 'registered-users' && !groups.isPrivilegeGroup(name));
 | 
				
			||||||
			db.getSortedSetRange('groups:createtime', 0, -1, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (groupNames, next) {
 | 
					 | 
				
			||||||
			groupNames = groupNames.filter(function (name) {
 | 
					 | 
				
			||||||
				return name !== 'registered-users' && !groups.isPrivilegeGroup(name);
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
			next(null, groupNames);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], callback);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,58 +1,10 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const helpers = require('../helpers');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var categories = require('../../categories');
 | 
					const homePageController = module.exports;
 | 
				
			||||||
var privileges = require('../../privileges');
 | 
					 | 
				
			||||||
var plugins = require('../../plugins');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var homePageController = module.exports;
 | 
					homePageController.get = async function (req, res) {
 | 
				
			||||||
 | 
						const routes = await helpers.getHomePageRoutes(req.uid);
 | 
				
			||||||
homePageController.get = function (req, res, next) {
 | 
						res.render('admin/general/homepage', { routes: routes });
 | 
				
			||||||
	async.waterfall([
 | 
					 | 
				
			||||||
		function (next) {
 | 
					 | 
				
			||||||
			categories.getAllCidsFromSet('categories:cid', next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (cids, next) {
 | 
					 | 
				
			||||||
			privileges.categories.filterCids('find', cids, 0, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (cids, next) {
 | 
					 | 
				
			||||||
			categories.getCategoriesFields(cids, ['name', 'slug'], next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (categoryData, next) {
 | 
					 | 
				
			||||||
			categoryData = categoryData.map(function (category) {
 | 
					 | 
				
			||||||
				return {
 | 
					 | 
				
			||||||
					route: 'category/' + category.slug,
 | 
					 | 
				
			||||||
					name: 'Category: ' + category.name,
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			plugins.fireHook('filter:homepage.get', { routes: [
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					route: 'categories',
 | 
					 | 
				
			||||||
					name: 'Categories',
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					route: 'recent',
 | 
					 | 
				
			||||||
					name: 'Recent',
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					route: 'top',
 | 
					 | 
				
			||||||
					name: 'Top',
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					route: 'popular',
 | 
					 | 
				
			||||||
					name: 'Popular',
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			].concat(categoryData) }, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (data) {
 | 
					 | 
				
			||||||
			data.routes.push({
 | 
					 | 
				
			||||||
				route: '',
 | 
					 | 
				
			||||||
				name: 'Custom',
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			res.render('admin/general/homepage', data);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,14 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const validator = require('validator');
 | 
					const validator = require('validator');
 | 
				
			||||||
var plugins = require('../../plugins');
 | 
					const plugins = require('../../plugins');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var hooksController = module.exports;
 | 
					const hooksController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
hooksController.get = function (req, res) {
 | 
					hooksController.get = function (req, res) {
 | 
				
			||||||
	var hooks = [];
 | 
						const hooks = [];
 | 
				
			||||||
	Object.keys(plugins.loadedHooks).forEach(function (key, hookIndex) {
 | 
						Object.keys(plugins.loadedHooks).forEach(function (key, hookIndex) {
 | 
				
			||||||
		var current = {
 | 
							const current = {
 | 
				
			||||||
			hookName: key,
 | 
								hookName: key,
 | 
				
			||||||
			methods: [],
 | 
								methods: [],
 | 
				
			||||||
			index: 'hook-' + hookIndex,
 | 
								index: 'hook-' + hookIndex,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,27 +1,24 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const os = require('os');
 | 
				
			||||||
var os = require('os');
 | 
					const winston = require('winston');
 | 
				
			||||||
var winston = require('winston');
 | 
					const nconf = require('nconf');
 | 
				
			||||||
var nconf = require('nconf');
 | 
					const exec = require('child_process').exec;
 | 
				
			||||||
var exec = require('child_process').exec;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pubsub = require('../../pubsub');
 | 
					const pubsub = require('../../pubsub');
 | 
				
			||||||
var rooms = require('../../socket.io/admin/rooms');
 | 
					const rooms = require('../../socket.io/admin/rooms');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var infoController = module.exports;
 | 
					const infoController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var info = {};
 | 
					let info = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
infoController.get = function (req, res) {
 | 
					infoController.get = function (req, res) {
 | 
				
			||||||
	info = {};
 | 
						info = {};
 | 
				
			||||||
	pubsub.publish('sync:node:info:start');
 | 
						pubsub.publish('sync:node:info:start');
 | 
				
			||||||
	var timeoutMS = 1000;
 | 
						const timeoutMS = 1000;
 | 
				
			||||||
	setTimeout(function () {
 | 
						setTimeout(function () {
 | 
				
			||||||
		var data = [];
 | 
							const data = [];
 | 
				
			||||||
		Object.keys(info).forEach(function (key) {
 | 
							Object.keys(info).forEach(key => data.push(info[key]));
 | 
				
			||||||
			data.push(info[key]);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		data.sort(function (a, b) {
 | 
							data.sort(function (a, b) {
 | 
				
			||||||
			if (a.id < b.id) {
 | 
								if (a.id < b.id) {
 | 
				
			||||||
				return -1;
 | 
									return -1;
 | 
				
			||||||
@@ -42,22 +39,22 @@ infoController.get = function (req, res) {
 | 
				
			|||||||
	}, timeoutMS);
 | 
						}, timeoutMS);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pubsub.on('sync:node:info:start', function () {
 | 
					pubsub.on('sync:node:info:start', async function () {
 | 
				
			||||||
	getNodeInfo(function (err, data) {
 | 
						try {
 | 
				
			||||||
		if (err) {
 | 
							const data = await getNodeInfo();
 | 
				
			||||||
			return winston.error(err);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		data.id = os.hostname() + ':' + nconf.get('port');
 | 
							data.id = os.hostname() + ':' + nconf.get('port');
 | 
				
			||||||
		pubsub.publish('sync:node:info:end', { data: data, id: data.id });
 | 
							pubsub.publish('sync:node:info:end', { data: data, id: data.id });
 | 
				
			||||||
	});
 | 
						} catch (err) {
 | 
				
			||||||
 | 
							winston.error(err);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pubsub.on('sync:node:info:end', function (data) {
 | 
					pubsub.on('sync:node:info:end', function (data) {
 | 
				
			||||||
	info[data.id] = data.data;
 | 
						info[data.id] = data.data;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getNodeInfo(callback) {
 | 
					async function getNodeInfo() {
 | 
				
			||||||
	var data = {
 | 
						const data = {
 | 
				
			||||||
		process: {
 | 
							process: {
 | 
				
			||||||
			port: nconf.get('port'),
 | 
								port: nconf.get('port'),
 | 
				
			||||||
			pid: process.pid,
 | 
								pid: process.pid,
 | 
				
			||||||
@@ -82,26 +79,16 @@ function getNodeInfo(callback) {
 | 
				
			|||||||
	data.process.cpuUsage.system = data.process.cpuUsage.system.toFixed(2);
 | 
						data.process.cpuUsage.system = data.process.cpuUsage.system.toFixed(2);
 | 
				
			||||||
	data.process.memoryUsage.humanReadable = (data.process.memoryUsage.rss / (1024 * 1024)).toFixed(2);
 | 
						data.process.memoryUsage.humanReadable = (data.process.memoryUsage.rss / (1024 * 1024)).toFixed(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async.waterfall([
 | 
						const [stats, gitInfo] = await Promise.all([
 | 
				
			||||||
		function (next) {
 | 
							rooms.getLocalStats(),
 | 
				
			||||||
			async.parallel({
 | 
							getGitInfo(),
 | 
				
			||||||
				stats: function (next) {
 | 
						]);
 | 
				
			||||||
					rooms.getLocalStats(next);
 | 
						data.git = gitInfo;
 | 
				
			||||||
				},
 | 
						data.stats = stats;
 | 
				
			||||||
				gitInfo: function (next) {
 | 
						return data;
 | 
				
			||||||
					getGitInfo(next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (results, next) {
 | 
					 | 
				
			||||||
			data.git = results.gitInfo;
 | 
					 | 
				
			||||||
			data.stats = results.stats;
 | 
					 | 
				
			||||||
			next(null, data);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], callback);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getGitInfo(callback) {
 | 
					async function getGitInfo() {
 | 
				
			||||||
	function get(cmd, callback) {
 | 
						function get(cmd, callback) {
 | 
				
			||||||
		exec(cmd, function (err, stdout) {
 | 
							exec(cmd, function (err, stdout) {
 | 
				
			||||||
			if (err) {
 | 
								if (err) {
 | 
				
			||||||
@@ -110,12 +97,10 @@ function getGitInfo(callback) {
 | 
				
			|||||||
			callback(null, stdout ? stdout.replace(/\n$/, '') : 'no-git-info');
 | 
								callback(null, stdout ? stdout.replace(/\n$/, '') : 'no-git-info');
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	async.parallel({
 | 
						const getAsync = require('util').promisify(get);
 | 
				
			||||||
		hash: function (next) {
 | 
						const [hash, branch] = await Promise.all([
 | 
				
			||||||
			get('git rev-parse HEAD', next);
 | 
							getAsync('git rev-parse HEAD'),
 | 
				
			||||||
		},
 | 
							getAsync('git rev-parse --abbrev-ref HEAD'),
 | 
				
			||||||
		branch: function (next) {
 | 
						]);
 | 
				
			||||||
			get('git rev-parse --abbrev-ref HEAD', next);
 | 
						return { hash: hash, branch: branch };
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}, callback);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +1,18 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const languages = require('../../languages');
 | 
				
			||||||
 | 
					const meta = require('../../meta');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var languages = require('../../languages');
 | 
					const languagesController = module.exports;
 | 
				
			||||||
var meta = require('../../meta');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var languagesController = module.exports;
 | 
					languagesController.get = async function (req, res) {
 | 
				
			||||||
 | 
						const languageData = await languages.list();
 | 
				
			||||||
languagesController.get = function (req, res, next) {
 | 
						languageData.forEach(function (language) {
 | 
				
			||||||
	async.waterfall([
 | 
					 | 
				
			||||||
		function (next) {
 | 
					 | 
				
			||||||
			languages.list(next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (languages) {
 | 
					 | 
				
			||||||
			languages.forEach(function (language) {
 | 
					 | 
				
			||||||
		language.selected = language.code === meta.config.defaultLang;
 | 
							language.selected = language.code === meta.config.defaultLang;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.render('admin/general/languages', {
 | 
						res.render('admin/general/languages', {
 | 
				
			||||||
				languages: languages,
 | 
							languages: languageData,
 | 
				
			||||||
		autoDetectLang: meta.config.autoDetectLang,
 | 
							autoDetectLang: meta.config.autoDetectLang,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var loggerController = module.exports;
 | 
					const loggerController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
loggerController.get = function (req, res) {
 | 
					loggerController.get = function (req, res) {
 | 
				
			||||||
	res.render('admin/development/logger', {});
 | 
						res.render('admin/development/logger', {});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,24 +1,20 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const validator = require('validator');
 | 
				
			||||||
var validator = require('validator');
 | 
					const winston = require('winston');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var meta = require('../../meta');
 | 
					const meta = require('../../meta');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var logsController = module.exports;
 | 
					const logsController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logsController.get = function (req, res, next) {
 | 
					logsController.get = async function (req, res) {
 | 
				
			||||||
	async.waterfall([
 | 
						let logs = '';
 | 
				
			||||||
		function (next) {
 | 
						try {
 | 
				
			||||||
			meta.logs.get(next);
 | 
							logs = await meta.logs.get();
 | 
				
			||||||
		},
 | 
						} catch (err) {
 | 
				
			||||||
		function (logs) {
 | 
							winston.error(err);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	res.render('admin/advanced/logs', {
 | 
						res.render('admin/advanced/logs', {
 | 
				
			||||||
		data: validator.escape(logs),
 | 
							data: validator.escape(logs),
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = logsController;
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,29 +1,25 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var navigationAdmin = require('../../navigation/admin');
 | 
					const navigationAdmin = require('../../navigation/admin');
 | 
				
			||||||
const groups = require('../../groups');
 | 
					const groups = require('../../groups');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var navigationController = module.exports;
 | 
					const navigationController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
navigationController.get = function (req, res, next) {
 | 
					navigationController.get = async function (req, res) {
 | 
				
			||||||
	async.waterfall([
 | 
						const [admin, allGroups] = await Promise.all([
 | 
				
			||||||
		function (next) {
 | 
							navigationAdmin.getAdmin(),
 | 
				
			||||||
			async.parallel({
 | 
							groups.getNonPrivilegeGroups('groups:createtime', 0, -1),
 | 
				
			||||||
				admin: async.apply(navigationAdmin.getAdmin),
 | 
						]);
 | 
				
			||||||
				groups: async.apply(groups.getNonPrivilegeGroups, 'groups:createtime', 0, -1),
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (result) {
 | 
					 | 
				
			||||||
			result.groups.sort((a, b) => b.system - a.system);
 | 
					 | 
				
			||||||
			result.groups = result.groups.map(group => ({ name: group.name, displayName: group.displayName }));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			result.admin.enabled.forEach(function (enabled, index) {
 | 
						allGroups.sort((a, b) => b.system - a.system);
 | 
				
			||||||
 | 
						const groupsData = allGroups.map(group => ({ name: group.name, displayName: group.displayName }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						admin.enabled.forEach(function (enabled, index) {
 | 
				
			||||||
		enabled.index = index;
 | 
							enabled.index = index;
 | 
				
			||||||
		enabled.selected = index === 0;
 | 
							enabled.selected = index === 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				enabled.groups = result.groups.map(function (group) {
 | 
							enabled.groups = groupsData.map(function (group) {
 | 
				
			||||||
			return {
 | 
								return {
 | 
				
			||||||
				displayName: group.displayName,
 | 
									displayName: group.displayName,
 | 
				
			||||||
				selected: enabled.groups.includes(group.name),
 | 
									selected: enabled.groups.includes(group.name),
 | 
				
			||||||
@@ -31,13 +27,11 @@ navigationController.get = function (req, res, next) {
 | 
				
			|||||||
		});
 | 
							});
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			result.admin.available.forEach(function (available) {
 | 
						admin.available.forEach(function (available) {
 | 
				
			||||||
				available.groups = result.groups;
 | 
							available.groups = groups;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			result.admin.navigation = result.admin.enabled.slice();
 | 
						admin.navigation = admin.enabled.slice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			res.render('admin/general/navigation', result.admin);
 | 
						res.render('admin/general/navigation', admin);
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,67 +1,58 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const nconf = require('nconf');
 | 
				
			||||||
var nconf = require('nconf');
 | 
					const winston = require('winston');
 | 
				
			||||||
var plugins = require('../../plugins');
 | 
					const plugins = require('../../plugins');
 | 
				
			||||||
var meta = require('../../meta');
 | 
					const meta = require('../../meta');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pluginsController = module.exports;
 | 
					const pluginsController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pluginsController.get = function (req, res, next) {
 | 
					pluginsController.get = async function (req, res) {
 | 
				
			||||||
	async.waterfall([
 | 
						const [compatible, all] = await Promise.all([
 | 
				
			||||||
		function (next) {
 | 
							getCompatiblePluigns(),
 | 
				
			||||||
			async.parallel({
 | 
							getAllPlugins(),
 | 
				
			||||||
				compatible: function (next) {
 | 
						]);
 | 
				
			||||||
					plugins.list(function (err, plugins) {
 | 
					 | 
				
			||||||
						if (err || !Array.isArray(plugins)) {
 | 
					 | 
				
			||||||
							plugins = [];
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
						next(null, plugins);
 | 
						const compatiblePkgNames = compatible.map(pkgData => pkgData.name);
 | 
				
			||||||
					});
 | 
						const installedPlugins = compatible.filter(plugin => plugin && plugin.installed);
 | 
				
			||||||
				},
 | 
						const activePlugins = all.filter(plugin => plugin && plugin.installed && plugin.active);
 | 
				
			||||||
				all: function (next) {
 | 
					 | 
				
			||||||
					plugins.list(false, function (err, plugins) {
 | 
					 | 
				
			||||||
						if (err || !Array.isArray(plugins)) {
 | 
					 | 
				
			||||||
							plugins = [];
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						next(null, plugins);
 | 
					 | 
				
			||||||
					});
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (payload) {
 | 
					 | 
				
			||||||
			var compatiblePkgNames = payload.compatible.map(function (pkgData) {
 | 
					 | 
				
			||||||
				return pkgData.name;
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
			var installedPlugins = payload.compatible.filter(function (plugin) {
 | 
					 | 
				
			||||||
				return plugin && plugin.installed;
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
			var activePlugins = payload.all.filter(function (plugin) {
 | 
					 | 
				
			||||||
				return plugin && plugin.installed && plugin.active;
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.render('admin/extend/plugins', {
 | 
						res.render('admin/extend/plugins', {
 | 
				
			||||||
		installed: installedPlugins,
 | 
							installed: installedPlugins,
 | 
				
			||||||
		installedCount: installedPlugins.length,
 | 
							installedCount: installedPlugins.length,
 | 
				
			||||||
		activeCount: activePlugins.length,
 | 
							activeCount: activePlugins.length,
 | 
				
			||||||
		inactiveCount: Math.max(0, installedPlugins.length - activePlugins.length),
 | 
							inactiveCount: Math.max(0, installedPlugins.length - activePlugins.length),
 | 
				
			||||||
				upgradeCount: payload.compatible.reduce(function (count, current) {
 | 
							upgradeCount: compatible.reduce(function (count, current) {
 | 
				
			||||||
			if (current.installed && current.outdated) {
 | 
								if (current.installed && current.outdated) {
 | 
				
			||||||
				count += 1;
 | 
									count += 1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return count;
 | 
								return count;
 | 
				
			||||||
		}, 0),
 | 
							}, 0),
 | 
				
			||||||
				download: payload.compatible.filter(function (plugin) {
 | 
							download: compatible.filter(function (plugin) {
 | 
				
			||||||
			return !plugin.installed;
 | 
								return !plugin.installed;
 | 
				
			||||||
		}),
 | 
							}),
 | 
				
			||||||
				incompatible: payload.all.filter(function (plugin) {
 | 
							incompatible: all.filter(function (plugin) {
 | 
				
			||||||
			return !compatiblePkgNames.includes(plugin.name);
 | 
								return !compatiblePkgNames.includes(plugin.name);
 | 
				
			||||||
		}),
 | 
							}),
 | 
				
			||||||
		submitPluginUsage: meta.config.submitPluginUsage,
 | 
							submitPluginUsage: meta.config.submitPluginUsage,
 | 
				
			||||||
		version: nconf.get('version'),
 | 
							version: nconf.get('version'),
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function getCompatiblePluigns() {
 | 
				
			||||||
 | 
						return await getPlugins(true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function getAllPlugins() {
 | 
				
			||||||
 | 
						return await getPlugins(false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function getPlugins(matching) {
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
							const pluginsData = await plugins.list(matching);
 | 
				
			||||||
 | 
							return pluginsData || [];
 | 
				
			||||||
 | 
						} catch (err) {
 | 
				
			||||||
 | 
							winston.error(err);
 | 
				
			||||||
 | 
							return [];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,48 +1,33 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const validator = require('validator');
 | 
				
			||||||
var validator = require('validator');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var db = require('../../database');
 | 
					const db = require('../../database');
 | 
				
			||||||
var user = require('../../user');
 | 
					const user = require('../../user');
 | 
				
			||||||
var topics = require('../../topics');
 | 
					const topics = require('../../topics');
 | 
				
			||||||
var categories = require('../../categories');
 | 
					const categories = require('../../categories');
 | 
				
			||||||
var pagination = require('../../pagination');
 | 
					const pagination = require('../../pagination');
 | 
				
			||||||
var plugins = require('../../plugins');
 | 
					const plugins = require('../../plugins');
 | 
				
			||||||
var utils = require('../../utils');
 | 
					const utils = require('../../utils');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var postQueueController = module.exports;
 | 
					const postQueueController = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
postQueueController.get = function (req, res, next) {
 | 
					postQueueController.get = async function (req, res) {
 | 
				
			||||||
	var page = parseInt(req.query.page, 10) || 1;
 | 
						const page = parseInt(req.query.page, 10) || 1;
 | 
				
			||||||
	var postsPerPage = 20;
 | 
						const postsPerPage = 20;
 | 
				
			||||||
	var results;
 | 
					 | 
				
			||||||
	async.waterfall([
 | 
					 | 
				
			||||||
		function (next) {
 | 
					 | 
				
			||||||
			async.parallel({
 | 
					 | 
				
			||||||
				ids: function (next) {
 | 
					 | 
				
			||||||
					db.getSortedSetRange('post:queue', 0, -1, next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				isAdminOrGlobalMod: function (next) {
 | 
					 | 
				
			||||||
					user.isAdminOrGlobalMod(req.uid, next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				moderatedCids: function (next) {
 | 
					 | 
				
			||||||
					user.getModeratedCids(req.uid, next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (_results, next) {
 | 
					 | 
				
			||||||
			results = _results;
 | 
					 | 
				
			||||||
			getQueuedPosts(results.ids, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (postData) {
 | 
					 | 
				
			||||||
			postData = postData.filter(function (postData) {
 | 
					 | 
				
			||||||
				return postData && (results.isAdminOrGlobalMod || results.moderatedCids.includes(String(postData.category.cid)));
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var pageCount = Math.max(1, Math.ceil(postData.length / postsPerPage));
 | 
						const [ids, isAdminOrGlobalMod, moderatedCids] = await Promise.all([
 | 
				
			||||||
			var start = (page - 1) * postsPerPage;
 | 
							db.getSortedSetRange('post:queue', 0, -1),
 | 
				
			||||||
			var stop = start + postsPerPage - 1;
 | 
							user.isAdminOrGlobalMod(req.uid),
 | 
				
			||||||
 | 
							user.getModeratedCids(req.uid),
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let postData = await getQueuedPosts(ids);
 | 
				
			||||||
 | 
						postData = postData.filter(p => p && (isAdminOrGlobalMod || moderatedCids.includes(String(p.category.cid))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const pageCount = Math.max(1, Math.ceil(postData.length / postsPerPage));
 | 
				
			||||||
 | 
						const start = (page - 1) * postsPerPage;
 | 
				
			||||||
 | 
						const stop = start + postsPerPage - 1;
 | 
				
			||||||
	postData = postData.slice(start, stop + 1);
 | 
						postData = postData.slice(start, stop + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.render('admin/manage/post-queue', {
 | 
						res.render('admin/manage/post-queue', {
 | 
				
			||||||
@@ -50,66 +35,42 @@ postQueueController.get = function (req, res, next) {
 | 
				
			|||||||
		posts: postData,
 | 
							posts: postData,
 | 
				
			||||||
		pagination: pagination.create(page, pageCount),
 | 
							pagination: pagination.create(page, pageCount),
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], next);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getQueuedPosts(ids, callback) {
 | 
					async function getQueuedPosts(ids) {
 | 
				
			||||||
	var postData;
 | 
					 | 
				
			||||||
	async.waterfall([
 | 
					 | 
				
			||||||
		function (next) {
 | 
					 | 
				
			||||||
	const keys = ids.map(id => 'post:queue:' + id);
 | 
						const keys = ids.map(id => 'post:queue:' + id);
 | 
				
			||||||
			db.getObjects(keys, next);
 | 
						const postData = await db.getObjects(keys);
 | 
				
			||||||
		},
 | 
						postData.forEach(function (data) {
 | 
				
			||||||
		function (data, next) {
 | 
					 | 
				
			||||||
			postData = data;
 | 
					 | 
				
			||||||
			data.forEach(function (data) {
 | 
					 | 
				
			||||||
		if (data) {
 | 
							if (data) {
 | 
				
			||||||
			data.data = JSON.parse(data.data);
 | 
								data.data = JSON.parse(data.data);
 | 
				
			||||||
			data.data.timestampISO = utils.toISOString(data.data.timestamp);
 | 
								data.data.timestampISO = utils.toISOString(data.data.timestamp);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
				return data;
 | 
					 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
			const uids = data.map(data => data && data.uid);
 | 
						const uids = postData.map(data => data && data.uid);
 | 
				
			||||||
			user.getUsersFields(uids, ['username', 'userslug', 'picture'], next);
 | 
						const userData = await user.getUsersFields(uids, ['username', 'userslug', 'picture']);
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (userData, next) {
 | 
					 | 
				
			||||||
	postData.forEach(function (postData, index) {
 | 
						postData.forEach(function (postData, index) {
 | 
				
			||||||
		if (postData) {
 | 
							if (postData) {
 | 
				
			||||||
			postData.user = userData[index];
 | 
								postData.user = userData[index];
 | 
				
			||||||
 | 
								postData.data.rawContent = validator.escape(String(postData.data.content));
 | 
				
			||||||
 | 
								postData.data.title = validator.escape(String(postData.data.title || ''));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			async.map(postData, function (postData, next) {
 | 
						await Promise.all(postData.map(p => addMetaData(p)));
 | 
				
			||||||
				if (!postData) {
 | 
						return postData;
 | 
				
			||||||
					return next(null, postData);
 | 
					}
 | 
				
			||||||
				}
 | 
					
 | 
				
			||||||
				postData.data.rawContent = validator.escape(String(postData.data.content));
 | 
					async function addMetaData(postData) {
 | 
				
			||||||
				postData.data.title = validator.escape(String(postData.data.title || ''));
 | 
						if (!postData) {
 | 
				
			||||||
				async.waterfall([
 | 
							return;
 | 
				
			||||||
					function (next) {
 | 
						}
 | 
				
			||||||
						if (postData.data.cid) {
 | 
						postData.topic = { cid: 0 };
 | 
				
			||||||
							next(null, { cid: postData.data.cid });
 | 
						if (postData.data.cid) {
 | 
				
			||||||
						} else if (postData.data.tid) {
 | 
							postData.topic = { cid: postData.data.cid };
 | 
				
			||||||
							topics.getTopicFields(postData.data.tid, ['title', 'cid'], next);
 | 
						} else if (postData.data.tid) {
 | 
				
			||||||
						} else {
 | 
							postData.topic = await topics.getTopicFields(postData.data.tid, ['title', 'cid']);
 | 
				
			||||||
							next(null, { cid: 0 });
 | 
						}
 | 
				
			||||||
						}
 | 
						postData.category = await categories.getCategoryData(postData.topic.cid);
 | 
				
			||||||
					},
 | 
						const result = await plugins.fireHook('filter:parse.post', { postData: postData.data });
 | 
				
			||||||
					function (topicData, next) {
 | 
						postData.data.content = result.postData.content;
 | 
				
			||||||
						postData.topic = topicData;
 | 
					 | 
				
			||||||
						categories.getCategoryData(topicData.cid, next);
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
					function (categoryData, next) {
 | 
					 | 
				
			||||||
						postData.category = categoryData;
 | 
					 | 
				
			||||||
						plugins.fireHook('filter:parse.post', { postData: postData.data }, next);
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
					function (result, next) {
 | 
					 | 
				
			||||||
						postData.data.content = result.postData.content;
 | 
					 | 
				
			||||||
						next(null, postData);
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				], next);
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], callback);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,62 +1,52 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var async = require('async');
 | 
					const categories = require('../../categories');
 | 
				
			||||||
 | 
					const privileges = require('../../privileges');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var categories = require('../../categories');
 | 
					const privilegesController = module.exports;
 | 
				
			||||||
var privileges = require('../../privileges');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
var privilegesController = module.exports;
 | 
					privilegesController.get = async function (req, res) {
 | 
				
			||||||
 | 
						const cid = req.params.cid ? parseInt(req.params.cid, 10) : 0;
 | 
				
			||||||
 | 
						const [privilegesData, categoriesData] = await Promise.all([
 | 
				
			||||||
 | 
							getPrivileges(cid),
 | 
				
			||||||
 | 
							getCategories(req.uid),
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
privilegesController.get = function (req, res, callback) {
 | 
						categoriesData.unshift({
 | 
				
			||||||
	var cid = req.params.cid ? parseInt(req.params.cid, 10) : 0;
 | 
					 | 
				
			||||||
	async.waterfall([
 | 
					 | 
				
			||||||
		function (next) {
 | 
					 | 
				
			||||||
			async.parallel({
 | 
					 | 
				
			||||||
				privileges: function (next) {
 | 
					 | 
				
			||||||
					if (!cid) {
 | 
					 | 
				
			||||||
						privileges.global.list(next);
 | 
					 | 
				
			||||||
					} else {
 | 
					 | 
				
			||||||
						privileges.categories.list(cid, next);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				categories: function (next) {
 | 
					 | 
				
			||||||
					async.waterfall([
 | 
					 | 
				
			||||||
						function (next) {
 | 
					 | 
				
			||||||
							categories.getAllCidsFromSet('categories:cid', next);
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
						function (cids, next) {
 | 
					 | 
				
			||||||
							categories.getCategories(cids, req.uid, next);
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
						function (categoriesData, next) {
 | 
					 | 
				
			||||||
							categoriesData = categories.getTree(categoriesData);
 | 
					 | 
				
			||||||
							categories.buildForSelectCategories(categoriesData, next);
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
					], next);
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}, next);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		function (data) {
 | 
					 | 
				
			||||||
			data.categories.unshift({
 | 
					 | 
				
			||||||
		cid: 0,
 | 
							cid: 0,
 | 
				
			||||||
		name: '[[admin/manage/privileges:global]]',
 | 
							name: '[[admin/manage/privileges:global]]',
 | 
				
			||||||
		icon: 'fa-list',
 | 
							icon: 'fa-list',
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
			data.categories.forEach(function (category) {
 | 
					
 | 
				
			||||||
 | 
						let selectedCategory;
 | 
				
			||||||
 | 
						categoriesData.forEach(function (category) {
 | 
				
			||||||
		if (category) {
 | 
							if (category) {
 | 
				
			||||||
			category.selected = category.cid === cid;
 | 
								category.selected = category.cid === cid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (category.selected) {
 | 
								if (category.selected) {
 | 
				
			||||||
						data.selected = category;
 | 
									selectedCategory = category;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.render('admin/manage/privileges', {
 | 
						res.render('admin/manage/privileges', {
 | 
				
			||||||
				privileges: data.privileges,
 | 
							privileges: privilegesData,
 | 
				
			||||||
				categories: data.categories,
 | 
							categories: categoriesData,
 | 
				
			||||||
				selectedCategory: data.selected,
 | 
							selectedCategory: selectedCategory,
 | 
				
			||||||
		cid: cid,
 | 
							cid: cid,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	], callback);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function getPrivileges(cid) {
 | 
				
			||||||
 | 
						if (!cid) {
 | 
				
			||||||
 | 
							return await privileges.global.list();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return await privileges.categories.list(cid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function getCategories(uid) {
 | 
				
			||||||
 | 
						const cids = await categories.getAllCidsFromSet('categories:cid');
 | 
				
			||||||
 | 
						const categoriesData = await categories.getCategories(cids, uid);
 | 
				
			||||||
 | 
						const tree = categories.getTree(categoriesData);
 | 
				
			||||||
 | 
						return await categories.buildForSelectCategories(tree);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -323,4 +323,46 @@ function recursive(category, categoriesData, level) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					helpers.getHomePageRoutes = async function (uid) {
 | 
				
			||||||
 | 
						let cids = await categories.getAllCidsFromSet('categories:cid');
 | 
				
			||||||
 | 
						cids = await privileges.categories.filterCids('find', cids, uid);
 | 
				
			||||||
 | 
						const categoryData = await categories.getCategoriesFields(cids, ['name', 'slug']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const categoryRoutes = categoryData.map(function (category) {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								route: 'category/' + category.slug,
 | 
				
			||||||
 | 
								name: 'Category: ' + category.name,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						const routes = [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								route: 'categories',
 | 
				
			||||||
 | 
								name: 'Categories',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								route: 'unread',
 | 
				
			||||||
 | 
								name: 'Unread',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								route: 'recent',
 | 
				
			||||||
 | 
								name: 'Recent',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								route: 'top',
 | 
				
			||||||
 | 
								name: 'Top',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								route: 'popular',
 | 
				
			||||||
 | 
								name: 'Popular',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						].concat(categoryRoutes, [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								route: 'custom',
 | 
				
			||||||
 | 
								name: 'Custom',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
						const data = await plugins.fireHook('filter:homepage.get', { routes: routes });
 | 
				
			||||||
 | 
						return data.routes;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
helpers.async = require('../promisify')(helpers);
 | 
					helpers.async = require('../promisify')(helpers);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +1,18 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var path = require('path');
 | 
					const path = require('path');
 | 
				
			||||||
var fs = require('fs');
 | 
					const fs = require('fs');
 | 
				
			||||||
 | 
					const util = require('util');
 | 
				
			||||||
var Logs = module.exports;
 | 
					const readFileAsync = util.promisify(fs.readFile);
 | 
				
			||||||
 | 
					const truncateAsync = util.promisify(fs.truncate);
 | 
				
			||||||
 | 
					const Logs = module.exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Logs.path = path.join(__dirname, '..', '..', 'logs', 'output.log');
 | 
					Logs.path = path.join(__dirname, '..', '..', 'logs', 'output.log');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Logs.get = function (callback) {
 | 
					Logs.get = async function () {
 | 
				
			||||||
	fs.readFile(Logs.path, {
 | 
						return await readFileAsync(Logs.path, 'utf-8');
 | 
				
			||||||
		encoding: 'utf-8',
 | 
					 | 
				
			||||||
	}, callback);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Logs.clear = function (callback) {
 | 
					Logs.clear = async function () {
 | 
				
			||||||
	fs.truncate(Logs.path, 0, callback);
 | 
						return await truncateAsync(Logs.path, 0);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -179,3 +179,5 @@ SocketRooms.getLocalStats = function (callback) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	callback(null, socketData);
 | 
						callback(null, socketData);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require('../../promisify')(SocketRooms);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user