From fe2f30717ac6a452296316408262b3eb68d26ef7 Mon Sep 17 00:00:00 2001 From: Sean Macfarlane Date: Tue, 12 May 2020 18:30:45 -0400 Subject: [PATCH 1/4] fixed User Provider and token --- app/containers/App/index.js | 20 ++++++++++++++------ app/containers/Login/index.js | 9 ++++----- app/contexts/UserProvider/index.js | 5 +++-- app/utils/localStorage.js | 4 +++- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/containers/App/index.js b/app/containers/App/index.js index 6369777..c0aa7c0 100644 --- a/app/containers/App/index.js +++ b/app/containers/App/index.js @@ -12,7 +12,7 @@ import Login from 'containers/Login'; import ClientDevices from 'containers/ClientDevices'; import UserProvider from 'contexts/UserProvider'; -import { getItem } from 'utils/localStorage'; +import { getItem, setItem } from 'utils/localStorage'; import { parseJwt } from 'utils/jwt'; import UnauthenticatedRoute from './components/UnauthenticatedRoute'; @@ -27,26 +27,34 @@ const RedirectToDashboard = () => ( ); const App = () => { + const token = getItem(AUTH_TOKEN); const [user, setUser] = useState({}); useEffect(() => { - const token = getItem(AUTH_TOKEN); if (token) { const { userId, userName, userRole, customerId } = parseJwt(token.access_token); - setUser({ id: userId, email: userName, role: userRole, customerId }); } }, []); + const updateToken = newToken => { + setItem(AUTH_TOKEN, newToken); + if (newToken) { + const { userId, userName, userRole, customerId } = parseJwt(newToken.access_token); + setUser({ id: userId, email: userName, role: userRole, customerId }); + } + }; + const updateUser = newUser => setUser({ ...user, ...newUser }); return ( diff --git a/app/containers/Login/index.js b/app/containers/Login/index.js index 1a6ece5..5388704 100644 --- a/app/containers/Login/index.js +++ b/app/containers/Login/index.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useContext } from 'react'; import gql from 'graphql-tag'; import { useMutation, useApolloClient } from '@apollo/react-hooks'; import { useHistory } from 'react-router-dom'; @@ -6,9 +6,7 @@ import { notification } from 'antd'; import { Login as LoginPage } from '@tip-wlan/wlan-cloud-ui-library'; -import { AUTH_TOKEN } from 'constants/index'; - -import { setItem } from 'utils/localStorage'; +import UserContext from 'contexts/UserContext'; const AUTHENTICATE_USER = gql` mutation AuthenticateUser($email: String!, $password: String!) { @@ -22,6 +20,7 @@ const AUTHENTICATE_USER = gql` const Login = () => { const history = useHistory(); + const { updateToken } = useContext(UserContext); const client = useApolloClient(); const [authenticateUser] = useMutation(AUTHENTICATE_USER); @@ -29,7 +28,7 @@ const Login = () => { authenticateUser({ variables: { email, password } }) .then(({ data }) => { client.resetStore(); - setItem(AUTH_TOKEN, data.authenticateUser, data.authenticateUser.expires_in); + updateToken(data.authenticateUser); history.push('/'); }) .catch(() => diff --git a/app/contexts/UserProvider/index.js b/app/contexts/UserProvider/index.js index 70b8198..a660bc2 100644 --- a/app/contexts/UserProvider/index.js +++ b/app/contexts/UserProvider/index.js @@ -3,8 +3,8 @@ import PropTypes from 'prop-types'; import UserContext from 'contexts/UserContext'; -const UserProvider = ({ children, id, email, role, customerId, updateUser }) => ( - +const UserProvider = ({ children, id, email, role, customerId, updateUser, updateToken }) => ( + {children} ); @@ -12,6 +12,7 @@ const UserProvider = ({ children, id, email, role, customerId, updateUser }) => UserProvider.propTypes = { children: PropTypes.node.isRequired, updateUser: PropTypes.func.isRequired, + updateToken: PropTypes.func.isRequired, id: PropTypes.number, email: PropTypes.string, role: PropTypes.string, diff --git a/app/utils/localStorage.js b/app/utils/localStorage.js index de6173c..4e75cc0 100644 --- a/app/utils/localStorage.js +++ b/app/utils/localStorage.js @@ -13,7 +13,9 @@ export const getItemExpiration = () => { export const setItem = (key, data, expiration) => { const localStorageState = data; - localStorageState.expiration = expiration || getItemExpiration(); + if (localStorageState) { + localStorageState.expiration = expiration || getItemExpiration(); + } window.localStorage.setItem(key, JSON.stringify(localStorageState)); }; From 448d7cb6b3fee139905c2ec8453eab572f100027 Mon Sep 17 00:00:00 2001 From: Sean Macfarlane Date: Tue, 12 May 2020 18:59:04 -0400 Subject: [PATCH 2/4] added eslint check to docker test --- Dockerfile.test | 1 + docker-compose.test.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile.test b/Dockerfile.test index 219ace3..69e16f6 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -29,4 +29,5 @@ EXPOSE 3000 COPY --from=build /app /app +RUN npm run eslint CMD ["npm", "start"] \ No newline at end of file diff --git a/docker-compose.test.yml b/docker-compose.test.yml index da74f5f..69313d9 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -5,4 +5,4 @@ services: build: context: . dockerfile: Dockerfile.test - command: npm run test \ No newline at end of file + command: npm test \ No newline at end of file From 87dc449ce893326d2572097c4fe879b63a5d5964 Mon Sep 17 00:00:00 2001 From: Sean Macfarlane Date: Tue, 12 May 2020 19:00:10 -0400 Subject: [PATCH 3/4] added eslint command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f0502d5..cef509d 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "start": "cross-env NODE_ENV=development webpack-dev-server", "build": "webpack --mode=production", "format": "prettier --write \"app/**/*.js\"", - "eslint-fix": "eslint --fix \"app/**/*.js\"" + "eslint-fix": "eslint --fix \"app/**/*.js\"", + "eslint": "eslint \"app/**/*.js\" --max-warnings=0" }, "license": "MIT", "dependencies": { From 900c1b36420096e226778eee25ecbc96dacb05a3 Mon Sep 17 00:00:00 2001 From: Sean Macfarlane Date: Wed, 13 May 2020 12:15:57 -0400 Subject: [PATCH 4/4] fixed User tokens --- app/containers/App/index.js | 16 +++++++--------- app/index.js | 8 +++++++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/containers/App/index.js b/app/containers/App/index.js index c0aa7c0..55dfa7a 100644 --- a/app/containers/App/index.js +++ b/app/containers/App/index.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { Helmet } from 'react-helmet'; import { Switch, Redirect } from 'react-router-dom'; @@ -28,14 +28,12 @@ const RedirectToDashboard = () => ( const App = () => { const token = getItem(AUTH_TOKEN); - const [user, setUser] = useState({}); - - useEffect(() => { - if (token) { - const { userId, userName, userRole, customerId } = parseJwt(token.access_token); - setUser({ id: userId, email: userName, role: userRole, customerId }); - } - }, []); + let initialUser = {}; + if (token) { + const { userId, userName, userRole, customerId } = parseJwt(token.access_token); + initialUser = { id: userId, email: userName, role: userRole, customerId }; + } + const [user, setUser] = useState(initialUser); const updateToken = newToken => { setItem(AUTH_TOKEN, newToken); diff --git a/app/index.js b/app/index.js index ddff113..3976ef8 100644 --- a/app/index.js +++ b/app/index.js @@ -11,7 +11,7 @@ import 'styles/index.scss'; import App from 'containers/App'; import { AUTH_TOKEN } from 'constants/index'; -import { getItem, setItem } from 'utils/localStorage'; +import { getItem, setItem, removeItem } from 'utils/localStorage'; const API_URI = process.env.NODE_ENV !== 'production' ? 'http://localhost:4000/' : ''; const MOUNT_NODE = document.getElementById('root'); @@ -41,6 +41,7 @@ const client = new ApolloClient({ graphQLErrors.forEach(err => { // handle errors differently based on its error code switch (err.extensions.code) { + case 'FORBIDDEN': case 'UNAUTHENTICATED': operation.setContext({ headers: { @@ -59,6 +60,11 @@ const client = new ApolloClient({ }, }); return forward(operation); + case 'INTERNAL_SERVER_ERROR': + if (err.path && err.path[0] === 'updateToken') { + removeItem(AUTH_TOKEN); + } + return forward(operation); default: return forward(operation); }