Merge pull request #2544 from bluewave-labs/fix/logs-rights

fix: logs access
This commit is contained in:
Alexander Holliday
2025-06-25 12:41:44 +08:00
committed by GitHub
4 changed files with 52 additions and 10 deletions

View File

@@ -0,0 +1,35 @@
import { Navigate } from "react-router-dom";
import { useSelector } from "react-redux";
import PropTypes from "prop-types";
/**
* ProtectedRoute is a wrapper component that ensures only authenticated users
* can access the wrapped content. It checks authentication status (e.g., from Redux or Context).
* If the user is authenticated, it renders the children; otherwise, it redirects to the login page.
*
* @param {Object} props - The props passed to the ProtectedRoute component.
* @param {React.ReactNode} props.children - The children to render if the user is authenticated.
* @returns {React.ReactElement} The children wrapped in a protected route or a redirect to the login page.
*/
const RoleProtectedRoute = ({ roles, children }) => {
const authState = useSelector((state) => state.auth);
const userRoles = authState?.user?.role || [];
const canAccess = userRoles.some((role) => roles.includes(role));
return canAccess ? (
children
) : (
<Navigate
to="/uptime"
replace
/>
);
};
RoleProtectedRoute.propTypes = {
children: PropTypes.element.isRequired,
roles: PropTypes.array,
};
export default RoleProtectedRoute;

View File

@@ -49,6 +49,8 @@ import { useDispatch, useSelector } from "react-redux";
import { useTranslation } from "react-i18next";
import { clearAuthState } from "../../Features/Auth/authSlice";
import { toggleSidebar } from "../../Features/UI/uiSlice";
import { TurnedIn } from "@mui/icons-material";
import { rules } from "eslint-plugin-react-refresh";
const getMenu = (t) => [
{ name: t("menu.uptime"), path: "uptime", icon: <Monitors /> },
@@ -121,7 +123,6 @@ function Sidebar() {
const { t } = useTranslation();
const authState = useSelector((state) => state.auth);
const menu = getMenu(t);
const otherMenuItems = getOtherMenuItems(t);
const accountMenuItems = getAccountMenuItems(t);
const collapsed = useSelector((state) => state.ui.sidebar.collapsed);
@@ -133,6 +134,13 @@ function Sidebar() {
const sidebarRef = useRef(null);
const [sidebarReady, setSidebarReady] = useState(false);
const TRANSITION_DURATION = 200;
let menu = getMenu(t);
menu = menu.filter((item) => {
if (item.path === "logs") {
return user.role?.includes("admin") || user.role?.includes("superadmin");
}
return true;
});
useEffect(() => {
if (!collapsed) {

View File

@@ -48,6 +48,7 @@ import Settings from "../Pages/Settings";
import Maintenance from "../Pages/Maintenance";
import ProtectedRoute from "../Components/ProtectedRoute";
import RoleProtectedRoute from "../Components/RoleProtectedRoute";
import CreateNewMaintenanceWindow from "../Pages/Maintenance/CreateMaintenance";
import withAdminCheck from "../Components/HOC/withAdminCheck";
import BulkImport from "../Pages/Uptime/BulkImport";
@@ -190,7 +191,11 @@ const Routes = () => {
<Route
path="logs"
element={<Logs />}
element={
<RoleProtectedRoute roles={["admin", "superadmin"]}>
<Logs />
</RoleProtectedRoute>
}
/>
</Route>

View File

@@ -4,14 +4,8 @@ import svgr from "vite-plugin-svgr";
import { execSync } from "child_process";
export default defineConfig(({ mode }) => {
let version = process.env.VITE_APP_VERSION;
if (!version || version === "unknown") {
try {
version = execSync("git describe --tags --abbrev=0").toString().trim();
} catch {
version = "unknown";
}
}
const env = loadEnv(mode, process.cwd(), "");
let version = 2.2;
return {
base: "/",