Skip to content
Snippets Groups Projects
post.js 5.18 KiB
Newer Older
} = require('pubsweet-component-helper-service')

const emailInvitations = require('./emails/invitations')

module.exports = models => async (req, res) => {
  const { email, role } = req.body
  if (!services.checkForUndefinedParams(email, role)) {
    res.status(400).json({ error: 'Missing parameters.' })
    return
  }

  if (role !== 'reviewer')
    return res
      .status(400)
      .json({ error: `Role ${role} is invalid. Only reviewer is accepted.` })

  const UserModel = models.User
  const reqUser = await UserModel.find(req.user)

  if (email === reqUser.email && !reqUser.admin)
    return res.status(400).json({ error: 'Cannot invite yourself.' })

  const { collectionId, fragmentId } = req.params
  let collection, fragment

  try {
    collection = await models.Collection.find(collectionId)
    if (!collection.fragments.includes(fragmentId))
      return res.status(400).json({
        error: `Fragment ${fragmentId} does not match collection ${collectionId}.`,
      })
    if (last(collection.fragments) !== fragmentId)
      return res.status(400).json({
        error: `Fragment ${fragmentId} is an older version.`,
      })
    fragment = await models.Fragment.find(fragmentId)
  } catch (e) {
    const notFoundError = await services.handleNotFoundError(e, 'item')
    return res.status(notFoundError.status).json({
      error: notFoundError.message,
    })
  }
  const { path } = req.route
  const authsome = authsomeHelper.getAuthsome(models)
  const target = {
    collection,
  }
  const canPost = await authsome.can(req.user, 'POST', target)
  if (!canPost)
    return res.status(403).json({
      error: 'Unauthorized.',
    })

  const collectionHelper = new Collection({ collection })
  const baseUrl = services.getBaseUrl(req)
  const teamHelper = new Team({
    TeamModel: models.Team,
    collectionId,
    fragmentId,
  })
  const invitationHelper = new Invitation({ role })

  try {
    const user = await UserModel.findByEmail(email)

    const canInvite = await authsome.can(req.user, '', {
      targetUser: user,
    })
    if (!canInvite) {
      return res.status(400).json({ error: 'Invited user is inactive.' })
    }

    await teamHelper.setupTeam({ user, role, objectType: 'fragment' })
    invitationHelper.userId = user.id

    let invitation = invitationHelper.getInvitation({
      invitations: fragment.invitations,
    })

    if (invitation) {
        return res
          .status(400)
          .json({ error: 'User has already replied to a previous invitation.' })
      // invitation.invitedOn = Date.now()
      // await fragment.save()
      // resend = true
      const { firstName, lastName, affiliation, country } = req.body
      if (
        !services.checkForUndefinedParams(
          firstName,
          lastName,
          affiliation,
          country,
        )
      ) {
        res.status(400).json({ error: 'Missing parameters.' })
      }
      invitation = await invitationHelper.createInvitation({
        parentObject: fragment,
      })

      emailInvitations.sendReviewInvitations({
        baseUrl,
        fragment,
        collection,
        invitation,
        invitedUser: user,
        UserModel: models.User,
        timestamp: invitation.invitedOn,
      })
    const fragmentHelper = new Fragment({ fragment })
    if (
      collection.status === 'heAssigned' ||
      (collection.status === 'reviewCompleted' &&
        !fragmentHelper.hasReviewReport())
    ) {
      collectionHelper.updateStatus({ newStatus: 'reviewersInvited' })
    }

    return res.status(200).json(invitation)
  } catch (e) {
    const userHelper = new User({ UserModel })

    const { firstName, lastName, isPublons } = userData
    if (!services.checkForUndefinedParams(firstName, lastName)) {
      return res
        .status(400)
        .json({ error: 'First name and last name are required.' })
    }
    if (isPublons && process.env.PUBLONS_MOCK_EMAIL) {
      const mockEmail = process.env.PUBLONS_MOCK_EMAIL
      userData.email = mockEmail.replace(
        '__NAME__',
        `${firstName.trim()}.${lastName.trim()}`,
      )
    let newUser
    try {
      newUser = await userHelper.createUser({
        role,
        body: userData,
      })
    } catch (e) {
      return res
        .status(400)
        .json({ error: `User already exists with email: ${userData.email}` })
    }

    if (collection.status === 'heAssigned')
      await collectionHelper.updateStatus({ newStatus: 'reviewersInvited' })

    await teamHelper.setupTeam({ user: newUser, role, objectType: 'fragment' })

    invitationHelper.userId = newUser.id

    const invitation = await invitationHelper.createInvitation({
      parentObject: fragment,
    })

    emailInvitations.sendReviewInvitations({
      baseUrl,
      fragment,
      collection,
      invitation,
      invitedUser: newUser,
      UserModel: models.User,
      timestamp: invitation.invitedOn,
    })

    return res.status(200).json(invitation)
  }
}