Skip to content
Snippets Groups Projects
delete.js 5.07 KiB
Newer Older
  authsome: authsomeHelper,
} = require('pubsweet-component-helper-service')
const {
  deleteFilesS3,
} = require('pubsweet-component-mts-package/src/PackageManager')

const { last, get, chain, difference } = require('lodash')

const s3Config = get(config, 'pubsweet-component-aws-s3', {})
const notifications = require('./emails/notifications')

module.exports = models => async (req, res) => {
  const { collectionId, invitationId } = req.params
  const teamHelper = new Team({ TeamModel: models.Team, collectionId })

  try {
    const collection = await models.Collection.find(collectionId)
    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.',
      })

    collection.invitations = collection.invitations || []
    const invitation = collection.invitations.find(
      invitation => invitation.id === invitationId,
    )
    if (!invitation)
      return res.status(404).json({
        error: `Invitation ${invitationId} not found`,
      })
    const team = await teamHelper.getTeam({

    collection.invitations = collection.invitations.filter(
      inv => inv.id !== invitation.id,
    )

    collection.status = 'submitted'
    delete collection.handlingEditor
    await collection.save()
    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()

    if (invitation.hasAnswer && invitation.isAccepted) {
      const FragmentModel = models.Fragment
      const fragment = await FragmentModel.find(
        last(get(collection, 'fragments', [])),
      )
      const fragmentHelper = new Fragment({ fragment })
      const fragmentId = fragment.id
      const teamHelperForFragment = new Team({
        TeamModel: models.Team,
        collectionId,
        fragmentId,
      })

      const teams = await teamHelperForFragment.getTeams('fragment')
      const reviewerTeam = teams.find(
        team => team.object.id === fragmentId && team.group === 'reviewer',
      )
      if (reviewerTeam) {
        reviewerTeam.delete()
      }

      const fileKeys = []
      fragment.recommendations &&
        fragment.recommendations.forEach(recommendation => {
          recommendation.comments.forEach(comment => {
            comment.files &&
              comment.files.forEach(file => {
                fileKeys.push(file.id)
              })
          })
      const revision = get(fragment, 'revision', false)
      if (revision) {
        const fragmentFilesIds = chain(get(fragment, 'files', []))
          .flatMap(item => item)
          .map(item => item.id)
          .value()
        const revisionFilesIds = chain(get(fragment, 'revision.files', []))
          .flatMap(item => item)
          .map(item => item.id)
          .value()
        const revisionFileIds = difference(revisionFilesIds, fragmentFilesIds)
        fileKeys.concat(revisionFileIds)
      }
      if (fileKeys.length > 1) {
        await deleteFilesS3({ fileKeys, s3Config })
      }

      let shouldAuthorBeNotified
        shouldAuthorBeNotified = true
        ...(await fragmentHelper.getReviewers({
          UserModel,
          type: 'accepted',
        })),
        ...(await fragmentHelper.getReviewers({
          UserModel,
          type: 'submitted',
        })),
      fragment.invitations.forEach(inv => {
        Job.cancelQueue(`removal-${inv.userId}-${inv.id}`)
        Job.cancelQueue(`reminders-${inv.userId}-${inv.id}`)
      })

      fragment.invitations = []
      fragment.recommendations = []
      fragment.revision && delete fragment.revision
      await fragment.save()
      notifications.notifyInvitedHEWhenRemoved({
        models,
        collection,
        invitedHE: user,
        baseUrl: services.getBaseUrl(req),
      })

      notifications.notifyReviewersWhenHERemoved({
        models,
        collection,
        reviewers,
        baseUrl: services.getBaseUrl(req),
      })

      if (shouldAuthorBeNotified) {
        notifications.notifyAuthorWhenHERemoved({
          models,
          collection,
          baseUrl: services.getBaseUrl(req),
        })
      }
    } else {
      notifications.sendInvitedHEEmail({
        models,
        collection,
        invitedHE: user,
        isCanceled: true,
        baseUrl: services.getBaseUrl(req),
      })
    }
  } catch (e) {
    const notFoundError = await services.handleNotFoundError(e, 'Collection')
    return res.status(notFoundError.status).json({
      error: notFoundError.message,
    })
  }
}