You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.0 KiB
JavaScript

'use strict';
const db = require('../database');
const user = require('../user');
const plugins = require('../plugins');
const cache = require('../cache');
module.exports = function (Groups) {
Groups.leave = async function (groupNames, uid) {
if (Array.isArray(groupNames) && !groupNames.length) {
return;
}
if (!Array.isArray(groupNames)) {
groupNames = [groupNames];
}
const [isMembers, exists] = await Promise.all([
Groups.isMemberOfGroups(uid, groupNames),
Groups.exists(groupNames),
]);
const groupsToLeave = groupNames.filter((groupName, index) => isMembers[index] && exists[index]);
if (!groupsToLeave.length) {
return;
}
await Promise.all([
db.sortedSetRemove(groupsToLeave.map(groupName => 'group:' + groupName + ':members'), uid),
db.setRemove(groupsToLeave.map(groupName => 'group:' + groupName + ':owners'), uid),
db.decrObjectField(groupsToLeave.map(groupName => 'group:' + groupName), 'memberCount'),
]);
Groups.clearCache(uid, groupsToLeave);
cache.del(groupsToLeave.map(name => 'group:' + name + ':members'));
const groupData = await Groups.getGroupsFields(groupsToLeave, ['name', 'hidden', 'memberCount']);
if (!groupData) {
return;
}
const emptyPrivilegeGroups = groupData.filter(g => g && Groups.isPrivilegeGroup(g.name) && g.memberCount === 0);
const visibleGroups = groupData.filter(g => g && !g.hidden);
const promises = [];
if (emptyPrivilegeGroups.length) {
promises.push(Groups.destroy, emptyPrivilegeGroups);
}
if (visibleGroups.length) {
promises.push(db.sortedSetAdd, 'groups:visible:memberCount',
visibleGroups.map(groupData => groupData.memberCount),
visibleGroups.map(groupData => groupData.name)
);
}
await Promise.all(promises);
await clearGroupTitleIfSet(groupsToLeave, uid);
plugins.fireHook('action:group.leave', {
groupNames: groupsToLeave,
uid: uid,
});
};
async function clearGroupTitleIfSet(groupNames, uid) {
groupNames = groupNames.filter(groupName => groupName !== 'registered-users' && !Groups.isPrivilegeGroup(groupName));
if (!groupNames.length) {
return;
}
const userData = await user.getUserData(uid);
if (!userData) {
return;
}
const newTitleArray = userData.groupTitleArray.filter(groupTitle => !groupNames.includes(groupTitle));
if (newTitleArray.length) {
await db.setObjectField('user:' + uid, 'groupTitle', JSON.stringify(newTitleArray));
} else {
await db.deleteObjectField('user:' + uid, 'groupTitle');
}
}
Groups.leaveAllGroups = async function (uid) {
const groups = await db.getSortedSetRange('groups:createtime', 0, -1);
await Promise.all([
Groups.leave(groups, uid),
Groups.rejectMembership(groups, uid),
]);
};
Groups.kick = async function (uid, groupName, isOwner) {
if (isOwner) {
// If the owners set only contains one member, error out!
const numOwners = await db.setCount('group:' + groupName + ':owners');
if (numOwners <= 1) {
throw new Error('[[error:group-needs-owner]]');
}
}
await Groups.leave(groupName, uid);
};
};