Skip to content

Commit

Permalink
feat(writeapi): added DELETE /groups/:slug/membership/:uid route
Browse files Browse the repository at this point in the history
  • Loading branch information
julianlam committed Oct 8, 2020
1 parent 68ecf41 commit 40dc1c3
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 55 deletions.
7 changes: 2 additions & 5 deletions public/src/admin/manage/admins-mods.js
Expand Up @@ -63,16 +63,13 @@ define('admin/manage/admins-mods', ['translator', 'benchpress', 'autocomplete',

bootbox.confirm('[[admin/manage/users:alerts.confirm-remove-global-mod]]', function (confirm) {
if (confirm) {
socket.emit('admin.groups.leave', { uid: uid, groupName: 'Global Moderators' }, function (err) {
if (err) {
return app.alertError(err.message);
}
api.del('/groups/global-moderators/membership/' + uid, undefined, () => {
app.alertSuccess('[[admin/manage/users:alerts.remove-global-mod-success]]');
userCard.remove();
if (!$('.global-moderator-area').children().length) {
$('#no-global-mods-warning').removeClass('hidden');
}
});
}, err => app.alertError(err.status.message));
}
});
});
Expand Down
14 changes: 4 additions & 10 deletions public/src/admin/manage/group.js
@@ -1,14 +1,14 @@
'use strict';


define('admin/manage/group', [
'forum/groups/memberlist',
'iconSelect',
'admin/modules/colorpicker',
'translator',
'categorySelector',
'groupSearch',
], function (memberList, iconSelect, colorpicker, translator, categorySelector, groupSearch) {
'api',
], function (memberList, iconSelect, colorpicker, translator, categorySelector, groupSearch, api) {
var Groups = {};

Groups.init = function () {
Expand Down Expand Up @@ -137,15 +137,9 @@ define('admin/manage/group', [
if (!confirm) {
return;
}
socket.emit('admin.groups.leave', {
uid: uid,
groupName: groupName,
}, function (err) {
if (err) {
return app.alertError(err.message);
}
api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + uid, undefined, () => {
userRow.slideUp().remove();
});
}, err => app.alertError(err.status.message));
});
break;
default:
Expand Down
7 changes: 2 additions & 5 deletions public/src/admin/manage/users.js
Expand Up @@ -108,12 +108,9 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete', 'api']
var groupCard = $(this).parents('[data-group-name]');
var groupName = groupCard.attr('data-group-name');
var uid = $(this).parents('[data-uid]').attr('data-uid');
socket.emit('admin.groups.leave', { uid: uid, groupName: groupName }, function (err) {
if (err) {
return app.alertError(err);
}
api.del('/groups/' + utils.slugify(groupName) + '/membership/' + uid, undefined, () => {
groupCard.remove();
});
}, err => app.alertError(err.status.message));
return false;
});
});
Expand Down
7 changes: 5 additions & 2 deletions public/src/client/groups/details.js
Expand Up @@ -109,8 +109,11 @@ define('forum/groups/details', [
api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined, () => ajaxify.refresh(), err => app.alertError(err.status.message));
break;

case 'leave': // intentional fall-throughs!
case 'accept':
case 'leave':
api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined, () => ajaxify.refresh(), err => app.alertError(err.status.message));
break;

case 'accept': // intentional fall-throughs!
case 'reject':
case 'issueInvite':
case 'rescindInvite':
Expand Down
11 changes: 8 additions & 3 deletions public/src/client/groups/memberlist.js
@@ -1,7 +1,6 @@
'use strict';


