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.
117 lines
3.9 KiB
JavaScript
117 lines
3.9 KiB
JavaScript
'use strict';
|
|
|
|
const _ = require('lodash');
|
|
|
|
const db = require('../database');
|
|
const user = require('../user');
|
|
const slugify = require('../slugify');
|
|
const plugins = require('../plugins');
|
|
const notifications = require('../notifications');
|
|
|
|
module.exports = function (Groups) {
|
|
Groups.requestMembership = async function (groupName, uid) {
|
|
await inviteOrRequestMembership(groupName, uid, 'request');
|
|
const username = await user.getUserField(uid, 'username');
|
|
const [notification, owners] = await Promise.all([
|
|
notifications.create({
|
|
type: 'group-request-membership',
|
|
bodyShort: `[[groups:request.notification_title, ${username}]]`,
|
|
bodyLong: `[[groups:request.notification_text, ${username}, ${groupName}]]`,
|
|
nid: `group:${groupName}:uid:${uid}:request`,
|
|
path: `/groups/${slugify(groupName)}`,
|
|
from: uid,
|
|
}),
|
|
Groups.getOwners(groupName),
|
|
]);
|
|
|
|
await notifications.push(notification, owners);
|
|
};
|
|
|
|
Groups.acceptMembership = async function (groupName, uid) {
|
|
await db.setsRemove([`group:${groupName}:pending`, `group:${groupName}:invited`], uid);
|
|
await Groups.join(groupName, uid);
|
|
|
|
const notification = await notifications.create({
|
|
type: 'group-invite',
|
|
bodyShort: `[[groups:membership.accept.notification_title, ${groupName}]]`,
|
|
nid: `group:${groupName}:uid:${uid}:invite-accepted`,
|
|
path: `/groups/${slugify(groupName)}`,
|
|
});
|
|
await notifications.push(notification, [uid]);
|
|
};
|
|
|
|
Groups.rejectMembership = async function (groupNames, uid) {
|
|
if (!Array.isArray(groupNames)) {
|
|
groupNames = [groupNames];
|
|
}
|
|
const sets = [];
|
|
groupNames.forEach(groupName => sets.push(`group:${groupName}:pending`, `group:${groupName}:invited`));
|
|
await db.setsRemove(sets, uid);
|
|
};
|
|
|
|
Groups.invite = async function (groupName, uids) {
|
|
uids = Array.isArray(uids) ? uids : [uids];
|
|
uids = await inviteOrRequestMembership(groupName, uids, 'invite');
|
|
|
|
const notificationData = await Promise.all(uids.map(uid => notifications.create({
|
|
type: 'group-invite',
|
|
bodyShort: `[[groups:invited.notification_title, ${groupName}]]`,
|
|
bodyLong: '',
|
|
nid: `group:${groupName}:uid:${uid}:invite`,
|
|
path: `/groups/${slugify(groupName)}`,
|
|
})));
|
|
|
|
await Promise.all(uids.map((uid, index) => notifications.push(notificationData[index], uid)));
|
|
};
|
|
|
|
async function inviteOrRequestMembership(groupName, uids, type) {
|
|
uids = Array.isArray(uids) ? uids : [uids];
|
|
uids = uids.filter(uid => parseInt(uid, 10) > 0);
|
|
const [exists, isMember, isPending, isInvited] = await Promise.all([
|
|
Groups.exists(groupName),
|
|
Groups.isMembers(uids, groupName),
|
|
Groups.isPending(uids, groupName),
|
|
Groups.isInvited(uids, groupName),
|
|
]);
|
|
|
|
if (!exists) {
|
|
throw new Error('[[error:no-group]]');
|
|
}
|
|
|
|
uids = uids.filter((uid, i) => !isMember[i] && ((type === 'invite' && !isInvited[i]) || (type === 'request' && !isPending[i])));
|
|
|
|
const set = type === 'invite' ? `group:${groupName}:invited` : `group:${groupName}:pending`;
|
|
await db.setAdd(set, uids);
|
|
const hookName = type === 'invite' ? 'action:group.inviteMember' : 'action:group.requestMembership';
|
|
plugins.hooks.fire(hookName, {
|
|
groupName: groupName,
|
|
uids: uids,
|
|
});
|
|
return uids;
|
|
}
|
|
|
|
Groups.isInvited = async function (uids, groupName) {
|
|
return await checkInvitePending(uids, `group:${groupName}:invited`);
|
|
};
|
|
|
|
Groups.isPending = async function (uids, groupName) {
|
|
return await checkInvitePending(uids, `group:${groupName}:pending`);
|
|
};
|
|
|
|
async function checkInvitePending(uids, set) {
|
|
const isArray = Array.isArray(uids);
|
|
uids = isArray ? uids : [uids];
|
|
const checkUids = uids.filter(uid => parseInt(uid, 10) > 0);
|
|
const isMembers = await db.isSetMembers(set, checkUids);
|
|
const map = _.zipObject(checkUids, isMembers);
|
|
return isArray ? uids.map(uid => !!map[uid]) : !!map[uids[0]];
|
|
}
|
|
|
|
Groups.getPending = async function (groupName) {
|
|
if (!groupName) {
|
|
return [];
|
|
}
|
|
return await db.getSetMembers(`group:${groupName}:pending`);
|
|
};
|
|
};
|