Skip to content
Snippets Groups Projects
Commit f22b0c8f authored by Alexandru Munteanu's avatar Alexandru Munteanu
Browse files

Merge branch 'develop' of gitlab.coko.foundation:xpub/xpub-faraday into develop

parents 5581cfce a250e41f
No related branches found
No related tags found
1 merge request!10Sprint #12
...@@ -145,6 +145,9 @@ module.exports = { ...@@ -145,6 +145,9 @@ module.exports = {
invitationId: meta.invitation.id, invitationId: meta.invitation.id,
agree: true, agree: true,
} }
const manuscriptDetailsLink = `/projects/${meta.collection.id}/versions/${
meta.fragment.id
}/details`
const declineUrl = helpers.createUrl(baseUrl, resetPasswordPath, { const declineUrl = helpers.createUrl(baseUrl, resetPasswordPath, {
...queryParams, ...queryParams,
...@@ -155,7 +158,7 @@ module.exports = { ...@@ -155,7 +158,7 @@ module.exports = {
let agreeUrl = helpers.createUrl( let agreeUrl = helpers.createUrl(
baseUrl, baseUrl,
`/projects/${meta.collection.id}/versions/${meta.fragment.id}/details`, manuscriptDetailsLink,
queryParams, queryParams,
) )
...@@ -173,7 +176,7 @@ module.exports = { ...@@ -173,7 +176,7 @@ module.exports = {
const replacements = { const replacements = {
agreeUrl, agreeUrl,
declineUrl, declineUrl,
baseUrl, manuscriptDetailsUrl: helpers.createUrl(baseUrl, manuscriptDetailsLink),
title: meta.fragment.title, title: meta.fragment.title,
authors: meta.fragment.authors, authors: meta.fragment.authors,
abstract: meta.fragment.abstract, abstract: meta.fragment.abstract,
...@@ -392,6 +395,25 @@ module.exports = { ...@@ -392,6 +395,25 @@ module.exports = {
replacements.signatureName replacements.signatureName
}` }`
break break
case 'no-response-reviewers-after-recommendation':
subject = meta.emailSubject
replacements.hasLink = false
replacements.previewText = 'a manuscript has reached a decision'
replacements.intro = `Dear Dr. ${user.firstName} ${user.lastName}`
replacements.paragraph = `An editorial decision has been made regarding manuscript "${
meta.fragment.title
}" by ${
meta.fragment.authorName
}. So, you do not need to proceed with the review of this manuscript. <br/>
If you have comments on this manuscript you believe the Editor should see, please email them to Hindawi as soon as possible.`
delete replacements.detailsUrl
replacements.signatureName = meta.handlingEditorName
textBody = `${replacements.intro} ${replacements.paragraph} ${
replacements.signatureName
}`
break
case 'eic-recommendation': case 'eic-recommendation':
subject = `${meta.collection.customId}: Manuscript Recommendation` subject = `${meta.collection.customId}: Manuscript Recommendation`
replacements.previewText = replacements.previewText =
......
...@@ -80,7 +80,7 @@ const getInvitationBody = (emailType, replacements) => { ...@@ -80,7 +80,7 @@ const getInvitationBody = (emailType, replacements) => {
handlePartial('signature', signatureContext) handlePartial('signature', signatureContext)
const lowerContext = { const lowerContext = {
baseUrl: replacements.baseUrl, manuscriptDetailsUrl: replacements.manuscriptDetailsUrl,
lowerContent: replacements.lowerContent, lowerContent: replacements.lowerContent,
signature: replacements.signature, signature: replacements.signature,
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<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">
<p data-pm-slice="1 1 []"> <p data-pm-slice="1 1 []">
<a href="{{baseUrl}}">See more information</a> <a href="{{ manuscriptDetailsUrl }}">See more information</a>
</p> </p>
<p data-pm-slice="1 1 []">&nbsp;</p> <p data-pm-slice="1 1 []">&nbsp;</p>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<tr> <tr>
<td style="padding:30px 23px 20px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> <td style="padding:30px 23px 20px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff">
<div> <div>
<p data-pm-slice="1 1 []">{{ intro}},</p> <p data-pm-slice="1 1 []">{{ intro }},</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<p>{{ upperContent }}</p> <p>{{ upperContent }}</p>
......
...@@ -84,6 +84,38 @@ const setupAgreedReviewersEmailData = async ({ ...@@ -84,6 +84,38 @@ const setupAgreedReviewersEmailData = async ({
) )
} }
const setupNoResponseReviewersEmailData = async ({
baseUrl,
fragment: { title, authorName },
collection,
mailService,
UserModel,
}) => {
const invitations = collection.invitations.filter(
inv => inv.role === 'reviewer' && inv.hasAnswer === false,
)
const userPromises = await invitations.map(async inv =>
UserModel.find(inv.userId),
)
let users = await Promise.all(userPromises)
users = users.filter(Boolean)
const subject = `${collection.customId}: Reviewer Unassigned`
users.forEach(user =>
mailService.sendNotificationEmail({
toEmail: user.email,
user,
emailType: 'no-response-reviewers-after-recommendation',
meta: {
collection: { customId: collection.customId },
fragment: { title, authorName },
handlingEditorName: collection.handlingEditor.name,
baseUrl,
emailSubject: subject,
},
}),
)
}
const setupEiCRecommendationEmailData = async ({ const setupEiCRecommendationEmailData = async ({
baseUrl, baseUrl,
UserModel, UserModel,
...@@ -184,4 +216,5 @@ module.exports = { ...@@ -184,4 +216,5 @@ module.exports = {
setupAgreedReviewersEmailData, setupAgreedReviewersEmailData,
setupEiCRecommendationEmailData, setupEiCRecommendationEmailData,
setupAuthorRequestToRevisionEmailData, setupAuthorRequestToRevisionEmailData,
setupNoResponseReviewersEmailData,
} }
...@@ -80,6 +80,13 @@ module.exports = models => async (req, res) => { ...@@ -80,6 +80,13 @@ module.exports = models => async (req, res) => {
fragment: { title, authorName }, fragment: { title, authorName },
recommendation, recommendation,
}) })
await userHelper.setupNoResponseReviewersEmailData({
baseUrl,
UserModel: models.User,
collection,
mailService,
fragment: { title, authorName },
})
await userHelper.setupEiCRecommendationEmailData({ await userHelper.setupEiCRecommendationEmailData({
baseUrl, baseUrl,
UserModel: models.User, UserModel: models.User,
......
...@@ -60,12 +60,7 @@ const filterObjectData = ( ...@@ -60,12 +60,7 @@ const filterObjectData = (
return object return object
} }
const getTeamsByPermissions = async ( const getTeamsByPermissions = async (teamIds = [], permissions, TeamModel) => {
teamIds = [],
permissions,
TeamModel,
object,
) => {
const teams = await Promise.all( const teams = await Promise.all(
teamIds.map(async teamId => { teamIds.map(async teamId => {
const team = await TeamModel.find(teamId) const team = await TeamModel.find(teamId)
......
...@@ -9,7 +9,6 @@ async function teamPermissions(user, operation, object, context) { ...@@ -9,7 +9,6 @@ async function teamPermissions(user, operation, object, context) {
user.teams, user.teams,
permissions, permissions,
context.models.Team, context.models.Team,
object,
) )
let collectionsPermissions = await Promise.all( let collectionsPermissions = await Promise.all(
...@@ -20,8 +19,12 @@ async function teamPermissions(user, operation, object, context) { ...@@ -20,8 +19,12 @@ async function teamPermissions(user, operation, object, context) {
permission: team.teamType.permissions, permission: team.teamType.permissions,
} }
const objectType = get(object, 'type') const objectType = get(object, 'type')
if (objectType === 'fragment' && collection.fragments.includes(object.id)) if (objectType === 'fragment') {
collPerm.fragmentId = object.id if (collection.fragments.includes(object.id))
collPerm.fragmentId = object.id
else return null
}
if (objectType === 'collection') if (objectType === 'collection')
if (object.id !== collection.id) return null if (object.id !== collection.id) return null
return collPerm return collPerm
...@@ -111,14 +114,13 @@ async function authenticatedUser(user, operation, object, context) { ...@@ -111,14 +114,13 @@ async function authenticatedUser(user, operation, object, context) {
return true return true
} }
// Allow the authenticated user to GET collections they own // allow authenticate owners full pass for a collection
if (operation === 'GET' && object === '/collections/') { if (get(object, 'type') === 'collection') {
return { if (operation === 'PATCH') {
filter: collection => collection.owners.includes(user.id), return {
filter: collection => omit(collection, 'filtered'),
}
} }
}
if (operation === 'GET' && get(object, 'type') === 'collection') {
if (object.owners.includes(user.id)) return true if (object.owners.includes(user.id)) return true
const owner = object.owners.find(own => own.id === user.id) const owner = object.owners.find(own => own.id === user.id)
if (owner !== undefined) return true if (owner !== undefined) return true
...@@ -198,7 +200,7 @@ async function authenticatedUser(user, operation, object, context) { ...@@ -198,7 +200,7 @@ async function authenticatedUser(user, operation, object, context) {
return false return false
} }
if (user.teams.length !== 0 && operation === 'GET') { if (user.teams.length !== 0 && ['GET'].includes(operation)) {
const permissions = await teamPermissions(user, operation, object, context) const permissions = await teamPermissions(user, operation, object, context)
if (permissions) { if (permissions) {
...@@ -216,19 +218,6 @@ async function authenticatedUser(user, operation, object, context) { ...@@ -216,19 +218,6 @@ async function authenticatedUser(user, operation, object, context) {
} }
} }
if (get(object, 'type') === 'collection') {
if (['GET', 'DELETE'].includes(operation)) {
return true
}
// Only allow filtered updating (mirroring filtered creation) for non-admin users)
if (operation === 'PATCH') {
return {
filter: collection => omit(collection, 'filtered'),
}
}
}
// A user can GET, DELETE and PATCH itself // A user can GET, DELETE and PATCH itself
if (get(object, 'type') === 'user' && get(object, 'id') === user.id) { if (get(object, 'type') === 'user' && get(object, 'id') === user.id) {
if (['GET', 'DELETE', 'PATCH'].includes(operation)) { if (['GET', 'DELETE', 'PATCH'].includes(operation)) {
......
...@@ -79,7 +79,7 @@ module.exports = { ...@@ -79,7 +79,7 @@ module.exports = {
}, },
}, },
mailer: { mailer: {
from: 'hindawi@thinslices.com', from: 'faraday@hindawi.com',
path: `${__dirname}/mailer`, path: `${__dirname}/mailer`,
}, },
publicKeys: [ publicKeys: [
......
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