const logger = require('@pubsweet/logger') const { Team, services, Collection, Invitation, authsome: authsomeHelper, } = require('pubsweet-component-helper-service') const notifications = require('./emails/notifications') module.exports = models => async (req, res) => { const { email, role } = req.body if (!services.checkForUndefinedParams(email, role)) return res.status(400).json({ error: 'Email and role are required' }) if (role !== 'handlingEditor') return res.status(400).json({ error: `Role ${role} is invalid. Only handlingEditor is allowed.`, }) const reqUser = await models.User.find(req.user) if (email === reqUser.email && !reqUser.admin) { logger.error(`${reqUser.email} tried to invite his own email`) return res.status(400).json({ error: 'Cannot invite yourself.' }) } const { collectionId } = req.params let collection try { collection = await models.Collection.find(collectionId) } catch (e) { const notFoundError = await services.handleNotFoundError(e, 'Collection') return res.status(notFoundError.status).json({ error: notFoundError.message, }) } const authsome = authsomeHelper.getAuthsome(models) const target = { collection, path: req.route.path, } const canPost = await authsome.can(req.user, 'POST', target) if (!canPost) return res.status(403).json({ error: 'Unauthorized.', }) if (!['submitted', 'heInvited'].includes(collection.status)) { return res.status(400).json({ error: `Cannot invite HE while collection is in the status: ${ collection.status }.`, }) } const collectionHelper = new Collection({ collection }) const teamHelper = new Team({ TeamModel: models.Team, collectionId, }) const invitationHelper = new Invitation({ role }) try { const user = await models.User.findByEmail(email) invitationHelper.userId = user.id let invitation = invitationHelper.getInvitation({ invitations: collection.invitations, }) if (invitation) { if (invitation.hasAnswer) return res .status(400) .json({ error: 'User has already replied to a previous invitation.' }) invitation.invitedOn = Date.now() await collection.save() } else { invitation = await invitationHelper.createInvitation({ parentObject: collection, }) } invitation.invitedOn = Date.now() await teamHelper.setupTeam({ user, role, objectType: 'collection' }) await collection.save() await collectionHelper.addHandlingEditor({ user, invitation }) notifications.sendInvitedHEEmail({ models, collection, invitedHE: user, baseUrl: services.getBaseUrl(req), }) return res.status(200).json(invitation) } catch (e) { const notFoundError = await services.handleNotFoundError(e, 'User') return res.status(notFoundError.status).json({ error: notFoundError.message, }) } }