📦 feat(authAdminGuard): add ProtectedAdminRoute component to handle authentication and authorization for admin pages

📦 feat(catchAllRoutes): add CatchAllRoute component to redirect to the root ("/") when the catch-all route is matched

🔧 refactor(api.tsx): remove console.log statement

🔧 refactor(AdminPage): remove disabled prop from Checkbox components

🔧 refactor(loginPage): change Link to="/signup" to Link to="/signup" to fix incorrect link

🔧 refactor(routes.tsx): remove import statement for ProtectedRoute component and add import statements for CatchAllRoute and ProtectedAdminRoute components
This commit is contained in:
Cristhian Zanforlin Lousa 2023-08-14 18:28:04 -03:00
commit 6d3d9569bd
6 changed files with 68 additions and 35 deletions

View file

@ -0,0 +1,28 @@
import { useContext, useEffect } from "react";
import { Navigate } from "react-router-dom";
import { AuthContext } from "../../contexts/authContext";
export const ProtectedAdminRoute = ({ children }) => {
const { isAuthenticated, logout, getAuthentication, userData } =
useContext(AuthContext);
useEffect(() => {
if (!isAuthenticated && !getAuthentication()) {
window.location.replace("/login");
logout();
}
if (userData && userData?.is_superuser === false) {
logout();
}
}, [isAuthenticated, getAuthentication, logout, userData]);
if (!isAuthenticated && !getAuthentication()) {
return <Navigate to="/login" replace />;
}
if (userData && userData?.is_superuser === false) {
return <Navigate to="/login" replace />;
}
return children;
};

View file

@ -0,0 +1,13 @@
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
export const CatchAllRoute = () => {
const navigate = useNavigate();
// Redirect to the root ("/") when the catch-all route is matched
useEffect(() => {
navigate('/');
}, []);
return null;
};

View file

@ -18,8 +18,6 @@ function ApiInterceptor() {
const navigate = useNavigate();
const cookies = new Cookies();
console.log(accessToken);
useEffect(() => {
const interceptor = api.interceptors.response.use(
(response) => response,
@ -49,7 +47,14 @@ function ApiInterceptor() {
navigate("/login");
}
}
} else {
}
if(!refreshToken && error?.config?.url?.includes(
"login"
) ){
return Promise.reject(error);
}
else{
logout();
navigate("/login");
}
@ -58,30 +63,7 @@ function ApiInterceptor() {
return Promise.reject(error);
// }
}
// else {
// let retryCount = 0;
// while (retryCount < 4) {
// await sleep(5000); // Sleep for 5 seconds
// retryCount++;
// try {
// const response = await axios.request(error.config);
// return response;
// } catch (error) {
// if (retryCount === 3) {
// setErrorData({
// title: "There was an error on web connection, please: ",
// list: [
// "Refresh the page",
// "Use a new flow tab",
// "Check if the backend is up",
// "Endpoint: " + error.config?.url,
// ],
// });
// return Promise.reject(error);
// }
// }
// }
// }
}
);

View file

@ -23,6 +23,7 @@ import {
} from "../../controllers/API";
import ConfirmationModal from "../../modals/ConfirmationModal";
import UserManagementModal from "../../modals/UserManagementModal";
import { AuthContext } from "../../contexts/authContext";
export default function AdminPage() {
const [inputValue, setInputValue] = useState("");
@ -31,6 +32,7 @@ export default function AdminPage() {
const [index, setPageIndex] = useState(0);
const [loadingUsers, setLoadingUsers] = useState(true);
const { setErrorData, setSuccessData } = useContext(alertContext);
const { userData } = useContext(AuthContext);
const userList = useRef([]);
@ -136,8 +138,13 @@ export default function AdminPage() {
}
return (
<>
<div className="main-page-panel">
{
userData && (
<div className="main-page-panel">
<div className="m-auto flex h-full flex-row justify-center">
<div className="basis-5/6">
<div className="m-auto flex h-full flex-col space-y-8 p-8 ">
@ -249,14 +256,12 @@ export default function AdminPage() {
<Checkbox
id="is_disabled"
checked={user.is_disabled}
disabled
/>
</TableCell>
<TableCell className="relative left-5 truncate py-2">
<Checkbox
id="is_superuser"
checked={user.is_superuser}
disabled
/>
</TableCell>
<TableCell className="truncate py-2 ">
@ -338,6 +343,9 @@ export default function AdminPage() {
</div>
</div>
</div>
)
}
</>
);
}

View file

@ -131,7 +131,7 @@ export default function LoginPage(): JSX.Element {
</Form.Submit>
</div>
<div className="w-full">
<Link to="">
<Link to="/signup">
<Button className="w-full" variant="outline">
Don't have an account?&nbsp;<b>Sign Up</b>
</Button>

View file

@ -1,5 +1,4 @@
import { Route, Routes } from "react-router-dom";
import { ProtectedRoute } from "./components/authGuard";
import { ProtectedLoginRoute } from "./components/authLoginGuard";
import AdminPage from "./pages/AdminPage";
import LoginAdminPage from "./pages/AdminPage/LoginPage";
@ -9,6 +8,9 @@ import HomePage from "./pages/MainPage";
import DeleteAccountPage from "./pages/deleteAccountPage";
import LoginPage from "./pages/loginPage";
import SignUp from "./pages/signUpPage";
import { CatchAllRoute } from "./components/catchAllRoutes";
import { ProtectedRoute } from "./components/authGuard";
import { ProtectedAdminRoute } from "./components/authAdminGuard";
const Router = () => {
return (
@ -43,7 +45,7 @@ const Router = () => {
path="*"
element={
<ProtectedRoute>
<HomePage />
<CatchAllRoute />
</ProtectedRoute>
}
/>
@ -76,9 +78,9 @@ const Router = () => {
<Route
path="/admin"
element={
<ProtectedRoute>
<ProtectedAdminRoute>
<AdminPage />
</ProtectedRoute>
</ProtectedAdminRoute>
}
/>