diff --git a/src/api/groups.js b/src/api/groups.js index 95074c4b6a..55e1ca10cd 100644 --- a/src/api/groups.js +++ b/src/api/groups.js @@ -118,19 +118,16 @@ async function canSearchMembers(uid, groupName) { } } -groupsAPI.join = async function (caller, data) { +function validateJoinRequest(caller, data) { if (!data) { throw new Error('[[error:invalid-data]]'); } if (caller.uid <= 0 || !data.uid) { throw new Error('[[error:invalid-uid]]'); } +} - const groupName = await groups.getGroupNameByGroupSlug(data.slug); - if (!groupName) { - throw new Error('[[error:no-group]]'); - } - +async function checkPrivileges(caller, groupName) { const isCallerAdmin = await privileges.admin.can('admin:groups', caller.uid); if (!isCallerAdmin && ( groups.systemGroups.includes(groupName) || @@ -138,6 +135,22 @@ groupsAPI.join = async function (caller, data) { )) { throw new Error('[[error:not-allowed]]'); } + return isCallerAdmin; +} + +function isGroupJoinDisabledForCaller(isCallerAdmin, isSelf, groupData) { + return !isCallerAdmin && isSelf && groupData.private && groupData.disableJoinRequests; +} + +groupsAPI.join = async function (caller, data) { + validateJoinRequest(caller, data); + + const groupName = await groups.getGroupNameByGroupSlug(data.slug); + if (!groupName) { + throw new Error('[[error:no-group]]'); + } + + const isCallerAdmin = await checkPrivileges(caller, groupName); const [groupData, userExists] = await Promise.all([ groups.getGroupData(groupName), @@ -159,7 +172,7 @@ groupsAPI.join = async function (caller, data) { return; } - if (!isCallerAdmin && isSelf && groupData.private && groupData.disableJoinRequests) { + if (isGroupJoinDisabledForCaller(isCallerAdmin, isSelf, groupData)) { throw new Error('[[error:group-join-disabled]]'); } diff --git a/test/groups.js b/test/groups.js index 7b5ae4d73c..f36dc13a51 100644 --- a/test/groups.js +++ b/test/groups.js @@ -1021,6 +1021,16 @@ describe('Groups', () => { assert.equal(updatedData.private, false); }); + it('should fail to join group if user does not exist', async () => { + const nonExistentUid = 123456789; + try { + await apiGroups.join({ uid: adminUid }, { uid: nonExistentUid, slug: 'test' }); + assert(false); + } catch (err) { + assert.strictEqual(err.message, '[[error:invalid-uid]]'); + } + }); + it('should fail to create a group with name guests', async () => { try { await apiGroups.create({ uid: adminUid }, { name: 'guests' });