Skip to content
Snippets Groups Projects
Commit 4f7cac35 authored by Sebastian's avatar Sebastian
Browse files

added teams for reviewers and HEs

parent 88ac1de2
No related branches found
No related tags found
No related merge requests found
module.exports = {
backend: () => app => require('./src/User')(app),
}
module.exports = {
backend: () => app => require('./src/Invite')(app),
}
{
"name": "pubsweet-component-admin",
"name": "pubsweet-component-invite",
"version": "0.0.1",
"description": "admin component for pubsweet",
"description": "invite component for pubsweet",
"license": "MIT",
"files": [
"src"
......
......@@ -3,71 +3,148 @@ const logger = require('@pubsweet/logger')
const uuid = require('uuid')
const crypto = require('crypto')
const mailService = require('pubsweet-component-mail-service')
const get = require('lodash/get')
const User = app => {
const Invite = app => {
app.use(bodyParser.json())
const authBearer = app.locals.passport.authenticate('bearer', {
session: false,
})
app.post('/api/admin/users', authBearer, async (req, res) => {
const reqUser = await app.locals.models.User.find(req.user)
if (reqUser.admin !== true) {
res.status(403).json({ error: 'Unauthorized' })
logger.error('unauthorized request')
return
}
app.post('/api/users/invite/:collectionId?', authBearer, async (req, res) => {
const { email, role } = req.body
if (email === undefined || role === undefined) {
res.status(400).json({ error: 'all parameters are required' })
if (!checkForUndefinedParams(email, role)) {
res.status(400).json({ error: 'Email and role are required' })
logger.error('some parameters are missing')
return
}
const collectionId = get(req, 'params.collectionId')
const reqUser = await app.locals.models.User.find(req.user)
let collection
if (collectionId) {
try {
if (role !== 'reviewer' && role !== 'handlingEditor') {
res.status(400).json({ error: 'Role does not exist for collections' })
logger.error(
`invitation has been attempted with invalid role: ${role}`,
)
return
}
if (reqUser.roles === undefined) {
res
.status(403)
.json({ error: 'Only HE or EiC can invite users to collection' })
logger.error(`request user does not have any defined roles`)
return
}
if (role === 'reviewer' && !reqUser.roles.includes('handlingEditor')) {
res.status(403).json({ error: 'Only HE can invite reviewers' })
logger.error(`incorrect role when inviting a reviewer`)
return
} else if (
role === 'handlingEditor' &&
!reqUser.roles.includes('editorInChief')
) {
res.status(403).json({ error: 'Only EiC can invite HE' })
logger.error(`incorrect role when inviting a handling editor`)
return
}
collection = await app.locals.models.Collection.find(collectionId)
} catch (e) {
if (e.name === 'NotFoundError') {
res.status(404).json({ error: 'Collection not found' })
logger.error(`invalid collection id when inviting ${role}`)
return
}
res.status(500).json({ error: 'Something went wrong' })
logger.error(e)
return
}
} else if (role !== 'editorInChief') {
res.status(400).json({ error: 'Collection id is required' })
logger.error('missing collection id when trying to invite reviewer/HE')
return
} else if (reqUser.admin !== true) {
res.status(403).json({ error: 'Only an admin can invite EiC' })
logger.error('non-admin user tried to invite an EiC')
return
}
try {
const user = await app.locals.models.User.findByEmail(email)
if (user) {
res.status(400).json({ error: 'User already exists' })
logger.error('admin tried to invite existing user')
return
}
} catch (e) {
if (e.name === 'NotFoundError') {
const userBody = {
username: uuid.v4().slice(0, 7),
email,
password: uuid.v4(),
roles: { role },
passwordResetToken: crypto.randomBytes(32).toString('hex'),
isConfirmed: false,
}
let newUser = new app.locals.models.User(userBody)
newUser = await newUser.save()
let emailType
switch (newUser.roles.role) {
case 'editorInChief':
emailType = 'invite-editor-in-chief'
break
if (e.name !== 'NotFoundError') {
res.status(500).json({ error: e })
logger.error(e)
return
}
const userBody = {
username: uuid.v4().slice(0, 7),
email,
password: uuid.v4(),
roles: [role],
passwordResetToken: crypto.randomBytes(32).toString('hex'),
isConfirmed: false,
}
let newUser = new app.locals.models.User(userBody)
newUser = await newUser.save()
let emailType = 'invite-editor-in-chief'
if (collection) {
let permissions, group, name
switch (newUser.roles[0]) {
case 'handlingEditor':
emailType = 'invite-handling-editor'
permissions = 'editor'
group = 'editor'
name = 'Handling Editor'
break
case 'reviewer':
emailType = 'invite-reviewer'
permissions = 'reviewer'
group = 'reviewer'
name = 'Reviewer'
break
default:
break
}
await mailService.setupEmail(
newUser.email,
emailType,
newUser.passwordResetToken,
)
const teamBody = {
teamType: {
name: newUser.roles[0],
permissions,
},
group,
name,
object: {
type: 'collection',
id: collection.id,
},
members: [newUser.id],
}
const team = new app.locals.models.Team(teamBody)
await team.save()
}
}
res.status(204).json()
await mailService.setupEmail(
newUser.email,
emailType,
newUser.passwordResetToken,
)
res.status(200).json(newUser)
}
})
app.post(
'/api/admin/users/password-reset',
'/api/users/invite/password/reset',
bodyParser.json(),
async (req, res) => {
const {
......@@ -76,7 +153,6 @@ const User = app => {
email,
firstName,
lastName,
username,
middleName,
affiliation,
position,
......@@ -84,14 +160,7 @@ const User = app => {
} = req.body
if (
!checkForUndefinedParams(
token,
password,
email,
firstName,
lastName,
username,
)
!checkForUndefinedParams(token, password, email, firstName, lastName)
) {
res.status(400).json({ error: 'missing required params' })
return
......@@ -101,7 +170,6 @@ const User = app => {
password,
firstName,
lastName,
username,
middleName,
affiliation,
position,
......@@ -147,4 +215,4 @@ const checkForUndefinedParams = (...params) => {
return true
}
module.exports = User
module.exports = Invite
......@@ -4,7 +4,7 @@ const querystring = require('querystring')
const SES = require('pubsweet-components-aws-ses')
const config = require('config')
const resetUrl = config.get('admin-reset-password.url')
const resetUrl = config.get('invite-reset-password.url')
module.exports = {
setupEmail: async (email, emailType, token, comment = '') => {
......@@ -37,14 +37,11 @@ module.exports = {
},
}
const readFile = path => {
const file = fs.readFileSync(path, { encoding: 'utf-8' }, (err, file) => {
const readFile = path =>
fs.readFileSync(path, { encoding: 'utf-8' }, (err, file) => {
if (err) {
throw err
} else {
return file
}
})
return file
}
......@@ -7,5 +7,5 @@
"pubsweet-component-wizard",
"pubsweet-components-faraday",
"pubsweet-components-aws-s3",
"pubsweet-component-admin"
"pubsweet-component-invite"
]
......@@ -60,10 +60,10 @@ module.exports = {
region: process.env.AWS_SES_REGION,
sender: process.env.EMAIL_SENDER,
},
'admin-reset-password': {
'invite-reset-password': {
url:
process.env.PUBSWEET_ADMIN_PASSWORD_RESET_URL ||
'http://localhost:3000/admin/password-reset',
process.env.PUBSWEET_INVITE_PASSWORD_RESET_URL ||
'http://localhost:3000/invite/password-reset',
},
publicKeys: [
'pubsweet-client',
......
......@@ -86,8 +86,8 @@ module.exports = {
},
],
user: {
name: Joi.string(), // TODO: add "name" to the login form
roles: Joi.object(),
name: Joi.string(),
roles: Joi.array(),
isConfirmed: Joi.boolean(),
firstName: Joi.string().allow(''),
lastName: Joi.string().allow(''),
......
......@@ -31,7 +31,7 @@
"pubsweet-component-xpub-submit": "^0.0.2",
"pubsweet-server": "1.0.5",
"pubsweet-components-aws-s3": "^0.0.1",
"pubsweet-component-admin": "^0.0.1",
"pubsweet-component-invite": "^0.0.1",
"react": "^15.6.1",
"react-dnd": "^2.5.4",
"react-dnd-html5-backend": "^2.5.4",
......
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