Newer
Older
Sebastian Mihalache
committed
const {
Sebastian Mihalache
committed
Team,
User,
Sebastian Mihalache
committed
services,
Collection,
Invitation,
Andrei Cioromila
committed
Fragment,
Sebastian Mihalache
committed
authsome: authsomeHelper,
Sebastian Mihalache
committed
} = require('pubsweet-component-helper-service')
Sebastian Mihalache
committed
const emailInvitations = require('./emails/invitations')
Andrei Cioromila
committed
const { last } = require('lodash')
Sebastian Mihalache
committed
module.exports = models => async (req, res) => {
const { email, role } = req.body
if (!services.checkForUndefinedParams(email, role)) {
res.status(400).json({ error: 'Missing parameters.' })
Sebastian Mihalache
committed
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}.`,
})
Andrei Cioromila
committed
if (last(collection.fragments) !== fragmentId)
return res.status(400).json({
error: `Fragment ${fragmentId} is an older version.`,
})
Sebastian Mihalache
committed
fragment = await models.Fragment.find(fragmentId)
} catch (e) {
const notFoundError = await services.handleNotFoundError(e, 'item')
return res.status(notFoundError.status).json({
error: notFoundError.message,
})
}
Sebastian Mihalache
committed
const authsome = authsomeHelper.getAuthsome(models)
const target = {
collection,
Sebastian Mihalache
committed
}
const canPost = await authsome.can(req.user, 'POST', target)
if (!canPost)
return res.status(403).json({
error: 'Unauthorized.',
})
const collectionHelper = new Collection({ collection })
Sebastian Mihalache
committed
Sebastian Mihalache
committed
const baseUrl = services.getBaseUrl(req)
Sebastian Mihalache
committed
Sebastian Mihalache
committed
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.' })
}
Sebastian Mihalache
committed
await teamHelper.setupTeam({ user, role, objectType: 'fragment' })
invitationHelper.userId = user.id
let invitation = invitationHelper.getInvitation({
invitations: fragment.invitations,
})
let resend = false
if (invitation) {
Sebastian Mihalache
committed
if (invitation.hasAnswer) {
Sebastian Mihalache
committed
return res
.status(400)
.json({ error: 'User has already replied to a previous invitation.' })
Sebastian Mihalache
committed
}
Sebastian Mihalache
committed
invitation.invitedOn = Date.now()
await fragment.save()
resend = true
} else {
const { firstName, lastName, affiliation, country } = req.body
if (
!services.checkForUndefinedParams(
firstName,
lastName,
affiliation,
country,
)
) {
res.status(400).json({ error: 'Missing parameters.' })
}
Sebastian Mihalache
committed
invitation = await invitationHelper.createInvitation({
parentObject: fragment,
})
}
Andrei Cioromila
committed
const fragmentHelper = new Fragment({ fragment })
if (
collection.status === 'heAssigned' ||
(collection.status === 'reviewCompleted' &&
!fragmentHelper.hasReviewReport())
) {
Sebastian Mihalache
committed
collectionHelper.updateStatus({ newStatus: 'reviewersInvited' })
}
Sebastian Mihalache
committed
emailInvitations.sendReviewInvitations({
Sebastian Mihalache
committed
resend,
Sebastian Mihalache
committed
baseUrl,
fragment,
collection,
invitation,
invitedUser: user,
UserModel: models.User,
timestamp: invitation.invitedOn,
Sebastian Mihalache
committed
})
return res.status(200).json(invitation)
} catch (e) {
const userHelper = new User({ UserModel })
const userData = req.body
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}` })
}
Sebastian Mihalache
committed
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({
Sebastian Mihalache
committed
baseUrl,
fragment,
collection,
invitation,
invitedUser: newUser,
UserModel: models.User,
Sebastian Mihalache
committed
timestamp: invitation.invitedOn,
})
return res.status(200).json(invitation)
}
}