diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6a9870968e93df0c20c5b054fc6afb5fabe2c78e..88c620dd790fcc45156cb8fbf7f76512055c3bee 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -64,5 +64,5 @@ demo:now:
     url: $NOW_URL
   script:
     - npm i -g --unsafe-perm now
-    - cd ${HOME}
-    - npm run deploy_now
\ No newline at end of file
+    - cd ${HOME}/now
+    - now --public --docker --token $NOW_TOKEN -e AWS_S3_ACCESS_KEY=$AWS_S3_ACCESS_KEY -e AWS_S3_SECRET_KEY=$AWS_S3_SECRET_KEY -e AWS_S3_REGION=$AWS_S3_REGION -e AWS_S3_BUCKET=$AWS_S3_BUCKET -e AWS_SES_SECRET_KEY=$AWS_SES_SECRET_KEY -e AWS_SES_ACCESS_KEY=$AWS_SES_ACCESS_KEY -e AWS_SES_REGION=$AWS_SES_REGION -e EMAIL_SENDER=$EMAIL_SENDER -e secret=$SECRET
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 698c88f458e85c2f87bdb64b4f9722ea6a2c6bfc..6b7916c6b878cd4d86b238fdca907fe1ea0aefbf 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,6 +3,7 @@ FROM xpub/xpub:base
 COPY package.json yarn.lock ./
 COPY lerna.json .babelrc .eslintignore .eslintrc .prettierrc .stylelintignore .stylelintrc ./
 COPY packages packages
+COPY now now
 
 RUN [ "yarn", "config", "set", "workspaces-experimental", "true" ]
 
diff --git a/package.json b/package.json
index d3ba020bbae08ea43170d63411b295dfcbc9a6bd..079e1d213d174a5d15d3b0943eded9c29c5e2881 100644
--- a/package.json
+++ b/package.json
@@ -36,8 +36,7 @@
     "lint:style": "stylelint packages/**/*.scss packages/**/*.css",
     "precommit": "lint-staged",
     "styleguide": "lerna run styleguide",
-    "test": "lerna run test",
-    "deploy_now": "cd now && now --public --docker --token $NOW_TOKEN -e AWS_S3_ACCESS_KEY=$AWS_S3_ACCESS_KEY -e AWS_S3_SECRET_KEY=$AWS_S3_SECRET_KEY -e AWS_S3_REGION=$AWS_S3_REGION -e AWS_S3_BUCKET=$AWS_S3_BUCKET -e AWS_SES_SECRET_KEY=$AWS_SES_SECRET_KEY -e AWS_SES_ACCESS_KEY=$AWS_SES_ACCESS_KEY -e AWS_SES_REGION=$AWS_SES_REGION -e EMAIL_SENDER=$EMAIL_SENDER -e secret=$SECRET"
+    "test": "lerna run test"
   },
   "lint-staged": {
     "*.js": [
diff --git a/packages/component-local-aws/index.js b/packages/component-local-aws/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..140b65ac0183438e989b7e7f552b3498baa32820
--- /dev/null
+++ b/packages/component-local-aws/index.js
@@ -0,0 +1,5 @@
+require('dotenv').config()
+
+module.exports = {
+  backend: () => app => require('./src/FileBackend')(app),
+}
diff --git a/packages/component-local-aws/package.json b/packages/component-local-aws/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..b38c67c0a3e07d5a3d4596db3ad356a20eb1c2ca
--- /dev/null
+++ b/packages/component-local-aws/package.json
@@ -0,0 +1,18 @@
+{
+  "name": "component-local-aws",
+  "version": "1.0.0",
+  "main": "index.js",
+  "license": "MIT",
+  "dependencies": {
+    "aws-sdk": "^2.185.0",
+    "body-parser": "^1.17.2",
+    "multer": "^1.3.0",
+    "multer-s3": "^2.7.0",
+    "node-mocks-http": "^1.6.6",
+    "nodemailer": "^4.4.2"
+  },
+  "peerDependencies": {
+    "@pubsweet/logger": "^0.0.1",
+    "pubsweet-server": "^1.0.1"
+  }
+}
diff --git a/packages/component-local-aws/src/FileBackend.js b/packages/component-local-aws/src/FileBackend.js
new file mode 100644
index 0000000000000000000000000000000000000000..b7866aa58574c21c3773ca443041bda361270cfe
--- /dev/null
+++ b/packages/component-local-aws/src/FileBackend.js
@@ -0,0 +1,45 @@
+const _ = require('lodash')
+const AWS = require('aws-sdk')
+const config = require('config')
+
+const s3Config = _.get(config, 'pubsweet-component-aws-s3')
+
+const FileBackend = app => {
+  const authBearer = app.locals.passport.authenticate('bearer', {
+    session: false,
+  })
+  AWS.config.update({
+    secretAccessKey: s3Config.secretAccessKey,
+    accessKeyId: s3Config.accessKeyId,
+    region: s3Config.region,
+  })
+  const s3 = new AWS.S3()
+  const upload = require('./middeware/upload').setupMulter(s3)
+
+  app.post(
+    '/api/files',
+    authBearer,
+    upload.single('file'),
+    require('./routeHandlers/postFile'),
+  )
+
+  app.get(
+    '/api/files/:fragmentId/:fileId',
+    authBearer,
+    require('./routeHandlers/getSignedUrl')(s3, s3Config),
+  )
+
+  app.get(
+    '/api/files/:fragmentId',
+    authBearer,
+    require('./routeHandlers/zipFiles')(s3, s3Config),
+  )
+
+  app.delete(
+    '/api/files/:fragmentId/:fileId',
+    authBearer,
+    require('./routeHandlers/deleteFile')(s3, s3Config),
+  )
+}
+
+module.exports = FileBackend
diff --git a/packages/component-local-aws/src/FileBackend.test.js b/packages/component-local-aws/src/FileBackend.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..95a026ff5866440953da6c75cee6042589d1abe1
--- /dev/null
+++ b/packages/component-local-aws/src/FileBackend.test.js
@@ -0,0 +1,188 @@
+process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
+process.env.SUPPRESS_NO_CONFIG_WARNING = true
+
+const httpMocks = require('node-mocks-http')
+
+const zipHandler = require('./routeHandlers/zipFiles')
+
+describe('ValidateFile for multer fileFilter', () => {
+  it('should return TRUE when fileType is supplementary', () => {
+    const validateFile = require('./middeware/upload').validateFile(
+      ...buildValidateFileParams('supplementary', 'image/png'),
+    )
+    expect(validateFile).toBe(true)
+  })
+  it('should return TRUE when fileType is manuscripts or coverLetter and the file is either Word Doc or PDF', () => {
+    const randFileType = getRandValueFromArray(['manuscripts', 'coverLetter'])
+    const randMimeType = getRandValueFromArray([
+      'application/pdf',
+      'application/msword',
+      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+    ])
+
+    const validateFile = require('./middeware/upload').validateFile(
+      ...buildValidateFileParams(randFileType, randMimeType),
+    )
+    expect(validateFile).toBe(true)
+  })
+  it('should return FALSE when fileType is manuscripts or coverLetter and the file is neither Word Doc or PDF', () => {
+    const randFileType = getRandValueFromArray(['manuscripts', 'coverLetter'])
+    const randMimeType = getRandValueFromArray([
+      'text/plain',
+      'text/html',
+      'image/jpeg',
+      'image/png',
+    ])
+
+    const validateFile = require('./middeware/upload').validateFile(
+      ...buildValidateFileParams(randFileType, randMimeType),
+    )
+    expect(validateFile).toBe(false)
+  })
+})
+
+describe('Upload file route handler', () => {
+  it('should return success when the file passed validation', async () => {
+    const file = {
+      key: '123abc',
+      originalname: 'file.txt',
+      size: 128,
+    }
+    const req = httpMocks.createRequest({
+      file,
+    })
+    const res = httpMocks.createResponse()
+    await require('./routeHandlers/postFile')(req, res)
+    expect(res.statusCode).toBe(200)
+    const data = JSON.parse(res._getData())
+    expect(data.id).toEqual(file.key)
+    expect(data.name).toEqual(file.originalname)
+    expect(data.size).toEqual(file.size)
+  })
+  it('should return an error when the file failed validation', async () => {
+    const req = httpMocks.createRequest({
+      fileValidationError: 'Only Word documents and PDFs are allowed',
+    })
+    const res = httpMocks.createResponse()
+    await require('./routeHandlers/postFile')(req, res)
+    expect(res.statusCode).toBe(400)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual(req.fileValidationError)
+  })
+})
+
+describe('Zip files endpoint', () => {
+  const testObject = {
+    Key: 'KeyToMyHeart',
+    Body: Buffer.alloc(10),
+    Metadata: {
+      filetype: 'manuscripts',
+      filename: 'test.txt',
+    },
+  }
+  const mockBucket = {
+    RandomKey: {
+      Contents: [testObject, testObject],
+    },
+  }
+
+  const s3 = {}
+  const mocks = {}
+  let mockArchiver = null
+  const s3Config = {
+    bucket: 'TestBucket',
+  }
+  beforeAll(() => {
+    s3.getObject = jest.fn((params, cb) => {
+      cb(null, testObject)
+    })
+
+    s3.listObjects = jest.fn((params, cb) => {
+      cb(null, mockBucket[params.Prefix])
+    })
+    mocks.pipe = jest.fn()
+    mocks.append = jest.fn()
+    mocks.finalize = jest.fn()
+    mocks.attachment = jest.fn()
+
+    mockArchiver = jest.fn(p => ({
+      pipe: mocks.pipe,
+      append: mocks.append,
+      finalize: mocks.finalize,
+    }))
+  })
+  afterEach(() => {
+    s3.getObject.mockClear()
+    s3.listObjects.mockClear()
+    mocks.pipe.mockClear()
+    mocks.append.mockClear()
+    mocks.attachment.mockClear()
+  })
+  it(`no zipping if no files found`, async () => {
+    const zipFiles = zipHandler(s3, s3Config, mockArchiver)
+    const request = httpMocks.createRequest({
+      method: 'GET',
+      params: {
+        fragmentId: 'NotFoundKey',
+      },
+    })
+    const response = httpMocks.createResponse()
+    response.attachment = mocks.attachment
+
+    await zipFiles(request, response)
+
+    expect(s3.listObjects.mock.calls).toHaveLength(1)
+    expect(s3.getObject.mock.calls).toHaveLength(0)
+    expect(mocks.attachment.mock.calls).toHaveLength(0)
+    expect(mocks.append.mock.calls).toHaveLength(0)
+    expect(mocks.pipe.mock.calls).toHaveLength(0)
+
+    const responseData = JSON.parse(response._getData())
+
+    expect(responseData.message).toEqual(
+      `No files found for the requested manuscript.`,
+    )
+    expect(response._getStatusCode()).toEqual(204)
+  })
+  it('zips all the files', async () => {
+    const zipFiles = zipHandler(s3, s3Config, mockArchiver)
+
+    const request = httpMocks.createRequest({
+      method: 'GET',
+      params: {
+        fragmentId: 'RandomKey',
+      },
+    })
+    const response = httpMocks.createResponse()
+    response.attachment = mocks.attachment
+
+    await zipFiles(request, response)
+
+    expect(s3.listObjects.mock.calls).toHaveLength(1)
+    expect(s3.getObject.mock.calls).toHaveLength(2)
+    expect(mocks.attachment.mock.calls).toHaveLength(1)
+    expect(mocks.attachment.mock.calls[0][0]).toEqual('RandomKey-archive.zip')
+    expect(mocks.append.mock.calls).toHaveLength(2)
+    expect(mocks.pipe.mock.calls).toHaveLength(1)
+    expect(response._getStatusCode()).toEqual(200)
+  })
+})
+
+const getRandValueFromArray = arr => arr[Math.floor(Math.random() * arr.length)]
+
+const buildValidateFileParams = (fileType, mimetype) => {
+  const req = {
+    body: {
+      fileType,
+    },
+  }
+  const file = {
+    mimetype,
+  }
+  const cb = (p1, p2) => {
+    if (p2 === true) return true
+    return false
+  }
+
+  return [req, file, cb]
+}
diff --git a/packages/component-local-aws/src/middeware/upload.js b/packages/component-local-aws/src/middeware/upload.js
new file mode 100644
index 0000000000000000000000000000000000000000..f46f4176621cfb62e3cfec3598a3ae0219b588e2
--- /dev/null
+++ b/packages/component-local-aws/src/middeware/upload.js
@@ -0,0 +1,53 @@
+const Joi = require('joi')
+const uuid = require('uuid')
+const config = require('config')
+const multer = require('multer')
+const { get } = require('lodash')
+const multerS3 = require('multer-s3')
+
+const s3Config = get(config, 'pubsweet-component-aws-s3')
+const uploadValidations = require(s3Config.validations)
+
+const setupMulter = s3 => {
+  const upload = multer({
+    storage: multerS3({
+      s3,
+      bucket: s3Config.bucket,
+      contentType: (req, file, cb) => {
+        cb(null, file.mimetype)
+      },
+      metadata: (req, file, cb) => {
+        cb(null, {
+          FileType: get(req, 'body.fileType'),
+          FileName: get(file, 'originalname'),
+        })
+      },
+      key: (req, file, cb) => {
+        const fileKey = `${req.body.fragmentId}/${uuid.v4()}`
+        cb(null, fileKey)
+      },
+    }),
+    fileFilter: (req, file, cb) => validateFile(req, file, cb),
+  })
+
+  return upload
+}
+
+const validateFile = (req, file, cb) => {
+  const { fileType } = req.body
+  const { mimetype } = file
+
+  const valid = Joi.validate({ [fileType]: mimetype }, uploadValidations)
+
+  if (valid.error) {
+    req.fileValidationError = valid.error.message
+    return cb(null, false)
+  }
+
+  return cb(null, true)
+}
+
+module.exports = {
+  setupMulter,
+  validateFile,
+}
diff --git a/packages/component-local-aws/src/routeHandlers/deleteFile.js b/packages/component-local-aws/src/routeHandlers/deleteFile.js
new file mode 100644
index 0000000000000000000000000000000000000000..9aa8974b76a053f0ea4229464c1f8ec9830c8fa3
--- /dev/null
+++ b/packages/component-local-aws/src/routeHandlers/deleteFile.js
@@ -0,0 +1,22 @@
+const { promisify } = require('util')
+const logger = require('@pubsweet/logger')
+
+const deleteFile = (s3, s3Config) => {
+  const asyncDeleteObject = promisify(s3.deleteObject.bind(s3))
+  return async (req, res) => {
+    const params = {
+      Bucket: s3Config.bucket,
+      Key: `${req.params.fragmentId}/${req.params.fileId}`,
+    }
+
+    try {
+      await asyncDeleteObject(params)
+      res.status(204)
+    } catch (err) {
+      logger.error(err.message)
+      res.status(err.statusCode).json({ error: err.message })
+    }
+  }
+}
+
+module.exports = deleteFile
diff --git a/packages/component-local-aws/src/routeHandlers/getSignedUrl.js b/packages/component-local-aws/src/routeHandlers/getSignedUrl.js
new file mode 100644
index 0000000000000000000000000000000000000000..edbad710242df2428920f69405c4313bd9f6c452
--- /dev/null
+++ b/packages/component-local-aws/src/routeHandlers/getSignedUrl.js
@@ -0,0 +1,24 @@
+const { promisify } = require('util')
+const logger = require('@pubsweet/logger')
+
+const getSignedUrl = (s3, s3Config) => {
+  const asyncGetSignedUrl = promisify(s3.getSignedUrl.bind(s3))
+  return async (req, res) => {
+    const params = {
+      Bucket: s3Config.bucket,
+      Key: `${req.params.fragmentId}/${req.params.fileId}`,
+    }
+
+    try {
+      const signedUrl = await asyncGetSignedUrl(params)
+      res.status(200).json({
+        signedUrl,
+      })
+    } catch (err) {
+      logger.error(err.message)
+      res.status(err.statusCode).json({ error: err.message })
+    }
+  }
+}
+
+module.exports = getSignedUrl
diff --git a/packages/component-local-aws/src/routeHandlers/postFile.js b/packages/component-local-aws/src/routeHandlers/postFile.js
new file mode 100644
index 0000000000000000000000000000000000000000..228c78fed2d5914cf1134453255053d7524c63d0
--- /dev/null
+++ b/packages/component-local-aws/src/routeHandlers/postFile.js
@@ -0,0 +1,15 @@
+const logger = require('@pubsweet/logger')
+
+module.exports = async (req, res) => {
+  if (req.fileValidationError !== undefined) {
+    logger.error(req.fileValidationError)
+    return res.status(400).json({ error: req.fileValidationError })
+  }
+  logger.debug(`${req.file.originalname} has been uploaded`)
+
+  return res.status(200).json({
+    id: req.file.key,
+    name: req.file.originalname,
+    size: req.file.size,
+  })
+}
diff --git a/packages/component-local-aws/src/routeHandlers/zipFiles.js b/packages/component-local-aws/src/routeHandlers/zipFiles.js
new file mode 100644
index 0000000000000000000000000000000000000000..272eccbfb8e93b7a96b6c573259c047d613f0a06
--- /dev/null
+++ b/packages/component-local-aws/src/routeHandlers/zipFiles.js
@@ -0,0 +1,55 @@
+const { get } = require('lodash')
+const { promisify } = require('util')
+const nodeArchiver = require('archiver')
+const logger = require('@pubsweet/logger')
+
+const zipFiles = (s3, s3Config, archiver = nodeArchiver) => {
+  const asyncGetObject = promisify(s3.getObject.bind(s3))
+  const asyncListObjects = promisify(s3.listObjects.bind(s3))
+  return async (req, res) => {
+    const { fragmentId } = req.params
+    try {
+      const params = {
+        Bucket: s3Config.bucket,
+        Prefix: `${fragmentId}`,
+      }
+      const s3Items = await asyncListObjects(params)
+
+      if (s3Items) {
+        const s3Files = await Promise.all(
+          s3Items.Contents.map(content =>
+            asyncGetObject({
+              Bucket: s3Config.bucket,
+              Key: content.Key,
+            }),
+          ),
+        )
+
+        if (s3Files) {
+          const archive = archiver('zip')
+          archive.pipe(res)
+          res.attachment(`${fragmentId}-archive.zip`)
+
+          s3Files.forEach(f => {
+            archive.append(f.Body, {
+              name: `${get(f, 'Metadata.filetype') || 'supplementary'}/${get(
+                f,
+                'Metadata.filename',
+              ) || f.ETag}`,
+            })
+          })
+          archive.finalize()
+        }
+      } else {
+        res.status(204).json({
+          message: `No files found for the requested manuscript.`,
+        })
+      }
+    } catch (err) {
+      logger.error(err.message)
+      res.status(err.statusCode).json({ error: err.message })
+    }
+  }
+}
+
+module.exports = zipFiles
diff --git a/packages/components-faraday/src/components/AuthorList/AuthorAdder.js b/packages/components-faraday/src/components/AuthorList/AuthorAdder.js
index eccca432675ccaadea8061465644fc4afe690571..2cb1d3258fbd47afa1004fa0fb6af36b29a46314 100644
--- a/packages/components-faraday/src/components/AuthorList/AuthorAdder.js
+++ b/packages/components-faraday/src/components/AuthorList/AuthorAdder.js
@@ -27,7 +27,7 @@ const AuthorAdder = ({
   isFetching,
 }) => (
   <Root>
-    <Button onClick={setEditMode(true)} primary>
+    <Button data-test="button-add-author" onClick={setEditMode(true)} primary>
       {authors.length === 0 ? '+ Add submitting author' : '+ Add author'}
     </Button>
     {editMode && (
@@ -54,9 +54,15 @@ const AuthorAdder = ({
           <MenuItem label="Country*" name="country" options={countries} />
         </Row>
         <ButtonsContainer>
-          <Button onClick={setEditMode(false)}>Cancel</Button>
+          <Button data-test="button-cancel-author" onClick={setEditMode(false)}>
+            Cancel
+          </Button>
           {!isFetching ? (
-            <Button onClick={handleSubmit} primary>
+            <Button
+              data-test="button-save-author"
+              onClick={handleSubmit}
+              primary
+            >
               Save
             </Button>
           ) : (
diff --git a/packages/components-faraday/src/components/AuthorList/FormItems.js b/packages/components-faraday/src/components/AuthorList/FormItems.js
index 807a34fe4cd3103414ecfb16871e67a9ad9851bc..96040013537ca947984c8151894f1e09fa4848e0 100644
--- a/packages/components-faraday/src/components/AuthorList/FormItems.js
+++ b/packages/components-faraday/src/components/AuthorList/FormItems.js
@@ -19,7 +19,7 @@ export const ValidatedTextField = ({
 }
 
 export const MenuItem = ({ label, name, options }) => (
-  <MenuItemRoot>
+  <MenuItemRoot data-test="country-selector-author">
     <StyledLabel>{label}</StyledLabel>
     <ValidatedField
       component={input => <Menu {...input} options={options} />}
diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
index 7e5dd322fd9ad1d535bcd19ca395381a77d92e5f..af8cd34a48f317f033810fc98d953c6a40cb9404 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
@@ -33,7 +33,6 @@ const DashboardCard = ({
   const manuscriptMeta = `${type} - ${
     journalIssueType ? journalIssueType.label : 'N/A'
   }`
-
   return version ? (
     <Card data-test={customId}>
       <ListView>
@@ -46,7 +45,11 @@ const DashboardCard = ({
             />
           </LeftDetails>
           <RightDetails flex="2">
-            <ZipFiles disabled={!hasFiles} fragmentId={version.id}>
+            <ZipFiles
+              archiveName={`ID-${project.customId}`}
+              disabled={!hasFiles}
+              fragmentId={version.id}
+            >
               <ClickableIcon disabled={!hasFiles}>
                 <Icon>download</Icon>
               </ClickableIcon>
diff --git a/packages/components-faraday/src/components/Dashboard/ZipFiles.js b/packages/components-faraday/src/components/Dashboard/ZipFiles.js
index 8f6e9ece1807e90e2ffa9ed214c47ed49e3c99e2..12f38e9a77e1e8a6c69e8ee3d469b859c494dcd6 100644
--- a/packages/components-faraday/src/components/Dashboard/ZipFiles.js
+++ b/packages/components-faraday/src/components/Dashboard/ZipFiles.js
@@ -45,7 +45,14 @@ const Zip = compose(
   })),
   withState('fetching', 'setFetching', false),
   withHandlers({
-    downloadFiles: ({ fragmentId, token, setFetching, archiveName }) => () => {
+    downloadFiles: ({
+      fragmentId,
+      collectionId,
+      token,
+      setFetching,
+      archiveName,
+    }) => () => {
+      const getUrl = `${window.location.origin}/api/files/${fragmentId}`
       if (cache[fragmentId]) {
         const fileName = archiveName || `${fragmentId}-archive.zip`
 
@@ -71,7 +78,7 @@ const Zip = compose(
             }
           }
         }
-        xhr.open('GET', `${window.location.origin}/api/fileZip/${fragmentId}`)
+        xhr.open('GET', getUrl)
         xhr.responseType = 'blob'
         xhr.setRequestHeader('Authorization', `Bearer ${token}`)
         xhr.send()
diff --git a/packages/components-faraday/src/components/Files/FileSection.js b/packages/components-faraday/src/components/Files/FileSection.js
index 453006fd28b79946f691ea5b8ef8140537731d9d..88459761fc6e566bb217373fd84d176ff2153c0b 100644
--- a/packages/components-faraday/src/components/Files/FileSection.js
+++ b/packages/components-faraday/src/components/Files/FileSection.js
@@ -65,7 +65,10 @@ const FileSection = ({
             disabled={disabledFilepicker()}
             onUpload={addFile}
           >
-            <UploadButton disabled={disabledFilepicker()}>
+            <UploadButton
+              data-test={`button-upload-${listId}`}
+              disabled={disabledFilepicker()}
+            >
               <Icon
                 color={
                   disabledFilepicker()
diff --git a/packages/components-faraday/src/redux/files.js b/packages/components-faraday/src/redux/files.js
index e1ba5b9d3766f3dc1992671a15fa460c9e2d1bba..0013b437ea13f916448b563abcc2133a6c6b665d 100644
--- a/packages/components-faraday/src/redux/files.js
+++ b/packages/components-faraday/src/redux/files.js
@@ -68,7 +68,7 @@ export const getFileError = state => state.files.error
 // thunked actions
 export const uploadFile = (file, type, fragmentId) => dispatch => {
   dispatch(uploadRequest(type))
-  return request('/file', createFileData(file, type, fragmentId)).then(
+  return request('/files', createFileData(file, type, fragmentId)).then(
     r => {
       dispatch(uploadSuccess())
       return r
@@ -82,7 +82,7 @@ export const uploadFile = (file, type, fragmentId) => dispatch => {
 
 export const deleteFile = fileId => dispatch => {
   dispatch(removeRequest())
-  return remove(`/file/${fileId}`)
+  return remove(`/files/${fileId}`)
     .then(r => {
       dispatch(removeSuccess())
       return r
diff --git a/packages/xpub-faraday/config/components.json b/packages/xpub-faraday/config/components.json
index 8c449cd1a00c8a703c2a0a55cced468541dcbb92..7a1555ce9bc5d36ac95e3eca4e33f466e66511e4 100644
--- a/packages/xpub-faraday/config/components.json
+++ b/packages/xpub-faraday/config/components.json
@@ -7,5 +7,6 @@
   "pubsweet-components-faraday",
   "@pubsweet/component-aws-s3",
   "pubsweet-component-invite",
-  "component-aws-download"
+  "component-aws-download",
+  "component-local-aws"
 ]
diff --git a/yarn.lock b/yarn.lock
index e24936ff287cce17c86c68a7597c79d9a3443183..69e6ba522167896f8da8df04186b054e218c2ccb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7210,10 +7210,6 @@ pkginfo@0.3.x:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21"
 
-pkginfo@0.x.x:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff"
-
 platform@1.3.5:
   version "1.3.5"
   resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444"
@@ -7909,18 +7905,7 @@ promise@^7.1.1:
   dependencies:
     asap "~2.0.3"
 
-prompt@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe"
-  dependencies:
-    colors "^1.1.2"
-    pkginfo "0.x.x"
-    read "1.0.x"
-    revalidator "0.1.x"
-    utile "0.3.x"
-    winston "2.1.x"
-
-prompt@flatiron/prompt#1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87:
+prompt@^1.0.0, prompt@flatiron/prompt#1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87:
   version "1.0.0"
   resolved "https://codeload.github.com/flatiron/prompt/tar.gz/1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87"
   dependencies:
@@ -10669,18 +10654,6 @@ winston@0.8.x:
     pkginfo "0.3.x"
     stack-trace "0.0.x"
 
-winston@2.1.x:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e"
-  dependencies:
-    async "~1.0.0"
-    colors "1.0.x"
-    cycle "1.0.x"
-    eyes "0.1.x"
-    isstream "0.1.x"
-    pkginfo "0.3.x"
-    stack-trace "0.0.x"
-
 winston@2.x, winston@^2.2.0, winston@^2.4.0:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.0.tgz#808050b93d52661ed9fb6c26b3f0c826708b0aee"