Skip to content
Snippets Groups Projects
Commit 72a11a4b authored by Defendi Alberto's avatar Defendi Alberto
Browse files

Merge branch 'feature/authorization/curry' into 'dev'

Feature/authorization/curry

See merge request !53
parents 6f4925ee d3a527bb
No related branches found
No related tags found
3 merge requests!56Refined auth flow and new website pages.,!53Feature/authorization/curry,!52Change folder structure and fix auth flow.
Pipeline #12486 passed
Showing
with 35 additions and 45 deletions
import React, { FC, useEffect, useState } from 'react';
import React, { FC } from 'react';
import { ThemeProvider } from '@material-ui/core/styles';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { AuthUser } from 'components/AuthUser/AuthUser';
import { LandingPage } from 'components/NonAuthUser/LandingPage/LandingPage';
import { PrivateRoute } from 'components/PrivateRoute/PrivateRoute';
import { AuthRoutes, NonAuthRoutes } from 'api/routes';
import { NotFound } from 'components/NonAuthUser/NotFound/NotFound';
import { ProfilePage } from 'components/AuthUser/Dashboard/ProfilePage/ProfilePage';
import { Roles } from 'api/userRoles';
import { Unauthorized } from 'components/NonAuthUser/Unauthorized/Unauthorized';
import { HomePage } from 'components/AuthUser/Dashboard/HomePage/HomePage';
import { AuthContext } from 'components/AuthUser/AuthContext';
import { configDjangoCookieName } from 'api/configDjangoCookieName';
import { Dashboard } from 'components/AuthUser/Dashboard/Dashboard';
import { isAuthenticated } from 'api/isAuthenticated';
import { muiTheme } from 'App.style';
import { getRole } from 'api/getRole';
import { withAuthorization } from 'components/Authorization/Authorization';
import { useRole } from 'hooks/useRole';
import { useAuth } from 'hooks/useAuth';
import { AuthUser } from 'components/Auth/Auth';
import { AuthContext } from 'components/Auth/AuthContext';
import { Dashboard } from 'components/Dashboard/Dashboard';
import { NotFound } from 'components/NotFound/NotFound';
import { Unauthorized } from 'components/Unauthorized/Unauthorized';
import { LandingPage } from 'components/LandingPage/LandingPage';
const Personal = withAuthorization(Dashboard);
const All = withAuthorization([
Roles.admin,
Roles.operator,
Roles.senior,
Roles.driver,
]);
/**
* Entry point of the app.
......@@ -39,16 +39,8 @@ export const App: FC = () => {
<Router>
<Switch>
<Route exact path={NonAuthRoutes.home} component={LandingPage} />
<Route path={NonAuthRoutes.auth} component={AuthUser} />
<Route
path={AuthRoutes.dashboard}
render={() => (
<Personal
allowedRoles={['admin', 'driver', 'senior', 'operator']}
/>
)}
/>
<Route path={AuthRoutes.dashboard} component={All(Dashboard)} />
<Route
path={NonAuthRoutes.unauthorized}
component={Unauthorized}
......
export enum Roles {
/** Website visitor, is not logged. Can access to NonAuthRoutes */
visitor = '',
/** Can access to private and restricted routes depending on their permissions level. */
/** Can access to routes wrapped by withAuthorization. */
senior = 'senior',
admin = 'admin',
operator = 'operator',
driver = 'driver',
}
......@@ -2,10 +2,9 @@ import React, { FC } from 'react';
import Container from '@material-ui/core/Container';
import { Redirect, Route, useRouteMatch } from 'react-router-dom';
import { AuthRoutes, NonAuthRoutes } from 'api/routes';
import { SignInForm } from 'components/AuthUser/SignInForm/SignInForm';
import { SignUpForm } from 'components/AuthUser/SignUpForm/SignUpForm';
import { ChoseRole } from 'components/AuthUser/ChoseRole/ChoseRole';
import { RestrictedRoute } from 'components/RestrictedRoute/RestrictedRoute';
import { ChoseRole } from 'components/Auth/ChoseRole/ChoseRole';
import { SignInForm } from 'components/Auth/SignInForm/SignInForm';
import { SignUpForm } from 'components/Auth/SignUpForm/SignUpForm';
/**
* Keeps all components related to SignIn/SignOut logic.
......
import React, { FC, useEffect, useState } from 'react';
import React, { FC, useContext, useEffect, useState } from 'react';
import Button from '@material-ui/core/Button';
import { getRoles } from 'api/getRoles';
import { setRole } from 'api/setRole';
import { useHistory } from 'react-router-dom';
import { AuthRoutes } from 'api/routes';
import { AuthContext } from 'components/Auth/AuthContext';
/**
* Page that let's users decide role between available roles.
......@@ -13,10 +14,12 @@ import { AuthRoutes } from 'api/routes';
export const ChoseRole: FC = () => {
const history = useHistory();
const [userRoles, setUserRoles] = useState<string[]>(['']);
const { setIsAuth } = useContext(AuthContext);
const choseAndForward = (role: string): void => {
// Set role in the server.
setRole(role);
setIsAuth(true);
// Push to homepage.
history.push(`${AuthRoutes.dashboard}${AuthRoutes.home}`);
};
......
......@@ -2,11 +2,11 @@ import React, { FC, useCallback, useContext, useState } from 'react';
import axios from 'axios';
import { SubmitHandler, useForm } from 'react-hook-form';
import { Button } from '@material-ui/core';
import { InputField } from 'components/AuthUser/InputField/InputField';
import { useHistory } from 'react-router-dom';
import { AuthRoutes, NonAuthRoutes } from 'api/routes';
import { AuthContext } from 'components/AuthUser/AuthContext';
import { fetchCookie } from 'api/fetchCookie';
import { AuthContext } from 'components/Auth/AuthContext';
import { InputField } from 'components/Auth/InputField/InputField';
import { useStyles } from './useStyles';
import { CredentialsType } from './CredentialsType';
......
import React, { FC } from 'react';
import { SubmitHandler, useForm } from 'react-hook-form';
import { Button } from '@material-ui/core';
import { InputField } from 'components/AuthUser/InputField/InputField';
import { useStyles } from 'components/AuthUser/SignUpForm/useStyles';
import axios from 'axios';
import { InputField } from 'components/Auth/InputField/InputField';
import { useStyles } from 'components/Auth/SignUpForm/useStyles';
// TODO: Data validation
// TODO: Replace notes with big input field
export const SignUpForm: FC = () => {
......
import React, { ComponentType, FC, useContext } from 'react';
import { BlurCircular } from '@material-ui/icons';
import { NonAuthRoutes } from 'api/routes';
import { AuthContext } from 'components/AuthUser/AuthContext';
import { Unauthorized } from 'components/NonAuthUser/Unauthorized/Unauthorized';
import { useAuth } from 'hooks/useAuth';
import { useRole } from 'hooks/useRole';
import { Redirect } from 'react-router-dom';
import { CircularProgressClassKey } from '@material-ui/core';
import { Unauthorized } from 'components/Unauthorized/Unauthorized';
import { AuthContext } from 'components/Auth/AuthContext';
const HandleIsAuth: FC<{ isAuth: boolean }> = ({ isAuth }) =>
isAuth ? (
......@@ -21,10 +18,6 @@ interface WithAuthProps {
allowedRoles: string[];
}
interface Props extends WithAuthProps {
children: React.ReactNode;
}
/* eslint-disable react/jsx-props-no-spreading */
/**
*
......@@ -32,20 +25,21 @@ interface Props extends WithAuthProps {
* This creates a "personal area" in the working implementation.
* @returns {FC<T>} wrapped component.
*/
export const withAuthorization = <T extends WithAuthProps = WithAuthProps>(
export const withAuthorization = (allowedRoles: string[]) => <
T extends WithAuthProps = WithAuthProps
>(
WrappedComponent: React.ComponentType<T>,
): FC<T> => {
// Creating the inner component. The calculated Props type here is the where the magic happens.
const ComponentWithAuthorization: FC<T> = (
props: Omit<T, keyof WithAuthProps>,
) => {
const { allowedRoles } = props as T;
const { role, isAuth } = useContext(AuthContext);
console.log(`ROLE ${role} AUTH ${isAuth}`);
/* eslint-disable no-nested-ternary */
return typeof isAuth === null || role === null ? (
return typeof isAuth === null && role === null ? (
<BlurCircular />
) : // props comes afterwards so the can override the default ones.
allowedRoles.includes(role) && isAuth ? (
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment