const { Team, services, Collection, authsome: authsomeHelper, } = require('pubsweet-component-helper-service') const notifications = require('./emails/notifications') const Job = require('pubsweet-component-jobs') module.exports = models => async (req, res) => { const { collectionId, invitationId, fragmentId } = req.params const teamHelper = new Team({ TeamModel: models.Team, collectionId, fragmentId, }) try { const collection = await models.Collection.find(collectionId) if (!collection.fragments.includes(fragmentId)) return res.status(400).json({ error: `Fragment ${fragmentId} does not match collection ${collectionId}.`, }) const fragment = await models.Fragment.find(fragmentId) const collectionHelper = new Collection({ collection }) const authsome = authsomeHelper.getAuthsome(models) const target = { collection, path: req.route.path, } const canDelete = await authsome.can(req.user, 'DELETE', target) if (!canDelete) return res.status(403).json({ error: 'Unauthorized.', }) fragment.invitations = fragment.invitations || [] const invitation = await fragment.invitations.find( invitation => invitation.id === invitationId, ) if (!invitation) return res.status(404).json({ error: `Invitation ${invitationId} not found`, }) const team = await teamHelper.getTeam({ role: invitation.role, objectType: 'fragment', }) fragment.invitations = fragment.invitations.filter( inv => inv.id !== invitation.id, ) await collectionHelper.updateStatusByNumberOfReviewers({ invitations: fragment.invitations, }) await teamHelper.removeTeamMember({ teamId: team.id, userId: invitation.userId, }) const UserModel = models.User const user = await UserModel.find(invitation.userId) user.teams = user.teams.filter(userTeamId => team.id !== userTeamId) await user.save() await fragment.save() const baseUrl = services.getBaseUrl(req) notifications.sendReviewerEmail({ baseUrl, fragment, collection, reviewer: user, isCanceled: true, UserModel: models.User, }) await Job.cancelQueue(`reminders-${user.id}-${invitation.id}`) await Job.cancelQueue(`removal-${user.id}-${invitation.id}`) return res.status(200).json({ fragment }) } catch (e) { const notFoundError = await services.handleNotFoundError(e, 'collection') return res.status(notFoundError.status).json({ error: notFoundError.message, }) } }