Files
NodeBB/src/controllers/admin/groups.js

97 lines
2.9 KiB
JavaScript
Raw Normal View History

2017-02-18 01:56:23 -07:00
'use strict';
const nconf = require('nconf');
const validator = require('validator');
const db = require('../../database');
const user = require('../../user');
const groups = require('../../groups');
const meta = require('../../meta');
const pagination = require('../../pagination');
const events = require('../../events');
const groupsController = module.exports;
groupsController.list = async function (req, res) {
const page = parseInt(req.query.page, 10) || 1;
const groupsPerPage = 20;
let groupNames = await getGroupNames();
const pageCount = Math.ceil(groupNames.length / groupsPerPage);
const start = (page - 1) * groupsPerPage;
const stop = start + groupsPerPage - 1;
groupNames = groupNames.slice(start, stop + 1);
const groupData = await groups.getGroupsData(groupNames);
res.render('admin/manage/groups', {
groups: groupData,
pagination: pagination.create(page, pageCount),
yourid: req.uid,
});
};
groupsController.get = async function (req, res, next) {
const groupName = req.params.name;
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
const [groupNames, group] = await Promise.all([
getGroupNames(),
groups.get(groupName, { uid: req.uid, truncateUserList: true, userListCount: 20 }),
]);
2020-12-14 09:20:41 +03:00
if (!group || groupName === groups.BANNED_USERS) {
return next();
}
group.isOwner = true;
2020-11-18 23:24:51 -05:00
2021-02-04 00:01:39 -07:00
const groupNameData = groupNames.map(name => ({
encodedName: encodeURIComponent(name),
displayName: validator.escape(String(name)),
selected: name === groupName,
}));
res.render('admin/manage/group', {
group: group,
groupNames: groupNameData,
allowPrivateGroups: meta.config.allowPrivateGroups,
maximumGroupNameLength: meta.config.maximumGroupNameLength,
maximumGroupTitleLength: meta.config.maximumGroupTitleLength,
});
};
2017-08-02 13:03:34 -04:00
async function getGroupNames() {
const groupNames = await db.getSortedSetRange('groups:createtime', 0, -1);
2021-02-04 00:12:32 -07:00
return groupNames.filter(name => (
name !== 'registered-users' &&
name !== 'verified-users' &&
name !== 'unverified-users' &&
2020-12-14 09:20:41 +03:00
name !== groups.BANNED_USERS &&
!groups.isPrivilegeGroup(name)
2021-02-04 00:12:32 -07:00
));
2017-08-02 13:03:34 -04:00
}
groupsController.getCSV = async function (req, res) {
2021-02-06 14:10:15 -07:00
const { referer } = req.headers;
if (!referer || !referer.replace(nconf.get('url'), '').startsWith('/admin/manage/groups')) {
return res.status(403).send('[[error:invalid-origin]]');
}
await events.log({
type: 'getGroupCSV',
uid: req.uid,
ip: req.ip,
2021-01-22 13:14:14 -05:00
group: req.params.groupname,
});
const groupName = req.params.groupname;
const members = (await groups.getMembersOfGroups([groupName]))[0];
const fields = ['email', 'username', 'uid'];
const userData = await user.getUsersFields(members, fields);
2021-02-03 23:59:08 -07:00
let csvContent = `${fields.join(',')}\n`;
csvContent += userData.reduce((memo, user) => {
2021-02-03 23:59:08 -07:00
memo += `${user.email},${user.username},${user.uid}\n`;
return memo;
}, '');
2021-02-03 23:59:08 -07:00
res.attachment(`${validator.escape(groupName)}_members.csv`);
res.setHeader('Content-Type', 'text/csv');
res.end(csvContent);
};