Skip to content
Snippets Groups Projects
Commit 5c1de794 authored by Sebastian's avatar Sebastian
Browse files

feat(component-invite): add new decline route

parent 1a210f84
No related branches found
No related tags found
1 merge request!6Agree/Decline to work on a manuscript
...@@ -124,6 +124,28 @@ const CollectionsInvitations = app => { ...@@ -124,6 +124,28 @@ const CollectionsInvitations = app => {
authBearer, authBearer,
require(`${routePath}/patch`)(app.locals.models), require(`${routePath}/patch`)(app.locals.models),
) )
/**
* @api {patch} /api/collections/:collectionId/invitations/:invitationId/decline Decline an invitation as a reviewer
* @apiGroup CollectionsInvitations
* @apiParam {collectionId} collectionId Collection id
* @apiParam {invitationId} invitationId Invitation id
* @apiParamExample {json} Body
* {
* "invitationToken": "f2d814f0-67a5-4590-ba4f-6a83565feb4f",
* }
* @apiSuccessExample {json} Success
* HTTP/1.1 200 OK
* {}
* @apiErrorExample {json} Update invitations errors
* HTTP/1.1 403 Forbidden
* HTTP/1.1 400 Bad Request
* HTTP/1.1 404 Not Found
* HTTP/1.1 500 Internal Server Error
*/
app.patch(
`${basePath}/:invitationId/decline`,
require(`${routePath}/decline`)(app.locals.models),
)
} }
module.exports = CollectionsInvitations module.exports = CollectionsInvitations
...@@ -99,6 +99,7 @@ const createNewUser = async ( ...@@ -99,6 +99,7 @@ const createNewUser = async (
editorInChief: role === 'editorInChief', editorInChief: role === 'editorInChief',
admin: role === 'admin', admin: role === 'admin',
handlingEditor: role === 'handlingEditor', handlingEditor: role === 'handlingEditor',
invitationToken: role === 'reviewer' ? uuid.v4() : '',
} }
let newUser = new UserModel(userBody) let newUser = new UserModel(userBody)
......
const logger = require('@pubsweet/logger')
const helpers = require('../../helpers/helpers')
const teamHelper = require('../../helpers/Team')
const mailService = require('pubsweet-component-mail-service')
module.exports = models => async (req, res) => {
const { collectionId, invitationId } = req.params
const { invitationToken } = req.body
if (!helpers.checkForUndefinedParams(invitationToken))
return res.status(400).json({ error: 'Token is required' })
try {
const user = await models.User.findOneByField(
'invitationToken',
invitationToken,
)
const collection = await models.Collection.find(collectionId)
const invitation = await collection.invitations.find(
invitation => invitation.id === invitationId,
)
if (invitation === undefined)
return res.status(404).json({
error: `Invitation ${invitationId} not found`,
})
if (invitation.hasAnswer)
return res
.status(400)
.json({ error: `${invitation.id} has already been answered` })
if (invitation.userId !== user.id)
return res.status(403).json({
error: `User ${user.email} is not allowed to modify invitation ${
invitation.id
}`,
})
invitation.timestamp = Date.now()
invitation.hasAnswer = true
const toEmail = collection.handlingEditor.email
invitation.isAccepted = false
const team = await teamHelper.getTeamByGroupAndCollection(
collectionId,
invitation.role,
models.Team,
)
await collection.save()
await teamHelper.removeTeamMember(team.id, user.id, models.Team)
user.teams = user.teams.filter(userTeamId => team.id !== userTeamId)
try {
await mailService.setupDeclineEmail(
toEmail,
user,
'decline',
collection.customId,
)
} catch (e) {
logger.error(e)
return res.status(500).json({ error: 'Email could not be sent.' })
}
await user.save()
res.status(200).json({})
return
} catch (e) {
const notFoundError = await helpers.handleNotFoundError(e, 'item')
return res.status(notFoundError.status).json({
error: notFoundError.message,
})
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> <html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml">
...@@ -164,17 +163,26 @@ ...@@ -164,17 +163,26 @@
<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> <table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;">
<tr> <tr>
<td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff">
<h1 style="text-align: center;">Your Reviewer invitation to a manuscript has been revoked.</h1> <div>
<p data-pm-slice="1 1 []">Dear {{ reivewerName }},</p>
<div style="text-align: center;">&nbsp;</div> <p>&nbsp;</p>
<div style="text-align: center;">&nbsp;</div> <p>You are no longer needed to review the article titled &quot;{{ title }}&quot; by {{
authorName }}. If you have comments on this manuscript you believe the Editor should
see, please email them to {{ staffEmail }} as soon as possible. Thank you for your
time and I hope you will consider reviewing for Hindawi again.</p>
<p>&nbsp;</p>
<p>Best regards,
<br /> {{editorName}}
</p>
</div>
</td> </td>
</tr> </tr>
</table> </table>
<div data-role="module-unsubscribe" class="module unsubscribe-css__unsubscribe___2CDlR" role="module" <div data-role="module-unsubscribe" class="module unsubscribe-css__unsubscribe___2CDlR" role="module" data-type="unsubscribe"
data-type="unsubscribe" style="color:#444444;font-size:12px;line-height:20px;padding:16px 16px 16px 16px;text-align:center"> style="color:#444444;font-size:12px;line-height:20px;padding:16px 16px 16px 16px;text-align:center">
<div class="Unsubscribe--addressLine"> <div class="Unsubscribe--addressLine">
<p class="Unsubscribe--senderName" style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">Hindawi Publishing Corporation</p> <p class="Unsubscribe--senderName" style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">Hindawi Publishing Corporation</p>
<p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px"> <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">
......
...@@ -101,6 +101,7 @@ module.exports = { ...@@ -101,6 +101,7 @@ module.exports = {
teams: Joi.array(), teams: Joi.array(),
editorInChief: Joi.boolean(), editorInChief: Joi.boolean(),
handlingEditor: Joi.boolean(), handlingEditor: Joi.boolean(),
invitationToken: Joi.string().allow(''),
}, },
team: { team: {
group: Joi.string(), group: Joi.string(),
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment