diff --git a/packages/component-admin/index.js b/packages/component-admin/index.js
deleted file mode 100644
index f569b273abd8938c1a205c421dff09fc32e824ec..0000000000000000000000000000000000000000
--- a/packages/component-admin/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
-  backend: () => app => require('./src/User')(app),
-}
diff --git a/packages/component-admin/src/User.js b/packages/component-admin/src/User.js
deleted file mode 100644
index f72f01649615103c983a34407c02ebd314a4596e..0000000000000000000000000000000000000000
--- a/packages/component-admin/src/User.js
+++ /dev/null
@@ -1,150 +0,0 @@
-const bodyParser = require('body-parser')
-const logger = require('@pubsweet/logger')
-const uuid = require('uuid')
-const crypto = require('crypto')
-const mailService = require('pubsweet-component-mail-service')
-
-const User = 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
-    }
-    const { email, role } = req.body
-    if (email === undefined || role === undefined) {
-      res.status(400).json({ error: 'all parameters are required' })
-      logger.error('some parameters are missing')
-      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
-          case 'handlingEditor':
-            emailType = 'invite-handling-editor'
-            break
-          case 'reviewer':
-            emailType = 'invite-reviewer'
-            break
-          default:
-            break
-        }
-        await mailService.setupEmail(
-          newUser.email,
-          emailType,
-          newUser.passwordResetToken,
-        )
-      }
-    }
-
-    res.status(204).json()
-  })
-  app.post(
-    '/api/admin/users/password-reset',
-    bodyParser.json(),
-    async (req, res) => {
-      const {
-        token,
-        password,
-        email,
-        firstName,
-        lastName,
-        username,
-        middleName,
-        affiliation,
-        position,
-        title,
-      } = req.body
-
-      if (
-        !checkForUndefinedParams(
-          token,
-          password,
-          email,
-          firstName,
-          lastName,
-          username,
-        )
-      ) {
-        res.status(400).json({ error: 'missing required params' })
-        return
-      }
-
-      const updateFields = {
-        password,
-        firstName,
-        lastName,
-        username,
-        middleName,
-        affiliation,
-        position,
-        title,
-        isConfirmed: true,
-      }
-
-      try {
-        const user = await app.locals.models.User.findByEmail(email)
-        if (user) {
-          if (token !== user.passwordResetToken) {
-            res.status(400).json({ error: 'invalid request' })
-            logger.error('admin pw reset tokens do not match')
-            return
-          }
-
-          let newUser = Object.assign(user, updateFields, user)
-          delete newUser.passwordResetToken
-
-          newUser = await newUser.save()
-          res.status(200).json(newUser)
-        }
-      } catch (e) {
-        if (e.name === 'NotFoundError') {
-          res.status(404).json({ error: 'user not found' })
-          logger.error('admin pw reset on non-existing user')
-        } else if (e.name === 'ValidationError') {
-          res.status(400).json({ error: e.details[0].message })
-          logger.error('admin pw reset validation error')
-        }
-        res.status(400).json({ error: e })
-        logger.error(e)
-      }
-    },
-  )
-}
-
-const checkForUndefinedParams = (...params) => {
-  if (params.includes(undefined)) {
-    return false
-  }
-
-  return true
-}
-
-module.exports = User
diff --git a/packages/component-admin/.gitignore b/packages/component-invite/.gitignore
similarity index 100%
rename from packages/component-admin/.gitignore
rename to packages/component-invite/.gitignore
diff --git a/packages/component-admin/README.md b/packages/component-invite/README.md
similarity index 100%
rename from packages/component-admin/README.md
rename to packages/component-invite/README.md
diff --git a/packages/component-invite/index.js b/packages/component-invite/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..1bdf5faede2f8361802cef49db4e1efb763998ed
--- /dev/null
+++ b/packages/component-invite/index.js
@@ -0,0 +1,3 @@
+module.exports = {
+  backend: () => app => require('./src/Invite')(app),
+}
diff --git a/packages/component-admin/package.json b/packages/component-invite/package.json
similarity index 84%
rename from packages/component-admin/package.json
rename to packages/component-invite/package.json
index 12bc8f99650bf87df42887c5d9d350090b7d8771..8f205cd7a469fc874f282ecc7f1918cc030df327 100644
--- a/packages/component-admin/package.json
+++ b/packages/component-invite/package.json
@@ -1,7 +1,7 @@
 {
-  "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"
diff --git a/packages/component-invite/src/Invite.js b/packages/component-invite/src/Invite.js
new file mode 100644
index 0000000000000000000000000000000000000000..3c92f595065f42746f8c4101d19c846a985b1562
--- /dev/null
+++ b/packages/component-invite/src/Invite.js
@@ -0,0 +1,218 @@
+const bodyParser = require('body-parser')
+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 Invite = app => {
+  app.use(bodyParser.json())
+  const authBearer = app.locals.passport.authenticate('bearer', {
+    session: false,
+  })
+  app.post('/api/users/invite/:collectionId?', authBearer, async (req, res) => {
+    const { email, role } = req.body
+    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') {
+        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
+        }
+
+        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()
+      }
+
+      await mailService.setupEmail(
+        newUser.email,
+        emailType,
+        newUser.passwordResetToken,
+      )
+
+      res.status(200).json(newUser)
+    }
+  })
+  app.post(
+    '/api/users/invite/password/reset',
+    bodyParser.json(),
+    async (req, res) => {
+      const {
+        token,
+        password,
+        email,
+        firstName,
+        lastName,
+        middleName,
+        affiliation,
+        position,
+        title,
+      } = req.body
+
+      if (
+        !checkForUndefinedParams(token, password, email, firstName, lastName)
+      ) {
+        res.status(400).json({ error: 'missing required params' })
+        return
+      }
+
+      const updateFields = {
+        password,
+        firstName,
+        lastName,
+        middleName,
+        affiliation,
+        position,
+        title,
+        isConfirmed: true,
+      }
+
+      try {
+        const user = await app.locals.models.User.findByEmail(email)
+        if (user) {
+          if (token !== user.passwordResetToken) {
+            res.status(400).json({ error: 'invalid request' })
+            logger.error('admin pw reset tokens do not match')
+            return
+          }
+
+          let newUser = Object.assign(user, updateFields, user)
+          delete newUser.passwordResetToken
+
+          newUser = await newUser.save()
+          res.status(200).json(newUser)
+        }
+      } catch (e) {
+        if (e.name === 'NotFoundError') {
+          res.status(404).json({ error: 'user not found' })
+          logger.error('admin pw reset on non-existing user')
+        } else if (e.name === 'ValidationError') {
+          res.status(400).json({ error: e.details[0].message })
+          logger.error('admin pw reset validation error')
+        }
+        res.status(400).json({ error: e })
+        logger.error(e)
+      }
+    },
+  )
+}
+
+const checkForUndefinedParams = (...params) => {
+  if (params.includes(undefined)) {
+    return false
+  }
+
+  return true
+}
+
+module.exports = Invite
diff --git a/packages/component-mail-service/src/Mail.js b/packages/component-mail-service/src/Mail.js
index 23644ec833d62036e394e8f933810fad077ae486..2b053dfdac820fd4242e9fc96c4a240f41563703 100644
--- a/packages/component-mail-service/src/Mail.js
+++ b/packages/component-mail-service/src/Mail.js
@@ -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
-}
diff --git a/packages/components-faraday/src/components/Admin/AddEditUser.js b/packages/components-faraday/src/components/Admin/AddEditUser.js
index f273f5d76533d5cbf1d5f5b3dbe709b8521f4adc..73da41f467687462474ce99641d919a682b0a6de 100644
--- a/packages/components-faraday/src/components/Admin/AddEditUser.js
+++ b/packages/components-faraday/src/components/Admin/AddEditUser.js
@@ -76,4 +76,6 @@ const Row = styled.div`
   display: flex;
   flex-direction: row;
   margin: 10px 0;
+  align-items: center;
+  justify-content: space-evenly;
 `
