diff --git a/app/components/app/App.js b/app/components/app/App.js
deleted file mode 100644
index 69f03f2cadbaca8f666852f0bca1e9c272b410b6..0000000000000000000000000000000000000000
--- a/app/components/app/App.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react'
-import { Link, withRouter } from 'react-router-dom'
-
-import { AppBar } from '@pubsweet/ui'
-
-const App = ({ children, history }) => (
-  <div>
-    <AppBar
-      brand="eLife"
-      navLinkComponents={[<Link to="/">Dashboard</Link>]}
-      onLogoutClick={() => {
-        window.localStorage.removeItem('token')
-        history.push('/')
-      }}
-      user={{ username: 'Dummy User', admin: true }}
-    />
-    <div>{children}</div>
-  </div>
-)
-
-export default withRouter(App)
diff --git a/app/components/app/App.md b/app/components/app/App.md
deleted file mode 100644
index 79c032b744b3937ebacc356691b6edcbabead905..0000000000000000000000000000000000000000
--- a/app/components/app/App.md
+++ /dev/null
@@ -1,3 +0,0 @@
-## App Component
-
-The aim of this component is to group things that are shared by apps (like the navbar). This is similar to [xpub app] (https://gitlab.coko.foundation/pubsweet/pubsweet/tree/master/packages/components/packages/xpub-app).
diff --git a/app/components/global/AppBar.js b/app/components/global/AppBar.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d0a0ce894e42d7cd120eca9dac86c2ff009fcf4
--- /dev/null
+++ b/app/components/global/AppBar.js
@@ -0,0 +1,22 @@
+import React from 'react'
+import { Link, withRouter } from 'react-router-dom'
+import { graphql, compose } from 'react-apollo'
+import { AppBar } from '@pubsweet/ui'
+import { withLoader } from 'pubsweet-client'
+import { CURRENT_USER } from './queries'
+
+const ElifeAppBar = ({ history, currentUser }) => (
+  <AppBar
+    brand="eLife"
+    navLinkComponents={[<Link to="/">Dashboard</Link>]}
+    onLogoutClick={() => {
+      window.localStorage.removeItem('token')
+      history.push('/')
+    }}
+    user={currentUser.user}
+  />
+)
+
+export default compose(withRouter, graphql(CURRENT_USER), withLoader())(
+  ElifeAppBar,
+)
diff --git a/app/components/global/AuthenticatedComponent.js b/app/components/global/AuthenticatedComponent.js
new file mode 100644
index 0000000000000000000000000000000000000000..56ba709cd6b51c99ee0a0dcd7ef118e8d16ad8e3
--- /dev/null
+++ b/app/components/global/AuthenticatedComponent.js
@@ -0,0 +1,26 @@
+import React from 'react'
+import { Redirect } from 'react-router'
+import { Query } from 'react-apollo'
+import { CURRENT_USER } from './queries'
+
+const AuthenticatedComponent = ({ children }) => (
+  <Query query={CURRENT_USER}>
+    {({ loading, error, data }) => {
+      if (!window.localStorage.getItem('token')) {
+        return <Redirect to="/login" />
+      }
+
+      if (loading) return 'Loading...'
+
+      if (error) return <div>{error.message}</div>
+
+      if (data.currentUser && !data.currentUser.user) {
+        return <Redirect to="/login" />
+      }
+
+      return children
+    }}
+  </Query>
+)
+
+export default AuthenticatedComponent
diff --git a/app/components/global/queries.js b/app/components/global/queries.js
new file mode 100644
index 0000000000000000000000000000000000000000..6dc3489b0ecb58946e6d6c9923cb372f19eb3be9
--- /dev/null
+++ b/app/components/global/queries.js
@@ -0,0 +1,13 @@
+import gql from 'graphql-tag'
+
+export const CURRENT_USER = gql`
+  query CurrentUser {
+    currentUser {
+      user {
+        id
+        username
+        admin
+      }
+    }
+  }
+`
diff --git a/app/components/index.js b/app/components/index.js
index c8c070e5ea6684e86400ff18dfbe36770c20b6da..7f08b3e36d64ba12ea18775bae8c6259f182b3ec 100644
--- a/app/components/index.js
+++ b/app/components/index.js
@@ -1,4 +1,7 @@
-export { default as App } from './app/App'
+export { default as AppBar } from './global/AppBar'
+export {
+  default as AuthenticatedComponent,
+} from './global/AuthenticatedComponent'
 export { default as Dashboard } from './dashboard/Dashboard'
 export { default as LoginPage } from './login/LoginPage'
 export { default as AuthorDetailsPage } from './submission/AuthorDetailsPage'
diff --git a/app/routes.js b/app/routes.js
index 07875c0d012f36a685b767ac2115ea98a7b9f1a8..ae0c3fab4bca8d9d5430cd29bbffc1303491c7a8 100644
--- a/app/routes.js
+++ b/app/routes.js
@@ -2,7 +2,8 @@ import React from 'react'
 import { Route, Switch } from 'react-router-dom'
 
 import {
-  App,
+  AppBar,
+  AuthenticatedComponent,
   Dashboard,
   AuthorDetailsPage,
   FileUploadsPage,
@@ -11,33 +12,28 @@ import {
   ReviewerSuggestionsPage,
 } from './components'
 
-/*
- * TODO: implement login/signup and wrap Component in AuthenticatedComponent:
- * <AuthenticatedComponent>
- *   <Component {...props}>
- * </AuthenticatedComponent>
- */
-const PrivateRoute = ({ component: Component, ...rest }) => (
-  <Route {...rest} render={props => <Component {...props} />} />
-)
-
 const Routes = () => (
-  <App>
-    <Switch>
-      <Route component={LoginPage} exact path="/login" />
-      <PrivateRoute component={AuthorDetailsPage} exact path="/submit" />
-      <PrivateRoute component={FileUploadsPage} exact path="/submit/upload" />
-      <PrivateRoute
-        component={ManuscriptMetadataPage}
-        path="/submit/metadata"
-      />
-      <PrivateRoute
-        component={ReviewerSuggestionsPage}
-        path="/submit/suggestions"
-      />
-      <PrivateRoute component={Dashboard} path="/" />
-    </Switch>
-  </App>
+  <Switch>
+    <Route component={LoginPage} path="/login" />
+    <AuthenticatedComponent>
+      <AppBar />
+      <Switch>
+        <Route component={AuthorDetailsPage} exact path="/submit" />
+        <Route component={FileUploadsPage} exact path="/submit/upload" />
+        <Route
+          component={ManuscriptMetadataPage}
+          exact
+          path="/submit/metadata"
+        />
+        <Route
+          component={ReviewerSuggestionsPage}
+          exact
+          path="/submit/suggestions"
+        />
+        <Route component={Dashboard} path="/" />
+      </Switch>
+    </AuthenticatedComponent>
+  </Switch>
 )
 
 export default Routes
diff --git a/client/login-orcid/Login.test.js b/client/login-orcid/Login.test.js
index 6001093e6fee7c22b391ef5908342efe839ad76d..4439e884b6121724f67e3c6241b59b4e0c5011e9 100644
--- a/client/login-orcid/Login.test.js
+++ b/client/login-orcid/Login.test.js
@@ -1,11 +1,8 @@
 import React from 'react'
-import Adapter from 'enzyme-adapter-react-16'
-import Enzyme, { shallow } from 'enzyme'
+import { shallow } from 'enzyme'
 
 import Login from './Login'
 
-Enzyme.configure({ adapter: new Adapter() })
-
 const makeWrapper = props => shallow(<Login {...props} />)
 
 describe('ORCID Login component', () => {
diff --git a/package.json b/package.json
index 5b5c1771772af01f68bcd0233cbeea58965394e5..9f82a5ebe7189b9ef764cc6adb26f0989ff619b5 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
     ]
   },
   "jest": {
+    "setupTestFrameworkScriptFile": "<rootDir>/test/helpers/jest-setup.js",
     "testMatch": [
       "**/*.test.js"
     ],
@@ -82,7 +83,7 @@
     "lodash": "^4.17.5",
     "prop-types": "^15.5.10",
     "pubsweet-client": "^2.4.0",
-    "pubsweet-server": "^2.0.4",
+    "pubsweet-server": "^5.0.0",
     "react": "^16.2.0",
     "react-apollo": "^2.1.2",
     "react-dom": "^16.2.0",
diff --git a/server/auth/orcid.test.js b/server/auth/orcid.test.js
index 6f1ac45e877712fd2128ee8474096e0494d3677f..ec0f44a23855894efcd8bdd491a472890fdbc395 100644
--- a/server/auth/orcid.test.js
+++ b/server/auth/orcid.test.js
@@ -1,4 +1,4 @@
-/** @jest-environment jest-environment-db */
+/** @jest-environment @elife/jest-environment-db */
 const express = require('express')
 const supertest = require('supertest')
 const nock = require('nock')
diff --git a/server/auth/package.json b/server/auth/package.json
index 2a31edd125ddfee93584a4f797eacd9e9e82a765..c53a095d1ed32ef39b84d3665e359c6ac5511701 100644
--- a/server/auth/package.json
+++ b/server/auth/package.json
@@ -5,13 +5,13 @@
   "main": "index.js",
   "scripts": {},
   "dependencies": {
-    "config": "^1.30.0",
-    "passport": "^0.4.0",
+    "config": "^1.29.0",
+    "passport": "^0.3.2",
     "passport-orcid": "^0.0.3"
   },
   "devDependencies": {
     "nock": "^9.2.3",
-    "jest-environment-db": "^1.0.0",
+    "@elife/jest-environment-db": "^1.0.0",
     "superagent": "^3.8.2",
     "supertest": "^3.0.0"
   },
diff --git a/server/jest-environment-db/package.json b/server/jest-environment-db/package.json
index d13ed5997132608db9c22f5de9f92491afc6e997..998b2c8047e42163a15dc0cb6c8a44305f2ad00c 100644
--- a/server/jest-environment-db/package.json
+++ b/server/jest-environment-db/package.json
@@ -1,5 +1,5 @@
 {
-  "name": "jest-environment-db",
+  "name": "@elife/jest-environment-db",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
diff --git a/styleguide.config.js b/styleguide.config.js
index 75085b5a3b94381a487f2b01b76ee5949f93dba0..f630d33c15c176df3ea9223754ad3efe37e70bfa 100644
--- a/styleguide.config.js
+++ b/styleguide.config.js
@@ -19,7 +19,6 @@ module.exports = {
   context: {
     formik: 'formik',
   },
-  skipComponentsWithoutExample: true,
   styleguideComponents: {
     StyleGuideRenderer: path.join(
       __dirname,
diff --git a/test/helpers/jest-setup.js b/test/helpers/jest-setup.js
new file mode 100644
index 0000000000000000000000000000000000000000..911f65635aa454bd5bf0b0ad58154b54414b33e1
--- /dev/null
+++ b/test/helpers/jest-setup.js
@@ -0,0 +1,4 @@
+import Adapter from 'enzyme-adapter-react-16'
+import Enzyme from 'enzyme'
+
+Enzyme.configure({ adapter: new Adapter() })
diff --git a/yarn.lock b/yarn.lock
index 37b2b40b23eec8fc19496fb973f5c20ae14ef3ea..f4cba40bf51ff545ea81f9d25c8999780ddd35a0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -697,10 +697,6 @@ attr-accept@^1.0.3:
   dependencies:
     core-js "^2.5.0"
 
-authsome@0.0.9:
-  version "0.0.9"
-  resolved "https://registry.yarnpkg.com/authsome/-/authsome-0.0.9.tgz#08b34f1797b3539e6a362f0fb11a01ae0613f928"
-
 authsome@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/authsome/-/authsome-0.1.0.tgz#4152e666afcaa7f7c51ddbed94145ad7105904d9"
@@ -2371,7 +2367,7 @@ concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.6.0:
     readable-stream "^2.2.2"
     typedarray "^0.0.6"
 
-config@^1.21.0, config@^1.26.2, config@^1.30.0:
+config@^1.21.0, config@^1.26.2, config@^1.29.0:
   version "1.30.0"
   resolved "https://registry.yarnpkg.com/config/-/config-1.30.0.tgz#1d60a9f35348a13c175798d384e81a5a16c3ba6e"
   dependencies:
@@ -7482,13 +7478,6 @@ passport@^0.3.2:
     passport-strategy "1.x.x"
     pause "0.0.1"
 
-passport@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811"
-  dependencies:
-    passport-strategy "1.x.x"
-    pause "0.0.1"
-
 path-browserify@0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
@@ -8203,14 +8192,14 @@ pubsweet-client@^2.4.0:
     styled-components "^3.2.5"
     styled-normalize "^3.0.1"
 
-pubsweet-server@^2.0.4:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/pubsweet-server/-/pubsweet-server-2.0.5.tgz#4e8c4868e59c83a67ab440417dcc5cd04a26b780"
+pubsweet-server@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/pubsweet-server/-/pubsweet-server-4.0.0.tgz#928d9b26e843649aaa38b49c70cd5c3d492e662c"
   dependencies:
     "@pubsweet/logger" "^0.2.2"
     apollo-server-express "^1.3.2"
     apollo-upload-server "^4.0.2"
-    authsome "0.0.9"
+    authsome "^0.1.0"
     bcrypt "^1.0.2"
     bluebird "^3.5.1"
     body-parser "^1.15.2"
@@ -8241,9 +8230,9 @@ pubsweet-server@^2.0.4:
     uuid "^3.0.1"
     winston "^2.2.0"
 
-pubsweet-server@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/pubsweet-server/-/pubsweet-server-4.0.0.tgz#928d9b26e843649aaa38b49c70cd5c3d492e662c"
+pubsweet-server@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/pubsweet-server/-/pubsweet-server-5.0.0.tgz#7b7f363834ac67ab0648b3cdcfc1a814fb15a15a"
   dependencies:
     "@pubsweet/logger" "^0.2.2"
     apollo-server-express "^1.3.2"
@@ -8274,7 +8263,7 @@ pubsweet-server@^4.0.0:
     pg "^7.4.1"
     promise-queue "^2.2.3"
     prompt "^1.0.0"
-    pubsweet-sse "^0.1.4"
+    pubsweet-sse "^0.1.5"
     require-relative "^0.8.7"
     uuid "^3.0.1"
     winston "^2.2.0"
@@ -8283,6 +8272,10 @@ pubsweet-sse@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/pubsweet-sse/-/pubsweet-sse-0.1.4.tgz#1ff38a230143cbd487a8d44afb28a6c4746ee464"
 
+pubsweet-sse@^0.1.5:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/pubsweet-sse/-/pubsweet-sse-0.1.5.tgz#c93195c52121e299c8a55896962d870f792ce963"
+
 pubsweet@^2.1.4:
   version "2.1.7"
   resolved "https://registry.yarnpkg.com/pubsweet/-/pubsweet-2.1.7.tgz#db00b3c71bfbc9e9805c82ce7baabb2c74180258"