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.

106 lines
2.9 KiB
JavaScript

'use strict';
const async = require('async');
const winston = require('winston');
const db = require('../database');
const user = require('../user');
const plugins = require('../plugins');
const cache = require('../cache');
module.exports = function (Groups) {
Groups.join = async function (groupNames, uid) {
if (!groupNames) {
throw new Error('[[error:invalid-data]]');
}
if (Array.isArray(groupNames) && !groupNames.length) {
return;
}
if (!Array.isArray(groupNames)) {
groupNames = [groupNames];
}
if (!uid) {
throw new Error('[[error:invalid-uid]]');
}
const [isMembers, exists, isAdmin] = await Promise.all([
Groups.isMemberOfGroups(uid, groupNames),
Groups.exists(groupNames),
user.isAdministrator(uid),
]);
const groupsToCreate = groupNames.filter((groupName, index) => groupName && !exists[index]);
const groupsToJoin = groupNames.filter((groupName, index) => !isMembers[index]);
if (!groupsToJoin.length) {
return;
}
await createNonExistingGroups(groupsToCreate);
const promises = [
db.sortedSetsAdd(groupsToJoin.map(groupName => 'group:' + groupName + ':members'), Date.now(), uid),
db.incrObjectField(groupsToJoin.map(groupName => 'group:' + groupName), 'memberCount'),
];
if (isAdmin) {
promises.push(db.setsAdd(groupsToJoin.map(groupName => 'group:' + groupName + ':owners'), uid));
}
await Promise.all(promises);
Groups.clearCache(uid, groupsToJoin);
cache.del(groupsToJoin.map(name => 'group:' + name + ':members'));
const groupData = await Groups.getGroupsFields(groupsToJoin, ['name', 'hidden', 'memberCount']);
const visibleGroups = groupData.filter(groupData => groupData && !groupData.hidden);
if (visibleGroups.length) {
await db.sortedSetAdd('groups:visible:memberCount',
visibleGroups.map(groupData => groupData.memberCount),
visibleGroups.map(groupData => groupData.name)
);
}
await setGroupTitleIfNotSet(groupsToJoin, uid);
plugins.fireHook('action:group.join', {
groupNames: groupsToJoin,
uid: uid,
});
};
async function createNonExistingGroups(groupsToCreate) {
if (!groupsToCreate.length) {
return;
}
await async.eachSeries(groupsToCreate, async function (groupName) {
try {
await Groups.create({
name: groupName,
hidden: 1,
});
} catch (err) {
if (err && err.message !== '[[error:group-already-exists]]') {
winston.error('[groups.join] Could not create new hidden group', err.stack);
throw err;
}
}
});
}
async function setGroupTitleIfNotSet(groupNames, uid) {
groupNames = groupNames.filter(groupName => groupName !== 'registered-users' && !Groups.isPrivilegeGroup(groupName));
if (!groupNames.length) {
return;
}
const currentTitle = await db.getObjectField('user:' + uid, 'groupTitle');
if (currentTitle || currentTitle === '') {
return;
}
await user.setUserField(uid, 'groupTitle', JSON.stringify(groupNames));
}
};