Resolve conflicts
This commit is contained in:
commit
ee82a20b4d
22 files changed
+1610
-1349
No files matched your search
+1
-1
@@ -71,7 +71,7 @@ function App() {
|
||||
element={<ProtectedRoute Component={Configure} />}
|
||||
/>
|
||||
<Route
|
||||
path="incidents"
|
||||
path="incidents/:monitorId?"
|
||||
element={<ProtectedRoute Component={Incidents} />}
|
||||
/>
|
||||
|
||||
|
||||
@@ -164,6 +164,44 @@ export const deleteMonitorChecksByTeamId = createAsyncThunk(
|
||||
}
|
||||
}
|
||||
);
|
||||
export const addDemoMonitors = createAsyncThunk(
|
||||
"monitors/addDemoMonitors",
|
||||
async (data, thunkApi) => {
|
||||
try {
|
||||
const { authToken } = data;
|
||||
const res = await networkService.addDemoMonitors(authToken);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
if (error.response && error.response.data) {
|
||||
return thunkApi.rejectWithValue(error.response.data);
|
||||
}
|
||||
const payload = {
|
||||
status: false,
|
||||
msg: error.message ? error.message : "Unknown error",
|
||||
};
|
||||
return thunkApi.rejectWithValue(payload);
|
||||
}
|
||||
}
|
||||
);
|
||||
export const deleteAllMonitors = createAsyncThunk(
|
||||
"monitors/deleteAllMonitors",
|
||||
async (data, thunkApi) => {
|
||||
try {
|
||||
const { authToken } = data;
|
||||
const res = await networkService.deleteAllMonitors(authToken);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
if (error.response && error.response.data) {
|
||||
return thunkApi.rejectWithValue(error.response.data);
|
||||
}
|
||||
const payload = {
|
||||
status: false,
|
||||
msg: error.message ? error.message : "Unknown error",
|
||||
};
|
||||
return thunkApi.rejectWithValue(payload);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const uptimeMonitorsSlice = createSlice({
|
||||
name: "uptimeMonitors",
|
||||
@@ -306,6 +344,42 @@ const uptimeMonitorsSlice = createSlice({
|
||||
state.msg = action.payload
|
||||
? action.payload.msg
|
||||
: "Failed to pause uptime monitor";
|
||||
})
|
||||
// *****************************************************
|
||||
// Add Demo Monitors
|
||||
// *****************************************************
|
||||
.addCase(addDemoMonitors.pending, (state) => {
|
||||
state.isLoading = true;
|
||||
})
|
||||
.addCase(addDemoMonitors.fulfilled, (state, action) => {
|
||||
state.isLoading = false;
|
||||
state.success = action.payload.success;
|
||||
state.msg = action.payload.msg;
|
||||
})
|
||||
.addCase(addDemoMonitors.rejected, (state, action) => {
|
||||
state.isLoading = false;
|
||||
state.success = false;
|
||||
state.msg = action.payload
|
||||
? action.payload.msg
|
||||
: "Failed to add demo uptime monitors";
|
||||
})
|
||||
// *****************************************************
|
||||
// Delete all Monitors
|
||||
// *****************************************************
|
||||
.addCase(deleteAllMonitors.pending, (state) => {
|
||||
state.isLoading = true;
|
||||
})
|
||||
.addCase(deleteAllMonitors.fulfilled, (state, action) => {
|
||||
state.isLoading = false;
|
||||
state.success = action.payload.success;
|
||||
state.msg = action.payload.msg;
|
||||
})
|
||||
.addCase(deleteAllMonitors.rejected, (state, action) => {
|
||||
state.isLoading = false;
|
||||
state.success = false;
|
||||
state.msg = action.payload
|
||||
? action.payload.msg
|
||||
: "Failed to delete all monitors";
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { ButtonGroup, Stack, Typography, Button } from "@mui/material";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import { networkService } from "../../main";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import Select from "../../Components/Inputs/Select";
|
||||
@@ -11,6 +13,7 @@ import SkeletonLayout from "./skeleton";
|
||||
const Incidents = () => {
|
||||
const theme = useTheme();
|
||||
const authState = useSelector((state) => state.auth);
|
||||
const { monitorId } = useParams();
|
||||
|
||||
const [monitors, setMonitors] = useState({});
|
||||
const [selectedMonitor, setSelectedMonitor] = useState("0");
|
||||
@@ -40,6 +43,7 @@ const Incidents = () => {
|
||||
return acc;
|
||||
}, {});
|
||||
setMonitors(monitorLookup);
|
||||
monitorId !== undefined && setSelectedMonitor(monitorId);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
@@ -125,7 +125,14 @@ const ActionsMenu = ({ monitor, isAdmin, updateCallback }) => {
|
||||
Details
|
||||
</MenuItem>
|
||||
{/* TODO - pass monitor id to Incidents page */}
|
||||
<MenuItem disabled>Incidents</MenuItem>
|
||||
<MenuItem
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
navigate(`/incidents/${actions.id}`);
|
||||
}}
|
||||
>
|
||||
Incidents
|
||||
</MenuItem>
|
||||
{isAdmin && (
|
||||
<MenuItem
|
||||
onClick={(e) => {
|
||||
@@ -137,14 +144,16 @@ const ActionsMenu = ({ monitor, isAdmin, updateCallback }) => {
|
||||
Configure
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
navigate(`/monitors/create/${actions.id}`);
|
||||
}}
|
||||
>
|
||||
Clone
|
||||
</MenuItem>
|
||||
{isAdmin && (
|
||||
<MenuItem
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
navigate(`/monitors/create/${actions.id}`);
|
||||
}}
|
||||
>
|
||||
Clone
|
||||
</MenuItem>
|
||||
)}
|
||||
{isAdmin && (
|
||||
<MenuItem
|
||||
onClick={(e) => {
|
||||
|
||||
@@ -20,6 +20,12 @@ const useUtils = () => {
|
||||
down: "Your site is down.",
|
||||
paused: "Pending...",
|
||||
};
|
||||
|
||||
const pagespeedStatusMsg = {
|
||||
up: "Live (collecting data)",
|
||||
down: "Inactive",
|
||||
paused: "Paused",
|
||||
};
|
||||
const statusStyles = {
|
||||
up: {
|
||||
backgroundColor: theme.palette.success.bg,
|
||||
@@ -51,6 +57,7 @@ const useUtils = () => {
|
||||
determineState,
|
||||
statusColor,
|
||||
statusMsg,
|
||||
pagespeedStatusMsg,
|
||||
statusStyles,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import PlayCircleOutlineRoundedIcon from "@mui/icons-material/PlayCircleOutlineRounded";
|
||||
import SkeletonLayout from "./skeleton";
|
||||
import "./index.css";
|
||||
import useUtils from "../../Monitors/utils";
|
||||
|
||||
const PageSpeedConfigure = () => {
|
||||
const theme = useTheme();
|
||||
@@ -34,6 +35,7 @@ const PageSpeedConfigure = () => {
|
||||
const { monitorId } = useParams();
|
||||
const [monitor, setMonitor] = useState({});
|
||||
const [errors, setErrors] = useState({});
|
||||
const { determineState, statusColor } = useUtils();
|
||||
|
||||
const frequencies = [
|
||||
{ _id: 3, name: "3 minutes" },
|
||||
@@ -147,13 +149,7 @@ const PageSpeedConfigure = () => {
|
||||
gap={theme.spacing(12)}
|
||||
>
|
||||
<Stack direction="row" gap={theme.spacing(2)}>
|
||||
<PulseDot
|
||||
color={
|
||||
monitor?.status
|
||||
? theme.palette.success.main
|
||||
: theme.palette.error.main
|
||||
}
|
||||
/>
|
||||
<PulseDot color={statusColor[determineState(monitor)]} />
|
||||
<Box>
|
||||
<Typography
|
||||
component="h1"
|
||||
@@ -166,12 +162,10 @@ const PageSpeedConfigure = () => {
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{
|
||||
color: monitor?.status
|
||||
? theme.palette.success.main
|
||||
: theme.palette.error.text,
|
||||
color: statusColor[determineState(monitor)],
|
||||
}}
|
||||
>
|
||||
Your pagespeed monitor is {monitor?.status ? "live" : "down"}.
|
||||
Your pagespeed monitor is {determineState(monitor)}.
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box alignSelf="flex-end" ml="auto">
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useDrawingArea } from "@mui/x-charts";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
@@ -39,6 +38,7 @@ const PageSpeedDetails = () => {
|
||||
const [audits, setAudits] = useState({});
|
||||
const { monitorId } = useParams();
|
||||
const { authToken } = useSelector((state) => state.auth);
|
||||
const { determineState, statusColor, pagespeedStatusMsg } = useUtils();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchMonitor = async () => {
|
||||
|
||||
@@ -5,12 +5,14 @@ import { StatusLabel } from "../../Components/Label";
|
||||
import { Box, Grid, Stack, Typography } from "@mui/material";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import useUtils from "../Monitors/utils";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const Card = ({ data }) => {
|
||||
const Card = ({ monitor }) => {
|
||||
const { determineState, pagespeedStatusMsg } = useUtils();
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const monitorState = determineState(monitor);
|
||||
return (
|
||||
<Grid
|
||||
item
|
||||
@@ -26,7 +28,7 @@ const Card = ({ data }) => {
|
||||
direction="row"
|
||||
gap={theme.spacing(6)}
|
||||
p={theme.spacing(8)}
|
||||
onClick={() => navigate(`/pagespeed/${data._id}`)}
|
||||
onClick={() => navigate(`/pagespeed/${monitor._id}`)}
|
||||
border={1}
|
||||
borderColor={theme.palette.border.light}
|
||||
borderRadius={theme.shape.borderRadius}
|
||||
@@ -46,23 +48,24 @@ const Card = ({ data }) => {
|
||||
mb={theme.spacing(2)}
|
||||
color={theme.palette.primary.main}
|
||||
>
|
||||
{data.name}
|
||||
{monitor.name}
|
||||
</Typography>
|
||||
<StatusLabel
|
||||
status={data.status ? "up" : "cannot resolve"}
|
||||
text={data.status ? "Live (collecting data)" : "Inactive"}
|
||||
status={monitorState}
|
||||
text={pagespeedStatusMsg[monitorState] || "Pending..."}
|
||||
customStyles={{ textTransform: "capitalize" }}
|
||||
/>
|
||||
</Stack>
|
||||
<Typography fontSize={13}>
|
||||
{data.url.replace(/^https?:\/\//, "")}
|
||||
{monitor.url.replace(/^https?:\/\//, "")}
|
||||
</Typography>
|
||||
<Typography mt={theme.spacing(12)}>
|
||||
<Typography component="span" fontWeight={600}>
|
||||
Last checked:{" "}
|
||||
</Typography>
|
||||
{formatDate(getLastChecked(data.checks, false))}{" "}
|
||||
{formatDate(getLastChecked(monitor.checks, false))}{" "}
|
||||
<Typography component="span" fontStyle="italic">
|
||||
({formatDurationRounded(getLastChecked(data.checks))} ago)
|
||||
({formatDurationRounded(getLastChecked(monitor.checks))} ago)
|
||||
</Typography>
|
||||
</Typography>
|
||||
</Box>
|
||||
@@ -72,7 +75,7 @@ const Card = ({ data }) => {
|
||||
};
|
||||
|
||||
Card.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
monitor: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default Card;
|
||||
@@ -74,7 +74,7 @@ const PageSpeed = ({ isAdmin }) => {
|
||||
</Box>
|
||||
<Grid container spacing={theme.spacing(12)}>
|
||||
{monitorsSummary?.monitors?.map((monitor) => (
|
||||
<Card data={monitor} key={monitor._id} />
|
||||
<Card monitor={monitor} key={monitor._id} />
|
||||
))}
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Box, Button, Stack, styled, Typography } from "@mui/material";
|
||||
import { Box, Stack, styled, Typography } from "@mui/material";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
import Link from "../../Components/Link";
|
||||
import Select from "../../Components/Inputs/Select";
|
||||
@@ -7,7 +7,11 @@ import { logger } from "../../Utils/Logger";
|
||||
import "./index.css";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { createToast } from "../../Utils/toastUtils";
|
||||
import { deleteMonitorChecksByTeamId } from "../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
||||
import {
|
||||
deleteMonitorChecksByTeamId,
|
||||
addDemoMonitors,
|
||||
deleteAllMonitors,
|
||||
} from "../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
||||
import PropTypes from "prop-types";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
const Settings = ({ isAdmin }) => {
|
||||
@@ -36,6 +40,34 @@ const Settings = ({ isAdmin }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleInsertDemoMonitors = async () => {
|
||||
try {
|
||||
const action = await dispatch(addDemoMonitors({ authToken }));
|
||||
if (addDemoMonitors.fulfilled.match(action)) {
|
||||
createToast({ body: "Successfully added demo monitors" });
|
||||
} else {
|
||||
createToast({ body: "Failed to add demo monitors" });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
createToast({ Body: "Failed to add demo monitors" });
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteAllMonitors = async () => {
|
||||
try {
|
||||
const action = await dispatch(deleteAllMonitors({ authToken }));
|
||||
if (deleteAllMonitors.fulfilled.match(action)) {
|
||||
createToast({ body: "Successfully deleted all monitors" });
|
||||
} else {
|
||||
createToast({ body: "Failed to add demo monitors" });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
createToast({ Body: "Failed to delete all monitors" });
|
||||
}
|
||||
};
|
||||
|
||||
const ConfigBox = styled("div")({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
@@ -140,6 +172,42 @@ const Settings = ({ isAdmin }) => {
|
||||
</Stack>
|
||||
</ConfigBox>
|
||||
)}
|
||||
{isAdmin && (
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h1">Demo Monitors</Typography>
|
||||
<Typography sx={{ mt: theme.spacing(2) }}>
|
||||
Here you can add and remove demo monitors
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(20)}>
|
||||
<Box>
|
||||
<Typography>Add demo monitors</Typography>
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
loading={isLoading}
|
||||
onClick={handleInsertDemoMonitors}
|
||||
sx={{ mt: theme.spacing(4) }}
|
||||
>
|
||||
Add demo monitors
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography>Remove all monitors</Typography>
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
color="error"
|
||||
loading={isLoading}
|
||||
onClick={handleDeleteAllMonitors}
|
||||
sx={{ mt: theme.spacing(4) }}
|
||||
>
|
||||
Remove all monitors
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
</Stack>
|
||||
</ConfigBox>
|
||||
)}
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h1">About</Typography>
|
||||
|
||||
@@ -274,6 +274,46 @@ class NetworkService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************
|
||||
* Adds demo monitors
|
||||
* ************************************
|
||||
*
|
||||
* @async
|
||||
* @param {string} authToken - The authorization token to be used in the request header.
|
||||
* @returns {Promise<AxiosResponse>} The response from the axios POST request.
|
||||
*/
|
||||
async addDemoMonitors(authToken) {
|
||||
return this.axiosInstance.post(
|
||||
`/monitors/demo`,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************
|
||||
* Deletes all monitors for a team by team ID
|
||||
* ************************************
|
||||
*
|
||||
* @async
|
||||
* @param {string} authToken - The authorization token to be used in the request header.
|
||||
* @returns {Promise<AxiosResponse>} The response from the axios DELETE request.
|
||||
*/
|
||||
async deleteAllMonitors(authToken) {
|
||||
return this.axiosInstance.delete(`/monitors/`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************
|
||||
* Gets the certificate expiry for a monitor
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -17,6 +17,7 @@ require("dotenv").config();
|
||||
const { errorMessages, successMessages } = require("../utils/messages");
|
||||
var jwt = require("jsonwebtoken");
|
||||
const SERVICE_NAME = "auth";
|
||||
const { getTokenFromHeaders } = require("../utils/utils");
|
||||
|
||||
/**
|
||||
* Creates and returns JWT token with an arbitrary payload
|
||||
@@ -30,17 +31,6 @@ const issueToken = (payload) => {
|
||||
return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: tokenTTL });
|
||||
};
|
||||
|
||||
const getTokenFromHeaders = (headers) => {
|
||||
const authorizationHeader = headers.authorization;
|
||||
if (!authorizationHeader) throw new Error("No auth headers");
|
||||
|
||||
const parts = authorizationHeader.split(" ");
|
||||
if (parts.length !== 2 || parts[0] !== "Bearer")
|
||||
throw new Error("Invalid auth headers");
|
||||
|
||||
return parts[1];
|
||||
};
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @param {express.Request} req
|
||||
|
||||
@@ -18,6 +18,9 @@ const {
|
||||
const sslChecker = require("ssl-checker");
|
||||
const SERVICE_NAME = "monitorController";
|
||||
const { errorMessages, successMessages } = require("../utils/messages");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const { getTokenFromHeaders } = require("../utils/utils");
|
||||
|
||||
/**
|
||||
* Returns all monitors
|
||||
* @async
|
||||
@@ -365,12 +368,24 @@ const deleteMonitor = async (req, res, next) => {
|
||||
|
||||
const deleteAllMonitors = async (req, res) => {
|
||||
try {
|
||||
const deleteCount = await req.db.deleteAllMonitors();
|
||||
console.log("WTF");
|
||||
const token = getTokenFromHeaders(req.headers);
|
||||
const { teamId } = jwt.verify(token, process.env.JWT_SECRET);
|
||||
const { monitors, deletedCount } = await req.db.deleteAllMonitors(teamId);
|
||||
await monitors.forEach(async (monitor) => {
|
||||
await req.jobQueue.deleteJob(monitor);
|
||||
await req.db.deleteChecks(monitor._id);
|
||||
await req.db.deleteAlertByMonitorId(monitor._id);
|
||||
await req.db.deletePageSpeedChecksByMonitorId(monitor._id);
|
||||
await req.db.deleteNotificationsByMonitorId(monitor._id);
|
||||
});
|
||||
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: `Deleted ${deleteCount} monitors` });
|
||||
.json({ success: true, msg: `Deleted ${deletedCount} monitors` });
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method === undefined && error.method === "deleteAllMonitors";
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
@@ -466,6 +481,26 @@ const pauseMonitor = async (req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
const addDemoMonitors = async (req, res, next) => {
|
||||
try {
|
||||
const token = getTokenFromHeaders(req.headers);
|
||||
const { _id, teamId } = jwt.verify(token, process.env.JWT_SECRET);
|
||||
const demoMonitors = await req.db.addDemoMonitors(_id, teamId);
|
||||
await demoMonitors.forEach(async (monitor) => {
|
||||
await req.jobQueue.addJob(monitor._id, monitor);
|
||||
});
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: successMessages.MONITOR_DEMO_ADDED,
|
||||
data: demoMonitors.length,
|
||||
});
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method === undefined && error.method === "addDemoMonitors";
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getAllMonitors,
|
||||
getMonitorAggregateStats,
|
||||
@@ -479,4 +514,5 @@ module.exports = {
|
||||
deleteAllMonitors,
|
||||
editMonitor,
|
||||
pauseMonitor,
|
||||
addDemoMonitors,
|
||||
};
|
||||
@@ -73,6 +73,7 @@ const {
|
||||
deleteAllMonitors,
|
||||
deleteMonitorsByUserId,
|
||||
editMonitor,
|
||||
addDemoMonitors,
|
||||
} = require("./modules/monitorModule");
|
||||
|
||||
//****************************************
|
||||
@@ -153,6 +154,7 @@ module.exports = {
|
||||
deleteMonitor,
|
||||
deleteAllMonitors,
|
||||
editMonitor,
|
||||
addDemoMonitors,
|
||||
createCheck,
|
||||
getChecksCount,
|
||||
getChecks,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const Check = require("../../../models/Check");
|
||||
const Monitor = require("../../../models/Monitor");
|
||||
const mongoose = require("mongoose");
|
||||
const logger = require("../../../utils/logger");
|
||||
const SERVICE_NAME = "checkModule";
|
||||
const dateRangeLookup = {
|
||||
day: new Date(new Date().setDate(new Date().getDate() - 1)),
|
||||
week: new Date(new Date().setDate(new Date().getDate() - 7)),
|
||||
@@ -24,21 +25,25 @@ const createCheck = async (checkData) => {
|
||||
try {
|
||||
const { monitorId, status } = checkData;
|
||||
|
||||
const n = await Check.countDocuments({ monitorId }) + 1;
|
||||
const n = (await Check.countDocuments({ monitorId })) + 1;
|
||||
|
||||
const check = await new Check({ ...checkData }).save();
|
||||
|
||||
const monitor = await Monitor.findById(monitorId);
|
||||
|
||||
if (!monitor) {
|
||||
throw new Error("Monitor not found");
|
||||
logger.error("Monitor not found", {
|
||||
service: SERVICE_NAME,
|
||||
monitorId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (monitor.uptimePercentage === undefined) {
|
||||
monitor.uptimePercentage = (status === true) ? 1 : 0;
|
||||
monitor.uptimePercentage = status === true ? 1 : 0;
|
||||
} else {
|
||||
monitor.uptimePercentage =
|
||||
(monitor.uptimePercentage * (n - 1) + (status === true ? 1: 0)) / n;
|
||||
(monitor.uptimePercentage * (n - 1) + (status === true ? 1 : 0)) / n;
|
||||
}
|
||||
|
||||
await monitor.save();
|
||||
|
||||
@@ -4,6 +4,7 @@ const PageSpeedCheck = require("../../../models/PageSpeedCheck");
|
||||
const { errorMessages } = require("../../../utils/messages");
|
||||
const Notification = require("../../../models/Notification");
|
||||
const { NormalizeData } = require("../../../utils/dataUtils");
|
||||
const demoMonitors = require("../../../utils/demoMonitors.json");
|
||||
|
||||
/**
|
||||
* Get all monitors
|
||||
@@ -450,10 +451,12 @@ const deleteMonitor = async (req, res) => {
|
||||
* DELETE ALL MONITORS (TEMP)
|
||||
*/
|
||||
|
||||
const deleteAllMonitors = async (req, res) => {
|
||||
const deleteAllMonitors = async (teamId) => {
|
||||
try {
|
||||
const deletedCount = await Monitor.deleteMany({});
|
||||
return deletedCount.deletedCount;
|
||||
const monitors = await Monitor.find({ teamId });
|
||||
const { deletedCount } = await Monitor.deleteMany({ teamId });
|
||||
|
||||
return { monitors, deletedCount };
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
@@ -493,6 +496,28 @@ const editMonitor = async (candidateId, candidateMonitor) => {
|
||||
);
|
||||
return editedMonitor;
|
||||
} catch (error) {
|
||||
error.method = "editMonitor";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const addDemoMonitors = async (userId, teamId) => {
|
||||
try {
|
||||
const demoMonitorsToInsert = demoMonitors.map((monitor) => {
|
||||
return {
|
||||
userId,
|
||||
teamId,
|
||||
name: monitor.name,
|
||||
description: monitor.name,
|
||||
type: "http",
|
||||
url: monitor.url,
|
||||
interval: 60000,
|
||||
};
|
||||
});
|
||||
const insertedMonitors = await Monitor.insertMany(demoMonitorsToInsert);
|
||||
return insertedMonitors;
|
||||
} catch (error) {
|
||||
error.method = "addDemoMonitors";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
@@ -508,4 +533,5 @@ module.exports = {
|
||||
deleteAllMonitors,
|
||||
deleteMonitorsByUserId,
|
||||
editMonitor,
|
||||
addDemoMonitors,
|
||||
};
|
||||
@@ -32,7 +32,7 @@ router.put(
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/all",
|
||||
"/",
|
||||
isAllowed(["superadmin"]),
|
||||
monitorController.deleteAllMonitors
|
||||
);
|
||||
@@ -43,4 +43,10 @@ router.post(
|
||||
monitorController.pauseMonitor
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/demo",
|
||||
isAllowed(["admin", "superadmin"]),
|
||||
monitorController.addDemoMonitors
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
@@ -278,6 +278,7 @@ class NetworkService {
|
||||
default:
|
||||
logger.error(`Unsupported type: ${job.data.type}`, {
|
||||
service: this.SERVICE_NAME,
|
||||
method: "getStatus",
|
||||
jobId: job.id,
|
||||
});
|
||||
return false;
|
||||
@@ -296,11 +297,13 @@ class NetworkService {
|
||||
async logAndStoreCheck(data, writeToDB) {
|
||||
try {
|
||||
const insertedCheck = await writeToDB(data);
|
||||
return insertedCheck.status;
|
||||
if (insertedCheck !== null && insertedCheck !== undefined) {
|
||||
return insertedCheck.status;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
logger.error(`Error wrtiting check for ${data.monitorId}`, {
|
||||
service: this.SERVICE_NAME,
|
||||
method: "logAndStoreCheck",
|
||||
monitorId: data.monitorId,
|
||||
error: error,
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -83,6 +83,7 @@ const successMessages = {
|
||||
MONITOR_DELETE: "Monitor deleted successfully",
|
||||
MONITOR_EDIT: "Monitor edited successfully",
|
||||
MONITOR_CERTIFICATE: "Got monitor certificate successfully",
|
||||
MONITOR_DEMO_ADDED: "Successfully added demo monitors",
|
||||
|
||||
//Job Queue
|
||||
JOB_QUEUE_DELETE_JOB: "Job removed successfully",
|
||||
|
||||
@@ -16,6 +16,18 @@ const ParseBoolean = (value) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getTokenFromHeaders = (headers) => {
|
||||
const authorizationHeader = headers.authorization;
|
||||
if (!authorizationHeader) throw new Error("No auth headers");
|
||||
|
||||
const parts = authorizationHeader.split(" ");
|
||||
if (parts.length !== 2 || parts[0] !== "Bearer")
|
||||
throw new Error("Invalid auth headers");
|
||||
|
||||
return parts[1];
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ParseBoolean,
|
||||
getTokenFromHeaders,
|
||||
};
|
||||
Reference in new issue
Block a user