diff --git a/src/api/getRoles.ts b/src/api/getRoles.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e00e4ef213203b003e3f01e5e4c82981a05c9d8 --- /dev/null +++ b/src/api/getRoles.ts @@ -0,0 +1,8 @@ +import axios from 'axios'; + +/** + * Ask the server all the roles of an user if the user has multiple roles. + * @returns array of roles. + */ +export const getRoles = async (): Promise<string[]> => + axios('/api/web/login/get_roles').then((res) => res.data.roles); diff --git a/src/api/setRole.ts b/src/api/setRole.ts new file mode 100644 index 0000000000000000000000000000000000000000..ac08f6f5bbbfa6ab9963b23f09b07ad7c05a0965 --- /dev/null +++ b/src/api/setRole.ts @@ -0,0 +1,7 @@ +import axios from 'axios'; + +/** + * Set the role of the user in the database. + */ +export const setRole = async (role: string): Promise<void> => + axios.post('/api/web/login/set_role', { role }); diff --git a/src/components/AuthUser/AuthUser.tsx b/src/components/AuthUser/AuthUser.tsx index 242bbb9c7153e73bdb14ec135cefb94bc7799986..7388e5924a2842b4e94ac71d78afdb5db273790e 100644 --- a/src/components/AuthUser/AuthUser.tsx +++ b/src/components/AuthUser/AuthUser.tsx @@ -7,6 +7,9 @@ import { SignUpForm } from 'components/AuthUser/SignUpForm/SignUpForm'; import { ChoseRole } from 'components/AuthUser/ChoseRole/ChoseRole'; import { RestrictedRoute } from 'components/RestrictedRoute/RestrictedRoute'; +/** + * Keeps all components related to SignIn/SignOut logic. + */ export const AuthUser: FC = () => { const { path } = useRouteMatch(); return ( diff --git a/src/components/AuthUser/ChoseRole/ChoseRole.tsx b/src/components/AuthUser/ChoseRole/ChoseRole.tsx index a100cbf3c255b465611f1ee3df250b35aafa19f1..c6fe0f5025f5c98b0a9cb9bc30b6e084e3f53318 100644 --- a/src/components/AuthUser/ChoseRole/ChoseRole.tsx +++ b/src/components/AuthUser/ChoseRole/ChoseRole.tsx @@ -1,39 +1,46 @@ -import React, { FC, useContext, useEffect, useState } from 'react'; -import axios from 'axios'; +import React, { FC, useEffect, useState } from 'react'; import Button from '@material-ui/core/Button'; -import { AuthContext } from '../AuthContext'; - -const choseAndForward = (e: unknown): void => { - // Do nothing. -}; +import { getRoles } from 'api/getRoles'; +import { setRole } from 'api/setRole'; +import { useHistory } from 'react-router-dom'; +import { AuthRoutes } from 'api/routes'; /** - * Screen that let's users decide role between available roles. + * Page that let's users decide role between available roles. * This is intended to use when a user has more than one role. * @returns ChoseRole component. */ export const ChoseRole: FC = () => { - const [userRoles, setUserRoles] = useState<Array<string>>(['']); + const history = useHistory(); + const [userRoles, setUserRoles] = useState<string[]>(['hello', 'world']); + + const choseAndForward = (role: string): void => { + // Set role in the server. + setRole(role); + // Push to homepage. + history.push(`${AuthRoutes.dashboard}${AuthRoutes.home}`); + }; useEffect(() => { - const getUserRoles = async (): Promise<unknown> => { - const response = await axios('/api/web/get_role'); - setUserRoles(response.data.token); - return null; - }; - getUserRoles(); - }, [userRoles]); + getRoles().then((fetchedRoles) => setUserRoles(fetchedRoles)); + }, []); - const { role } = useContext(AuthContext); return ( <div data-testid="ChoseRole"> - <Button - variant="outlined" - color="default" - onClick={(e) => choseAndForward(e)} - > - {role} - </Button> + {userRoles ? ( + userRoles.map((role) => ( + <Button + variant="outlined" + color="default" + key={role} + onClick={() => choseAndForward(role)} + > + {role} + </Button> + )) + ) : ( + <h1>No roles were returned.</h1> + )} </div> ); }; diff --git a/src/components/AuthUser/Dashboard/ProfilePage/ProfilePage.tsx b/src/components/AuthUser/Dashboard/ProfilePage/ProfilePage.tsx index bf861488aa174e961acf0ed49550801a956b4249..1f52c2442fb1a57c1f610d1348f6f32fa05fb228 100644 --- a/src/components/AuthUser/Dashboard/ProfilePage/ProfilePage.tsx +++ b/src/components/AuthUser/Dashboard/ProfilePage/ProfilePage.tsx @@ -9,7 +9,7 @@ export const ProfilePage: FC = () => { const logout = (): void => { axios - .post('/api/web/login/logout') + .get('/api/web/login/logout') .then(() => history.replace(NonAuthRoutes.home)); }; diff --git a/src/components/AuthUser/SignInForm/SignInForm.tsx b/src/components/AuthUser/SignInForm/SignInForm.tsx index a640ce6dcb3b3c36b620e7402c48d401123982fb..528252e4896ebc948ba244a2c676aa25248414b4 100644 --- a/src/components/AuthUser/SignInForm/SignInForm.tsx +++ b/src/components/AuthUser/SignInForm/SignInForm.tsx @@ -1,10 +1,10 @@ -import React, { FC, useContext, useEffect, useState } from 'react'; +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 } from 'api/routes'; +import { AuthRoutes, NonAuthRoutes } from 'api/routes'; import { AuthContext } from 'components/AuthUser/AuthContext'; import { fetchCookie } from 'api/fetchCookie'; import { useStyles } from './useStyles'; @@ -20,7 +20,7 @@ export const SignInForm: FC = () => { const { setRole, setIsAuth } = useContext(AuthContext); const [cookie, setCookie] = useState<string>(''); - useEffect(() => { + useCallback(() => { let isMounted = true; if (isMounted) fetchCookie().then((cookieResponse) => setCookie(cookieResponse)); @@ -61,6 +61,8 @@ export const SignInForm: FC = () => { type: 'server', message: 'Something went wrong with password', }); + } else if (response.data.status === 'role-choice-needed') { + history.replace(`${NonAuthRoutes.auth}${AuthRoutes.choseRole}`); } else if (response.data.status === 'success') { setRole(response.data.role); setIsAuth(true); diff --git a/src/components/RestrictedRoute/RestrictedRoute.tsx b/src/components/RestrictedRoute/RestrictedRoute.tsx index 3be9157b076fd142ff3f9e7a7c4b7c02b9b4bc0e..2f10632cba2b63271465c060ef4758144e250ea0 100644 --- a/src/components/RestrictedRoute/RestrictedRoute.tsx +++ b/src/components/RestrictedRoute/RestrictedRoute.tsx @@ -4,11 +4,10 @@ import { AuthRoutes } from 'api/routes'; import { isAuthenticated } from 'api/isAuthenticated'; import { CircularProgress } from '@material-ui/core'; -/** - * - * */ type Props = { + /** Children where the authenticated user will be redirected. */ Component: React.FC<RouteProps>; + /** Path of the children. */ path: string; }; @@ -25,19 +24,11 @@ export const RestrictedRoute = ({ Component, path }: Props): JSX.Element => { const [isLoading, setLoading] = useState<boolean>(false); useEffect(() => { - let isMounted = true; - - isAuthenticated().then((state) => { - if (isMounted) { - setIsAuth(state); - setLoading(true); - } + isAuthenticated().then((res) => { + setIsAuth(res); + setLoading(true); }); - - return () => { - isMounted = false; - }; - }, [isLoading]); + }, [isAuth, setLoading]); return !isLoading ? ( <CircularProgress />