Untitled

 avatar
unknown
plain_text
19 days ago
2.6 kB
1
Indexable
import { Route, Redirect, RouteComponentProps } from 'react-router-dom'
import { AuthService } from '../auth/auth-service'
import { AuthenticatedScreen } from '../auth/AuthenticatedScreen'
import { UserRole } from '../auth/types'
import {
  HOME_ROUTE,
  LOGIN_ROUTE,
  ROUTE_GUARD_TYPE_AUTH,
  ROUTE_GUARD_TYPE_UNAUTH,
} from './routes'

interface Props {
  exact: boolean
  children: React.ReactNode
  guard: string
  path: string
  roles: UserRole[]
}

export const RouteGuard = ({ children, exact, guard, path, roles }: Props) => {

  const authUser = AuthService.getAuthUser()
  const isAuthenticated = authUser ? true : false


  const renderProp = ({ location }: RouteComponentProps) => {
    if (guard === ROUTE_GUARD_TYPE_AUTH && !isAuthenticated) {
      return (
        <Redirect
          to={{
            pathname: LOGIN_ROUTE.path,
            state: { from: location },
          }}
        />
      )
    } else if (
      isAuthenticated &&
      // User is trying to access a route
      // which is only accessible without auth(ex. login)
      (guard === ROUTE_GUARD_TYPE_UNAUTH ||
        // User is trying to access unauthorised route
        (authUser &&
          roles.indexOf(authUser.role) === -1 &&
          roles.indexOf(UserRole.All) === -1))
    ) {
      return (
        <Redirect
          to={{
            pathname: HOME_ROUTE.path,
            state: { from: location },
          }}
        />
      )
    }

    return guard === ROUTE_GUARD_TYPE_AUTH ? (
      <AuthenticatedScreen>{children}</AuthenticatedScreen>
    ) : (
      <>{children}</>
    )
  }

  return <Route exact={exact} path={path} render={renderProp} />
}


import {BrowserRouter as Router, Switch} from 'react-router-dom'
import {ROUTES} from './routes/routes'
import {RouteGuard} from './routes/RouteGuard'
import {AdapterDateFns} from '@mui/x-date-pickers/AdapterDateFns'
import {LocalizationProvider} from '@mui/x-date-pickers'

function App() {
  return (
    <LocalizationProvider dateAdapter={AdapterDateFns}>
      <Router>
        <Switch>
          {/* TODO: type route */}
          {ROUTES.map((route: any) => (
            <RouteGuard
              exact={route.exact}
              guard={route.guard}
              key={route.name}
              path={route.path}
              roles={route.roles}
            >
              <route.component />
            </RouteGuard>
          ))}
        </Switch>
      </Router>
    </LocalizationProvider>
  )
}

export default App

Leave a Comment