From 808211279441c0c63ceaa0e06b50b12dbd4548dc Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 31 Jul 2025 20:01:10 +0200 Subject: [PATCH 1/2] fix: dont allow invite when opportunity is closed --- .../copilotRequest/approveRequest.service.js | 6 ++--- src/routes/projectMemberInvites/update.js | 27 ++++++++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/routes/copilotRequest/approveRequest.service.js b/src/routes/copilotRequest/approveRequest.service.js index 31e8db89..5ef4d2c1 100644 --- a/src/routes/copilotRequest/approveRequest.service.js +++ b/src/routes/copilotRequest/approveRequest.service.js @@ -4,7 +4,7 @@ import moment from 'moment'; import { Op } from 'sequelize'; import models from '../../models'; -import { CONNECT_NOTIFICATION_EVENT, COPILOT_REQUEST_STATUS, TEMPLATE_IDS, USER_ROLE } from '../../constants'; +import { CONNECT_NOTIFICATION_EVENT, COPILOT_OPPORTUNITY_STATUS, COPILOT_REQUEST_STATUS, TEMPLATE_IDS, USER_ROLE } from '../../constants'; import util from '../../util'; import { createEvent } from '../../services/busApi'; import { getCopilotTypeLabel } from '../../utils/copilot'; @@ -46,13 +46,13 @@ module.exports = (req, data, existingTransaction) => { projectId, type: data.type, status: { - [Op.notIn]: [COPILOT_REQUEST_STATUS.CANCELED], + [Op.in]: [COPILOT_OPPORTUNITY_STATUS.ACTIVE], } }, }) .then((existingCopilotOpportunityOfSameType) => { if (existingCopilotOpportunityOfSameType) { - const err = new Error('There\'s an opportunity of same type already!'); + const err = new Error('There\'s an active opportunity of same type already!'); _.assign(err, { status: 403, }); diff --git a/src/routes/projectMemberInvites/update.js b/src/routes/projectMemberInvites/update.js index d7ff1d66..19414817 100644 --- a/src/routes/projectMemberInvites/update.js +++ b/src/routes/projectMemberInvites/update.js @@ -50,7 +50,7 @@ module.exports = [ // get invite by id and project id return models.ProjectMemberInvite.getPendingOrRequestedProjectInviteById(projectId, inviteId) - .then((invite) => { + .then(async (invite) => { // if invite doesn't exist, return 404 if (!invite) { const err = new Error(`invite not found for project id ${projectId}, inviteId ${inviteId},` + @@ -85,6 +85,31 @@ module.exports = [ return next(err); } + // Check if the copilot opportunity is still active + // When the invited user tries to accept the invite + if (invite.applicationId) { + req.log.debug(`Invite from copilot application: ${invite.applicationId}`); + const application = await models.CopilotApplication.findOne({ + where: { + id: invite.applicationId, + } + }); + + const opportunity = await models.CopilotOpportunity.findOne({ + where: { + id: application.opportunityId, + }, + }); + + req.log.debug(`Copilot opportunity status: ${opportunity.status}`); + if (opportunity.status !== COPILOT_OPPORTUNITY_STATUS.ACTIVE) { + req.log.debug(`Copilot opportunity status is not active`); + const err = new Error('The copilot opportunity is not in active status'); + err.status = 409; + return next(err); + } + } + req.log.debug('Updating invite status'); return invite .update({ From 82dee4ede3fd558badfef8f601d50fee9403e75c Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 31 Jul 2025 20:01:28 +0200 Subject: [PATCH 2/2] fix: dont allow invite when opportunity is closed --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9bdd9263..b3f2600c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -149,7 +149,7 @@ workflows: context : org-global filters: branches: - only: ['develop', 'migration-setup', 'PM-1314'] + only: ['develop', 'migration-setup', 'pm-1398'] - deployProd: context : org-global filters: