🐛 fix(authGuard): add check for getAuthentication() in ProtectedRoute component to prevent unauthorized access and logout user

✨ feat(authContext): add getAuthentication() function to check if user is authenticated using cookies
🔧 chore(index.tsx): reorganize context providers to wrap AuthProvider around other providers
This commit is contained in:
Cristhian Zanforlin Lousa 2023-08-11 11:56:12 -03:00
commit f030234438
4 changed files with 36 additions and 5 deletions

View file

@ -3,10 +3,10 @@ import { Navigate } from "react-router-dom";
import { AuthContext } from "../../contexts/authContext"; import { AuthContext } from "../../contexts/authContext";
export const ProtectedRoute = ({ children }) => { export const ProtectedRoute = ({ children }) => {
const { isAuthenticated, logout, getAuthentication } = useContext(AuthContext);
const { isAuthenticated } = useContext(AuthContext); if (!isAuthenticated && !getAuthentication()) {
logout();
if (!isAuthenticated) {
return <Navigate to="/login" replace />; return <Navigate to="/login" replace />;
} }

View file

@ -2,6 +2,7 @@ import { createContext, useEffect, useState } from "react";
import { AuthContextType, userData } from "../types/contexts/auth"; import { AuthContextType, userData } from "../types/contexts/auth";
import { LoginType } from "../types/api"; import { LoginType } from "../types/api";
import { api } from "../controllers/API/api"; import { api } from "../controllers/API/api";
import Cookies from 'universal-cookie';
const initialValue: AuthContextType = { const initialValue: AuthContextType = {
isAuthenticated: false, isAuthenticated: false,
@ -12,6 +13,7 @@ const initialValue: AuthContextType = {
refreshAccessToken: () => Promise.resolve(), refreshAccessToken: () => Promise.resolve(),
userData: null, userData: null,
setUserData: () => {}, setUserData: () => {},
getAuthentication: () => false,
}; };
export const AuthContext = createContext<AuthContextType>(initialValue); export const AuthContext = createContext<AuthContextType>(initialValue);
@ -21,6 +23,7 @@ export function AuthProvider({ children }): React.ReactElement {
const [refreshToken, setRefreshToken] = useState<string | null>(null); const [refreshToken, setRefreshToken] = useState<string | null>(null);
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false); const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
const [userData, setUserData] = useState<userData>(null); const [userData, setUserData] = useState<userData>(null);
const cookies = new Cookies();
useEffect(() => { useEffect(() => {
const storedAccessToken = localStorage.getItem("access_token"); const storedAccessToken = localStorage.getItem("access_token");
@ -29,7 +32,26 @@ export function AuthProvider({ children }): React.ReactElement {
} }
}, []); }, []);
function getAuthentication(){
const storedRefreshToken = cookies.get('refresh_token');
const storedAccess = cookies.get('refresh_token');
if (storedAccess && storedRefreshToken) {
setAccessToken(storedAccess);
setRefreshToken(storedRefreshToken);
return true;
}
else{
return false;
}
}
function login(newAccessToken: string, refreshToken: string) { function login(newAccessToken: string, refreshToken: string) {
//if we want to use cookie
cookies.set('access_token', newAccessToken, { path: '/' });
cookies.set('refresh_token', refreshToken, { path: '/' });
localStorage.setItem("access_token", newAccessToken); localStorage.setItem("access_token", newAccessToken);
setAccessToken(newAccessToken); setAccessToken(newAccessToken);
@ -40,11 +62,16 @@ export function AuthProvider({ children }): React.ReactElement {
} }
function logout() { function logout() {
//if we want to use cookie
cookies.remove('access_token');
cookies.remove('refresh_token');
localStorage.removeItem("access_token"); localStorage.removeItem("access_token");
localStorage.removeItem("refresh_token"); localStorage.removeItem("refresh_token");
setAccessToken(null); setAccessToken(null);
setRefreshToken(null); setRefreshToken(null);
setIsAuthenticated(false); setIsAuthenticated(false);
} }
async function refreshAccessToken(refreshToken: string) { async function refreshAccessToken(refreshToken: string) {
@ -81,6 +108,7 @@ export function AuthProvider({ children }): React.ReactElement {
refreshAccessToken, refreshAccessToken,
setUserData, setUserData,
userData, userData,
getAuthentication
}} }}
> >
{children} {children}

View file

@ -14,12 +14,13 @@ export default function ContextWrapper({ children }: { children: ReactNode }) {
//element to wrap all context //element to wrap all context
return ( return (
<> <>
<AuthProvider>
<TooltipProvider> <TooltipProvider>
<ReactFlowProvider> <ReactFlowProvider>
<DarkProvider> <DarkProvider>
<TypesProvider> <TypesProvider>
<LocationProvider> <LocationProvider>
<AuthProvider>
<AlertProvider> <AlertProvider>
<SSEProvider> <SSEProvider>
<TabsProvider> <TabsProvider>
@ -27,12 +28,13 @@ export default function ContextWrapper({ children }: { children: ReactNode }) {
</TabsProvider> </TabsProvider>
</SSEProvider> </SSEProvider>
</AlertProvider> </AlertProvider>
</AuthProvider>
</LocationProvider> </LocationProvider>
</TypesProvider> </TypesProvider>
</DarkProvider> </DarkProvider>
</ReactFlowProvider> </ReactFlowProvider>
</TooltipProvider> </TooltipProvider>
</AuthProvider>
</> </>
); );
} }

View file

@ -7,6 +7,7 @@ export type AuthContextType = {
refreshAccessToken: (refreshToken: string) => Promise<void>; refreshAccessToken: (refreshToken: string) => Promise<void>;
userData: userData | null; userData: userData | null;
setUserData: (userData: userData | null) => void; setUserData: (userData: userData | null) => void;
getAuthentication: () => boolean;
}; };
export type userData = { export type userData = {