|
|
|
'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);
|
|
|
|
};
|
|
|
|
};
|