🐛 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:
parent
c0f586ad89
commit
f030234438
4 changed files with 36 additions and 5 deletions
|
|
@ -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) {
|
if (!isAuthenticated && !getAuthentication()) {
|
||||||
|
logout();
|
||||||
return <Navigate to="/login" replace />;
|
return <Navigate to="/login" replace />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue