Files
NodeBB/src/groups/join.js

110 lines
3.0 KiB
JavaScript
Raw Normal View History

'use strict';
const winston = require('winston');
const db = require('../database');
const user = require('../user');
const plugins = require('../plugins');
const cache = require('../cache');
module.exports = function (Groups) {
2019-07-18 17:11:59 -04:00
Groups.join = async function (groupNames, uid) {
if (!groupNames) {
2019-07-18 17:11:59 -04:00
throw new Error('[[error:invalid-data]]');
}
2019-05-30 21:41:54 -04:00
if (Array.isArray(groupNames) && !groupNames.length) {
2019-07-18 17:11:59 -04:00
return;
2019-05-30 21:41:54 -04:00
}
if (!Array.isArray(groupNames)) {
groupNames = [groupNames];
}
if (!uid) {
2019-07-18 17:11:59 -04:00
throw new Error('[[error:invalid-uid]]');
}
2019-07-18 17:11:59 -04:00
const [isMembers, exists, isAdmin] = await Promise.all([
Groups.isMemberOfGroups(uid, groupNames),
Groups.exists(groupNames),
user.isAdministrator(uid),
]);
2019-07-18 17:11:59 -04:00
const groupsToCreate = groupNames.filter((groupName, index) => groupName && !exists[index]);
const groupsToJoin = groupNames.filter((groupName, index) => !isMembers[index]);
2019-07-18 17:11:59 -04:00
if (!groupsToJoin.length) {
return;
}
await createNonExistingGroups(groupsToCreate);
2019-07-18 17:11:59 -04:00
const promises = [
2021-02-03 23:59:08 -07:00
db.sortedSetsAdd(groupsToJoin.map(groupName => `group:${groupName}:members`), Date.now(), uid),
db.incrObjectField(groupsToJoin.map(groupName => `group:${groupName}`), 'memberCount'),
2019-07-18 17:11:59 -04:00
];
if (isAdmin) {
2021-02-03 23:59:08 -07:00
promises.push(db.setsAdd(groupsToJoin.map(groupName => `group:${groupName}:owners`), uid));
2019-07-18 17:11:59 -04:00
}
await Promise.all(promises);
Groups.clearCache(uid, groupsToJoin);
2021-02-03 23:59:08 -07:00
cache.del(groupsToJoin.map(name => `group:${name}:members`));
2019-07-18 17:11:59 -04:00
const groupData = await Groups.getGroupsFields(groupsToJoin, ['name', 'hidden', 'memberCount']);
const visibleGroups = groupData.filter(groupData => groupData && !groupData.hidden);
if (visibleGroups.length) {
2021-02-04 00:12:32 -07:00
await db.sortedSetAdd(
'groups:visible:memberCount',
2019-07-18 17:11:59 -04:00
visibleGroups.map(groupData => groupData.memberCount),
visibleGroups.map(groupData => groupData.name)
);
}
await setGroupTitleIfNotSet(groupsToJoin, uid);
plugins.hooks.fire('action:group.join', {
2019-07-18 17:11:59 -04:00
groupNames: groupsToJoin,
uid: uid,
});
};
2019-07-18 17:11:59 -04:00
async function createNonExistingGroups(groupsToCreate) {
if (!groupsToCreate.length) {
2019-07-18 17:11:59 -04:00
return;
}
2019-07-18 17:11:59 -04:00
for (const groupName of groupsToCreate) {
2019-07-18 17:11:59 -04:00
try {
// eslint-disable-next-line no-await-in-loop
2019-07-18 17:11:59 -04:00
await Groups.create({
name: groupName,
hidden: 1,
});
} catch (err) {
if (err && err.message !== '[[error:group-already-exists]]') {
2021-02-03 23:59:08 -07:00
winston.error(`[groups.join] Could not create new hidden group (${groupName})\n${err.stack}`);
2019-07-18 17:11:59 -04:00
throw err;
}
2019-07-18 17:11:59 -04:00
}
}
}
2019-07-18 17:11:59 -04:00
async function setGroupTitleIfNotSet(groupNames, uid) {
2020-12-14 09:20:41 +03:00
const ignore = ['registered-users', 'verified-users', 'unverified-users', Groups.BANNED_USERS];
groupNames = groupNames.filter(
groupName => !ignore.includes(groupName) && !Groups.isPrivilegeGroup(groupName)
);
if (!groupNames.length) {
2019-07-18 17:11:59 -04:00
return;
}
2021-02-03 23:59:08 -07:00
const currentTitle = await db.getObjectField(`user:${uid}`, 'groupTitle');
2019-07-18 17:11:59 -04:00
if (currentTitle || currentTitle === '') {
return;
}
2019-07-18 17:11:59 -04:00
await user.setUserField(uid, 'groupTitle', JSON.stringify(groupNames));
}
};