From 51ec69a3cba33f140a0ae9fce88f1a016fbfe08c Mon Sep 17 00:00:00 2001 From: rui hildt Date: Fri, 21 Aug 2020 11:51:52 +0200 Subject: [PATCH] Refactor authentication with Context --- src/App.js | 48 ++++++++++++++++++--------- src/components/Navbar/MenuDropdown.js | 27 +++++++++++---- src/components/Routes/PrivateRoute.js | 19 +++++++++++ src/components/Routes/PublicRoute.js | 25 ++++++++++++++ src/components/routes/PrivateRoute.js | 29 ---------------- src/components/routes/PublicRoute.js | 22 ------------ src/helpers/authContext.js | 7 ++++ src/{utils => helpers}/http-common.js | 0 src/screens/Home.js | 19 +++++++++++ src/screens/Login.js | 24 ++++++++------ src/utils/common.js | 26 --------------- 11 files changed, 137 insertions(+), 109 deletions(-) create mode 100644 src/components/Routes/PrivateRoute.js create mode 100644 src/components/Routes/PublicRoute.js delete mode 100644 src/components/routes/PrivateRoute.js delete mode 100644 src/components/routes/PublicRoute.js create mode 100644 src/helpers/authContext.js rename src/{utils => helpers}/http-common.js (100%) create mode 100644 src/screens/Home.js delete mode 100644 src/utils/common.js diff --git a/src/App.js b/src/App.js index 9cee18c..9e421f1 100644 --- a/src/App.js +++ b/src/App.js @@ -1,10 +1,12 @@ -import React from 'react'; +import React, { useState } from 'react'; import 'rsuite/lib/styles/index.less'; import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; -import PrivateRoute from './components/routes/PrivateRoute'; -import PublicRoute from './components/routes/PublicRoute'; +import { AuthContext } from './helpers/authContext'; +import PrivateRoute from './components/Routes/PrivateRoute'; + +import Home from './screens/Home'; import Dashboard from './screens/Dashboard'; import Schedule from './screens/Schedule/Schedule'; import Availability from './screens/Availability/Availability'; @@ -12,21 +14,35 @@ import Invite from './screens/Invite/Invite'; import Login from './screens/Login'; import Register from './screens/Register'; +const existingToken = localStorage.getItem('token'); +// const existingUser = JSON.parse(localStorage.getItem('user')); + export default function App() { + const [authToken, setAuthToken] = useState(existingToken); + + const setToken = (data) => { + localStorage.setItem('token', JSON.stringify(data)); + setAuthToken(data); + }; + return ( - - - + + + + + + - - - - - - - - - - + + + + + + + + ); } diff --git a/src/components/Navbar/MenuDropdown.js b/src/components/Navbar/MenuDropdown.js index 5d9baf6..70426be 100644 --- a/src/components/Navbar/MenuDropdown.js +++ b/src/components/Navbar/MenuDropdown.js @@ -1,6 +1,5 @@ import React from 'react'; import { useHistory } from 'react-router-dom'; - import { Nav, Icon, Dropdown, Popover, Whisper } from 'rsuite'; export default function MenuDropdown() { @@ -12,18 +11,34 @@ export default function MenuDropdown() { triggerRef.current.hide(); } + function handleLogout() { + localStorage.removeItem('token'); + localStorage.removeItem('user'); + history.push('/'); + } + const MenuPopover = ({ onSelect, ...rest }) => ( Dashboard Register Login - 1 - Schedule a meeting - 2 - Invite participants - 3 - Add your availability - 4 - Confirm meeting date + + 1 - Schedule a meeting + + + 2 - Invite participants + + + 3 - Add your availability + + + 4 - Confirm meeting date + Settings - Log Out + handleLogout()}> + Log Out + ); diff --git a/src/components/Routes/PrivateRoute.js b/src/components/Routes/PrivateRoute.js new file mode 100644 index 0000000..3298d08 --- /dev/null +++ b/src/components/Routes/PrivateRoute.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { Redirect, Route } from 'react-router-dom'; + +import { useAuth } from '../../helpers/authContext'; + +const PrivateRoute = ({ component: Component, ...rest }) => { + const { authToken } = useAuth(); + + return ( + + authToken ? : + } + /> + ); +}; + +export default PrivateRoute; diff --git a/src/components/Routes/PublicRoute.js b/src/components/Routes/PublicRoute.js new file mode 100644 index 0000000..d1ae9fa --- /dev/null +++ b/src/components/Routes/PublicRoute.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { Redirect, Route } from 'react-router-dom'; + +import { useAuth } from '../../helpers/authContext'; + + +// TODO Make sure it's used, else delete it and remove message in App +const PublicRoute = ({ component: Component, ...rest }) => { + const isAuthenticated = useAuth(); + + return ( + + isAuthenticated ? ( + + ) : ( + + ) + } + /> + ); +}; + +export default PublicRoute; diff --git a/src/components/routes/PrivateRoute.js b/src/components/routes/PrivateRoute.js deleted file mode 100644 index 6a840ba..0000000 --- a/src/components/routes/PrivateRoute.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import { Route, Redirect } from 'react-router-dom'; -import { getToken } from '../../utils/common'; - -const isLoggedIn = getToken(); - -const PrivateRoute = ({ component: Component, user, ...rest }) => { - return ( - - isLoggedIn ? ( - - ) : ( - - ) - } - /> - ); -}; - -export default PrivateRoute; diff --git a/src/components/routes/PublicRoute.js b/src/components/routes/PublicRoute.js deleted file mode 100644 index 8a3ab72..0000000 --- a/src/components/routes/PublicRoute.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { Route, Redirect } from 'react-router-dom'; -import { getToken } from '../../utils/common'; - -const isLoggedIn = getToken(); - -function PublicRoute({ component: Component, ...rest }) { - return ( - - !isLoggedIn ? ( - - ) : ( - - ) - } - /> - ); -} - -export default PublicRoute; diff --git a/src/helpers/authContext.js b/src/helpers/authContext.js new file mode 100644 index 0000000..f62af10 --- /dev/null +++ b/src/helpers/authContext.js @@ -0,0 +1,7 @@ +import { createContext, useContext } from 'react'; + +export const AuthContext = createContext(); + +export function useAuth() { + return useContext(AuthContext); +} diff --git a/src/utils/http-common.js b/src/helpers/http-common.js similarity index 100% rename from src/utils/http-common.js rename to src/helpers/http-common.js diff --git a/src/screens/Home.js b/src/screens/Home.js new file mode 100644 index 0000000..7a48f1a --- /dev/null +++ b/src/screens/Home.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { Panel } from 'rsuite'; + +import NavBar from '../components/Navbar/NavBar'; + +const boxStyle = { + margin: '50px 10px', +}; + +export default function Home() { + return ( + <> + + Home} bordered style={boxStyle}> +

