diff --git a/client/src/Components/v1/HOC/withAdminCheck.jsx b/client/src/Components/v1/HOC/withAdminCheck.jsx deleted file mode 100644 index 6343b2e4e..000000000 --- a/client/src/Components/v1/HOC/withAdminCheck.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import { useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; - -import { logger } from "../../../Utils/Logger.js"; -import { useLazyGet } from "@/Hooks/UseApi"; - -const withAdminCheck = (WrappedComponent) => { - const WithAdminCheck = (props) => { - const navigate = useNavigate(); - const [superAdminExists, setSuperAdminExists] = useState(false); - const [hasChecked, setHasChecked] = useState(false); - const { get: checkSuperAdmin, loading: isChecking } = useLazyGet(); - - useEffect(() => { - checkSuperAdmin("/auth/users/superadmin") - .then((response) => { - if (response?.data === true) { - navigate("/login"); - } else { - setSuperAdminExists(false); - } - }) - .catch((error) => { - logger.error(error); - }) - .finally(() => { - setHasChecked(true); - }); - }, [navigate, checkSuperAdmin]); - - if (!hasChecked || isChecking) { - return null; - } - - return ( - - ); - }; - const wrappedComponentName = - WrappedComponent.displayName || WrappedComponent.name || "Component"; - WithAdminCheck.displayName = `WithAdminCheck(${wrappedComponentName})`; - - return WithAdminCheck; -}; - -export default withAdminCheck; diff --git a/client/src/Components/v2/routing/RouteProtected.tsx b/client/src/Components/v2/routing/RouteProtected.tsx index e69de29bb..7064c26a4 100644 --- a/client/src/Components/v2/routing/RouteProtected.tsx +++ b/client/src/Components/v2/routing/RouteProtected.tsx @@ -0,0 +1,41 @@ +import { Navigate } from "react-router-dom"; +import { useSelector } from "react-redux"; +import type { RootState } from "@/Types/state"; +import type { UserRole } from "@/Types/User"; + +interface ProtectedRouteProps { + children: React.ReactNode; +} + +export const ProtectedRoute = ({ children }: ProtectedRouteProps) => { + const authState = useSelector((state: RootState) => state.auth); + + return authState.authToken ? ( + children + ) : ( + + ); +}; + +interface RoleProtectedRouteProps { + roles: UserRole[]; + children: React.ReactNode; +} + +export const RoleProtectedRoute = ({ roles, children }: RoleProtectedRouteProps) => { + const authState = useSelector((state: RootState) => state.auth); + const userRoles = authState?.user?.role || []; + const canAccess = userRoles.some((role) => roles.includes(role)); + + return canAccess ? ( + children + ) : ( + + ); +}; diff --git a/client/src/Components/v2/routing/RouteRoleProtected.tsx b/client/src/Components/v2/routing/RouteRoleProtected.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/src/Pages/Auth/Register/index.tsx b/client/src/Pages/Auth/Register/index.tsx index 75d27649f..3c8a4e4bc 100644 --- a/client/src/Pages/Auth/Register/index.tsx +++ b/client/src/Pages/Auth/Register/index.tsx @@ -5,7 +5,7 @@ import { zodResolver } from "@hookform/resolvers/zod/dist/zod.js"; import { useRegisterForm } from "@/Hooks/useRegisterForm"; import type { RegisterFormData } from "@/Validation/register"; import { useTranslation } from "react-i18next"; -import { usePost } from "@/Hooks/UseApi"; +import { usePost, useGet } from "@/Hooks/UseApi"; import { setAuthState } from "@/Features/Auth/authSlice"; import { useDispatch } from "react-redux"; import { useNavigate, useParams } from "react-router-dom"; @@ -32,11 +32,21 @@ const RegisterPage = () => { const { post: verifyToken } = usePost<{ token: string }, InviteVerifyResponse>(); const hasVerified = useRef(false); + const { data: superAdminExists, isLoading: isCheckingAdmin } = useGet( + token ? null : "/auth/users/superadmin" + ); + const { control, handleSubmit, setError, reset } = useForm({ resolver: zodResolver(schema), defaultValues: defaults, }); + useEffect(() => { + if (superAdminExists === true) { + navigate("/login", { replace: true }); + } + }, [superAdminExists, navigate]); + useEffect(() => { if (!token || hasVerified.current) return; hasVerified.current = true; @@ -53,6 +63,8 @@ const RegisterPage = () => { }); }, [token]); + if (isCheckingAdmin) return null; + const onSubmit = async (data: RegisterFormData) => { if (loading) return; diff --git a/client/src/Routes/index.jsx b/client/src/Routes/index.jsx index 178d00b2d..3b0b76fc6 100644 --- a/client/src/Routes/index.jsx +++ b/client/src/Routes/index.jsx @@ -47,10 +47,15 @@ import Settings from "@/Pages/Settings"; import Maintenance from "@/Pages/Maintenance"; import CreateNewMaintenanceWindow from "@/Pages/Maintenance/create"; -import ProtectedRoute from "@/Components/v1/ProtectedRoute"; -import RoleProtectedRoute from "@/Components/v1/RoleProtectedRoute"; +// Logs & Diagnostics import Logs from "@/Pages/Logs"; +// Routing +import { + ProtectedRoute, + RoleProtectedRoute, +} from "@/Components/v2/routing/RouteProtected"; + import CreateMonitor from "@/Pages/CreateMonitor"; const Routes = () => {