diff --git a/packages/component-invite/src/controllers/assignCollectionRole.js b/packages/component-invite/src/controllers/assignCollectionRole.js
index aa194324155156c40f30ed7945d2118a51876a8b..c3f8fd95e6e144ab1694120492e15234fe683387 100644
--- a/packages/component-invite/src/controllers/assignCollectionRole.js
+++ b/packages/component-invite/src/controllers/assignCollectionRole.js
@@ -1,6 +1,7 @@
 const logger = require('@pubsweet/logger')
 const config = require('config')
 const helpers = require('../helpers/helpers')
+const teamHelper = require('../helpers/Team')
 const mailService = require('pubsweet-component-mail-service')
 
 const configRoles = config.get('roles')
@@ -29,6 +30,27 @@ module.exports = async (
       .json({ error: `Role ${role} cannot be set on collections` })
   }
 
+  if (!reqUser.editorInChief && reqUser.teams === undefined) {
+    return res
+      .status(403)
+      .json({ error: `User ${reqUser.username} is not part of any teams` })
+  } else if (reqUser.editorInChief === false) {
+    const matchingTeams = await teamHelper.getMatchingTeams(
+      reqUser.teams,
+      models.Team,
+      collectionId,
+      role,
+    )
+
+    if (matchingTeams.length === 0) {
+      return res.status(403).json({
+        error: `User ${
+          reqUser.email
+        } cannot invite a ${role} to ${collectionId}`,
+      })
+    }
+  }
+
   try {
     await models.Collection.find(collectionId)
   } catch (e) {
@@ -40,7 +62,6 @@ module.exports = async (
 
   try {
     let user = await models.User.findByEmail(email)
-    user.roles.push(role)
     const assignation = {
       type: role,
       hasAnswer: false,
@@ -56,8 +77,9 @@ module.exports = async (
       url,
     )
 
-    // TODO: create a team and add the team id to the user's teams array
+    await teamHelper.setupManuscriptTeam(models, user, collectionId, role)
 
+    user = await models.User.find(user)
     return res.status(200).json(user)
   } catch (e) {
     const notFoundError = await helpers.handleNotFoundError(e, 'user')
diff --git a/packages/component-invite/src/controllers/inviteGlobalRole.js b/packages/component-invite/src/controllers/inviteGlobalRole.js
index ea05a8d5c09bf0c2913a9a0c7c55a63b0f33c469..a3f7e57a828f8bcc73bc532d5609899b2d3290b7 100644
--- a/packages/component-invite/src/controllers/inviteGlobalRole.js
+++ b/packages/component-invite/src/controllers/inviteGlobalRole.js
@@ -1,15 +1,25 @@
 const logger = require('@pubsweet/logger')
 const helpers = require('../helpers/helpers')
 const mailService = require('pubsweet-component-mail-service')
+const config = require('config')
 
-module.exports = async (body, UserModel, res, url) => {
+const configRoles = config.get('roles')
+
+module.exports = async (body, models, res, url) => {
   const { email, role, firstName, lastName, affiliation, title } = body
 
+  if (!configRoles.inviteRights.admin.includes(role)) {
+    logger.error(`admin ${email} tried to invite a ${role}`)
+    return res
+      .status(403)
+      .json({ error: `admin tried to invite an invalid role: ${role}` })
+  }
+
   try {
-    const user = await UserModel.findByEmail(email)
+    const user = await models.User.findByEmail(email)
 
     if (user) {
-      logger.error('someone tried to invite existing user')
+      logger.error(`admin tried to invite existing user: ${email}`)
       return res.status(400).json({ error: 'User already exists' })
     }
   } catch (e) {
@@ -20,12 +30,12 @@ module.exports = async (body, UserModel, res, url) => {
 
     const newUser = await helpers.createNewUser(
       email,
-      role,
       firstName,
       lastName,
       affiliation,
       title,
-      UserModel,
+      models.User,
+      role,
     )
 
     await mailService.setupInviteEmail(
diff --git a/packages/component-invite/src/helpers/Team.js b/packages/component-invite/src/helpers/Team.js
new file mode 100644
index 0000000000000000000000000000000000000000..aa967186b165ae6141c764e6cc76bc249314f775
--- /dev/null
+++ b/packages/component-invite/src/helpers/Team.js
@@ -0,0 +1,121 @@
+const logger = require('@pubsweet/logger')
+const config = require('config')
+
+const configRoles = config.get('roles')
+
+const createNewTeam = async (collectionId, role, userId, TeamModel) => {
+  let permissions, group, name
+  switch (role) {
+    case 'handlingEditor':
+      permissions = 'handlingEditor'
+      group = 'handlingEditor'
+      name = 'Handling Editor'
+      break
+    case 'reviewer':
+      permissions = 'reviewer'
+      group = 'reviewer'
+      name = 'Reviewer'
+      break
+    default:
+      break
+  }
+
+  const teamBody = {
+    teamType: {
+      name: role,
+      permissions,
+    },
+    group,
+    name,
+    object: {
+      type: 'collection',
+      id: collectionId,
+    },
+    members: [userId],
+  }
+  const team = new TeamModel(teamBody)
+  try {
+    await team.save()
+  } catch (e) {
+    logger.error(e)
+  }
+}
+
+const setupEiCTeams = async (models, user) => {
+  const collections = await models.Collection.all()
+  const teams = await models.Team.all()
+  user.teams = []
+  const collectionIDs = []
+  /* eslint-disable */
+  for (const collection of collections) {
+    for (let team of teams) {
+      if (
+        team.group === 'editorInChief' &&
+        team.object.type === 'collection' &&
+        team.object.id === collection.id
+      ) {
+        collectionIDs.push(collection.id)
+        team.members.push(user.id)
+        try {
+          team = await team.updateProperties(team)
+          team = await team.save()
+        } catch (e) {
+          logger.error(e)
+        }
+      }
+    }
+
+    if (!collectionIDs.includes(collection.id)) {
+      await createNewTeam(collection.id, 'editorInChief', user.id, models.Team)
+    }
+  }
+  /* eslint-enable */
+  user = await models.User.find(user.id)
+  return user
+}
+
+const setupManuscriptTeam = async (models, user, collectionId, role) => {
+  const teams = await models.Team.all()
+  user.teams = []
+  const filteredTeams = teams.filter(
+    team =>
+      team.group === role &&
+      team.object.type === 'collection' &&
+      team.object.id === collectionId,
+  )
+
+  if (filteredTeams.length > 0) {
+    let team = filteredTeams[0]
+    team.members.push(user.id)
+
+    try {
+      team = await team.updateProperties(team)
+      team = await team.save()
+    } catch (e) {
+      logger.error(e)
+    }
+  } else {
+    await createNewTeam(collectionId, role, user.id, models.Team)
+  }
+}
+
+const getMatchingTeams = (teams, TeamModel, collectionId, role) =>
+  teams
+    .map(async teamId => {
+      const team = await TeamModel.find(teamId)
+      if (
+        team.object.id === collectionId &&
+        configRoles.inviteRights[team.group].includes(role)
+      ) {
+        return team
+      }
+      return null
+    })
+    .filter(Boolean)
+
+module.exports = {
+  createNewTeam,
+  setupEiCTeams,
+  setupManuscriptTeam,
+  getMatchingTeams,
+}
diff --git a/packages/component-invite/src/helpers/helpers.js b/packages/component-invite/src/helpers/helpers.js
index 8ea26ed992dfad7ca59241f211e348a87c506c18..b575118780be1e6c3da1932adac332d543051a5b 100644
--- a/packages/component-invite/src/helpers/helpers.js
+++ b/packages/component-invite/src/helpers/helpers.js
@@ -58,26 +58,6 @@ const validateEmailAndToken = async (email, token, userModel) => {
   }
 }
 
-const hasInviteRight = (configRoles, userRoles, role) => {
-  const includesRole = existingRole =>
-    configRoles.inviteRights[existingRole].includes(role)
-  if (!userRoles.some(includesRole)) {
-    logger.error(`incorrect role when inviting a user`)
-
-    return {
-      success: false,
-      status: 403,
-      message: `${userRoles} cannot invite a ${role}`,
-    }
-  }
-
-  return {
-    success: true,
-    status: null,
-    message: null,
-  }
-}
-
 const handleNotFoundError = async (error, item) => {
   const response = {
     success: false,
@@ -95,72 +75,40 @@ const handleNotFoundError = async (error, item) => {
   return response
 }
 
-const createNewTeam = async (collectionId, user, TeamModel) => {
-  let permissions, group, name
-  switch (user.roles[0]) {
-    case 'handlingEditor':
-      permissions = 'editor'
-      group = 'editor'
-      name = 'Handling Editor'
-      break
-    case 'reviewer':
-      permissions = 'reviewer'
-      group = 'reviewer'
-      name = 'Reviewer'
-      break
-    default:
-      break
-  }
-
-  const teamBody = {
-    teamType: {
-      name: user.roles[0],
-      permissions,
-    },
-    group,
-    name,
-    object: {
-      type: 'collection',
-      id: collectionId,
-    },
-    members: [user.id],
-  }
-  const team = new TeamModel(teamBody)
-  await team.save()
-}
-
 const createNewUser = async (
   email,
-  role,
   firstName,
   lastName,
   affiliation,
   title,
   UserModel,
+  role,
 ) => {
   const userBody = {
     username: uuid.v4().slice(0, 8),
     email,
     password: uuid.v4(),
-    roles: [role],
     passwordResetToken: crypto.randomBytes(32).toString('hex'),
     isConfirmed: false,
     firstName,
     lastName,
     affiliation,
     title,
+    editorInChief: role === 'editorInChief',
     admin: role === 'admin',
   }
   let newUser = new UserModel(userBody)
-  newUser = await newUser.save()
-  return newUser
+  try {
+    newUser = await newUser.save()
+    return newUser
+  } catch (e) {
+    logger.error(e)
+  }
 }
 
 module.exports = {
   checkForUndefinedParams,
   validateEmailAndToken,
-  hasInviteRight,
   handleNotFoundError,
-  createNewTeam,
   createNewUser,
 }
diff --git a/packages/component-invite/src/routes/postInvite.js b/packages/component-invite/src/routes/postInvite.js
index 40050fad233caed4334c8a7a1379c89ac43659b5..113f8b21a436110a610d08c694d1a777773796fd 100644
--- a/packages/component-invite/src/routes/postInvite.js
+++ b/packages/component-invite/src/routes/postInvite.js
@@ -1,10 +1,7 @@
 const logger = require('@pubsweet/logger')
 const get = require('lodash/get')
-const config = require('config')
 const helpers = require('../helpers/helpers')
 
-const configRoles = config.get('roles')
-
 module.exports = models => async (req, res) => {
   const { email, role } = req.body
 
@@ -16,15 +13,6 @@ module.exports = models => async (req, res) => {
 
   const reqUser = await models.User.find(req.user)
   const collectionId = get(req, 'params.collectionId')
-  if (reqUser.admin) reqUser.roles = reqUser.roles || ['admin']
-  const inviteRight = helpers.hasInviteRight(configRoles, reqUser.roles, role)
-  if (!inviteRight.success) {
-    res.status(inviteRight.status).json({
-      error: inviteRight.message,
-    })
-    logger.error(`incorrect role when inviting a ${role}`)
-    return
-  }
 
   const url = `${req.protocol}://${req.get('host')}`
   if (collectionId) {
@@ -42,12 +30,12 @@ module.exports = models => async (req, res) => {
   if (reqUser.admin)
     return require('../controllers/inviteGlobalRole')(
       req.body,
-      models.User,
+      models,
       res,
       url,
     )
 
   res.status(403).json({
-    error: `${reqUser.roles} cannot invite a ${role} without a collection`,
+    error: `${reqUser.username} cannot invite a ${role} without a collection`,
   })
 }
diff --git a/packages/component-invite/src/tests/fixtures/teams.js b/packages/component-invite/src/tests/fixtures/teams.js
index 1410dc9e2ce5475bd299847a0fa1db65dee57f66..28cdaf9a8e5bc9b914988f860a8b947f4f8f55ae 100644
--- a/packages/component-invite/src/tests/fixtures/teams.js
+++ b/packages/component-invite/src/tests/fixtures/teams.js
@@ -1,15 +1,51 @@
 const users = require('./users')
 
-module.exports = {
-  teamType: {
-    name: 'editorInChief',
-    permissions: 'editor',
+const { editorInChief, handlingEditor, reviewer } = users
+const teams = {
+  eicTeam: {
+    teamType: {
+      name: 'editorInChief',
+      permissions: 'editorInChief',
+    },
+    group: 'editorInChief',
+    name: 'Editor in Chief',
+    object: {
+      type: 'collection',
+      id: '123',
+    },
+    members: [editorInChief.id],
+    save: jest.fn(() => teams.eicTeam),
+    updateProperties: jest.fn(() => teams.eicTeam),
   },
-  group: 'editor',
-  name: 'Editor in Chief',
-  object: {
-    type: 'collection',
-    id: '123',
+  heTeam: {
+    teamType: {
+      name: 'handlingEditor',
+      permissions: 'handlingEditor',
+    },
+    group: 'handlingEditor',
+    name: 'HandlingEditor',
+    object: {
+      type: 'collection',
+      id: '123',
+    },
+    members: [handlingEditor.id],
+    save: jest.fn(() => teams.heTeam),
+    updateProperties: jest.fn(() => teams.heTeam),
+  },
+  reviewerTeam: {
+    teamType: {
+      name: 'reviewer',
+      permissions: 'reviewer',
+    },
+    group: 'reviewer',
+    name: 'Reviewer',
+    object: {
+      type: 'collection',
+      id: '123',
+    },
+    members: [reviewer.id],
+    save: jest.fn(() => teams.reviewerTeam),
+    updateProperties: jest.fn(() => teams.reviewerTeam),
   },
-  members: [users.editorInChief.id],
 }
+module.exports = teams
diff --git a/packages/component-invite/src/tests/fixtures/users.js b/packages/component-invite/src/tests/fixtures/users.js
index 3b4baec68d3297d8d5f64ca5baf94c56f6920b58..daef8ad168bbc95f704b71235ab4c375a96f91a2 100644
--- a/packages/component-invite/src/tests/fixtures/users.js
+++ b/packages/component-invite/src/tests/fixtures/users.js
@@ -1,6 +1,7 @@
 const collections = require('./collections')
 
 const { standardCollection } = collections
+
 const users = {
   admin: {
     type: 'user',
@@ -17,14 +18,14 @@ const users = {
     password: 'test1234',
     admin: false,
     id: 'editor123',
-    roles: ['editorInChief'],
     passwordResetToken: 'token123',
-    firstName: 'vlad',
-    lastName: 'dracul',
+    firstName: 'john',
+    lastName: 'smith',
     affiliation: 'MIT',
-    title: 'prof',
+    title: 'Mr',
     save: jest.fn(() => users.editorInChief),
     isConfirmed: false,
+    editorInChief: true,
   },
   handlingEditor: {
     type: 'user',
@@ -33,7 +34,6 @@ const users = {
     password: 'test',
     admin: false,
     id: 'handling123',
-    roles: ['handlingEditor'],
     assignations: [
       {
         type: 'handlingEditor',
@@ -43,6 +43,7 @@ const users = {
       },
     ],
     save: jest.fn(() => users.handlingEditor),
+    editorInChief: false,
   },
   author: {
     type: 'user',
@@ -51,15 +52,30 @@ const users = {
     password: 'test',
     admin: false,
     id: 'author123',
-    roles: ['author'],
     passwordResetToken: 'token123',
     firstName: 'leopold',
     lastName: 'smith',
     affiliation: 'MIT',
-    title: 'mr',
+    title: 'Mr',
     save: jest.fn(() => users.author),
     isConfirmed: false,
   },
+  reviewer: {
+    type: 'user',
+    username: 'reviewer',
+    email: 'reviewer@example.com',
+    password: 'test',
+    admin: false,
+    id: 'reviewer123',
+    passwordResetToken: 'token123',
+    firstName: 'angela',
+    lastName: 'smith',
+    affiliation: 'MIT',
+    title: 'Ms',
+    save: jest.fn(() => users.reviewer),
+    isConfirmed: false,
+    teams: [],
+  },
 }
 
 module.exports = users
diff --git a/packages/component-invite/src/tests/postInvite.test.js b/packages/component-invite/src/tests/postInvite.test.js
index 5a3bdc423ac6499fe156ff50ad5f1b32d92d95af..1e6de6eb5f8120039e12676ef52b82ec9115fb92 100644
--- a/packages/component-invite/src/tests/postInvite.test.js
+++ b/packages/component-invite/src/tests/postInvite.test.js
@@ -4,6 +4,7 @@ process.env.SUPPRESS_NO_CONFIG_WARNING = true
 const httpMocks = require('node-mocks-http')
 const random = require('lodash/random')
 const fixtures = require('./fixtures/fixtures')
+
 const UserMock = require('./mocks/User')
 const Chance = require('chance')
 const TeamMock = require('./mocks/Team')
@@ -16,7 +17,7 @@ const chance = new Chance()
 const globalRoles = ['editorInChief', 'author', 'admin']
 const manuscriptRoles = ['handlingEditor', 'reviewer']
 
-const buildModels = (collection, findUser, emailUser) => {
+const buildModels = (collection, findUser, emailUser, team) => {
   const models = {
     User: {},
     Collection: {
@@ -29,12 +30,18 @@ const buildModels = (collection, findUser, emailUser) => {
     },
     Team: {},
   }
-  UserMock.find = jest.fn(
-    () =>
-      findUser instanceof Error
-        ? Promise.reject(findUser)
-        : Promise.resolve(findUser),
-  )
+  UserMock.find = jest.fn(user => {
+    const foundUser = Object.values(fixtures.users).find(
+      fixUser => fixUser.id === user.id,
+    )
+
+    if (foundUser === undefined) {
+      return Promise.reject(findUser)
+    }
+
+    return Promise.resolve(foundUser)
+  })
+
   UserMock.findByEmail = jest.fn(
     () =>
       emailUser instanceof Error
@@ -42,6 +49,12 @@ const buildModels = (collection, findUser, emailUser) => {
         : Promise.resolve(emailUser),
   )
 
+  TeamMock.find = jest.fn(
+    () =>
+      team instanceof Error ? Promise.reject(team) : Promise.resolve(team),
+  )
+  TeamMock.all = jest.fn(() => Object.values(fixtures.teams))
+
   models.User = UserMock
   models.Team = TeamMock
   return models
@@ -63,6 +76,7 @@ notFoundError.status = 404
 
 const { admin, editorInChief, handlingEditor, author } = fixtures.users
 const { standardCollection } = fixtures.collections
+const { heTeam } = fixtures.teams
 const postInvitePath = '../routes/postInvite'
 describe('Post invite route handler', () => {
   it('should return success when the admin invites a global role', async () => {
@@ -76,7 +90,6 @@ describe('Post invite route handler', () => {
 
     expect(res.statusCode).toBe(200)
     const data = JSON.parse(res._getData())
-    expect(data.roles[0]).toEqual(body.role)
     expect(data.firstName).toEqual(body.firstName)
     expect(data.email).toEqual(body.email)
     expect(data.admin).toEqual(body.admin)
@@ -108,7 +121,9 @@ describe('Post invite route handler', () => {
     await require(postInvitePath)(models)(req, res)
     expect(res.statusCode).toBe(403)
     const data = JSON.parse(res._getData())
-    expect(data.error).toEqual(`admin cannot invite a ${body.role}`)
+    expect(data.error).toEqual(
+      `admin tried to invite an invalid role: ${body.role}`,
+    )
   })
   it('should return an error params are missing', async () => {
     delete body.email
@@ -137,9 +152,7 @@ describe('Post invite route handler', () => {
     await require(postInvitePath)(models)(req, res)
     expect(res.statusCode).toBe(403)
     const data = JSON.parse(res._getData())
-    expect(data.error).toEqual(
-      `${req.user.roles[0]} cannot invite a ${body.role}`,
-    )
+    expect(data.error).toEqual(`Role ${body.role} cannot be set on collections`)
   })
   it('should return an error when an editorInChief invites a handlingEditor without a collection', async () => {
     body.role = 'handlingEditor'
@@ -155,7 +168,7 @@ describe('Post invite route handler', () => {
     expect(res.statusCode).toBe(403)
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual(
-      `${req.user.roles} cannot invite a ${body.role} without a collection`,
+      `${req.user.username} cannot invite a ${body.role} without a collection`,
     )
   })
   it('should return an error when an handlingEditor invites a reviewer without a collection', async () => {
@@ -172,7 +185,7 @@ describe('Post invite route handler', () => {
     expect(res.statusCode).toBe(403)
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual(
-      `${req.user.roles} cannot invite a ${body.role} without a collection`,
+      `${req.user.username} cannot invite a ${body.role} without a collection`,
     )
   })
   it('should return an error when inviting an existing user', async () => {
@@ -201,12 +214,11 @@ describe('Post invite route handler', () => {
     req.user = editorInChief
     req.params.collectionId = '123'
     const res = httpMocks.createResponse()
-    const models = buildModels(standardCollection, editorInChief, author)
+    const models = buildModels(standardCollection, author, author)
     await require(postInvitePath)(models)(req, res)
 
     expect(res.statusCode).toBe(200)
     const data = JSON.parse(res._getData())
-    expect(data.roles).toContain(body.role)
     expect(data.email).toEqual(body.email)
     expect(data.assignations[0].collectionId).toEqual(req.params.collectionId)
   })
@@ -218,6 +230,7 @@ describe('Post invite route handler', () => {
     const req = httpMocks.createRequest({
       body,
     })
+    handlingEditor.teams = [heTeam.id]
     req.user = handlingEditor
     req.params.collectionId = '123'
     const res = httpMocks.createResponse()
@@ -226,7 +239,6 @@ describe('Post invite route handler', () => {
 
     expect(res.statusCode).toBe(200)
     const data = JSON.parse(res._getData())
-    expect(data.roles).toContain(body.role)
     expect(data.email).toEqual(body.email)
     expect(data.assignations[0].collectionId).toEqual(req.params.collectionId)
   })
diff --git a/packages/xpub-faraday/config/mailer.js b/packages/xpub-faraday/config/mailer.js
index b62cdc759efa43df07e795f8f6899b8e725902d9..61822e96e26af7b59b961d290431d1e67c9bc713 100644
--- a/packages/xpub-faraday/config/mailer.js
+++ b/packages/xpub-faraday/config/mailer.js
@@ -4,7 +4,7 @@ module.exports = {
   from: process.env.EMAIL_SENDER,
   transport: {
     SES: new AWS.SES({
-      accessKeyId: process.env.AWS_SES_ACCESS_KEYs,
+      accessKeyId: process.env.AWS_SES_ACCESS_KEY,
       secretAccessKey: process.env.AWS_SES_SECRET_KEY,
       region: process.env.AWS_SES_REGION,
     }),
diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js
index 49323a02f1db61c4055a8908af6cd5496b8f8df1..7a30fb1cf1a0d6d51e9f75360ba6a538fab437dc 100644
--- a/packages/xpub-faraday/config/validations.js
+++ b/packages/xpub-faraday/config/validations.js
@@ -87,13 +87,14 @@ module.exports = {
   ],
   user: {
     name: Joi.string(),
-    roles: Joi.array(),
     isConfirmed: Joi.boolean(),
     firstName: Joi.string().allow(''),
     lastName: Joi.string().allow(''),
     affiliation: Joi.string().allow(''),
     title: Joi.string().allow(''),
     assignations: Joi.array(),
+    teams: Joi.array(),
+    editorInChief: Joi.boolean(),
   },
   team: {
     group: Joi.string(),