mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-29 13:19:33 -06:00
Merge branch 'develop' into feat/dark-mode-switch
This commit is contained in:
@@ -8,7 +8,8 @@ Mention the issue number(s) this PR addresses (e.g., #123).
|
||||
|
||||
## Please ensure all items are checked off before requesting a review:
|
||||
|
||||
- [ ] I have performed a self-review of my code.
|
||||
- [ ] I deployed the application locally.
|
||||
- [ ] I have performed a self-review and testing of my code.
|
||||
- [ ] I have included the issue # in the PR.
|
||||
- [ ] I have labelled the PR correctly.
|
||||
- [ ] The issue I am working on is assigned to me.
|
||||
@@ -17,5 +18,3 @@ Mention the issue number(s) this PR addresses (e.g., #123).
|
||||
- [ ] My PR is granular and targeted to one specific feature.
|
||||
- [ ] I took a screenshot or a video and attached to this PR if there is a UI change.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +1,8 @@
|
||||
import { useEffect } from "react";
|
||||
import { Routes, Route, Navigate } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
import NotFound from "./Pages/NotFound";
|
||||
import Login from "./Pages/Auth/Login";
|
||||
import Register from "./Pages/Auth/Register/Register";
|
||||
import Account from "./Pages/Account";
|
||||
import Uptime from "./Pages/Uptime/Home";
|
||||
import CreateMonitor from "./Pages/Uptime/CreateUptime";
|
||||
import CreateInfrastructureMonitor from "./Pages/Infrastructure/CreateMonitor";
|
||||
import Incidents from "./Pages/Incidents";
|
||||
import Status from "./Pages/Status";
|
||||
import Integrations from "./Pages/Integrations";
|
||||
import Settings from "./Pages/Settings";
|
||||
import ForgotPassword from "./Pages/Auth/ForgotPassword";
|
||||
import CheckEmail from "./Pages/Auth/CheckEmail";
|
||||
import SetNewPassword from "./Pages/Auth/SetNewPassword";
|
||||
import NewPasswordConfirmed from "./Pages/Auth/NewPasswordConfirmed";
|
||||
import ProtectedRoute from "./Components/ProtectedRoute";
|
||||
import UptimeDetails from "./Pages/Uptime/Details";
|
||||
import AdvancedSettings from "./Pages/AdvancedSettings";
|
||||
import Maintenance from "./Pages/Maintenance";
|
||||
import Configure from "./Pages/Uptime/Configure";
|
||||
import PageSpeed from "./Pages/PageSpeed";
|
||||
import CreatePageSpeed from "./Pages/PageSpeed/CreatePageSpeed";
|
||||
import CreateNewMaintenanceWindow from "./Pages/Maintenance/CreateMaintenance";
|
||||
import PageSpeedDetails from "./Pages/PageSpeed/Details";
|
||||
import PageSpeedConfigure from "./Pages/PageSpeed/Configure";
|
||||
import HomeLayout from "./Components/Layouts/HomeLayout";
|
||||
import withAdminCheck from "./Components/HOC/withAdminCheck";
|
||||
import withAdminProp from "./Components/HOC/withAdminProp";
|
||||
import { ThemeProvider } from "@emotion/react";
|
||||
import lightTheme from "./Utils/Theme/lightTheme";
|
||||
import darkTheme from "./Utils/Theme/darkTheme";
|
||||
@@ -39,18 +10,9 @@ import { CssBaseline, GlobalStyles } from "@mui/material";
|
||||
import { getAppSettings } from "./Features/Settings/settingsSlice";
|
||||
import { logger } from "./Utils/Logger"; // Import the logger
|
||||
import { networkService } from "./main";
|
||||
import { Infrastructure } from "./Pages/Infrastructure";
|
||||
import InfrastructureDetails from "./Pages/Infrastructure/Details";
|
||||
import { Routes } from "./Routes";
|
||||
|
||||
function App() {
|
||||
const AdminCheckedRegister = withAdminCheck(Register);
|
||||
const UptimeWithAdminProp = withAdminProp(Uptime);
|
||||
const UptimeDetailsWithAdminProp = withAdminProp(UptimeDetails);
|
||||
const PageSpeedWithAdminProp = withAdminProp(PageSpeed);
|
||||
const PageSpeedDetailsWithAdminProp = withAdminProp(PageSpeedDetails);
|
||||
const MaintenanceWithAdminProp = withAdminProp(Maintenance);
|
||||
const SettingsWithAdminProp = withAdminProp(Settings);
|
||||
const AdvancedSettingsWithAdminProp = withAdminProp(AdvancedSettings);
|
||||
const InfrastructureDetailsWithAdminProp = withAdminProp(InfrastructureDetails);
|
||||
const mode = useSelector((state) => state.ui.mode);
|
||||
const { authToken } = useSelector((state) => state.auth);
|
||||
const dispatch = useDispatch();
|
||||
@@ -82,161 +44,7 @@ function App() {
|
||||
};
|
||||
}}
|
||||
/>
|
||||
{/* Extract Routes to Routes */}
|
||||
<Routes>
|
||||
<Route
|
||||
exact
|
||||
path="/"
|
||||
element={<HomeLayout />}
|
||||
>
|
||||
<Route
|
||||
exact
|
||||
path="/"
|
||||
element={<Navigate to="/uptime" />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime"
|
||||
element={<ProtectedRoute Component={UptimeWithAdminProp} />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime/create/:monitorId?"
|
||||
element={<ProtectedRoute Component={CreateMonitor} />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime/:monitorId/"
|
||||
element={<ProtectedRoute Component={UptimeDetailsWithAdminProp} />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime/configure/:monitorId/"
|
||||
element={<ProtectedRoute Component={Configure} />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed"
|
||||
element={<ProtectedRoute Component={PageSpeedWithAdminProp} />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed/create"
|
||||
element={<ProtectedRoute Component={CreatePageSpeed} />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed/:monitorId"
|
||||
element={<ProtectedRoute Component={PageSpeedDetailsWithAdminProp} />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed/configure/:monitorId"
|
||||
element={<ProtectedRoute Component={PageSpeedConfigure} />}
|
||||
/>
|
||||
<Route
|
||||
path="infrastructure"
|
||||
element={<ProtectedRoute Component={Infrastructure} />}
|
||||
/>
|
||||
<Route
|
||||
path="infrastructure/create"
|
||||
element={<ProtectedRoute Component={CreateInfrastructureMonitor} />}
|
||||
/>
|
||||
<Route
|
||||
path="infrastructure/:monitorId"
|
||||
element={<ProtectedRoute Component={InfrastructureDetailsWithAdminProp} />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="incidents/:monitorId?"
|
||||
element={<ProtectedRoute Component={Incidents} />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="status"
|
||||
element={<ProtectedRoute Component={Status} />}
|
||||
/>
|
||||
<Route
|
||||
path="integrations"
|
||||
element={<ProtectedRoute Component={Integrations} />}
|
||||
/>
|
||||
<Route
|
||||
path="maintenance"
|
||||
element={<ProtectedRoute Component={MaintenanceWithAdminProp} />}
|
||||
/>
|
||||
<Route
|
||||
path="/maintenance/create/:maintenanceWindowId?"
|
||||
element={<CreateNewMaintenanceWindow />}
|
||||
/>
|
||||
<Route
|
||||
path="settings"
|
||||
element={<ProtectedRoute Component={SettingsWithAdminProp} />}
|
||||
/>
|
||||
<Route
|
||||
path="advanced-settings"
|
||||
element={<ProtectedRoute Component={AdvancedSettingsWithAdminProp} />}
|
||||
/>
|
||||
<Route
|
||||
path="account/profile"
|
||||
element={
|
||||
<ProtectedRoute
|
||||
Component={Account}
|
||||
open="profile"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="account/password"
|
||||
element={
|
||||
<ProtectedRoute
|
||||
Component={Account}
|
||||
open="password"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="account/team"
|
||||
element={
|
||||
<ProtectedRoute
|
||||
Component={Account}
|
||||
open="team"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Route>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path="/login"
|
||||
element={<Login />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path="/register"
|
||||
element={<AdminCheckedRegister />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path="/register/:token"
|
||||
element={<Register />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="*"
|
||||
element={<NotFound />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/forgot-password"
|
||||
element={<ForgotPassword />}
|
||||
/>
|
||||
<Route
|
||||
path="/check-email"
|
||||
element={<CheckEmail />}
|
||||
/>
|
||||
<Route
|
||||
path="/set-new-password/:token"
|
||||
element={<SetNewPassword />}
|
||||
/>
|
||||
<Route
|
||||
path="/new-password-confirmed"
|
||||
element={<NewPasswordConfirmed />}
|
||||
/>
|
||||
</Routes>
|
||||
<Routes />
|
||||
<ToastContainer />
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
const withAdminProp = (WrappedComponent) => {
|
||||
const WithAdminProp = (props) => {
|
||||
const { user } = useSelector((state) => state.auth);
|
||||
const isAdmin =
|
||||
(user?.role?.includes("admin") ?? false) ||
|
||||
(user?.role?.includes("superadmin") ?? false);
|
||||
|
||||
return (
|
||||
<WrappedComponent
|
||||
{...props}
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const wrappedComponentName =
|
||||
WrappedComponent.displayName || WrappedComponent.name || "Component";
|
||||
WithAdminProp.displayName = `WithAdminProp(${wrappedComponentName})`;
|
||||
|
||||
return WithAdminProp;
|
||||
};
|
||||
|
||||
export default withAdminProp;
|
||||
@@ -3,21 +3,20 @@ import { useSelector } from "react-redux";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
/**
|
||||
* ProtectedRoute is a higher-order component that wraps the `Route` component from `react-router-dom`
|
||||
* to create a protected route. It uses Redux to check if the user is authenticated. If the user is
|
||||
* authenticated, it renders the component passed to it; otherwise, it redirects the user to the login page.
|
||||
* 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.ComponentType} props.Component - The component to render if the user is authenticated.
|
||||
* @param {Object} rest - The remaining props passed to the Route component.
|
||||
* @returns {React.ReactElement} A Route component that conditionally renders the passed Component or redirects to the login page.
|
||||
* @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 ProtectedRoute = ({ Component, ...rest }) => {
|
||||
const ProtectedRoute = ({ children }) => {
|
||||
const authState = useSelector((state) => state.auth);
|
||||
|
||||
return authState.authToken ? (
|
||||
<Component {...rest} />
|
||||
children
|
||||
) : (
|
||||
<Navigate
|
||||
to="/login"
|
||||
@@ -27,7 +26,7 @@ const ProtectedRoute = ({ Component, ...rest }) => {
|
||||
};
|
||||
|
||||
ProtectedRoute.propTypes = {
|
||||
Component: PropTypes.elementType.isRequired,
|
||||
children: PropTypes.elementType.isRequired,
|
||||
};
|
||||
|
||||
export default ProtectedRoute;
|
||||
|
||||
@@ -14,10 +14,11 @@ import { useState, useEffect } from "react";
|
||||
import Select from "../../Components/Inputs/Select";
|
||||
import { advancedSettingsValidation } from "../../Validation/validation";
|
||||
import { buildErrors, hasValidationErrors } from "../../Validation/error";
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
|
||||
const AdvancedSettings = ({ isAdmin }) => {
|
||||
const AdvancedSettings = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const isAdmin = useIsAdmin();
|
||||
useEffect(() => {
|
||||
if (!isAdmin) {
|
||||
navigate("/");
|
||||
|
||||
@@ -8,13 +8,14 @@ import { useSelector } from "react-redux";
|
||||
import { networkService } from "../../main";
|
||||
import Breadcrumbs from "../../Components/Breadcrumbs";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
|
||||
const Maintenance = ({ isAdmin }) => {
|
||||
const Maintenance = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const { authToken } = useSelector((state) => state.auth);
|
||||
const { rowsPerPage } = useSelector((state) => state.ui.maintenance);
|
||||
|
||||
const isAdmin = useIsAdmin();
|
||||
const [maintenanceWindows, setMaintenanceWindows] = useState([]);
|
||||
const [maintenanceWindowCount, setMaintenanceWindowCount] = useState(0);
|
||||
const [page, setPage] = useState(0);
|
||||
@@ -99,7 +100,7 @@ const Maintenance = ({ isAdmin }) => {
|
||||
"Stop sending alerts in maintenance windows",
|
||||
]}
|
||||
link="/maintenance/create"
|
||||
isAdmin={true}
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@@ -21,10 +21,12 @@ import Checkbox from "../../../Components/Inputs/Checkbox";
|
||||
import PieChart from "./Charts/PieChart";
|
||||
import useUtils from "../../Uptime/utils";
|
||||
import "./index.css";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
|
||||
const PageSpeedDetails = ({ isAdmin }) => {
|
||||
const PageSpeedDetails = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const isAdmin = useIsAdmin();
|
||||
const { statusColor, pagespeedStatusMsg, determineState } = useUtils();
|
||||
const [monitor, setMonitor] = useState({});
|
||||
const [audits, setAudits] = useState({});
|
||||
|
||||
@@ -12,11 +12,12 @@ import SkeletonLayout from "./skeleton";
|
||||
import Card from "./card";
|
||||
import { networkService } from "../../main";
|
||||
import { Heading } from "../../Components/Heading";
|
||||
const PageSpeed = ({ isAdmin }) => {
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
const PageSpeed = () => {
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const isAdmin = useIsAdmin();
|
||||
const { user, authToken } = useSelector((state) => state.auth);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [monitors, setMonitors] = useState([]);
|
||||
|
||||
@@ -23,11 +23,13 @@ import { networkService } from "../../main";
|
||||
import { settingsValidation } from "../../Validation/validation";
|
||||
import { useNavigate } from "react-router";
|
||||
import Dialog from "../../Components/Dialog";
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
|
||||
const SECONDS_PER_DAY = 86400;
|
||||
|
||||
const Settings = ({ isAdmin }) => {
|
||||
const Settings = () => {
|
||||
const theme = useTheme();
|
||||
const isAdmin = useIsAdmin();
|
||||
const { user, authToken } = useSelector((state) => state.auth);
|
||||
const { checkTTL } = user;
|
||||
const { isLoading } = useSelector((state) => state.uptimeMonitors);
|
||||
|
||||
@@ -32,14 +32,16 @@ import SkeletonLayout from "./skeleton";
|
||||
import "./index.css";
|
||||
import useUtils from "../utils";
|
||||
import { formatDateWithTz } from "../../../Utils/timeUtils";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
|
||||
/**
|
||||
* Details page component displaying monitor details and related information.
|
||||
* @component
|
||||
*/
|
||||
const DetailsPage = ({ isAdmin }) => {
|
||||
const DetailsPage = () => {
|
||||
const theme = useTheme();
|
||||
const { statusColor, statusStyles, statusMsg, determineState } = useUtils();
|
||||
const isAdmin = useIsAdmin();
|
||||
const [monitor, setMonitor] = useState({});
|
||||
const { monitorId } = useParams();
|
||||
const { authToken } = useSelector((state) => state.auth);
|
||||
|
||||
@@ -12,12 +12,14 @@ import StatusBox from "./StatusBox";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import Greeting from "../../../Utils/greeting";
|
||||
import { CurrentMonitoring } from "./CurrentMonitoring";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
|
||||
const BREADCRUMBS = [{ name: `Uptime`, path: "/uptime" }];
|
||||
|
||||
const UptimeMonitors = ({ isAdmin }) => {
|
||||
const UptimeMonitors = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const isAdmin = useIsAdmin();
|
||||
const uptimeMonitorsState = useSelector((state) => state.uptimeMonitors);
|
||||
const authState = useSelector((state) => state.auth);
|
||||
const dispatch = useDispatch({});
|
||||
|
||||
176
Client/src/Routes/index.jsx
Normal file
176
Client/src/Routes/index.jsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import { Navigate, Route, Routes as LibRoutes } from "react-router";
|
||||
import HomeLayout from "../Components/Layouts/HomeLayout";
|
||||
import { Infrastructure } from "../Pages/Infrastructure";
|
||||
import InfrastructureDetails from "../Pages/Infrastructure/Details";
|
||||
import NotFound from "../Pages/NotFound";
|
||||
import Login from "../Pages/Auth/Login";
|
||||
import Register from "../Pages/Auth/Register/Register";
|
||||
import Account from "../Pages/Account";
|
||||
import Monitors from "../Pages/Uptime/Home";
|
||||
import CreateMonitor from "../Pages/Uptime/CreateUptime";
|
||||
import CreateInfrastructureMonitor from "../Pages/Infrastructure/CreateMonitor";
|
||||
import Incidents from "../Pages/Incidents";
|
||||
import Status from "../Pages/Status";
|
||||
import Integrations from "../Pages/Integrations";
|
||||
import Settings from "../Pages/Settings";
|
||||
import ForgotPassword from "../Pages/Auth/ForgotPassword";
|
||||
import CheckEmail from "../Pages/Auth/CheckEmail";
|
||||
import SetNewPassword from "../Pages/Auth/SetNewPassword";
|
||||
import NewPasswordConfirmed from "../Pages/Auth/NewPasswordConfirmed";
|
||||
import ProtectedRoute from "../Components/ProtectedRoute";
|
||||
import Details from "../Pages/Uptime/Details";
|
||||
import AdvancedSettings from "../Pages/AdvancedSettings";
|
||||
import Maintenance from "../Pages/Maintenance";
|
||||
import Configure from "../Pages/Uptime/Configure";
|
||||
import PageSpeed from "../Pages/PageSpeed";
|
||||
import CreatePageSpeed from "../Pages/PageSpeed/CreatePageSpeed";
|
||||
import CreateNewMaintenanceWindow from "../Pages/Maintenance/CreateMaintenance";
|
||||
import PageSpeedDetails from "../Pages/PageSpeed/Details";
|
||||
import PageSpeedConfigure from "../Pages/PageSpeed/Configure";
|
||||
import withAdminCheck from "../Components/HOC/withAdminCheck";
|
||||
|
||||
const Routes = () => {
|
||||
const AdminCheckedRegister = withAdminCheck(Register);
|
||||
return (
|
||||
<LibRoutes>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<HomeLayout />
|
||||
</ProtectedRoute>
|
||||
}
|
||||
>
|
||||
<Route
|
||||
path="/"
|
||||
element={<Navigate to="/uptime" />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime"
|
||||
element={<Monitors />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime/create/:monitorId?"
|
||||
element={<CreateMonitor />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime/:monitorId/"
|
||||
element={<Details />}
|
||||
/>
|
||||
<Route
|
||||
path="/uptime/configure/:monitorId/"
|
||||
element={<Configure />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed"
|
||||
element={<PageSpeed />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed/create"
|
||||
element={<CreatePageSpeed />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed/:monitorId"
|
||||
element={<PageSpeedDetails />}
|
||||
/>
|
||||
<Route
|
||||
path="pagespeed/configure/:monitorId"
|
||||
element={<PageSpeedConfigure />}
|
||||
/>
|
||||
<Route
|
||||
path="infrastructure"
|
||||
element={<Infrastructure />}
|
||||
/>
|
||||
<Route
|
||||
path="infrastructure/create"
|
||||
element={<CreateInfrastructureMonitor />}
|
||||
/>
|
||||
<Route
|
||||
path="infrastructure/:monitorId"
|
||||
element={<InfrastructureDetails />}
|
||||
/>
|
||||
<Route
|
||||
path="incidents/:monitorId?"
|
||||
element={<Incidents />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="status"
|
||||
element={<Status />}
|
||||
/>
|
||||
<Route
|
||||
path="integrations"
|
||||
element={<Integrations />}
|
||||
/>
|
||||
<Route
|
||||
path="maintenance"
|
||||
element={<Maintenance />}
|
||||
/>
|
||||
<Route
|
||||
path="/maintenance/create/:maintenanceWindowId?"
|
||||
element={<CreateNewMaintenanceWindow />}
|
||||
/>
|
||||
<Route
|
||||
path="settings"
|
||||
element={<Settings />}
|
||||
/>
|
||||
<Route
|
||||
path="advanced-settings"
|
||||
element={<AdvancedSettings />}
|
||||
/>
|
||||
<Route
|
||||
path="account/profile"
|
||||
element={<Account open={"profile"} />}
|
||||
/>
|
||||
<Route
|
||||
path="account/password"
|
||||
element={<Account open={"password"} />}
|
||||
/>
|
||||
<Route
|
||||
path="account/team"
|
||||
element={<Account open={"team"} />}
|
||||
/>
|
||||
</Route>
|
||||
|
||||
<Route
|
||||
path="/login"
|
||||
element={<Login />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/register"
|
||||
element={<AdminCheckedRegister />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path="/register/:token"
|
||||
element={<Register />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/forgot-password"
|
||||
element={<ForgotPassword />}
|
||||
/>
|
||||
<Route
|
||||
path="/check-email"
|
||||
element={<CheckEmail />}
|
||||
/>
|
||||
<Route
|
||||
path="/set-new-password/:token"
|
||||
element={<SetNewPassword />}
|
||||
/>
|
||||
<Route
|
||||
path="/new-password-confirmed"
|
||||
element={<NewPasswordConfirmed />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="*"
|
||||
element={<NotFound />}
|
||||
/>
|
||||
</LibRoutes>
|
||||
);
|
||||
};
|
||||
|
||||
export { Routes };
|
||||
27
README.md
27
README.md
@@ -1,4 +1,9 @@
|
||||
**Need support or have a suggestion? Check our [Discord channel](https://discord.gg/NAb6H3UTjK)**
|
||||
**Need support or have a suggestion? Check our [Discord channel](https://discord.gg/NAb6H3UTjK) or [Discussions](https://github.com/bluewave-labs/checkmate/discussions) forum.**
|
||||
|
||||
**Checkmate is on [GitHub trending](https://github.com/trending) and #1 trending for JavaScript apps on Fri Dec 13!**
|
||||
|
||||

|
||||
|
||||
|
||||

|
||||

|
||||
@@ -16,7 +21,9 @@
|
||||
|
||||
Checkmate is an open source uptime manager, server & Docker monitoring tool used to track the operational status and performance of servers and websites. It regularly checks whether a server/website is accessible and performs optimally, providing real-time alerts and reports on the monitored services' availability, downtime, and response time.
|
||||
|
||||
Checkmate also has an agent, called [Capture](https://github.com/bluewave-labs/capture), to retrieve data from remote servers. While Capture is not required to run Checkmate, it provides additional insigths about your servers' CPU, RAM, disk and temperature status.
|
||||
Checkmate also has an agent, called [Capture](https://github.com/bluewave-labs/capture), to retrieve data from remote servers. While Capture is not required to run Checkmate, it provides additional insigths about your servers' CPU, RAM, disk and temperature status.
|
||||
|
||||
We've run stress tests with 1000+ active monitors without any particular issues or performance bottlenecks.
|
||||
|
||||
We **love** what we are building here, and learn a few things about Reactjs, Nodejs, MongoDB and Docker while building Checkmate. **If you would like to support us, please consider giving it a ⭐, think about contributing or providing feedback.** Please note that we do not operate a monetary donation program, make money by deploying servers, or run a SaaS business.
|
||||
|
||||
@@ -30,7 +37,7 @@ Usage instructions can be found [here](https://bluewavelabs.gitbook.io/checkmate
|
||||
|
||||
## 🛠️ Installation
|
||||
|
||||
See installation instructions in [Checkmate documentation portal](https://bluewavelabs.gitbook.io/checkmate/quickstart).
|
||||
See installation instructions in [Checkmate documentation portal](https://bluewavelabs.gitbook.io/checkmate/quickstart). Alternatively, you can also use [Coolify](https://coolify.io/) for a one click Docker deployment.
|
||||
|
||||
## 💚 Questions & ideas
|
||||
|
||||
@@ -48,6 +55,7 @@ If you have any questions, suggestions or comments, please use our [Discord chan
|
||||
- Incidents at a glance
|
||||
- E-mail notifications
|
||||
- Scheduled maintenance
|
||||
- Can monitor 1000+ servers at the same time on a moderate server
|
||||
|
||||
**Short term roadmap:**
|
||||
|
||||
@@ -74,16 +82,17 @@ If you have any questions, suggestions or comments, please use our [Discord chan
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
We pride ourselves on building strong connections with contributors at every level. Despite being a young project, Checkmate has already earned 1500 stars and attracted 35+ contributors from around the globe. So, don’t hold back — jump in, contribute and learn with us!
|
||||
We pride ourselves on building strong connections with contributors at every level. Despite being a young project, Checkmate has already earned 1900 stars and attracted 35+ contributors from around the globe. So, don’t hold back — jump in, contribute and learn with us!
|
||||
|
||||
Here's how you can contribute:
|
||||
|
||||
0. Star this repo :)
|
||||
1. Check [Contributor's guideline](https://github.com/bluewave-labs/bluewave-uptime/blob/master/CONTRIBUTING.md).
|
||||
2. Have a look at our Figma designs [here](https://www.figma.com/design/RPSfaw66HjzSwzntKcgDUV/Uptime-Genie?node-id=0-1&t=WqOFv9jqNTFGItpL-1). We encourage you to copy to your own Figma page, then work on it as it is read-only.
|
||||
3. Open an issue if you believe you've encountered a bug
|
||||
4. Check for good-first-issue's if you are a newcomer
|
||||
5. Make a pull request to add new features/make quality-of-life improvements/fix bugs.
|
||||
1. Check [Contributor's guideline](https://github.com/bluewave-labs/bluewave-uptime/blob/master/CONTRIBUTING.md). First timers are encouraged to check `good-first-issue` tag.
|
||||
2. Optionally, read [project structure](https://bluewavelabs.gitbook.io/checkmate/developers-guide/general-project-structure) and [high level overview](https://bluewavelabs.gitbook.io/checkmate/developers-guide/high-level-overview).
|
||||
3. Have a look at our Figma designs [here](https://www.figma.com/design/RPSfaw66HjzSwzntKcgDUV/Uptime-Genie?node-id=0-1&t=WqOFv9jqNTFGItpL-1) if you are going to use one of our designs. We encourage you to copy to your own Figma page, then work on it as it is read-only.
|
||||
4. Open an issue if you believe you've encountered a bug.
|
||||
5. Check for good-first-issue's if you are a newcomer.
|
||||
6. Make a pull request to add new features/make quality-of-life improvements/fix bugs.
|
||||
|
||||
<a href="https://github.com/bluewave-labs/bluewave-uptime/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=bluewave-labs/bluewave-uptime" />
|
||||
|
||||
68
Server/package-lock.json
generated
68
Server/package-lock.json
generated
@@ -11,7 +11,7 @@
|
||||
"dependencies": {
|
||||
"axios": "^1.7.2",
|
||||
"bcrypt": "^5.1.1",
|
||||
"bullmq": "5.34.0",
|
||||
"bullmq": "5.34.2",
|
||||
"cors": "^2.8.5",
|
||||
"dockerode": "4.0.2",
|
||||
"dotenv": "^16.4.5",
|
||||
@@ -36,7 +36,7 @@
|
||||
"chai": "5.1.2",
|
||||
"esm": "3.2.25",
|
||||
"mocha": "11.0.1",
|
||||
"nodemon": "3.1.7",
|
||||
"nodemon": "3.1.9",
|
||||
"prettier": "^3.3.3",
|
||||
"sinon": "19.0.2"
|
||||
}
|
||||
@@ -660,9 +660,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mongodb-js/saslprep": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz",
|
||||
"integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==",
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
|
||||
"integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
@@ -1169,9 +1170,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bson": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz",
|
||||
"integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==",
|
||||
"version": "6.10.1",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz",
|
||||
"integrity": "sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.20.1"
|
||||
}
|
||||
@@ -1221,9 +1223,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bullmq": {
|
||||
"version": "5.34.0",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.34.0.tgz",
|
||||
"integrity": "sha512-TyzeYDkIGkooYUn/P1CeiJW3Am1TboC3unwhlg1cJIwKksoyuRp97TkHyCZcwLchXbYCUtsGBZFUYf/lTAhdSg==",
|
||||
"version": "5.34.2",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.34.2.tgz",
|
||||
"integrity": "sha512-eUzeCswrKbQDE1WY8h4ZTBtynOzCU5qx9felFdYOmIJrsy0warDahHKUiCZ6dUCs6ZxYMGtcaciIMcAf1L54yw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cron-parser": "^4.6.0",
|
||||
@@ -3641,7 +3643,8 @@
|
||||
"node_modules/memory-pager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="
|
||||
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mensch": {
|
||||
"version": "0.3.4",
|
||||
@@ -4431,13 +4434,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mongodb": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz",
|
||||
"integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==",
|
||||
"version": "6.12.0",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.12.0.tgz",
|
||||
"integrity": "sha512-RM7AHlvYfS7jv7+BXund/kR64DryVI+cHbVAy9P61fnb1RcWZqOW1/Wj2YhqMCx+MuYhqTRGv7AwHBzmsCKBfA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@mongodb-js/saslprep": "^1.1.5",
|
||||
"bson": "^6.7.0",
|
||||
"@mongodb-js/saslprep": "^1.1.9",
|
||||
"bson": "^6.10.1",
|
||||
"mongodb-connection-string-url": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -4445,7 +4448,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@aws-sdk/credential-providers": "^3.188.0",
|
||||
"@mongodb-js/zstd": "^1.1.0",
|
||||
"@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
|
||||
"gcp-metadata": "^5.2.0",
|
||||
"kerberos": "^2.0.1",
|
||||
"mongodb-client-encryption": ">=6.0.0 <7",
|
||||
@@ -4486,14 +4489,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mongoose": {
|
||||
"version": "8.8.4",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.4.tgz",
|
||||
"integrity": "sha512-yJbn695qCsqDO+xyPII29x2R7flzXhxCDv09mMZPSGllf0sm4jKw3E9s9uvQ9hjO6bL2xjU8KKowYqcY9eSTMQ==",
|
||||
"version": "8.9.0",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.0.tgz",
|
||||
"integrity": "sha512-b58zY3PLNBcoz6ZXFckr0leJcVVBMAOBvD+7Bj2ZjghAwntXmNnqwlDixTKQU3UYoQIGTv+AQx/0ThsvaeVrCA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bson": "^6.7.0",
|
||||
"bson": "^6.10.1",
|
||||
"kareem": "2.6.3",
|
||||
"mongodb": "~6.10.0",
|
||||
"mongodb": "~6.12.0",
|
||||
"mpath": "0.9.0",
|
||||
"mquery": "5.0.0",
|
||||
"ms": "2.1.3",
|
||||
@@ -4627,9 +4630,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -4758,9 +4761,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/nodemon": {
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz",
|
||||
"integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==",
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
|
||||
"integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -4787,9 +4790,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/nodemon/node_modules/debug": {
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -6175,6 +6178,7 @@
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||
"integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"dependencies": {
|
||||
"axios": "^1.7.2",
|
||||
"bcrypt": "^5.1.1",
|
||||
"bullmq": "5.34.0",
|
||||
"bullmq": "5.34.2",
|
||||
"cors": "^2.8.5",
|
||||
"dockerode": "4.0.2",
|
||||
"dotenv": "^16.4.5",
|
||||
@@ -39,7 +39,7 @@
|
||||
"chai": "5.1.2",
|
||||
"esm": "3.2.25",
|
||||
"mocha": "11.0.1",
|
||||
"nodemon": "3.1.7",
|
||||
"nodemon": "3.1.9",
|
||||
"prettier": "^3.3.3",
|
||||
"sinon": "19.0.2"
|
||||
}
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended"
|
||||
]
|
||||
],
|
||||
"labels": ["dependencies"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user