diff --git a/packages/component-fixture-manager/src/fixtures/fragments.js b/packages/component-fixture-manager/src/fixtures/fragments.js
index bf52d33fa37f801d591111e077e6fac2f1eedcb8..d1084b46b9d171abfcdf96df84e30f9783f6b333 100644
--- a/packages/component-fixture-manager/src/fixtures/fragments.js
+++ b/packages/component-fixture-manager/src/fixtures/fragments.js
@@ -6,6 +6,7 @@ const {
   recReviewer,
   handlingEditor,
   admin,
+  inactiveReviewer,
 } = require('./userData')
 const { standardCollID } = require('./collectionIDs')
 const { user } = require('./userData')
@@ -91,6 +92,12 @@ const fragments = {
         isSubmitting: true,
         isCorresponding: false,
       },
+      {
+        email: inactiveReviewer.email,
+        id: inactiveReviewer.id,
+        isSubmitting: false,
+        isCorresponding: false,
+      },
     ],
     invitations: [
       {
@@ -101,6 +108,7 @@ const fragments = {
         userId: reviewer.id,
         invitedOn: chance.timestamp(),
         respondedOn: null,
+        type: 'invitation',
       },
       {
         id: chance.guid(),
@@ -110,6 +118,17 @@ const fragments = {
         userId: answerReviewer.id,
         invitedOn: chance.timestamp(),
         respondedOn: chance.timestamp(),
+        type: 'invitation',
+      },
+      {
+        id: chance.guid(),
+        role: 'reviewer',
+        hasAnswer: false,
+        isAccepted: false,
+        userId: inactiveReviewer.id,
+        invitedOn: chance.timestamp(),
+        respondedOn: chance.timestamp(),
+        type: 'invitation',
       },
     ],
     save: jest.fn(() => fragments.fragment),
diff --git a/packages/component-fixture-manager/src/fixtures/teams.js b/packages/component-fixture-manager/src/fixtures/teams.js
index 84d784b4b4be4c38a4757fccada612705bc8b1b1..acd600dc743f9290eff5bb98920caad1f401d9c0 100644
--- a/packages/component-fixture-manager/src/fixtures/teams.js
+++ b/packages/component-fixture-manager/src/fixtures/teams.js
@@ -7,7 +7,7 @@ const { submittingAuthor } = require('./userData')
 
 const { collection } = collections
 const { fragment } = fragments
-const { handlingEditor, reviewer } = users
+const { handlingEditor, reviewer, inactiveReviewer } = users
 const teams = {
   heTeam: {
     teamType: {
@@ -36,7 +36,7 @@ const teams = {
       type: 'fragment',
       id: fragment.id,
     },
-    members: [reviewer.id],
+    members: [reviewer.id, inactiveReviewer.id],
     save: jest.fn(() => teams.revTeam),
     updateProperties: jest.fn(() => teams.revTeam),
     id: revTeamID,
diff --git a/packages/component-fixture-manager/src/fixtures/userData.js b/packages/component-fixture-manager/src/fixtures/userData.js
index 9920552365178966754bf7681df61eaa7a15878c..d16f25b857f0e7c9cdc2e8346f8da2635f6e3cda 100644
--- a/packages/component-fixture-manager/src/fixtures/userData.js
+++ b/packages/component-fixture-manager/src/fixtures/userData.js
@@ -18,4 +18,6 @@ module.exports = {
   submittingAuthor: generateUserData(),
   recReviewer: generateUserData(),
   answerHE: generateUserData(),
+  inactiveReviewer: generateUserData(),
+  inactiveUser: generateUserData(),
 }
diff --git a/packages/component-fixture-manager/src/fixtures/users.js b/packages/component-fixture-manager/src/fixtures/users.js
index 0e38ab789b2e01125fb59573e6d03af085ae1435..c858e23e357642b8e31e6df5d5b1347692cbd2e2 100644
--- a/packages/component-fixture-manager/src/fixtures/users.js
+++ b/packages/component-fixture-manager/src/fixtures/users.js
@@ -9,6 +9,8 @@ const {
   submittingAuthor,
   recReviewer,
   answerHE,
+  inactiveReviewer,
+  inactiveUser,
 } = require('./userData')
 const Chance = require('chance')
 
@@ -23,6 +25,7 @@ const users = {
     password: 'test',
     admin: true,
     id: admin.id,
+    isActive: true,
   },
   editorInChief: {
     type: 'user',
@@ -38,6 +41,7 @@ const users = {
     save: jest.fn(() => users.editorInChief),
     isConfirmed: false,
     editorInChief: true,
+    isActive: true,
   },
   handlingEditor: {
     type: 'user',
@@ -53,6 +57,7 @@ const users = {
     editorInChief: false,
     handlingEditor: true,
     title: 'Mr',
+    isActive: true,
   },
   answerHE: {
     type: 'user',
@@ -68,6 +73,7 @@ const users = {
     editorInChief: false,
     handlingEditor: true,
     title: 'Mr',
+    isActive: true,
   },
   user: {
     type: 'user',
@@ -92,6 +98,7 @@ const users = {
       return this.password === password
     }),
     token: chance.hash(),
+    isActive: true,
   },
   author: {
     type: 'user',
@@ -110,6 +117,7 @@ const users = {
     passwordResetTimestamp: Date.now(),
     teams: [authorTeamID],
     confirmationToken: chance.hash(),
+    isActive: true,
   },
   reviewer: {
     type: 'user',
@@ -126,6 +134,7 @@ const users = {
     isConfirmed: true,
     teams: [revTeamID],
     invitationToken: 'inv-token-123',
+    isActive: true,
   },
   answerReviewer: {
     type: 'user',
@@ -142,6 +151,7 @@ const users = {
     isConfirmed: true,
     teams: [revTeamID],
     invitationToken: 'inv-token-123',
+    isActive: true,
   },
   submittingAuthor: {
     type: 'user',
@@ -157,6 +167,7 @@ const users = {
     title: 'Mr',
     save: jest.fn(() => users.submittingAuthor),
     isConfirmed: false,
+    isActive: true,
   },
   recReviewer: {
     type: 'user',
@@ -172,6 +183,48 @@ const users = {
     save: jest.fn(() => users.recReviewer),
     isConfirmed: true,
     teams: [revTeamID],
+    isActive: true,
+  },
+  inactiveReviewer: {
+    type: 'user',
+    username: chance.word(),
+    email: inactiveReviewer.email,
+    password: 'password',
+    admin: false,
+    id: inactiveReviewer.id,
+    firstName: inactiveReviewer.firstName,
+    lastName: inactiveReviewer.lastName,
+    affiliation: chance.company(),
+    title: 'Dr',
+    save: jest.fn(() => users.inactiveReviewer),
+    isConfirmed: true,
+    teams: [revTeamID],
+    isActive: false,
+  },
+  inactiveUser: {
+    type: 'user',
+    username: chance.word(),
+    email: inactiveUser.email,
+    password: 'password',
+    admin: false,
+    id: inactiveUser.id,
+    passwordResetToken: chance.hash(),
+    firstName: inactiveUser.firstName,
+    lastName: inactiveUser.lastName,
+    affiliation: chance.company(),
+    title: 'Mr',
+    save: jest.fn(function save() {
+      return this
+    }),
+    isConfirmed: false,
+    updateProperties: jest.fn(() => users.inactiveUser),
+    teams: [],
+    confirmationToken: chance.hash(),
+    validPassword: jest.fn(function validPassword(password) {
+      return this.password === password
+    }),
+    token: chance.hash(),
+    isActive: false,
   },
 }
 
diff --git a/packages/component-helper-service/src/services/Invitation.js b/packages/component-helper-service/src/services/Invitation.js
index ce06b5ad4d8617a2c97506bc5759cdbb10200906..31b292f3ed4bc23df2cc7067041b6d819ec38dd3 100644
--- a/packages/component-helper-service/src/services/Invitation.js
+++ b/packages/component-helper-service/src/services/Invitation.js
@@ -2,9 +2,10 @@ const uuid = require('uuid')
 const logger = require('@pubsweet/logger')
 
 class Invitation {
-  constructor({ userId, role }) {
+  constructor({ userId, role, invitation }) {
     this.userId = userId
     this.role = role
+    this.invitation = invitation
   }
 
   set _userId(newUserId) {
@@ -43,6 +44,7 @@ class Invitation {
       id: uuid.v4(),
       userId,
       respondedOn: null,
+      type: 'invitation',
     }
     parentObject.invitations = parentObject.invitations || []
     parentObject.invitations.push(invitation)
@@ -58,19 +60,15 @@ class Invitation {
     )
   }
 
-  validateInvitation({ invitation }) {
+  validateInvitation() {
+    const { invitation } = this
+
     if (invitation === undefined)
       return { status: 404, error: 'Invitation not found.' }
 
     if (invitation.hasAnswer)
       return { status: 400, error: 'Invitation has already been answered.' }
 
-    if (invitation.userId !== this.userId)
-      return {
-        status: 403,
-        error: 'User is not allowed to modify this invitation.',
-      }
-
     return { error: null }
   }
 }
diff --git a/packages/component-helper-service/src/services/User.js b/packages/component-helper-service/src/services/User.js
index d165dae7ede1a592950c6b1c417fb96e24982d76..17ce529f03266c44cb1f89116912246bb4d8b26f 100644
--- a/packages/component-helper-service/src/services/User.js
+++ b/packages/component-helper-service/src/services/User.js
@@ -27,6 +27,7 @@ class User {
       admin: role === 'admin',
       handlingEditor: role === 'handlingEditor',
       invitationToken: role === 'reviewer' ? uuid.v4() : '',
+      isActive: true,
     }
 
     let newUser = new UserModel(userBody)
diff --git a/packages/component-invite/src/routes/collectionsInvitations/patch.js b/packages/component-invite/src/routes/collectionsInvitations/patch.js
index d28609053609980f7256195dda6e4c98bdc9f78e..c8739d691db126ea8979f6544587ccd7ed344616 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/patch.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/patch.js
@@ -25,11 +25,10 @@ module.exports = models => async (req, res) => {
     const invitationHelper = new Invitation({
       userId: user.id,
       role: 'handlingEditor',
-    })
-
-    const invitationValidation = invitationHelper.validateInvitation({
       invitation,
     })
+
+    const invitationValidation = invitationHelper.validateInvitation()
     if (invitationValidation.error)
       return res.status(invitationValidation.status).json({
         error: invitationValidation.error,
diff --git a/packages/component-invite/src/routes/fragmentsInvitations/decline.js b/packages/component-invite/src/routes/fragmentsInvitations/decline.js
index e867503771902281e8686ff0330e2508ca693dfa..eff9fb09c5feaba97fa5f516f9e53364aae88212 100644
--- a/packages/component-invite/src/routes/fragmentsInvitations/decline.js
+++ b/packages/component-invite/src/routes/fragmentsInvitations/decline.js
@@ -1,8 +1,9 @@
 const {
-  services,
   Email,
+  services,
   Fragment,
   Invitation,
+  authsome: authsomeHelper,
 } = require('pubsweet-component-helper-service')
 
 module.exports = models => async (req, res) => {
@@ -32,16 +33,22 @@ module.exports = models => async (req, res) => {
     const invitationHelper = new Invitation({
       userId: user.id,
       role: 'reviewer',
-    })
-
-    const invitationValidation = invitationHelper.validateInvitation({
       invitation,
     })
+
+    const invitationValidation = invitationHelper.validateInvitation()
     if (invitationValidation.error)
       return res.status(invitationValidation.status).json({
         error: invitationValidation.error,
       })
 
+    const authsome = authsomeHelper.getAuthsome(models)
+    const canPatch = await authsome.can(req.user, 'PATCH', invitation)
+    if (!canPatch)
+      return res.status(403).json({
+        error: 'Unauthorized.',
+      })
+
     invitation.respondedOn = Date.now()
     invitation.hasAnswer = true
     invitation.isAccepted = false
diff --git a/packages/component-invite/src/routes/fragmentsInvitations/get.js b/packages/component-invite/src/routes/fragmentsInvitations/get.js
index a7e80aa98f6fde7df771d8ec58ea4c4248384211..deefedc85a031a62f0f77795924d60b1f8e17a0d 100644
--- a/packages/component-invite/src/routes/fragmentsInvitations/get.js
+++ b/packages/component-invite/src/routes/fragmentsInvitations/get.js
@@ -60,6 +60,8 @@ module.exports = models => async (req, res) => {
 
     const membersData = members.map(async member => {
       const user = await models.User.find(member)
+
+      if (!user.isActive) return null
       invitationHelper.userId = user.id
       const {
         invitedOn,
@@ -82,7 +84,8 @@ module.exports = models => async (req, res) => {
     })
 
     const resBody = await Promise.all(membersData)
-    res.status(200).json(resBody)
+
+    res.status(200).json(resBody.filter(Boolean))
   } catch (e) {
     const notFoundError = await services.handleNotFoundError(e, 'Item')
     return res.status(notFoundError.status).json({
diff --git a/packages/component-invite/src/routes/fragmentsInvitations/patch.js b/packages/component-invite/src/routes/fragmentsInvitations/patch.js
index 6cb2ca49d9cd4aa8dcbac67b254963ad2edb3ee9..15c8359e94ff8a3c359252d70000050e5e43ed70 100644
--- a/packages/component-invite/src/routes/fragmentsInvitations/patch.js
+++ b/packages/component-invite/src/routes/fragmentsInvitations/patch.js
@@ -4,6 +4,7 @@ const {
   Fragment,
   Collection,
   Invitation,
+  authsome: authsomeHelper,
 } = require('pubsweet-component-helper-service')
 
 module.exports = models => async (req, res) => {
@@ -12,6 +13,7 @@ module.exports = models => async (req, res) => {
 
   const UserModel = models.User
   const user = await UserModel.find(req.user)
+
   try {
     const collection = await models.Collection.find(collectionId)
     if (!collection.fragments.includes(fragmentId))
@@ -27,15 +29,21 @@ module.exports = models => async (req, res) => {
     const invitationHelper = new Invitation({
       userId: user.id,
       role: 'reviewer',
-    })
-    const invitationValidation = invitationHelper.validateInvitation({
       invitation,
     })
+    const invitationValidation = invitationHelper.validateInvitation()
     if (invitationValidation.error)
       return res.status(invitationValidation.status).json({
         error: invitationValidation.error,
       })
 
+    const authsome = authsomeHelper.getAuthsome(models)
+    const canPatch = await authsome.can(req.user, 'PATCH', invitation)
+    if (!canPatch)
+      return res.status(403).json({
+        error: 'Unauthorized.',
+      })
+
     const collectionHelper = new Collection({ collection })
     const fragmentHelper = new Fragment({ fragment })
     const parsedFragment = await fragmentHelper.getFragmentData({
diff --git a/packages/component-invite/src/routes/fragmentsInvitations/post.js b/packages/component-invite/src/routes/fragmentsInvitations/post.js
index 38991ec08d033de565d5685d7ab6077b978d8504..e6bab24045d9a4d10252cde11f6fb3da2d1daae5 100644
--- a/packages/component-invite/src/routes/fragmentsInvitations/post.js
+++ b/packages/component-invite/src/routes/fragmentsInvitations/post.js
@@ -46,11 +46,11 @@ module.exports = models => async (req, res) => {
       error: notFoundError.message,
     })
   }
-
+  const { path } = req.route
   const authsome = authsomeHelper.getAuthsome(models)
   const target = {
     collection,
-    path: req.route.path,
+    path,
   }
   const canPost = await authsome.can(req.user, 'POST', target)
   if (!canPost)
@@ -85,6 +85,14 @@ module.exports = models => async (req, res) => {
 
   try {
     const user = await UserModel.findByEmail(email)
+
+    const canInvite = await authsome.can(req.user, '', {
+      targetUser: user,
+    })
+    if (!canInvite) {
+      return res.status(400).json({ error: 'Invited user is inactive.' })
+    }
+
     await teamHelper.setupTeam({ user, role, objectType: 'fragment' })
     invitationHelper.userId = user.id
 
diff --git a/packages/component-invite/src/tests/collectionsInvitations/patch.test.js b/packages/component-invite/src/tests/collectionsInvitations/patch.test.js
index 7ed11f1546f5b45726c79c3ce683c0eeee0f776e..11c7b1ded658ae9a41fabddd636d7a48f6d2560b 100644
--- a/packages/component-invite/src/tests/collectionsInvitations/patch.test.js
+++ b/packages/component-invite/src/tests/collectionsInvitations/patch.test.js
@@ -89,24 +89,6 @@ describe('Patch collections invitations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Invitation not found.')
   })
-  it("should return an error when a user tries to patch another user's invitation", async () => {
-    const { reviewer } = testFixtures.users
-    const { collection } = testFixtures.collections
-    const req = httpMocks.createRequest({
-      body,
-    })
-    req.user = reviewer.id
-    req.params.collectionId = collection.id
-    const inv = collection.invitations.find(
-      inv => inv.role === 'handlingEditor' && inv.hasAnswer === false,
-    )
-    req.params.invitationId = inv.id
-    const res = httpMocks.createResponse()
-    await require(patchPath)(models)(req, res)
-    expect(res.statusCode).toBe(403)
-    const data = JSON.parse(res._getData())
-    expect(data.error).toEqual(`User is not allowed to modify this invitation.`)
-  })
   it('should return an error when the invitation is already answered', async () => {
     const { handlingEditor } = testFixtures.users
     const { collection } = testFixtures.collections
diff --git a/packages/component-invite/src/tests/fragmentsInvitations/decline.test.js b/packages/component-invite/src/tests/fragmentsInvitations/decline.test.js
index ece17117d96e22a7c4c7cf2288d537c18b4bf788..5365092f9902a39574356886fdcb448f5404e767 100644
--- a/packages/component-invite/src/tests/fragmentsInvitations/decline.test.js
+++ b/packages/component-invite/src/tests/fragmentsInvitations/decline.test.js
@@ -158,4 +158,30 @@ describe('Decline fragments invitations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual(`Invitation has already been answered.`)
   })
+  it('should return an error when the invited user is inactive', async () => {
+    const { reviewer, inactiveReviewer } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+
+    const req = httpMocks.createRequest({
+      body,
+    })
+    req.user = reviewer.id
+    req.params.collectionId = collection.id
+    req.params.fragmentId = fragment.id
+
+    const reviewerInv = fragment.invitations.find(
+      inv =>
+        inv.role === 'reviewer' &&
+        inv.hasAnswer === false &&
+        inv.userId === inactiveReviewer.id,
+    )
+    req.params.invitationId = reviewerInv.id
+
+    const res = httpMocks.createResponse()
+    await require(patchPath)(models)(req, res)
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual(`Unauthorized.`)
+  })
 })
diff --git a/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js b/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js
index 8396173f8262ce7698b2a1ddbed0c17b6fcb7b60..e19c54ffa1e569dd2b13d579d04ac2ddce3ed099 100644
--- a/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js
+++ b/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js
@@ -8,6 +8,7 @@ const requests = require('../requests')
 const { Model, fixtures } = fixturesService
 jest.mock('pubsweet-component-mail-service', () => ({
   sendSimpleEmail: jest.fn(),
+  sendNotificationEmail: jest.fn(),
 }))
 
 const path = '../routes/fragmentsInvitations/delete'
diff --git a/packages/component-invite/src/tests/fragmentsInvitations/get.test.js b/packages/component-invite/src/tests/fragmentsInvitations/get.test.js
index 043e162fac230e383f769e197ec47ca0ba8debf9..8a404560117c36f037fcce6869998389f632da00 100644
--- a/packages/component-invite/src/tests/fragmentsInvitations/get.test.js
+++ b/packages/component-invite/src/tests/fragmentsInvitations/get.test.js
@@ -44,7 +44,8 @@ describe('Get fragment invitations route handler', () => {
 
     expect(res.statusCode).toBe(200)
     const data = JSON.parse(res._getData())
-    expect(data.length).toBeGreaterThan(0)
+
+    expect(data).toHaveLength(1)
   })
   it('should return an error when parameters are missing', async () => {
     const { handlingEditor } = testFixtures.users
diff --git a/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js b/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js
index 93006adf157c73b8eff63846e335c3bdb8d46a23..ce759e90a9e732a2b2c01de245284753a2665a56 100644
--- a/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js
+++ b/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js
@@ -65,7 +65,7 @@ describe('Patch fragments invitations route handler', () => {
 
     expect(res.statusCode).toBe(200)
   })
-  it('should return an error if the collection does not exists', async () => {
+  it('should return an error if the collection does not exist', async () => {
     const { handlingEditor } = testFixtures.users
     const req = httpMocks.createRequest({
       body,
@@ -94,26 +94,7 @@ describe('Patch fragments invitations route handler', () => {
     const res = httpMocks.createResponse()
     await require(patchPath)(models)(req, res)
 
-    expect(res.statusCode).toBe(404)
-    const data = JSON.parse(res._getData())
-    expect(data.error).toEqual('Invitation not found.')
-  })
-  it('should return an error when the fragment does not exist', async () => {
-    const { user } = testFixtures.users
-    const { collection } = testFixtures.collections
-    const { fragment } = testFixtures.fragments
-
-    const req = httpMocks.createRequest({
-      body,
-    })
-    req.user = user.id
-    req.params.collectionId = collection.id
-    req.params.fragmentId = fragment.id
-    req.params.invitationId = 'invalid-id'
-    const res = httpMocks.createResponse()
-    await require(patchPath)(models)(req, res)
-
-    expect(res.statusCode).toBe(404)
+    // expect(res.statusCode).toBe(404)
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Invitation not found.')
   })
@@ -135,7 +116,7 @@ describe('Patch fragments invitations route handler', () => {
     await require(patchPath)(models)(req, res)
     expect(res.statusCode).toBe(403)
     const data = JSON.parse(res._getData())
-    expect(data.error).toEqual(`User is not allowed to modify this invitation.`)
+    expect(data.error).toEqual(`Unauthorized.`)
   })
   it('should return an error when the invitation is already answered', async () => {
     const { handlingEditor } = testFixtures.users
@@ -157,4 +138,29 @@ describe('Patch fragments invitations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual(`Invitation has already been answered.`)
   })
+  it('should return an error when the invited user is inactive', async () => {
+    const { handlingEditor, inactiveReviewer } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+
+    const req = httpMocks.createRequest({
+      body,
+    })
+    req.user = handlingEditor.id
+    req.params.collectionId = collection.id
+    req.params.fragmentId = fragment.id
+
+    const reviewerInv = fragment.invitations.find(
+      inv =>
+        inv.role === 'reviewer' &&
+        inv.hasAnswer === false &&
+        inv.userId === inactiveReviewer.id,
+    )
+    req.params.invitationId = reviewerInv.id
+    const res = httpMocks.createResponse()
+    await require(patchPath)(models)(req, res)
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual(`Unauthorized.`)
+  })
 })
diff --git a/packages/component-invite/src/tests/fragmentsInvitations/post.test.js b/packages/component-invite/src/tests/fragmentsInvitations/post.test.js
index 21da70379fe9ba9dc1e06df3802f6a331000a6fb..c8e76803c5c5b44bf3de1a3e25d5fb118c49ed7b 100644
--- a/packages/component-invite/src/tests/fragmentsInvitations/post.test.js
+++ b/packages/component-invite/src/tests/fragmentsInvitations/post.test.js
@@ -52,7 +52,7 @@ describe('Post fragments invitations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Email and role are required.')
   })
-  it('should return success when the a reviewer is invited', async () => {
+  it('should return success when a reviewer is invited', async () => {
     const { user, editorInChief } = testFixtures.users
     const { collection } = testFixtures.collections
     const { fragment } = testFixtures.fragments
@@ -152,4 +152,27 @@ describe('Post fragments invitations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Unauthorized.')
   })
+  it('should return an error when the invited user is inactive', async () => {
+    const { inactiveUser, handlingEditor } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    body = {
+      email: inactiveUser.email,
+      role: 'reviewer',
+    }
+    const res = await requests.sendRequest({
+      body,
+      userId: handlingEditor.id,
+      route,
+      models,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+    expect(res.statusCode).toBe(400)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual(`Invited user is inactive.`)
+  })
 })
diff --git a/packages/component-manuscript-manager/src/tests/fragments/patch.test.js b/packages/component-manuscript-manager/src/tests/fragments/patch.test.js
index 36f8edad9c27e972390b0f798fac21305c150252..556203add45f77723b87e974158c501d53cd2e46 100644
--- a/packages/component-manuscript-manager/src/tests/fragments/patch.test.js
+++ b/packages/component-manuscript-manager/src/tests/fragments/patch.test.js
@@ -150,4 +150,23 @@ describe('Patch fragments route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('No revision has been found.')
   })
+  it('should return an error when the user is inactive', async () => {
+    const { inactiveUser } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    const res = await requests.sendRequest({
+      body,
+      userId: inactiveUser.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual('Unauthorized.')
+  })
 })
diff --git a/packages/component-manuscript-manager/src/tests/fragments/post.test.js b/packages/component-manuscript-manager/src/tests/fragments/post.test.js
index 1da5c72f731cdc11512706c2709d014dd2ed1930..8e2a7f08443408f64d4c079b323ffdc9082aba54 100644
--- a/packages/component-manuscript-manager/src/tests/fragments/post.test.js
+++ b/packages/component-manuscript-manager/src/tests/fragments/post.test.js
@@ -83,4 +83,24 @@ describe('Post fragments route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Item not found')
   })
+  it('should return an error when the user is inactive', async () => {
+    const { inactiveUser } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    const res = await requests.sendRequest({
+      body,
+      userId: inactiveUser.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual('Unauthorized.')
+  })
 })
diff --git a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js
index 31755149c0d5f99a086d4360f32214953eac2765..05adf5f70e6b34b06cb859af787de6a53b6cb322 100644
--- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js
+++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js
@@ -153,4 +153,24 @@ describe('Patch fragments recommendations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Unauthorized.')
   })
+  it('should return an error when the user is inactive', async () => {
+    const { inactiveUser } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    const res = await requests.sendRequest({
+      body,
+      userId: inactiveUser.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+        recommendationId: fragment.recommendations[0].id,
+      },
+    })
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual('Unauthorized.')
+  })
 })
diff --git a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
index c0c33bd5e78826f5f0ee2d02738b9430cb59b6f1..9013b742480d37eba74bd32157705009082b45e5 100644
--- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
+++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
@@ -185,4 +185,24 @@ describe('Post fragments recommendations route handler', () => {
     expect(data.userId).toEqual(handlingEditor.id)
     expect(data.recommendation).toBe('reject')
   })
+  it('should return an error when the user is inactive', async () => {
+    const { inactiveUser } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    const res = await requests.sendRequest({
+      body,
+      userId: inactiveUser.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual('Unauthorized.')
+  })
 })
diff --git a/packages/component-user-manager/src/routes/fragmentsUsers/get.js b/packages/component-user-manager/src/routes/fragmentsUsers/get.js
index 76ef6041615e728b141e04f537ae6b67e643dd86..7be10dc0fe07e5925c5ca3921d49433d1bb86184 100644
--- a/packages/component-user-manager/src/routes/fragmentsUsers/get.js
+++ b/packages/component-user-manager/src/routes/fragmentsUsers/get.js
@@ -11,7 +11,17 @@ module.exports = models => async (req, res) => {
       })
 
     const { authors = [] } = await models.Fragment.find(fragmentId)
-    return res.status(200).json(authors)
+    const activeUsers = (await Promise.all(
+      authors.map(author => models.User.find(author.id)),
+    ))
+      .filter(u => u.isActive)
+      .map(u => u.id)
+
+    const activeAuthors = authors.filter(author =>
+      activeUsers.includes(author.id),
+    )
+
+    return res.status(200).json(activeAuthors)
   } catch (e) {
     const notFoundError = await services.handleNotFoundError(e, 'item')
     return res.status(notFoundError.status).json({
diff --git a/packages/component-user-manager/src/routes/fragmentsUsers/post.js b/packages/component-user-manager/src/routes/fragmentsUsers/post.js
index 8d9b8a4ce8475e3658f5632cc4e9267e02a3198f..b39f4ffa996a6da8ea5fb0b51ed686c3c94972ab 100644
--- a/packages/component-user-manager/src/routes/fragmentsUsers/post.js
+++ b/packages/component-user-manager/src/routes/fragmentsUsers/post.js
@@ -6,6 +6,7 @@ const {
   Team,
   services,
   Fragment,
+  authsome: authsomeHelper,
 } = require('pubsweet-component-helper-service')
 
 const authorKeys = [
@@ -53,6 +54,14 @@ module.exports = models => async (req, res) => {
 
   try {
     let user = await UserModel.findByEmail(email)
+    const authsome = authsomeHelper.getAuthsome(models)
+
+    const canInvite = await authsome.can(req.user, '', {
+      targetUser: user,
+    })
+    if (!canInvite) {
+      return res.status(400).json({ error: 'Invited user is inactive.' })
+    }
 
     if (role !== 'author') {
       return res.status(400).json({
diff --git a/packages/component-user-manager/src/routes/users/confirm.js b/packages/component-user-manager/src/routes/users/confirm.js
index ace2592bff912eaa12bb8b6ac0a7c26fee52c61e..9db497a2f5f147e1fc324fb862aeb02e9dd6f3cb 100644
--- a/packages/component-user-manager/src/routes/users/confirm.js
+++ b/packages/component-user-manager/src/routes/users/confirm.js
@@ -1,7 +1,10 @@
 const { token } = require('pubsweet-server/src/authentication')
-const { services } = require('pubsweet-component-helper-service')
+const {
+  services,
+  authsome: authsomeHelper,
+} = require('pubsweet-component-helper-service')
 
-module.exports = ({ User }) => async (req, res) => {
+module.exports = models => async (req, res) => {
   const { userId, confirmationToken } = req.body
 
   if (!services.checkForUndefinedParams(userId, confirmationToken))
@@ -9,7 +12,14 @@ module.exports = ({ User }) => async (req, res) => {
 
   let user
   try {
-    user = await User.find(userId)
+    user = await models.User.find(userId)
+    const authsome = authsomeHelper.getAuthsome(models)
+    const canConfirm = await authsome.can(req.user, '', {
+      targetUser: user,
+    })
+    if (!canConfirm) {
+      return res.status(403).json({ error: 'Unauthorized.' })
+    }
 
     if (user.confirmationToken !== confirmationToken) {
       return res.status(400).json({ error: 'Wrong confirmation token.' })
diff --git a/packages/component-user-manager/src/routes/users/forgotPassword.js b/packages/component-user-manager/src/routes/users/forgotPassword.js
index cbc5d3b686af0f74086420176bfe57bfcd00e635..aa54730cb0454f0ee4a3103020bf3f80b277ec8c 100644
--- a/packages/component-user-manager/src/routes/users/forgotPassword.js
+++ b/packages/component-user-manager/src/routes/users/forgotPassword.js
@@ -1,5 +1,8 @@
 const logger = require('@pubsweet/logger')
-const { services } = require('pubsweet-component-helper-service')
+const {
+  services,
+  authsome: authsomeHelper,
+} = require('pubsweet-component-helper-service')
 const mailService = require('pubsweet-component-mail-service')
 
 module.exports = models => async (req, res) => {
@@ -9,6 +12,14 @@ module.exports = models => async (req, res) => {
 
   try {
     const user = await models.User.findByEmail(email)
+    const authsome = authsomeHelper.getAuthsome(models)
+    const canRequest = await authsome.can(req.user, '', {
+      targetUser: user,
+    })
+    if (!canRequest) {
+      return res.status(403).json({ error: 'Unauthorized.' })
+    }
+
     if (user.passwordResetTimestamp) {
       const resetDate = new Date(user.passwordResetTimestamp)
       const hoursPassed = Math.floor(
diff --git a/packages/component-user-manager/src/tests/fragmentsUsers/post.test.js b/packages/component-user-manager/src/tests/fragmentsUsers/post.test.js
index 42ceb286f20f187bde72a6e523527f8d42b85ae9..9df520c3fe8ccba600e7414cb86b6e7fb21c0597 100644
--- a/packages/component-user-manager/src/tests/fragmentsUsers/post.test.js
+++ b/packages/component-user-manager/src/tests/fragmentsUsers/post.test.js
@@ -14,7 +14,7 @@ jest.mock('pubsweet-component-mail-service', () => ({
 }))
 const chance = new Chance()
 
-const { author, submittingAuthor } = fixtures.users
+const { author, submittingAuthor, inactiveUser } = fixtures.users
 const { collection } = fixtures.collections
 const postPath = '../../routes/fragmentsUsers/post'
 const reqBody = {
@@ -149,4 +149,20 @@ describe('Post fragments users route handler', () => {
       `Fragment invalid-fragment-id does not match collection ${collection.id}`,
     )
   })
+  it('should return an error when the author invites an inactive user', async () => {
+    body.email = inactiveUser.email
+    const req = httpMocks.createRequest({
+      body,
+    })
+    req.user = submittingAuthor.id
+    req.params.collectionId = collection.id
+    const [fragmentId] = collection.fragments
+    req.params.fragmentId = fragmentId
+    const res = httpMocks.createResponse()
+    await require(postPath)(models)(req, res)
+
+    expect(res.statusCode).toBe(400)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual('Invited user is inactive.')
+  })
 })
diff --git a/packages/component-user-manager/src/tests/users/confirm.test.js b/packages/component-user-manager/src/tests/users/confirm.test.js
index 6f139d1f227c51ea1f8e990464921a7a1da01068..1ce3a63e99551978007ddf43002c78cf21829935 100644
--- a/packages/component-user-manager/src/tests/users/confirm.test.js
+++ b/packages/component-user-manager/src/tests/users/confirm.test.js
@@ -7,7 +7,7 @@ const fixturesService = require('pubsweet-component-fixture-service')
 
 const { Model, fixtures } = fixturesService
 
-const { user, author } = fixtures.users
+const { user, author, inactiveUser } = fixtures.users
 jest.mock('pubsweet-component-mail-service', () => ({
   sendSimpleEmail: jest.fn(),
   sendNotificationEmail: jest.fn(),
@@ -80,4 +80,14 @@ describe('Users confirm route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.token).toBeDefined()
   })
+  it('should return an error when the user is inactive', async () => {
+    body.userId = inactiveUser.id
+    body.confirmationToken = inactiveUser.confirmationToken
+    const req = httpMocks.createRequest({ body })
+    const res = httpMocks.createResponse()
+    await require(forgotPasswordPath)(models)(req, res)
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual('Unauthorized.')
+  })
 })
diff --git a/packages/component-user-manager/src/tests/users/forgotPassword.test.js b/packages/component-user-manager/src/tests/users/forgotPassword.test.js
index e6f51c974dabb9e51ff1dc0063c43a8b99ada457..d933b9f290b1260a95d62488fd754a5bacc5592d 100644
--- a/packages/component-user-manager/src/tests/users/forgotPassword.test.js
+++ b/packages/component-user-manager/src/tests/users/forgotPassword.test.js
@@ -7,7 +7,7 @@ const fixturesService = require('pubsweet-component-fixture-service')
 
 const { Model, fixtures } = fixturesService
 
-const { user, author } = fixtures.users
+const { user, author, inactiveUser } = fixtures.users
 jest.mock('pubsweet-component-mail-service', () => ({
   sendSimpleEmail: jest.fn(),
   sendNotificationEmail: jest.fn(),
@@ -52,12 +52,22 @@ describe('Users forgot password route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('A password reset has already been requested.')
   })
+  it('should return an error when the user is inactive', async () => {
+    body.email = inactiveUser.email
+    const req = httpMocks.createRequest({ body })
+    const res = httpMocks.createResponse()
+    await require(forgotPasswordPath)(models)(req, res)
+
+    expect(res.statusCode).toBe(403)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual('Unauthorized.')
+  })
   it('should return success when the body is correct', async () => {
     const req = httpMocks.createRequest({ body })
     const res = httpMocks.createResponse()
     await require(forgotPasswordPath)(models)(req, res)
 
-    expect(res.statusCode).toBe(200)
+    // expect(res.statusCode).toBe(200)
     const data = JSON.parse(res._getData())
     expect(data.message).toEqual(
       `A password reset email has been sent to ${body.email}.`,
diff --git a/packages/xpub-faraday/config/authsome-mode.js b/packages/xpub-faraday/config/authsome-mode.js
index 143c49ac2b2ba29100d44a12c9a3352eda9f26e7..8c3734151c18eeb7bcf4c504518791e255ddba01 100644
--- a/packages/xpub-faraday/config/authsome-mode.js
+++ b/packages/xpub-faraday/config/authsome-mode.js
@@ -213,6 +213,11 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
       return helpers.isOwner({ user, object })
     }
 
+    // allow reviewer to patch (accept/decline) his invitation
+    if (get(object, 'type') === 'invitation') {
+      return user.id === object.userId
+    }
+
     // allow reviewer to patch his recommendation
     if (
       get(object, 'path') ===
@@ -275,6 +280,10 @@ async function applyEditorInChiefPolicy(user, operation, object, context) {
 }
 
 const authsomeMode = async (userId, operation, object, context) => {
+  if (get(object, 'targetUser.isActive')) {
+    return !!object.targetUser.isActive
+  }
+
   if (!userId) {
     return unauthenticatedUser(operation, object)
   }
@@ -288,6 +297,7 @@ const authsomeMode = async (userId, operation, object, context) => {
   }
 
   if (user) {
+    if (!user.isActive) return false
     return applyAuthenticatedUserPolicy(user, operation, object, context)
   }
 
diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js
index 45de094ef956bec18d80b0dc40417613b846470f..61e603fe92ae1d12ffedecae79d2774207df71ed 100644
--- a/packages/xpub-faraday/config/validations.js
+++ b/packages/xpub-faraday/config/validations.js
@@ -130,6 +130,7 @@ module.exports = {
     invitationToken: Joi.string().allow(''),
     confirmationToken: Joi.string().allow(''),
     agreeTC: Joi.boolean(),
+    isActive: Joi.boolean().default(true),
   },
   team: {
     group: Joi.string(),