define('forum/groups/memberlist', function () {
define('forum/groups/memberlist', ['api'], function (api) {
var MemberList = {};
var searchInterval;
var groupName;
Expand Down Expand Up @@ -83,7 +82,13 @@ define('forum/groups/memberlist', function () {
if (groupName === 'administrators') {
socket.emit('admin.user.makeAdmins', uids, done);
} else {
socket.emit('groups.addMember', { groupName: groupName, uid: uids }, done);
var requests = uids.map(function (uid) {
return api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + uid);
});

$.when(requests)
.done(done)
.fail(err => app.alertError(err.status.message));
}
}

Expand Down
40 changes: 40 additions & 0 deletions src/controllers/write/groups.js
@@ -1,9 +1,13 @@
'use strict';

const validator = require('validator');

const user = require('../../user');
const groups = require('../../groups');
const events = require('../../events');
const meta = require('../../meta');
const utils = require('../../utils');
const notifications = require('../../notifications');

const helpers = require('../helpers');

Expand Down Expand Up @@ -85,6 +89,42 @@ Groups.join = async (req, res) => {
});
};

Groups.leave = async (req, res) => {
const [group, userExists] = await Promise.all([
groups.getByGroupslug(req.params.slug, {
uid: req.params.uid,
}),
user.exists(req.params.uid),
]);

if (!userExists) {
throw new Error('[[error:invalid-uid]]');
} else if (group.disableLeave) {
throw new Error('[[error:group-leave-disabled]]');
} else if (!group.isMember) {
// No change
return helpers.formatApiResponse(200, res);
}

await groups.leave(group.name, req.params.uid);

// Notify owners of user having left
const username = await user.getUserField(req.params.uid, 'username');
const notification = await notifications.create({
type: 'group-leave',
bodyShort: '[[groups:membership.leave.notification-title, ' + username + ', ' + group.name + ']]',
nid: 'group:' + validator.escape(group.name) + ':uid:' + req.params.uid + ':group-leave',
path: '/groups/' + utils.slugify(group.name),
});
const uids = await groups.getOwners(group.name);
await notifications.push(notification, uids);

helpers.formatApiResponse(200, res);
logGroupEvent(req, 'group-leave', {
groupName: group.name,
});
};

function logGroupEvent(req, event, additional) {
events.log({
type: event,
Expand Down
31 changes: 1 addition & 30 deletions src/routes/write/groups.js
Expand Up @@ -13,36 +13,7 @@ module.exports = function () {
setupApiRoute(router, '/', middleware, [...middlewares, middleware.checkRequired.bind(null, ['name']), middleware.exposePrivilegeSet], 'post', controllers.write.groups.create);
setupApiRoute(router, '/:slug', middleware, [...middlewares, middleware.assertGroup, middleware.exposePrivileges], 'delete', controllers.write.groups.delete);
setupApiRoute(router, '/:slug/membership/:uid', middleware, [...middlewares, middleware.assertGroup, middleware.exposePrivileges], 'put', controllers.write.groups.join);

// app.put('/:slug/membership/:uid', middleware.exposeGroupName, apiMiddleware.validateGroup, apiMiddleware.requireUser, apiMiddleware.requireAdmin, function(req, res) {
// Groups.join(res.locals.groupName, req.params.uid, function(err) {
// errorHandler.handle(err, res);
// });
// });

// app.delete('/:slug/membership', apiMiddleware.requireUser, middleware.exposeGroupName, apiMiddleware.validateGroup, function(req, res) {
// Groups.isMember(req.user.uid, res.locals.groupName, function(err, isMember) {
// if (isMember) {
// Groups.leave(res.locals.groupName, req.user.uid, function(err) {
// errorHandler.handle(err, res);
// });
// } else {
// errorHandler.respond(400, res);
// }
// });
// });

// app.delete('/:slug/membership/:uid', middleware.exposeGroupName, apiMiddleware.validateGroup, apiMiddleware.requireUser, apiMiddleware.requireAdmin, function(req, res) {
// Groups.isMember(req.params.uid, res.locals.groupName, function(err, isMember) {
// if (isMember) {
// Groups.leave(res.locals.groupName, req.params.uid, function(err) {
// errorHandler.handle(err, res);
// });
// } else {
// errorHandler.respond(400, res);
// }
// });
// });
setupApiRoute(router, '/:slug/membership/:uid', middleware, [...middlewares, middleware.assertGroup, middleware.exposePrivileges], 'delete', controllers.write.groups.leave);

return router;
};
2 changes: 2 additions & 0 deletions src/socket.io/admin/groups.js
Expand Up @@ -39,6 +39,8 @@ Groups.join = async (socket, data) => {
};

Groups.leave = async function (socket, data) {
sockets.warnDeprecated(socket, 'DELETE /api/v1/groups/:slug/membership/:uid');

if (!data) {
throw new Error('[[error:invalid-data]]');
}
Expand Down
2 changes: 2 additions & 0 deletions src/socket.io/groups.js
Expand Up @@ -69,6 +69,8 @@ SocketGroups.join = async (socket, data) => {
};

SocketGroups.leave = async (socket, data) => {
sockets.warnDeprecated(socket, 'DELETE /api/v1/groups/:slug/membership/:uid');

if (socket.uid <= 0) {
throw new Error('[[error:invalid-uid]]');
}
Expand Down

0 comments on commit 40dc1c3

Please sign in to comment.