diff --git a/README.md b/README.md
index 2e1022c31..dfc57064d 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,13 @@ BlueWave uptime monitoring application
- POST [/api/v1/checks/{monitorId}](#post-checks)
- GET [/api/v1/checks/{monitorId}](#get-checks)
- POST [/api/v1/checks/delete/{monitorId}](#delete-checks)
+ ###### Alerts
+ - POST [/api/v1/alerts/{monitorId}](#create-alert)
+ - GET [/api/v1/alerts/user/{userId}](#get-alerts-user-id)
+ - GET [/api/v1/alerts/monitor/{monitorId}](#get-alerts-monitor-id)
+ - GET [/api/v1/alerts/{alertId}](#get-alert-alert-id)
+ - POST [/api/v1/alerts/edit/{alertId}](#edit-alert)
+ - POST [/api/v1/alerts/delete/{alertId}](#delete-alert)
5. [Error Handling](#error-handling)
6. [Contributors](#contributors)
@@ -333,9 +340,9 @@ curl --request POST \
##### Response Payload
-> | Type | Notes |
-> | ---------------- | ----------------- |
-> | `Array[Monitor]` | Array of monitors |
+> | Type | Notes |
+> | ---------------- | --------------------- |
+> | `Array` | Array of all monitors |
###### Sample cURL Request
@@ -439,9 +446,9 @@ curl --request GET \
###### Response Payload
-> | Type | Notes |
-> | ---------------- | ------------------------------------------------------------------ |
-> | `Array[Monitor]` | Array of monitors created by user with userId specified in request |
+> | Type | Notes |
+> | ---------------- | ------------------------------------------------------- |
+> | `Array` | Array of monitors created by user with specified UserID |
###### Sample cURL Request
@@ -499,9 +506,9 @@ curl --request GET \
###### Response Payload
-> | Type | Notes |
-> | --------- | --------------------------------- |
-> | `Monitor` | Newly created monitor is returned |
+> | Type | Notes |
+> | --------- | ------------------------------- |
+> | `Monitor` | Returns newly created `Monitor` |
##### Sample CURL request
@@ -681,7 +688,7 @@ curl --request POST \
> | Type | Notes |
> | --------------- | ------------------------ |
-> | `Array[Checks]` | Array of `Check` objects |
+> | `Array` | Array of `Check` objects |
##### Sample CURL request
@@ -730,6 +737,188 @@ curl --request POST \
---
+###### Alerts
+
+
+POST/api/v1/alerts/{monitorId}
+
+###### Method/Headers
+
+> | Method/Headers | Value |
+> | -------------- | ----- |
+> | Method | POST |
+
+###### Response Payload
+
+> | Type | Notes |
+> | ------- | ----------------------------- |
+> | `Alert` | Returns newly created `Alert` |
+
+###### Body
+
+##### Sample CURL request
+
+```
+
+```
+
+###### Sample Response
+
+```json
+
+```
+
+
+
+
+GET/api/v1/alerts/user/{userId}
+
+###### Method/Headers
+
+> | Method/Headers | Value |
+> | -------------- | ----- |
+> | Method | GET |
+
+###### Response Payload
+
+> | Type | Notes |
+> | -------------- | --------------------------------------- |
+> | `Array` | Returns all `Alert` created by a `User` |
+
+##### Sample CURL request
+
+```
+
+```
+
+###### Sample Response
+
+```json
+
+```
+
+
+
+GET/api/v1/alerts/monitor/{monitorId}
+
+###### Method/Headers
+
+> | Method/Headers | Value |
+> | -------------- | ----- |
+> | Method | GET |
+
+###### Response Payload
+
+> | Type | Notes |
+> | -------------- | -------------------------------------------------------------- |
+> | `Array` | Returns an array of `Alert` belonging to a specified `Monitor` |
+
+##### Sample CURL request
+
+```
+
+```
+
+###### Sample Response
+
+```json
+
+```
+
+
+
+
+GET/api/v1/alerts/{alertId}
+
+###### Method/Headers
+
+> | Method/Headers | Value |
+> | -------------- | ----- |
+> | Method | GET |
+
+###### Response Payload
+
+> | Type | Notes |
+> | ------- | ------------------------- |
+> | `Alert` | Returns specified `Alert` |
+
+##### Sample CURL request
+
+```
+
+```
+
+###### Sample Response
+
+```json
+
+```
+
+
+
+
+POST/api/v1/alerts/edit/{alertId}
+
+###### Method/Headers
+
+> | Method/Headers | Value |
+> | -------------- | ----- |
+> | Method | POST |
+
+###### Response Payload
+
+> | Type | Notes |
+> | ------- | -------------------- |
+> | `Alert` | Returns edited alert |
+
+###### Body
+
+##### Sample CURL request
+
+```
+
+```
+
+###### Sample Response
+
+```json
+
+```
+
+
+
+POST/api/v1/alerts/delete/{alertId}
+
+###### Method/Headers
+
+> | Method/Headers | Value |
+> | -------------- | ----- |
+> | Method | POST |
+
+###### Response Payload
+
+> | Type | Notes |
+> | ---- | ------------------- |
+> | None | No payload returned |
+
+###### Body
+
+##### Sample CURL request
+
+```
+
+```
+
+###### Sample Response
+
+```json
+
+```
+
+
+
+---
+
### Error handling {#error-handling}
Errors are returned in a standard format:
diff --git a/Server/controllers/alertController.js b/Server/controllers/alertController.js
new file mode 100644
index 000000000..91bb56971
--- /dev/null
+++ b/Server/controllers/alertController.js
@@ -0,0 +1,139 @@
+const express = require("express");
+const logger = require("../utils/logger");
+require("dotenv").config();
+const {
+ createAlertParamValidation,
+ createAlertBodyValidation,
+ getAlertsByUserIdParamValidation,
+ getAlertsByMonitorIdParamValidation,
+ getAlertByIdParamValidation,
+ editAlertParamValidation,
+ editAlertBodyValidation,
+ deleteAlertParamValidation,
+} = require("../validation/joi");
+
+const SERVICE_NAME = "alerts";
+
+/**
+ * Creates an alert for a monitor
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {Promise}
+ * @throws {Error}
+ */
+const createAlert = async (req, res, next) => {
+ try {
+ await createAlertParamValidation.validateAsync(req.params);
+ await createAlertBodyValidation.validateAsync(req.body);
+ } catch (error) {
+ error.status = 422;
+ error.message = error.details[0].message;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+
+ try {
+ req.db.createAlert(req, res);
+ } catch (error) {
+ error.service = SERVICE_NAME;
+ next(error);
+ }
+};
+
+/**
+ * Gets all alerts for a user
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {Promise}
+ * @throws {Error}
+ */
+const getAlertsByUserId = async (req, res, next) => {
+ try {
+ await getAlertsByUserIdParamValidation.validateAsync(req.params);
+ } catch (error) {
+ error.status = 422;
+ error.message = error.details[0].message;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+
+ try {
+ req.db.getAlertsByUserId(req, res);
+ } catch (error) {
+ error.service = SERVICE_NAME;
+ next(error);
+ }
+};
+
+const getAlertsByMonitorId = async (req, res, next) => {
+ try {
+ await getAlertsByMonitorIdParamValidation.validateAsync(req.params);
+ res.status(200).json({
+ success: true,
+ msg: "Get Alerts By MonitorID",
+ data: req.params.monitorId,
+ });
+ } catch (error) {
+ error.status = 422;
+ res.status(200).json({ success: true, msg: "Edit alert" });
+
+ error.message = error.details[0].message;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+};
+const getAlertById = async (req, res, next) => {
+ try {
+ await getAlertByIdParamValidation.validateAsync(req.params);
+ res.status(200).json({
+ success: true,
+ msg: "Get Alert By alertID",
+ data: req.params.alertId,
+ });
+ } catch (error) {
+ error.status = 422;
+ error.message = error.details[0].message;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+};
+const editAlert = async (req, res, next) => {
+ try {
+ await editAlertParamValidation(req.params);
+ await editAlertBodyValidation(req.body);
+ res.status(200).json({ success: true, msg: "Edit alert" });
+ } catch (error) {
+ error.status = 422;
+ error.message = error.details[0].message;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+};
+const deleteAlert = async (req, res, next) => {
+ try {
+ await deleteAlertParamValidation(req.params);
+ res.status(200).json({ success: true, msg: "Delete alert" });
+ } catch (error) {
+ error.status = 422;
+ error.message = error.details[0].message;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+};
+
+module.exports = {
+ createAlert,
+ getAlertsByUserId,
+ getAlertsByMonitorId,
+ getAlertById,
+ editAlert,
+ deleteAlert,
+};
diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js
index cc476ab54..257048937 100644
--- a/Server/controllers/authController.js
+++ b/Server/controllers/authController.js
@@ -17,7 +17,7 @@ const SERVICE_NAME = "auth";
* @returns {String}
*/
const issueToken = (payload) => {
- return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "1h" });
+ return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "99d" });
};
/**
@@ -31,7 +31,7 @@ const registerController = async (req, res, next) => {
try {
await registerValidation.validateAsync(req.body);
} catch (error) {
- error.status = 400;
+ error.status = 422;
error.service = SERVICE_NAME;
error.message = error.details[0].message;
next(error);
diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js
index a4c9422a3..32d5d33f7 100644
--- a/Server/db/MongoDB.js
+++ b/Server/db/MongoDB.js
@@ -265,6 +265,123 @@ const deleteChecks = async (req, res) => {
}
};
+//****************************************
+// Alerts
+//****************************************
+
+/**
+ * Creates an Alert associated with a Monitor and User
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {>}
+ * @throws {Error}
+ */
+const createAlert = async (req, res) => {
+ try {
+ res
+ .status(200)
+ .json({ success: true, msg: "Create Alert", data: req.params.monitorId });
+ } catch (error) {
+ throw error;
+ }
+};
+
+/**
+ * Gets all alerts a User has set
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {>}
+ * @throws {Error}
+ */
+const getAlertsByUserId = async (req, res) => {
+ try {
+ res.status(200).json({
+ success: true,
+ msg: "Get Alerts By UserID",
+ data: req.params.userId,
+ });
+ } catch (error) {
+ throw error;
+ }
+};
+
+/**
+ * Gets all alerts a for an associated Monitor
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {>}
+ * @throws {Error}
+ */
+const getAlertsByMonitorId = async (req, res) => {
+ try {
+ res.status(200).json({
+ success: true,
+ msg: "Get Alerts By MonitorID",
+ data: req.params.monitorId,
+ });
+ } catch (error) {
+ throw error;
+ }
+};
+
+/**
+ * Gets an alert with specified ID
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {Promise}
+ * @throws {Error}
+ */
+const getAlertById = async (req, res) => {
+ try {
+ res.status(200).json({
+ success: true,
+ msg: "Get Alert By alertID",
+ data: req.params.alertId,
+ });
+ } catch (error) {
+ throw error;
+ }
+};
+
+/**
+ * Returns an edited monitor with the specified ID
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {Promise>}
+ * @throws {Error}
+ */
+const editAlert = async (req, res) => {
+ try {
+ res
+ .status(200)
+ .json({ success: true, msg: "Edit alert", data: req.params.alertId });
+ } catch (error) {
+ throw error;
+ }
+};
+
+/**
+ * Deletes a monitor with the specified ID
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @throws {Error}
+ */
+const deleteAlert = async (req, res) => {
+ try {
+ res
+ .status(200)
+ .json({ success: true, msg: "Delete alert", data: req.params.alertId });
+ } catch (error) {
+ throw error;
+ }
+};
+
module.exports = {
connect,
insertUser,
@@ -279,4 +396,10 @@ module.exports = {
createCheck,
getChecks,
deleteChecks,
+ createAlert,
+ getAlertsByUserId,
+ getAlertsByMonitorId,
+ getAlertById,
+ editAlert,
+ deleteAlert,
};
diff --git a/Server/index.js b/Server/index.js
index 1596e0862..96f7553fd 100644
--- a/Server/index.js
+++ b/Server/index.js
@@ -4,6 +4,7 @@ const cors = require("cors");
const authRouter = require("./routes/authRoute");
const monitorRouter = require("./routes/monitorRoute");
const checkRouter = require("./routes/checkRoute");
+const alertRouter = require("./routes/alertRoute");
const { connectDbAndRunServer } = require("./configs/db");
require("dotenv").config();
const logger = require("./utils/logger");
@@ -64,6 +65,7 @@ app.use((req, res, next) => {
app.use("/api/v1/auth", authRouter);
app.use("/api/v1/monitors", verifyJWT, monitorRouter);
app.use("/api/v1/checks", verifyJWT, checkRouter);
+app.use("/api/v1/alerts", verifyJWT, alertRouter);
// Testing email service
// app.use('/sendEmail', async (req, res) => {
diff --git a/Server/routes/alertRoute.js b/Server/routes/alertRoute.js
new file mode 100644
index 000000000..be252e8c4
--- /dev/null
+++ b/Server/routes/alertRoute.js
@@ -0,0 +1,27 @@
+const router = require("express").Router();
+const alertController = require("../controllers/alertController");
+const { verifyOwnership } = require("../middleware/verifyOwnership");
+const Alert = require("../models/Alert");
+
+// Create alert
+router.post("/:monitorId", alertController.createAlert);
+// Get all alerts for a user
+router.get("/user/:userId", alertController.getAlertsByUserId);
+// Get all alerts for a monitor
+router.get("/monitor/:monitorId", alertController.getAlertsByMonitorId);
+// Get a single alert
+router.get("/:alertId", alertController.getAlertById);
+// Edit
+router.post(
+ "/edit/:alertId",
+ verifyOwnership(Alert, "alertId"),
+ alertController.editAlert
+);
+//Delete
+router.post(
+ "/delete/:alertId",
+ verifyOwnership(Alert, "alertId"),
+ alertController.deleteAlert
+);
+
+module.exports = router;
diff --git a/Server/validation/joi.js b/Server/validation/joi.js
index 399c243dc..01a0d0ada 100644
--- a/Server/validation/joi.js
+++ b/Server/validation/joi.js
@@ -39,6 +39,47 @@ const editUserBodyValidation = joi.object({
profilePicUrl: joi.string(),
});
+const createAlertParamValidation = joi.object({
+ monitorId: joi.string().required(),
+});
+
+const createAlertBodyValidation = joi.object({
+ checkId: joi.string().required(),
+ monitorId: joi.string().required(),
+ userId: joi.string().required(),
+ status: joi.boolean(),
+ message: joi.string(),
+ notifiedStatus: joi.boolean(),
+ acknowledgeStatus: joi.boolean(),
+});
+
+const getAlertsByUserIdParamValidation = joi.object({
+ userId: joi.string().required(),
+});
+
+const getAlertsByMonitorIdParamValidation = joi.object({
+ monitorId: joi.string().required(),
+});
+
+const getAlertByIdParamValidation = joi.object({
+ alertId: joi.string().required(),
+});
+
+const editAlertParamValidation = joi.object({
+ alertId: joi.string().required(),
+});
+
+const editAlertBodyValidation = joi.object({
+ status: joi.boolean(),
+ message: joi.string(),
+ notifiedStatus: joi.boolean(),
+ acknowledgeStatus: joi.boolean(),
+});
+
+const deleteAlertParamValidation = joi.object({
+ alertId: joi.string().required(),
+});
+
module.exports = {
loginValidation,
registerValidation,
@@ -47,4 +88,12 @@ module.exports = {
monitorValidation,
editUserParamValidation,
editUserBodyValidation,
+ createAlertParamValidation,
+ createAlertBodyValidation,
+ getAlertsByUserIdParamValidation,
+ getAlertsByMonitorIdParamValidation,
+ getAlertByIdParamValidation,
+ editAlertParamValidation,
+ editAlertBodyValidation,
+ deleteAlertParamValidation,
};