diff --git a/test/api/v3/integration/tasks/challenges/POST-tasks_challenge_id.test.js b/test/api/v3/integration/tasks/challenges/POST-tasks_challenge_id.test.js index c28fe15a6f..54c99ac964 100644 --- a/test/api/v3/integration/tasks/challenges/POST-tasks_challenge_id.test.js +++ b/test/api/v3/integration/tasks/challenges/POST-tasks_challenge_id.test.js @@ -54,6 +54,21 @@ describe('POST /tasks/challenge/:challengeId', () => { expect(tasksOrder.habits).to.include(task.id); }); + it('allows non-leader admin to add tasks to a challenge when not a member', async () => { + const admin = await generateUser({'contributor.admin': true}); + let task = await admin.post(`/tasks/challenge/${challenge._id}`, { + text: 'test habit from admin', + type: 'habit', + up: false, + down: true, + notes: 1976, + }); + + let {tasksOrder} = await user.get(`/challenges/${challenge._id}`); + + expect(tasksOrder.habits).to.include(task.id); + }); + it('returns error when user tries to create task with a alias', async () => { await expect(user.post(`/tasks/challenge/${challenge._id}`, { text: 'test habit', diff --git a/website/server/controllers/api-v3/tasks.js b/website/server/controllers/api-v3/tasks.js index c7035f0f99..1d2b7ab747 100644 --- a/website/server/controllers/api-v3/tasks.js +++ b/website/server/controllers/api-v3/tasks.js @@ -244,7 +244,7 @@ api.createChallengeTasks = { // If the challenge does not exist, or if it exists but user is not the leader -> throw error if (!challenge) throw new NotFound(res.t('challengeNotFound')); - if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); + if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); let tasks = await createTasks(req, res, {user, challenge}); @@ -454,7 +454,7 @@ api.updateTask = { } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); + if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one throw new NotFound(res.t('taskNotFound')); } @@ -797,7 +797,7 @@ api.addChecklistItem = { } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); + if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one throw new NotFound(res.t('taskNotFound')); } @@ -913,7 +913,7 @@ api.updateChecklistItem = { } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); + if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one throw new NotFound(res.t('taskNotFound')); } @@ -978,7 +978,7 @@ api.removeChecklistItem = { } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); + if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one throw new NotFound(res.t('taskNotFound')); } @@ -1298,7 +1298,7 @@ api.deleteTask = { } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); + if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one throw new NotFound(res.t('taskNotFound')); } else if (task.userId && task.challenge.id && !task.challenge.broken) {