diff --git a/src/App.tsx b/src/App.tsx index 0a7b221e86417816a42e8a0da01c47456ad858d1..f0a86b423f208efb3b101ef2fc6e00b593940150 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,14 +5,23 @@ import { AuthUser } from 'components/AuthUser/AuthUser'; import { LandingPage } from 'components/LandingPage/LandingPage'; import { PrivateRoute } from 'components/api/PrivateRoute/PrivateRoute'; import { AuthRoutes, NonAuthRoutes } from 'components/api/routes'; +import { NotFound } from 'components/NotFound/NotFound'; +import { Roles } from 'components/api/userRoles'; +import { Unauthorized } from 'components/Unauthorized/Unauthorized'; export const App: FC = () => ( <Router> <div data-testid="App"> <Switch> - <Route path={NonAuthRoutes.login} component={AuthUser} /> + <Route path={NonAuthRoutes.signIn} component={AuthUser} /> <Route exact path={NonAuthRoutes.home} component={LandingPage} /> - <PrivateRoute path={AuthRoutes.dashboard} Component={HomePage} /> + <PrivateRoute + path={AuthRoutes.dashboard} + Component={HomePage} + requiredRoles={[Roles.admin, Roles.operator, Roles.senior]} + /> + <Route path={NonAuthRoutes.unauthorized} component={Unauthorized} /> + <Route component={NotFound} /> </Switch> </div> </Router> diff --git a/src/components/LandingPage/LandingPage.tsx b/src/components/LandingPage/LandingPage.tsx index df5cc0b53af919c30d511576ac898abbd1b50ce6..fae4bba76e98ced845155da37e41f40e78cbca66 100644 --- a/src/components/LandingPage/LandingPage.tsx +++ b/src/components/LandingPage/LandingPage.tsx @@ -6,7 +6,7 @@ import { NonAuthRoutes } from 'components/api/routes'; export const LandingPage: FC = () => ( <> <Button variant="contained"> - <Link to={NonAuthRoutes.login}>Login</Link> + <Link to={NonAuthRoutes.signIn}>Login</Link> </Button> <section> <h2>What is MoveAid?</h2> diff --git a/src/components/NotFound/NotFound.tsx b/src/components/NotFound/NotFound.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f514a0f1691cf6d689854436d0ed932f3b0af9cd --- /dev/null +++ b/src/components/NotFound/NotFound.tsx @@ -0,0 +1,3 @@ +import React, { FC } from 'react'; + +export const NotFound: FC = () => <h1>Page not found</h1>; diff --git a/src/components/Unauthorized/Unauthorized.tsx b/src/components/Unauthorized/Unauthorized.tsx new file mode 100644 index 0000000000000000000000000000000000000000..0e53bf59f28c1f9e4abf43489906f1b6e8f59b10 --- /dev/null +++ b/src/components/Unauthorized/Unauthorized.tsx @@ -0,0 +1,3 @@ +import React, { FC } from 'react'; + +export const Unauthorized: FC = () => <h1>You cannot access this page</h1>; diff --git a/src/components/api/PrivateRoute/PrivateRoute.tsx b/src/components/api/PrivateRoute/PrivateRoute.tsx index 89c5962bfc29c5d79a961e6b47f555fae77c7aa3..7c3256102d3fb2b7c2f131e4219276a3662fa497 100644 --- a/src/components/api/PrivateRoute/PrivateRoute.tsx +++ b/src/components/api/PrivateRoute/PrivateRoute.tsx @@ -9,23 +9,33 @@ import { NonAuthRoutes } from 'components/api/routes'; type Props = { Component: React.FC<RouteProps>; path: string; + requiredRoles: string[]; }; /* eslint-disable react/jsx-props-no-spreading */ -export const PrivateRoute = ({ Component, path }: Props): JSX.Element => { - const isAuthed = false; - const message = 'Please log in to view this page'; +export const PrivateRoute = ({ + Component, + path, + requiredRoles, +}: Props): JSX.Element => { + const isAuthed = true; + const userHasRequiredRole = requiredRoles.includes('admin'); + const message = userHasRequiredRole + ? 'Please log in to view this page' + : 'Your role is not allowed'; return ( <Route exact={false} path={path} render={(props: RouteProps) => - isAuthed ? ( + isAuthed && userHasRequiredRole ? ( <Component {...props} /> ) : ( <Redirect to={{ - pathname: NonAuthRoutes.login, + pathname: userHasRequiredRole + ? NonAuthRoutes.signIn + : NonAuthRoutes.unauthorized, state: { message, requestedPath: path, diff --git a/src/components/api/routes.ts b/src/components/api/routes.ts index 52ee5982734df8730522c6ee2199b15419da4e74..e06d35ea5775c78bec55c98ca22574e477730659 100644 --- a/src/components/api/routes.ts +++ b/src/components/api/routes.ts @@ -1,10 +1,18 @@ +/** + * Allowed routes for authenticated users. + * Routes must be defined there and then reused across components + * importing AuthRoutes and NonAuthRoutes + */ export enum AuthRoutes { dashboard = '/dashboard', account = '/account', } +/** + * Allowed routes for non authenticated users + */ export enum NonAuthRoutes { home = '/', - login = '/login', + signIn = '/signIn', unauthorized = '/unauthorized', } diff --git a/src/components/api/userRoles.ts b/src/components/api/userRoles.ts new file mode 100644 index 0000000000000000000000000000000000000000..add57691555c87750a834de2c58ad941f834e43c --- /dev/null +++ b/src/components/api/userRoles.ts @@ -0,0 +1,5 @@ +export enum Roles { + senior = 'senior', + admin = 'admin', + operator = 'operator', +}