mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: #11420, add new GET routes to retrieve pending and invited members of a group, plus accept/reject pending
This commit is contained in:
@@ -154,6 +154,8 @@
|
||||
"group-already-requested": "Your membership request has already been submitted",
|
||||
"group-join-disabled": "You are not able to join this group at this time",
|
||||
"group-leave-disabled": "You are not able to leave this group at this time",
|
||||
"group-user-not-pending": "User does not have a pending request to join this group.",
|
||||
"gorup-user-not-invited": "User has not been invited to join this group.",
|
||||
|
||||
"post-already-deleted": "This post has already been deleted",
|
||||
"post-already-restored": "This post has already been restored",
|
||||
|
||||
@@ -2,7 +2,10 @@ put:
|
||||
tags:
|
||||
- groups
|
||||
summary: join a group
|
||||
description: This operation joins an existing group, or causes another user to join a group. If the group is private and you are not an administrator, this method will cause that user to request membership, instead. For user _invitations_, you'll want to call `PUT /groups/{slug}/invites/{uid}`.
|
||||
description: |
|
||||
This operation joins an existing group, or causes another user to join a group.
|
||||
If the group is private and you are not an administrator, this method will cause that user to request membership, instead.
|
||||
For user _invitations_, you'll want to call `POST /groups/{slug}/invites/{uid}`.
|
||||
parameters:
|
||||
- in: path
|
||||
name: slug
|
||||
|
||||
@@ -206,11 +206,57 @@ groupsAPI.rescind = async (caller, data) => {
|
||||
|
||||
await groups.ownership.rescind(data.uid, groupName);
|
||||
logGroupEvent(caller, 'group-owner-rescind', {
|
||||
groupName: groupName,
|
||||
groupName,
|
||||
targetUid: data.uid,
|
||||
});
|
||||
};
|
||||
|
||||
groupsAPI.getPending = async (caller, { slug }) => {
|
||||
const groupName = await groups.getGroupNameByGroupSlug(slug);
|
||||
await isOwner(caller, groupName);
|
||||
|
||||
return await groups.getPending(groupName);
|
||||
};
|
||||
|
||||
groupsAPI.accept = async (caller, { slug, uid }) => {
|
||||
const groupName = await groups.getGroupNameByGroupSlug(slug);
|
||||
|
||||
await isOwner(caller, groupName);
|
||||
const isPending = await groups.isPending(uid, groupName);
|
||||
if (!isPending) {
|
||||
throw new Error('[[error:group-user-not-pending]]');
|
||||
}
|
||||
|
||||
await groups.acceptMembership(groupName, uid);
|
||||
logGroupEvent(caller, 'group-accept-membership', {
|
||||
groupName,
|
||||
targetUid: uid,
|
||||
});
|
||||
};
|
||||
|
||||
groupsAPI.reject = async (caller, { slug, uid }) => {
|
||||
const groupName = await groups.getGroupNameByGroupSlug(slug);
|
||||
|
||||
await isOwner(caller, groupName);
|
||||
const isPending = await groups.isPending(uid, groupName);
|
||||
if (!isPending) {
|
||||
throw new Error('[[error:group-user-not-pending]]');
|
||||
}
|
||||
|
||||
await groups.rejectMembership(groupName, uid);
|
||||
logGroupEvent(caller, 'group-reject-membership', {
|
||||
groupName,
|
||||
targetUid: uid,
|
||||
});
|
||||
};
|
||||
|
||||
groupsAPI.getInvites = async (caller, { slug }) => {
|
||||
const groupName = await groups.getGroupNameByGroupSlug(slug);
|
||||
await isOwner(caller, groupName);
|
||||
|
||||
return await groups.getInvites(groupName);
|
||||
};
|
||||
|
||||
async function isOwner(caller, groupName) {
|
||||
if (typeof groupName !== 'string') {
|
||||
throw new Error('[[error:invalid-group-name]]');
|
||||
|
||||
@@ -47,3 +47,23 @@ Groups.rescind = async (req, res) => {
|
||||
await api.groups.rescind(req, req.params);
|
||||
helpers.formatApiResponse(200, res);
|
||||
};
|
||||
|
||||
Groups.getPending = async (req, res) => {
|
||||
const pending = await api.groups.getPending(req, req.params);
|
||||
helpers.formatApiResponse(200, res, { pending });
|
||||
};
|
||||
|
||||
Groups.accept = async (req, res) => {
|
||||
await api.groups.accept(req, req.params);
|
||||
helpers.formatApiResponse(200, res);
|
||||
};
|
||||
|
||||
Groups.reject = async (req, res) => {
|
||||
await api.groups.reject(req, req.params);
|
||||
helpers.formatApiResponse(200, res);
|
||||
};
|
||||
|
||||
Groups.getInvites = async (req, res) => {
|
||||
const invites = await api.groups.getInvites(req, req.params);
|
||||
helpers.formatApiResponse(200, res, { invites });
|
||||
};
|
||||
|
||||
@@ -123,8 +123,8 @@ Groups.get = async function (groupName, options) {
|
||||
const [groupData, members, pending, invited, isMember, isPending, isInvited, isOwner] = await Promise.all([
|
||||
Groups.getGroupData(groupName),
|
||||
Groups.getOwnersAndMembers(groupName, options.uid, 0, stop),
|
||||
Groups.getUsersFromSet(`group:${groupName}:pending`, ['username', 'userslug', 'picture']),
|
||||
Groups.getUsersFromSet(`group:${groupName}:invited`, ['username', 'userslug', 'picture']),
|
||||
Groups.getPending(groupName),
|
||||
Groups.getInvites(groupName),
|
||||
Groups.isMember(options.uid, groupName),
|
||||
Groups.isPending(options.uid, groupName),
|
||||
Groups.isInvited(options.uid, groupName),
|
||||
|
||||
@@ -9,6 +9,14 @@ const plugins = require('../plugins');
|
||||
const notifications = require('../notifications');
|
||||
|
||||
module.exports = function (Groups) {
|
||||
Groups.getPending = async function (groupName) {
|
||||
return await Groups.getUsersFromSet(`group:${groupName}:pending`, ['username', 'userslug', 'picture']);
|
||||
};
|
||||
|
||||
Groups.getInvites = async function (groupName) {
|
||||
return await Groups.getUsersFromSet(`group:${groupName}:invited`, ['username', 'userslug', 'picture']);
|
||||
};
|
||||
|
||||
Groups.requestMembership = async function (groupName, uid) {
|
||||
await inviteOrRequestMembership(groupName, uid, 'request');
|
||||
const { displayname } = await user.getUserFields(uid, ['username']);
|
||||
@@ -107,11 +115,4 @@ module.exports = function (Groups) {
|
||||
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`);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -14,10 +14,21 @@ module.exports = function () {
|
||||
setupApiRoute(router, 'head', '/:slug', [middleware.assert.group], controllers.write.groups.exists);
|
||||
setupApiRoute(router, 'put', '/:slug', [...middlewares, middleware.assert.group], controllers.write.groups.update);
|
||||
setupApiRoute(router, 'delete', '/:slug', [...middlewares, middleware.assert.group], controllers.write.groups.delete);
|
||||
|
||||
setupApiRoute(router, 'put', '/:slug/membership/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.join);
|
||||
setupApiRoute(router, 'delete', '/:slug/membership/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.leave);
|
||||
|
||||
setupApiRoute(router, 'put', '/:slug/ownership/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.grant);
|
||||
setupApiRoute(router, 'delete', '/:slug/ownership/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.rescind);
|
||||
|
||||
setupApiRoute(router, 'get', '/:slug/pending', [...middlewares, middleware.assert.group], controllers.write.groups.getPending);
|
||||
setupApiRoute(router, 'put', '/:slug/pending/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.accept);
|
||||
setupApiRoute(router, 'delete', '/:slug/pending/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.reject);
|
||||
|
||||
setupApiRoute(router, 'get', '/:slug/invites', [...middlewares, middleware.assert.group], controllers.write.groups.getInvites);
|
||||
// setupApiRoute(router, 'post', '/:slug/invites', [...middlewares, middleware.assert.group], controllers.write.groups.issueInvite);
|
||||
// setupApiRoute(router, 'put', '/:slug/invites/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.acceptInvite);
|
||||
// setupApiRoute(router, 'delete', '/:slug/invites/:uid', [...middlewares, middleware.assert.group], controllers.write.groups.rejectInvite);
|
||||
|
||||
return router;
|
||||
};
|
||||
|
||||
@@ -66,24 +66,6 @@ async function isInvited(socket, data) {
|
||||
}
|
||||
}
|
||||
|
||||
SocketGroups.accept = async (socket, data) => {
|
||||
await isOwner(socket, data);
|
||||
await groups.acceptMembership(data.groupName, data.toUid);
|
||||
logGroupEvent(socket, 'group-accept-membership', {
|
||||
groupName: data.groupName,
|
||||
targetUid: data.toUid,
|
||||
});
|
||||
};
|
||||
|
||||
SocketGroups.reject = async (socket, data) => {
|
||||
await isOwner(socket, data);
|
||||
await groups.rejectMembership(data.groupName, data.toUid);
|
||||
logGroupEvent(socket, 'group-reject-membership', {
|
||||
groupName: data.groupName,
|
||||
targetUid: data.toUid,
|
||||
});
|
||||
};
|
||||
|
||||
SocketGroups.acceptAll = async (socket, data) => {
|
||||
await isOwner(socket, data);
|
||||
await acceptRejectAll(SocketGroups.accept, socket, data);
|
||||
@@ -98,7 +80,8 @@ async function acceptRejectAll(method, socket, data) {
|
||||
if (typeof data.groupName !== 'string') {
|
||||
throw new Error('[[error:invalid-group-name]]');
|
||||
}
|
||||
const uids = await groups.getPending(data.groupName);
|
||||
const users = await groups.getPending(data.groupName);
|
||||
const uids = users.map(u => u.uid);
|
||||
await Promise.all(uids.map(async (uid) => {
|
||||
await method(socket, { groupName: data.groupName, toUid: uid });
|
||||
}));
|
||||
|
||||
@@ -944,7 +944,8 @@ describe('Groups', () => {
|
||||
]);
|
||||
await requestMembership(uid1, uid2);
|
||||
await socketGroups.rejectAll({ uid: adminUid }, { groupName: 'PrivateCanJoin' });
|
||||
const pending = await Groups.getPending('PrivateCanJoin');
|
||||
let pending = await Groups.getPending('PrivateCanJoin');
|
||||
pending = pending.map(u => u.uid);
|
||||
assert.equal(pending.length, 0);
|
||||
await requestMembership(uid1, uid2);
|
||||
await socketGroups.acceptAll({ uid: adminUid }, { groupName: 'PrivateCanJoin' });
|
||||
|
||||
Reference in New Issue
Block a user