diff --git a/packages/components-faraday/src/components/SignUp/SignUpInvitationForm.js b/packages/components-faraday/src/components/SignUp/SignUpInvitationForm.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f4a61f1437d83927db7145d3c8d103714eddc7c
--- /dev/null
+++ b/packages/components-faraday/src/components/SignUp/SignUpInvitationForm.js
@@ -0,0 +1,57 @@
+import React from 'react'
+import styled from 'styled-components'
+
+import Step0 from './SignUpStep0'
+import Step1 from './SignUpStep1'
+
+const SignUpInvitation = ({
+  journal,
+  email,
+  token,
+  step,
+  nextStep,
+  submitConfirmation,
+}) => (
+  <Root>
+    <Title>Add New Account Details</Title>
+    <Subtitle>
+      Your details have been pre-filled, please review and confirm before set
+      your password.
+    </Subtitle>
+    <Email>{email}</Email>
+    {step === 0 && <Step0 journal={journal} onSubmit={nextStep} />}
+    {step === 1 && <Step1 journal={journal} onSubmit={submitConfirmation} />}
+  </Root>
+)
+
+export default SignUpInvitation
+
+const Root = styled.div`
+  max-width: 500px;
+  min-width: 300px;
+  margin: 0 auto;
+  display: flex;
+  border: 1px solid var(--color-pending);
+  padding: 20px;
+  flex-direction: column;
+`
+
+const Title = styled.div`
+  font-size: 24px;
+  font-weight: bold;
+  text-align: center;
+  margin: 10px auto;
+`
+const Subtitle = styled.div`
+  font-size: 13px;
+  font-weight: normal;
+  text-align: center;
+  margin: 10px auto;
+`
+
+const Email = styled.div`
+  font-size: 16px;
+  font-weight: normal;
+  text-align: center;
+  margin: 10px auto;
+`
diff --git a/packages/components-faraday/src/components/SignUp/SignUpInvitationPage.js b/packages/components-faraday/src/components/SignUp/SignUpInvitationPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..5a4164c173dc64ba312f4c62eb1f32e05eca47f6
--- /dev/null
+++ b/packages/components-faraday/src/components/SignUp/SignUpInvitationPage.js
@@ -0,0 +1,20 @@
+import { withJournal } from 'xpub-journal'
+import { compose, withState, withProps, withHandlers } from 'recompose'
+
+import SignUpInvitation from './SignUpInvitationForm'
+
+export default compose(
+  withJournal,
+  withState('step', 'changeStep', 0),
+  withHandlers({
+    nextStep: ({ changeStep }) => () => changeStep(step => step + 1),
+    prevStep: ({ changeStep }) => () => changeStep(step => step - 1),
+    submitConfirmation: () => values => values,
+  }),
+  withProps(({ location }) => {
+    const params = new URLSearchParams(location.search)
+    const email = params.get('email')
+    const token = params.get('token')
+    return { email, token }
+  }),
+)(SignUpInvitation)
diff --git a/packages/components-faraday/src/components/SignUp/SignUpStep0.js b/packages/components-faraday/src/components/SignUp/SignUpStep0.js
new file mode 100644
index 0000000000000000000000000000000000000000..809423c82ce5bdc2d9028b39b2677a971e8b2f28
--- /dev/null
+++ b/packages/components-faraday/src/components/SignUp/SignUpStep0.js
@@ -0,0 +1,87 @@
+import React from 'react'
+import styled from 'styled-components'
+import { reduxForm } from 'redux-form'
+import { required } from 'xpub-validators'
+import { Button, ValidatedField, TextField, Menu } from '@pubsweet/ui'
+
+const Step0 = ({ journal, handleSubmit }) => (
+  <FormContainer onSubmit={handleSubmit}>
+    <Row>
+      <RowItem>
+        <Label> First name </Label>
+        <ValidatedField
+          component={TextField}
+          name="firstName"
+          validate={[required]}
+        />
+      </RowItem>
+      <RowItem>
+        <Label> Affiliation </Label>
+        <ValidatedField component={TextField} name="affiliation" />
+      </RowItem>
+    </Row>
+    <Row>
+      <RowItem>
+        <Label> Middle name </Label>
+        <ValidatedField component={TextField} name="middleName" />
+      </RowItem>
+      <RowItem>
+        <Label> Position </Label>
+        <ValidatedField
+          component={TextField}
+          name="position"
+          validate={[required]}
+        />
+      </RowItem>
+    </Row>
+    <Row>
+      <RowItem>
+        <Label> Last name </Label>
+        <ValidatedField
+          component={TextField}
+          name="lastName"
+          validate={[required]}
+        />
+      </RowItem>
+      <RowItem>
+        <Label> Title </Label>
+        <ValidatedField
+          component={input => <Menu {...input} options={journal.title} />}
+          name="title"
+          validate={[required]}
+        />
+      </RowItem>
+    </Row>
+    <Row>
+      <Button primary type="submit">
+        CONFIRM & PROCEED TO SET PASSWORD
+      </Button>
+    </Row>
+  </FormContainer>
+)
+
+export default reduxForm({
+  form: 'signUpInvitation',
+  destroyOnUnmount: false,
+  forceUnregisterOnUnmount: true,
+})(Step0)
+
+const FormContainer = styled.form``
+
+const Row = styled.div`
+  display: flex;
+  flex-direction: row;
+  margin: 20px 0;
+  align-items: center;
+  justify-content: space-evenly;
+`
+
+const RowItem = styled.div`
+  flex: 1;
+  margin-right: 20px;
+`
+
+const Label = styled.div`
+  font-size: 14px;
+  text-transform: uppercase;
+`
diff --git a/packages/components-faraday/src/components/SignUp/SignUpStep1.js b/packages/components-faraday/src/components/SignUp/SignUpStep1.js
new file mode 100644
index 0000000000000000000000000000000000000000..53da9b98ef2dba046e25d534b5a2c6e95f6dd550
--- /dev/null
+++ b/packages/components-faraday/src/components/SignUp/SignUpStep1.js
@@ -0,0 +1,51 @@
+import React from 'react'
+import styled from 'styled-components'
+import { reduxForm } from 'redux-form'
+import { required } from 'xpub-validators'
+import { Button, ValidatedField, TextField } from '@pubsweet/ui'
+
+const Step1 = ({ journal, handleSubmit }) => (
+  <FormContainer onSubmit={handleSubmit}>
+    <Row>
+      <RowItem>
+        <Label> Password </Label>
+        <ValidatedField
+          component={input => <TextField {...input} type="password" />}
+          name="password"
+          validate={[required]}
+        />
+      </RowItem>
+    </Row>
+    <Row>
+      <Button primary type="submit">
+        CONFIRM
+      </Button>
+    </Row>
+  </FormContainer>
+)
+
+export default reduxForm({
+  form: 'signUpInvitation',
+  destroyOnUnmount: false,
+  forceUnregisterOnUnmount: true,
+})(Step1)
+
+const FormContainer = styled.form``
+
+const Row = styled.div`
+  display: flex;
+  flex-direction: row;
+  margin: 20px 0;
+  align-items: center;
+  justify-content: space-evenly;
+`
+
+const RowItem = styled.div`
+  flex: 1;
+  margin-right: 20px;
+`
+
+const Label = styled.div`
+  font-size: 14px;
+  text-transform: uppercase;
+`
diff --git a/packages/xpub-faraday/app/config/journal/index.js b/packages/xpub-faraday/app/config/journal/index.js
index 874f461288cd76f59551a4018215c1ff5408c99e..e3666200803bc17b8d68f62b8695bc96b8c6d87c 100644
--- a/packages/xpub-faraday/app/config/journal/index.js
+++ b/packages/xpub-faraday/app/config/journal/index.js
@@ -10,3 +10,4 @@ export { default as issueTypes } from './issues-types'
 export { default as articleTypes } from './article-types-tbrm'
 export { default as articleSections } from './article-sections-tbrm'
 export { default as manuscriptTypes } from './manuscript-types'
