# BlueWave Uptime BlueWave uptime monitoring application ## Getting Started - Clone this repository to your local machine 1. [Installation (Client)](#client) 2. [Installation (Server)](#server) 3. [Configuration(Server)](#config-server) 4. [Endpoints](#endpoints) ###### Auth - POST [/api/v1/auth/register](#post-register) - POST [/api/v1/auth/login](#post-login) - POST [/api/v1/auth/user/{userId}](#post-auth-user-edit-id) ###### Monitors - GET [/api/v1/monitors](#get-monitors) - GET [/api/v1/monitor/{id}](#get-monitor-id) - GET [/api/v1/monitors/user/{userId}](#get-monitors-user-userid) - POST [/api/v1/monitors](#post-monitors) - POST [/api/v1/monitors/delete/{monitorId}](#post-monitors-del-id) - POST [/api/v1/monitors/edit/{monitorId}](#post-monitors-edit-id) ###### Checks - 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) --- ### Client #### Installation 1. Change directory to the `Client` directory 2. Install all dependencies by running `npm install` #### Starting Development Server 1. Run `npm run dev` to start the development server. --- ### Server #### Installation 1. Change directory to the `Server` directory 2. Install all dependencies by running `npm install` --- #### Configuration {#config-server} Configure the server with the following environmental variables | ENV Variable Name | Required/Optional | Type | Description | Accepted Values | | -------------------- | ----------------- | --------- | ----------------------------------------------------- | ------------------- | | JWT_SECRET | Required | `string` | JWT secret | | | DB_TYPE | Optional | `string` | Specify DB to use | `MongoDB \| FakeDB` | | DB_CONNECTION_STRING | Required | `string` | Specifies URL for MongoDB Database | | | PORT | Optional | `integer` | Specifies Port for Server | | | MAILERSEND_API_KEY | Required | `string` | Specifies API KEY for MailerSend service | | | SYSTEM_EMAIL_ADDRESS | Required | `string` | Specifies System email to be used in emailing service | | --- #### Starting the Development Server 1. run `npm run dev` to start the development server --- #### Endpoints All endpoints return a response in this format: | Name | Type | Notes | | ------- | --------- | ----------------------------- | | success | `boolean` | Success or failure of request | | msg | `string` | Message describing response | | data | `Object` | Arbitrary Payload | Example: ``` {success: true, msg: "Successful Request", data: {test: testData}} ``` --- ##### Data Types
User | Name | Type | Notes | | ------------- | --------- | --------------------- | | firstname | `string` | First name | | lastname | `string` | Last name | | email | `string` | User's email | | profilePicUrl | `string` | URL to User's picture | | isActive | `boolean` | Default to `true` | | isVerified | `boolean` | Default to `false` | | updated_at | `Date` | Last update time | | created_at | `Date` | Time created at |
Monitor | Name | Type | Notes | | ----------- | --------- | ---------------------------------------- | | userId | `string` | Unique ID identifying monitor creator | | name | `string` | Name of the monitor | | description | `string` | Description of the monitor | | url | `string` | Url the monitor will ping | | isActive | `boolean` | Whether or not the monitor is active | | interval | `integer` | Interval with which to ping monitor (ms) | | updatedAt | `Date` | Last time the monitor was updated | | CreatedAt | `Date` | When the monitor was updated |
Check | Name | Type | Notes | | ------------ | --------- | ----------------------------------------------- | | monitorId | `string` | Unique ID for the monitor | | status | `boolean` | Indicates the service is Up or Down | | responseTime | `integer` | Indicates the response time of the service (ms) | | statusCode | `integer` | Status Code returned from the service | | message | `string` | Message returned from the service | | updatedAt | `Date` | Last time the check was updated | | CreatedAt | `Date` | When the check was created |
Alert | Name | Type | Notes | | ----------------- | --------- | ------------------------------------------------- | | checkId | `string` | Unique ID for the associated check | | monitorId | `string` | Unique ID for the associated monitor | | userId | `string` | Unique ID for the associated user | | status | `boolean` | Indicates the service is Up or Down | | message | `string` | Message for the user about the down service | | notifiedStatus | `boolean` | Indicates whether the user is notified | | acknowledgeStatus | `boolean` | Indicates whether the user acknowledged the alert | | updatedAt | `Date` | Last time the alert was updated | | CreatedAt | `Date` | When the alert was created |
--- ###### Auth
POST /api/v1/auth/register ##### Method/Headers > | Method/Headers | Value | > | -------------- | ---------------- | > | Method | POST | > | content-type | application/json | ##### Body > | Name | Type | Notes | > | --------- | -------- | ------------------- | > | firstname | `string` | | > | lastname | `string` | > | email | `string` | Valid email address | > | password | `string` | Min 8 chars | ##### Response Payload > | Type | Notes | > | ---- | ---------------------------------- | > | JWT | JSON Web Token containing a `User` | ##### Sample CURL request ``` curl --request POST \ --url http://localhost:5000/api/v1/auth/register \ --header 'Content-Type: application/json' \ --data '{ "firstname" : "User First Name", "lastname": "User Last Name", "email" : "user@gmail.com", "password": "user_password" }' ``` ##### Sample Response ```json { "success": true, "msg": "User created", "data": "" } ```
POST /api/v1/auth/login ##### Method/Headers > | Method/Headers | Value | > | -------------- | ---------------- | > | Method | POST | > | content-type | application/json | ##### Body > | Name | Type | Notes | > | -------- | -------- | ------------------- | > | email | `string` | Valid email address | > | password | `string` | Min 8 chars | ##### Response Payload > | Type | Notes | > | ---- | ---------------------------------- | > | JWT | JSON Web Token Containing a `User` | ##### Sample CURL request ``` curl --request POST \ --url http://localhost:5000/api/v1/auth/login \ --header 'Content-Type: application/json' \ --data '{ "email" : "user@gmail.com", "password": "user_password" }' ``` ##### Sample response ```json { "success": true, "msg": "Found user", "data": "" } ```
POST/api/v1/auth/user/{userId} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | POST | ##### Body > | Name | Type | Notes | > | ------------- | -------- | ----------- | > | firstname | `string` | | > | lastname | `string` | | > | profilePicUrl | `string` | | > | password | `string` | Min 8 chars | ###### Response Payload > | Type | Notes | > | ------ | ------------------------ | > | `User` | Returns the updated user | ##### Sample CURL request ``` curl --request POST \ --url http://localhost:5000/api/v1/auth/user/6654d156634754f789e1f10e \ --header 'Authorization: ' \ --header 'Content-Type: application/json' \ --data '{ "firstname": "First Name", "lastname: "Last Name" }' ``` ###### Sample Response ```json { "success": true, "msg": "User updated", "data": { "_id": "6654d156634754f789e1f10e", "firstname": "First Name", "lastname": "Last Name", "email": "me@gmail.com", "isActive": true, "isVerified": false, "createdAt": "2024-05-27T18:30:46.358Z", "updatedAt": "2024-05-27T19:21:51.747Z", "__v": 0 } } ```
--- ###### Monitors
GET /api/v1/monitors ##### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | GET | ##### Response Payload > | Type | Notes | > | ---------------- | --------------------- | > | `Array` | Array of all monitors | ###### Sample cURL Request ``` curl --request GET \ --url http://localhost:5000/api/v1/monitors \ --header '' \ ``` ###### Sample Response ```json { "success": true, "msg": "Monitors found", "data": [ { "_id": "664d070786e62625ac612ca1", "userId": "6645079aae0b439371913972", "name": "Wha3", "description": "Description", "url": "https://monitor0.com", "isActive": true, "interval": 60000, "createdAt": "2024-05-21T20:41:43.051Z", "updatedAt": "2024-05-21T20:45:10.496Z", "__v": 0 }, { "_id": "664e5ccf189c864800debc16", "userId": "6645079aae0b439371913972", "name": "Inserting a new Monitor", "description": "Description", "url": "https://monitor0.com", "isActive": true, "interval": 60000, "createdAt": "2024-05-22T20:59:59.295Z", "updatedAt": "2024-05-22T20:59:59.295Z", "__v": 0 } ] } ```
GET /api/v1/monitor/{id} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | GET | ###### Response Payload > | Type | Notes | > | --------- | --------------------------------------------------- | > | `Monitor` | Single monitor with the id in the request parameter | ###### Sample cURL Request ``` curl --request GET \ --url http://localhost:5000/api/v1/monitors/664d070786e62625ac612ca1 \ --header '' \ ``` ###### Sample Response ```json { "success": true, "msg": "Monitor found", "data": { "_id": "664d070786e62625ac612ca1", "userId": "6645079aae0b439371913972", "name": "My Monitor", "description": "Description", "url": "https://monitor0.com", "isActive": true, "interval": 60000, "createdAt": "2024-05-21T20:41:43.051Z", "updatedAt": "2024-05-21T20:45:10.496Z", "__v": 0 } } ```
GET /api/v1/monitors/user/{userId} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | GET | ###### Response Payload > | Type | Notes | > | ---------------- | ------------------------------------------------------- | > | `Array` | Array of monitors created by user with specified UserID | ###### Sample cURL Request ``` curl --request GET \ --url http://localhost:5000/api/v1/monitors/user/6645079aae0b439371913972 \ --header '' \ ``` ###### Sample Response ```json { "success": true, "msg": "Monitors for user 6645079aae0b439371913972 found", "data": [ { "_id": "664d070786e62625ac612ca1", "userId": "6645079aae0b439371913972", "name": "Wha3", "description": "Description", "url": "https://monitor0.com", "isActive": true, "interval": 60000, "createdAt": "2024-05-21T20:41:43.051Z", "updatedAt": "2024-05-21T20:45:10.496Z", "__v": 0 }, { "_id": "664e5ccf189c864800debc16", "userId": "6645079aae0b439371913972", "name": "Inserting a new Monitor", "description": "Description", "url": "https://monitor0.com", "isActive": true, "interval": 60000, "createdAt": "2024-05-22T20:59:59.295Z", "updatedAt": "2024-05-22T20:59:59.295Z", "__v": 0 } ] } ```
POST/api/v1/monitors ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | POST | ###### Response Payload > | Type | Notes | > | --------- | ------------------------------- | > | `Monitor` | Returns newly created `Monitor` | ##### Sample CURL request ``` curl --request POST \ --url http://localhost:5000/api/v1/monitors \ --header \ --header 'Content-Type: application/json' \ --data '{"userId": "6645079aae0b439371913972", "name": "Inserting a new Monitor", "description": "Description", "url": "https://monitor0.com", "isActive": true, "interval": 60000}' ``` ##### Sample Response ```json { "success": true, "msg": "Monitor created", "data": { "userId": "6645079aae0b439371913972", "name": "Inserting a new Monitor", "description": "Description", "url": "https://monitor0.com", "isActive": true, "interval": 60000, "_id": "664e5ccf189c864800debc16", "createdAt": "2024-05-22T20:59:59.295Z", "updatedAt": "2024-05-22T20:59:59.295Z", "__v": 0 } } ```
POST/api/v1/monitors/delete/{monitorId} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | POST | ###### Response Payload > | Type | Notes | > | ---- | ------------------- | > | None | No payload returned | ###### Sample CURL request ``` curl --request POST \ --url http://localhost:5000/api/v1/monitors/delete/664e632a7a3ee9d620761938 \ --header '' \ --header 'Content-Type: application/json' \ ``` ###### Sample Response ```json { "success": true, "msg": "Monitor deleted" } ``` ##
POST/api/v1/monitors/edit/{monitorId} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | POST | ###### Response Payload > | Type | Notes | > | --------- | --------------------------- | > | `Monitor` | Returns the updated monitor | ##### Sample CURL request ``` curl --request POST \ --url http://localhost:5000/api/v1/monitors/edit/664e5ccf189c864800debc16 \ --header ' --- ###### Checks
POST/api/v1/checks/{monitorId} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | POST | ###### Response Payload > | Type | Notes | > | ---- | ------------------- | > | None | No payload returned | ###### Body ##### Sample CURL request ``` ``` ###### Sample Response ```json ```
GET/api/v1/checks/{monitorId} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | POST | ###### Response Payload > | Type | Notes | > | --------------- | ------------------------ | > | `Array` | Array of `Check` objects | ##### Sample CURL request ``` ``` ###### Sample Response ```json ```
POST/api/v1/checks/delete/{monitorId} ###### Method/Headers > | Method/Headers | Value | > | -------------- | ----- | > | Method | POST | ###### Response Payload > | Type | Notes | > | ---- | ------------------- | > | None | No payload returned | ###### Body ##### Sample CURL request ``` ``` ###### Sample Response ```json ```
--- ###### 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: `{"success": false, "msg": "No token provided"}` Errors are handled by error handling middleware and should be thrown with the following parameters | Name | Type | Default | Notes | | ------- | --------- | ---------------------- | ------------------------------------ | | status | `integer` | 500 | Standard HTTP codes | | message | `string` | "Something went wrong" | An error message | | service | `string` | "Unknown Service" | Name of service that threw the error | Example: ``` const myRoute = async(req, res, next) => { try{ const result = myRiskyOperationHere(); } catch(error){ error.status = 404 error.message = "Resource not found" error.service = service name next(error) return; } } ``` Errors should not be handled at the controller level and should be left to the middleware to handle. ## Contributors Made with [contrib.rocks](https://contrib.rocks).