Merge branch 'develop' into feat/fe/connect-config
This commit is contained in:
commit
60b408dc19
19 files changed
+373
-98
No files matched your search
+2
-2
@@ -2,11 +2,11 @@ language: "en-CA"
|
||||
tone_instructions: "His palms are sweaty, knees weak, arms are heavy There’s vomit on his sweater already, mom’s spaghetti"
|
||||
early_access: false
|
||||
reviews:
|
||||
profile: "assertive"
|
||||
profile: "chill"
|
||||
request_changes_workflow: false
|
||||
high_level_summary: false
|
||||
poem: false
|
||||
review_status: true
|
||||
review_status: false
|
||||
auto_review:
|
||||
enabled: true
|
||||
drafts: false
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
.MuiButtonBase-root.button-rotate90 svg {
|
||||
transition: transform 500ms ease;
|
||||
}
|
||||
.MuiButtonBase-root.button-rotate90:hover svg {
|
||||
transform: rotate(90deg);
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.MuiButtonBase-root.button-rotate180 svg {
|
||||
transition: transform 700ms ease;
|
||||
}
|
||||
.MuiButtonBase-root.button-rotate180:hover svg {
|
||||
transform: rotate(180deg);
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.MuiButtonBase-root.button-slideLeft {
|
||||
padding-left: 45px;
|
||||
}
|
||||
.MuiButtonBase-root.button-slideLeft svg {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
transition: left 250ms cubic-bezier(0.65, 0, 0.076, 1);
|
||||
}
|
||||
.MuiButtonBase-root.button-slideLeft:hover svg {
|
||||
left: 11px;
|
||||
}
|
||||
|
||||
.MuiButtonBase-root.button-slideLeft:hover,
|
||||
.MuiButtonBase-root.button-rotate180:hover,
|
||||
.MuiButtonBase-root.button-rotate90:hover {
|
||||
background-color: rgba(71, 84, 103, 0.08);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Button as MuiButton } from "@mui/material";
|
||||
import PropTypes from "prop-types";
|
||||
import "./index.css";
|
||||
|
||||
const levelConfig = {
|
||||
primary: {
|
||||
@@ -48,11 +49,22 @@ const levelConfig = {
|
||||
* <Button type="submit" level="error" label="Error" disabled sx={{marginTop: "1rem"}}/>
|
||||
*/
|
||||
|
||||
const Button = ({ id, type, level, label, disabled, img, onClick, sx }) => {
|
||||
const Button = ({
|
||||
id,
|
||||
animate,
|
||||
type,
|
||||
level,
|
||||
label,
|
||||
disabled,
|
||||
img,
|
||||
onClick,
|
||||
sx,
|
||||
}) => {
|
||||
const { variant, color } = levelConfig[level];
|
||||
return (
|
||||
<MuiButton
|
||||
id={id}
|
||||
className={`button-${animate}`}
|
||||
type={type}
|
||||
variant={variant}
|
||||
color={color}
|
||||
@@ -60,15 +72,20 @@ const Button = ({ id, type, level, label, disabled, img, onClick, sx }) => {
|
||||
onClick={onClick}
|
||||
disableRipple
|
||||
sx={{
|
||||
lineHeight: 1,
|
||||
boxShadow: "none",
|
||||
textTransform: "none",
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
"&:hover": {
|
||||
boxShadow: "none",
|
||||
},
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
{img && img}
|
||||
{label}
|
||||
<span>{label}</span>
|
||||
</MuiButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -72,10 +72,15 @@ const ButtonSpinner = ({
|
||||
loading={isLoading}
|
||||
disableRipple
|
||||
sx={{
|
||||
boxShadow: "none",
|
||||
textTransform: "none",
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
"&:hover": {
|
||||
boxShadow: "none",
|
||||
transition: "none"
|
||||
},
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
padding-bottom: 60px;
|
||||
border: 1px solid var(--env-var-color-16);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
background-color: var(--env-var-color-8);
|
||||
}
|
||||
.configure-monitor .config-box .MuiBox-root,
|
||||
.configure-monitor .config-box .MuiStack-root {
|
||||
@@ -74,4 +75,4 @@
|
||||
body:has(.configure-monitor) .select-dropdown .MuiMenuItem-root,
|
||||
.configure-monitor .select-wrapper .select-component > .MuiSelect-select {
|
||||
text-transform: lowercase;
|
||||
}
|
||||
}
|
||||
@@ -122,6 +122,7 @@ const Configure = () => {
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate(-1)}
|
||||
sx={{
|
||||
@@ -129,7 +130,8 @@ const Configure = () => {
|
||||
mb: theme.gap.medium,
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
pr: theme.gap.small,
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
@@ -166,13 +168,14 @@ const Configure = () => {
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Pause"
|
||||
animate="rotate180"
|
||||
img={<PauseCircleOutlineIcon />}
|
||||
sx={{
|
||||
backgroundColor: "#f4f4f4",
|
||||
pl: theme.gap.small,
|
||||
pr: theme.gap.medium,
|
||||
"& svg": {
|
||||
pr: theme.gap.xs,
|
||||
mr: theme.gap.xs,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
border-radius: var(--env-var-radius-1);
|
||||
flex-direction: row;
|
||||
gap: var(--env-var-spacing-4);
|
||||
background-color: var(--env-var-color-8);
|
||||
}
|
||||
.create-monitor .config-box .MuiBox-root,
|
||||
.create-monitor .config-box .MuiStack-root {
|
||||
|
||||
@@ -145,6 +145,7 @@ const CreateMonitor = () => {
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate("/monitors")}
|
||||
sx={{
|
||||
@@ -152,7 +153,8 @@ const CreateMonitor = () => {
|
||||
mb: theme.gap.medium,
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
pr: theme.gap.small,
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -37,13 +37,18 @@
|
||||
.monitor-details .stat-box {
|
||||
flex: 1;
|
||||
min-width: 100px;
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
border: solid 1px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
padding: var(--env-var-spacing-1-plus) var(--env-var-spacing-2);
|
||||
background-color: var(--env-var-color-8);
|
||||
}
|
||||
.monitor-details .stat-box:not(:first-of-type) {
|
||||
margin-left: var(--env-var-spacing-2);
|
||||
}
|
||||
.monitor-details .stat-box h6.MuiTypography-root {
|
||||
margin-bottom: var(--env-var-spacing-1);
|
||||
}
|
||||
}
|
||||
.monitor-details button.MuiButtonBase-root,
|
||||
.monitor-details .stat-box {
|
||||
border-color: var(--env-var-color-16);
|
||||
}
|
||||
@@ -147,6 +147,7 @@ const DetailsPage = () => {
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back to Monitors"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate("/monitors")}
|
||||
sx={{
|
||||
@@ -154,7 +155,8 @@ const DetailsPage = () => {
|
||||
mb: theme.gap.medium,
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
pr: theme.gap.small,
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
@@ -184,15 +186,16 @@ const DetailsPage = () => {
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Configure"
|
||||
animate="rotate90"
|
||||
img={<SettingsIcon />}
|
||||
onClick={() => navigate(`/monitors/configure/${monitorId}`)}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
backgroundColor: "#f4f4f4",
|
||||
px: theme.gap.ml,
|
||||
px: theme.gap.medium,
|
||||
"& svg": {
|
||||
pr: theme.gap.xs,
|
||||
mr: "6px",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
@@ -222,19 +225,28 @@ const DetailsPage = () => {
|
||||
level="secondary"
|
||||
label="Day"
|
||||
onClick={() => setFilter("day")}
|
||||
sx={{ backgroundColor: filter === "day" && "#f4f4f4" }}
|
||||
sx={{
|
||||
backgroundColor:
|
||||
filter === "day" && theme.palette.otherColors.fillGray,
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
level="secondary"
|
||||
label="Week"
|
||||
onClick={() => setFilter("week")}
|
||||
sx={{ backgroundColor: filter === "week" && "#f4f4f4" }}
|
||||
sx={{
|
||||
backgroundColor:
|
||||
filter === "week" && theme.palette.otherColors.fillGray,
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
level="secondary"
|
||||
label="Month"
|
||||
onClick={() => setFilter("month")}
|
||||
sx={{ backgroundColor: filter === "month" && "#f4f4f4" }}
|
||||
sx={{
|
||||
backgroundColor:
|
||||
filter === "month" && theme.palette.otherColors.fillGray,
|
||||
}}
|
||||
/>
|
||||
</ButtonGroup>
|
||||
</Stack>
|
||||
|
||||
@@ -6,24 +6,57 @@
|
||||

|
||||

|
||||
|
||||
|
||||
<h1 align="center"><a href="https://bluewavelabs.ca" target="_blank">BlueWave Uptime</a></h1>
|
||||
|
||||
<p align="center"><strong>An open source server monitoring application</strong></p>
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
BlueWave Uptime is an open source server monitoring application 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.
|
||||
|
||||
## Features
|
||||
|
||||
* Completely open source, deployable on your servers
|
||||
* Website monitoring
|
||||
* Port monitoring
|
||||
* Ping monitoring
|
||||
* Incidents at a glance
|
||||
* Status pages
|
||||
* Page speed monitoring (in the works)
|
||||
|
||||
**Roadmap:**
|
||||
* 3rd party integrations
|
||||
* Domain monitoring
|
||||
* SSL monitoring
|
||||
|
||||
## Tech stack
|
||||
|
||||
* [ReactJs](https://react.dev/)
|
||||
* [MUI (React framework)](https://mui.com/)
|
||||
* [Node.js](https://nodejs.org/en)
|
||||
* [MongoDB](https://mongodb.com)
|
||||
|
||||
## Contributing
|
||||
|
||||
You are welcome to provide contributions to the project. It uses React on the FE, and Nodejs and MongoDB on the BE, hence if you are comfortable with working with those technologies, you are encouraged to send your PRs. Please read [Contributor's guideline](https://github.com/bluewave-labs/bluewave-uptime/blob/master/CONTRIBUTING.md). Once you start contributing, we can also add you to our weekly team calls (every Thursday).
|
||||
We love contributors. Here's how you can contribute:
|
||||
|
||||
Note that We have a Figma file that includes:
|
||||
* Check [Contributor's guideline](https://github.com/bluewave-labs/bluewave-uptime/blob/master/CONTRIBUTING.md).
|
||||
* 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.
|
||||
* Open an issue if you believe you've encountered a bug
|
||||
* Make a pull request to add new features/make quality-of-life improvements/fix bugs.
|
||||
|
||||
- All the dashboard elements and components
|
||||
- The design guideline for the app
|
||||
<a href="https://github.com/bluewave-labs/bluewave-uptime/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=bluewave-labs/bluewave-uptime" />
|
||||
</a>
|
||||
|
||||
Made with [contrib.rocks](https://contrib.rocks).
|
||||
|
||||

|
||||
|
||||
You can see the designs [here](https://www.figma.com/design/RPSfaw66HjzSwzntKcgDUV/Uptime-Genie?node-id=0-1&t=WqOFv9jqNTFGItpL-1). Since it is read-only, we encourage you to copy to your own Figma page, then work on it.
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -2067,10 +2100,3 @@ const myRoute = async(req, res, next) => {
|
||||
|
||||
Errors should not be handled at the controller level and should be left to the middleware to handle.
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/bluewave-labs/bluewave-uptime/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=bluewave-labs/bluewave-uptime" />
|
||||
</a>
|
||||
|
||||
Made with [contrib.rocks](https://contrib.rocks).
|
||||
@@ -27,7 +27,8 @@ const createAlert = async (req, res, next) => {
|
||||
await createAlertBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
@@ -58,7 +59,8 @@ const getAlertsByUserId = async (req, res, next) => {
|
||||
await getAlertsByUserIdParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
@@ -82,7 +84,8 @@ const getAlertsByMonitorId = async (req, res, next) => {
|
||||
await getAlertsByMonitorIdParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
@@ -106,7 +109,8 @@ const getAlertById = async (req, res, next) => {
|
||||
await getAlertByIdParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
@@ -132,7 +136,8 @@ const editAlert = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
@@ -156,7 +161,8 @@ const deleteAlert = async (req, res, next) => {
|
||||
await deleteAlertParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
|
||||
@@ -54,7 +54,8 @@ const registerController = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
@@ -115,14 +116,20 @@ const registerController = async (req, res, next) => {
|
||||
*/
|
||||
const loginController = async (req, res, next) => {
|
||||
try {
|
||||
// Validate input
|
||||
await loginValidation.validateAsync(req.body);
|
||||
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Check if user exists
|
||||
const user = await req.db.getUserByEmail(req, res);
|
||||
|
||||
// Compare password
|
||||
|
||||
const match = await user.comparePassword(req.body.password);
|
||||
if (match !== true) {
|
||||
throw new Error(errorMessages.AUTH_INCORRECT_PASSWORD);
|
||||
@@ -157,7 +164,8 @@ const userEditController = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
@@ -216,8 +224,18 @@ const inviteController = async (req, res, next) => {
|
||||
// Only admins can invite
|
||||
const token = getTokenFromHeaders(req.headers);
|
||||
const { role, firstname } = jwt.decode(token);
|
||||
await inviteRoleValidation.validateAsync({ roles: role });
|
||||
await inviteBodyValidation.validateAsync(req.body);
|
||||
try {
|
||||
await inviteRoleValidation.validateAsync({ roles: role });
|
||||
await inviteBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
const inviteToken = await req.db.requestInviteToken(req, res);
|
||||
req.emailService.buildAndSendEmail(
|
||||
"employeeActivationTemplate",
|
||||
@@ -242,6 +260,16 @@ const inviteController = async (req, res, next) => {
|
||||
const inviteVerifyController = async (req, res, next) => {
|
||||
try {
|
||||
await inviteVerifciationBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const invite = await req.db.getInviteToken(req, res);
|
||||
|
||||
res
|
||||
@@ -289,6 +317,16 @@ const checkAdminController = async (req, res) => {
|
||||
const recoveryRequestController = async (req, res, next) => {
|
||||
try {
|
||||
await recoveryValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await req.db.getUserByEmail(req, res);
|
||||
if (user) {
|
||||
const recoveryToken = await req.db.requestRecoveryToken(req, res);
|
||||
@@ -328,6 +366,16 @@ const recoveryRequestController = async (req, res, next) => {
|
||||
const validateRecoveryTokenController = async (req, res, next) => {
|
||||
try {
|
||||
await recoveryTokenValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await req.db.validateRecoveryToken(req, res);
|
||||
// TODO Redirect user to reset password after validating token
|
||||
return res.status(200).json({
|
||||
@@ -354,6 +402,15 @@ const validateRecoveryTokenController = async (req, res, next) => {
|
||||
const resetPasswordController = async (req, res, next) => {
|
||||
try {
|
||||
await newPasswordValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const user = await req.db.resetPassword(req, res);
|
||||
const token = issueToken(user._doc);
|
||||
res.status(200).json({
|
||||
@@ -392,9 +449,18 @@ const deleteUserController = async (req, res, next) => {
|
||||
};
|
||||
|
||||
// Validate user
|
||||
await deleteUserParamValidation.validateAsync(
|
||||
decodedTokenCastedAsRequest.body
|
||||
);
|
||||
try {
|
||||
await deleteUserParamValidation.validateAsync(
|
||||
decodedTokenCastedAsRequest.body
|
||||
);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the user exists
|
||||
const user = await req.db.getUserByEmail(decodedTokenCastedAsRequest);
|
||||
@@ -408,25 +474,19 @@ const deleteUserController = async (req, res, next) => {
|
||||
);
|
||||
|
||||
if (monitors) {
|
||||
// 2. Delete jobs associated with each monitor
|
||||
for (const monitor of monitors) {
|
||||
await req.jobQueue.deleteJob(monitor);
|
||||
}
|
||||
//2. Remove all jobs, delete checks and alerts
|
||||
await Promise.all(
|
||||
monitors.map(async (monitor) => {
|
||||
await req.jobQueue.deleteJob(monitor);
|
||||
await req.db.deleteChecks(monitor._id);
|
||||
await req.db.deleteAlertByMonitorId(monitor._id);
|
||||
})
|
||||
);
|
||||
|
||||
// 3. Delete all checks associated with each monitor
|
||||
for (const monitor of monitors) {
|
||||
await req.db.deleteChecks(monitor._id);
|
||||
}
|
||||
|
||||
// 4. Delete all alerts associated with each monitor
|
||||
for (const monitor of monitors) {
|
||||
await req.db.deleteAlertByMonitorId(monitor._id);
|
||||
}
|
||||
|
||||
// 5. Delete each monitor
|
||||
// 3. Delete each monitor
|
||||
await req.db.deleteMonitorsByUserId(user._id);
|
||||
|
||||
// 6. Delete the user by id
|
||||
// 4. Delete the user by id
|
||||
await req.db.deleteUser(decodedTokenCastedAsRequest);
|
||||
|
||||
return res.status(200).json({
|
||||
|
||||
@@ -14,7 +14,8 @@ const createCheck = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
@@ -37,7 +38,8 @@ const getChecks = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
@@ -59,20 +61,19 @@ const deleteChecks = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const deletedCount = await req.db.deleteChecks(req.params.monitorId);
|
||||
return res
|
||||
.status(200)
|
||||
.json({
|
||||
success: true,
|
||||
msg: successMessages.CHECK_DELETE,
|
||||
data: { deletedCount },
|
||||
});
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: successMessages.CHECK_DELETE,
|
||||
data: { deletedCount },
|
||||
});
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
|
||||
@@ -15,7 +15,8 @@ const createMaintenanceWindow = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
@@ -48,7 +49,15 @@ const getMaintenanceWindowsByUserId = async (req, res, next) => {
|
||||
await getMaintenanceWindowsByUserIdParamValidation.validateAsync(
|
||||
req.params
|
||||
);
|
||||
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const maintenanceWindows = await req.db.getMaintenanceWindowsByUserId(
|
||||
req.params.userId
|
||||
);
|
||||
@@ -69,7 +78,16 @@ const getMaintenanceWindowsByMonitorId = async (req, res, next) => {
|
||||
await getMaintenanceWindowsByMonitorIdParamValidation.validateAsync(
|
||||
req.params
|
||||
);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const maintenanceWindows = await req.db.getMaintenanceWindowsByMonitorId(
|
||||
req.params.monitorId
|
||||
);
|
||||
|
||||
@@ -9,7 +9,6 @@ const {
|
||||
|
||||
const SERVICE_NAME = "monitorController";
|
||||
const { errorMessages, successMessages } = require("../utils/messages");
|
||||
const { error } = require("winston");
|
||||
|
||||
/**
|
||||
* Returns all monitors
|
||||
@@ -47,7 +46,8 @@ const getMonitorById = async (req, res, next) => {
|
||||
await getMonitorByIdQueryValidation.validateAsync(req.query);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
@@ -83,6 +83,16 @@ const getMonitorsByUserId = async (req, res, next) => {
|
||||
try {
|
||||
await getMonitorsByUserIdValidation.validateAsync(req.params);
|
||||
await getMonitorsByUserIdQueryValidation.validateAsync(req.query);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const userId = req.params.userId;
|
||||
const monitors = await req.db.getMonitorsByUserId(req, res);
|
||||
|
||||
@@ -112,7 +122,9 @@ const createMonitor = async (req, res, next) => {
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
@@ -143,21 +155,24 @@ const createMonitor = async (req, res, next) => {
|
||||
|
||||
const deleteMonitor = async (req, res, next) => {
|
||||
try {
|
||||
await getMonitorByIdValidation.validateAsync(req.params);
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const monitor = await req.db.deleteMonitor(req, res, next);
|
||||
// Delete associated checks and alerts
|
||||
// Delete associated checks,alerts,and notifications
|
||||
await req.jobQueue.deleteJob(monitor);
|
||||
await req.db.deleteChecks(monitor._id);
|
||||
await req.db.deleteAlertByMonitorId(monitor._id);
|
||||
await req.db.deleteNotificationsByMonitorId(monitor._id);
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* We should remove all checks and alerts associated with this monitor
|
||||
@@ -195,12 +210,13 @@ const deleteAllMonitors = async (req, res) => {
|
||||
*/
|
||||
const editMonitor = async (req, res, next) => {
|
||||
try {
|
||||
await getMonitorByIdValidation.validateAsync(req.params);
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
await editMonitorBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const PageSpeedCheck = require("../models/PageSpeedCheck");
|
||||
const PageSpeedService = require("../service/pageSpeedService");
|
||||
const { successMessages } = require("../utils/messages");
|
||||
const pageSpeedService = new PageSpeedService();
|
||||
@@ -22,12 +21,19 @@ const getPageSpeedChecks = async (req, res, next) => {
|
||||
try {
|
||||
// Validate monitorId parameter
|
||||
await getPageSpeedCheckParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
return res.status(200).json({ msg: "Hit getPageSpeedChecks" });
|
||||
} catch (error) {
|
||||
if (error.isJoi) {
|
||||
return res.status(400).json({ error: error.details[0].message });
|
||||
}
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
@@ -42,12 +48,18 @@ const getPageSpeedChecks = async (req, res, next) => {
|
||||
*/
|
||||
const createPageSpeedCheck = async (req, res, next) => {
|
||||
try {
|
||||
// Validate monitorId parameter
|
||||
await createPageSpeedCheckParamValidation.validateAsync(req.params);
|
||||
|
||||
// Validate request body
|
||||
await createPageSpeedCheckBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { monitorId } = req.params;
|
||||
const { url } = req.body;
|
||||
|
||||
@@ -74,9 +86,6 @@ const createPageSpeedCheck = async (req, res, next) => {
|
||||
data: newPageSpeedCheck,
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.isJoi) {
|
||||
return res.status(400).json({ error: error.details[0].message });
|
||||
}
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
@@ -94,12 +103,17 @@ const deletePageSpeedCheck = async (req, res, next) => {
|
||||
try {
|
||||
// Validate monitorId parameter
|
||||
await deletePageSpeedCheckParamValidation.validateAsync(req.params);
|
||||
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
return res.status(200).json({ msg: "Hit deletePageSpeedCheck" });
|
||||
} catch (error) {
|
||||
if (error.isJoi) {
|
||||
return res.status(400).json({ error: error.details[0].message });
|
||||
}
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
|
||||
@@ -65,8 +65,6 @@ const {
|
||||
getAllMonitors,
|
||||
getMonitorById,
|
||||
getMonitorsByUserId,
|
||||
getMonitorByIdForIncidents,
|
||||
getMonitorsByUserIdForIncidents,
|
||||
createMonitor,
|
||||
deleteMonitor,
|
||||
deleteAllMonitors,
|
||||
@@ -120,6 +118,12 @@ const {
|
||||
deleteMaintenanceWindowByUserId,
|
||||
} = require("./modules/maintenaceWindowModule");
|
||||
|
||||
const {
|
||||
createNotification,
|
||||
getNotificationsByMonitorId,
|
||||
deleteNotificationsByMonitorId,
|
||||
} = require("./modules/notificationModule");
|
||||
|
||||
module.exports = {
|
||||
connect,
|
||||
insertUser,
|
||||
@@ -136,8 +140,6 @@ module.exports = {
|
||||
getAllMonitors,
|
||||
getMonitorById,
|
||||
getMonitorsByUserId,
|
||||
getMonitorByIdForIncidents,
|
||||
getMonitorsByUserIdForIncidents,
|
||||
createMonitor,
|
||||
deleteMonitor,
|
||||
deleteAllMonitors,
|
||||
@@ -162,4 +164,7 @@ module.exports = {
|
||||
deleteMaintenaceWindowById,
|
||||
deleteMaintenanceWindowByMonitorId,
|
||||
deleteMaintenanceWindowByUserId,
|
||||
createNotification,
|
||||
getNotificationsByMonitorId,
|
||||
deleteNotificationsByMonitorId,
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
const Notification = require("../../../models/Notification");
|
||||
|
||||
/**
|
||||
* Creates a new notification.
|
||||
* @param {Object} notificationData - The data for the new notification.
|
||||
* @param {mongoose.Types.ObjectId} notificationData.monitorId - The ID of the monitor.
|
||||
* @param {string} notificationData.type - The type of the notification (e.g., "email", "sms").
|
||||
* @param {string} [notificationData.address] - The address for the notification (if applicable).
|
||||
* @param {string} [notificationData.phone] - The phone number for the notification (if applicable).
|
||||
* @returns {Promise<Object>} The created notification.
|
||||
* @throws Will throw an error if the notification cannot be created.
|
||||
*/
|
||||
const createNotification = async (notificationData) => {
|
||||
try {
|
||||
const notification = await new Notification({ ...notificationData }).save();
|
||||
return notification;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves notifications by monitor ID.
|
||||
* @param {mongoose.Types.ObjectId} monitorId - The ID of the monitor.
|
||||
* @returns {Promise<Array<Object>>} An array of notifications.
|
||||
* @throws Will throw an error if the notifications cannot be retrieved.
|
||||
*/
|
||||
const getNotificationsByMonitorId = async (monitorId) => {
|
||||
try {
|
||||
const notifications = await Notification.find({ monitorId });
|
||||
return notifications;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const deleteNotificationsByMonitorId = async (monitorId) => {
|
||||
try {
|
||||
const result = await Notification.deleteMany({ monitorId });
|
||||
return result.deletedCount;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createNotification,
|
||||
getNotificationsByMonitorId,
|
||||
deleteNotificationsByMonitorId,
|
||||
};
|
||||
Reference in new issue
Block a user