This will be the home page

+
+ + ); +} diff --git a/src/screens/Login.js b/src/screens/Login.js index b46bd72..99de3ff 100644 --- a/src/screens/Login.js +++ b/src/screens/Login.js @@ -1,6 +1,5 @@ import React, { useState } from 'react'; -import { useHistory } from 'react-router-dom'; -import { backend } from '../utils/http-common'; +import { Redirect } from 'react-router-dom'; import { Panel, Form, @@ -11,18 +10,19 @@ import { Message, } from 'rsuite'; -import { setUserSession } from '../utils/common'; import NavBar from './../components/Navbar/NavBar'; +import { backend } from '../helpers/http-common'; +import { useAuth } from '../helpers/authContext'; export default function Login() { - const history = useHistory(); - const [error, setError] = useState(false); const [credentials, setCredentials] = useState({ email: '', password: '', }); + const { setAuthToken, authToken } = useAuth(); + const handleChange = (value, evt) => { setCredentials({ ...credentials, @@ -34,16 +34,20 @@ export default function Login() { backend .post('/auth/login', credentials) .then((response) => { - setUserSession(response.data.token, response.data.user); - history.push('/dashboard'); + setAuthToken(response.data.token); }) .catch((error) => { - if (error.response.status === 401) - setError('Incorrect credentials. Please try again.'); - else setError('Something went wrong. Please try again later.'); + if (error.response.status === 401) { + setError('The credentials provided were incorrect.'); + } else + setError('Something went wrong. Please try again later.'); }); }; + if (authToken) { + return ; + } + return ( <> diff --git a/src/utils/common.js b/src/utils/common.js deleted file mode 100644 index c24569e..0000000 --- a/src/utils/common.js +++ /dev/null @@ -1,26 +0,0 @@ -// Set/Remove user and token to local storage -export const setUserSession = (token, user) => { - localStorage.setItem('token', token); - localStorage.setItem('user', JSON.stringify(user)); -}; - -export const getUser = () => { - const userJSON = localStorage.getItem('user'); - - if (userJSON) { - const user = JSON.parse(userJSON); - return user; - } else return null; -}; - -export const getToken = () => { - const token = localStorage.getItem('token'); - - if (token) return token; - else return null; -}; - -export const removeUserSession = () => { - localStorage.removeItem('token'); - localStorage.removeItem('user'); -};