+export { default as title } from './title'
diff --git a/packages/xpub-faraday/app/config/journal/title.js b/packages/xpub-faraday/app/config/journal/title.js
new file mode 100644
index 0000000000000000000000000000000000000000..d2829fac00346ecc4782359c6e290bc2cc053f88
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/title.js
@@ -0,0 +1,6 @@
+export default [
+  {
+    label: 'Prof.',
+    value: 'prof',
+  },
+]
diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js
index 290a73e113619d66173385177aab5484cbba5254..032d54a0b756a49422696621e168087fdc7b0287 100644
--- a/packages/xpub-faraday/app/routes.js
+++ b/packages/xpub-faraday/app/routes.js
@@ -19,6 +19,7 @@ import {
   AdminUsers,
 } from 'pubsweet-components-faraday/src/components/Admin'
 import AddEditUser from 'pubsweet-components-faraday/src/components/Admin/AddEditUser'
+import SignUpInvitationPage from 'pubsweet-components-faraday/src/components/SignUp/SignUpInvitationPage'
 
 import FaradayApp from './FaradayApp'
 
@@ -42,6 +43,7 @@ const Routes = () => (
         path="/admin/users/edit/:userId"
       />
       <PrivateRoute component={LogoutPage} exact path="/logout" />
+      <PrivateRoute component={SignUpInvitationPage} exact path="/invite" />
       <PrivateRoute
         component={Wizard}
         exact
diff --git a/packages/xpub-faraday/config/components.json b/packages/xpub-faraday/config/components.json
index d64253bf25516eebd779a3f72a6f728e37ef63c6..0219f3fda35effeebc20af6c48b484e5ed3ca2d4 100644
--- a/packages/xpub-faraday/config/components.json
+++ b/packages/xpub-faraday/config/components.json
@@ -7,5 +7,5 @@
   "pubsweet-component-wizard",
   "pubsweet-components-faraday",
   "pubsweet-components-aws-s3",
-  "pubsweet-component-admin"
+  "pubsweet-component-invite"
 ]
diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js
index 245f1dbe7b3d34ab7c80d7399c2d000240341f51..b5acdae84239af709cacddfc81852a9fb7d37b62 100644
--- a/packages/xpub-faraday/config/default.js
+++ b/packages/xpub-faraday/config/default.js
@@ -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',
   },
   publicKeys: [
     'pubsweet-client',
diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js
index 8b98883df175275ecb57a268cf4f549d065a92c3..879eeb43eebaaf892bca5dabdc81e483456c5809 100644
--- a/packages/xpub-faraday/config/validations.js
+++ b/packages/xpub-faraday/config/validations.js
@@ -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(''),
diff --git a/packages/xpub-faraday/package.json b/packages/xpub-faraday/package.json
index e3b80d41b71900568e6bb0eb5d821f06df2765f7..f344bc49ec85ca3a6bcc1dff01299b0c19211e00 100644
--- a/packages/xpub-faraday/package.json
+++ b/packages/xpub-faraday/package.json
@@ -21,6 +21,7 @@
     "prop-types": "^15.5.10",
     "pubsweet": "^1.1.1",
     "pubsweet-client": "^1.1.1",
+    "pubsweet-component-admin": "^0.0.1",
     "pubsweet-component-ink-backend": "^0.1.1",
     "pubsweet-component-ink-frontend": "^0.2.3",
     "pubsweet-component-xpub-app": "^0.0.2",
@@ -29,9 +30,9 @@
     "pubsweet-component-xpub-manuscript": "^0.0.2",
     "pubsweet-component-xpub-review": "^0.0.2",
     "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",
+    "pubsweet-server": "1.0.5",
     "react": "^15.6.1",
     "react-dnd": "^2.5.4",
     "react-dnd-html5-backend": "^2.5.4",