Merge branch 'bluewave-labs:master' into register-page
This commit is contained in:
22 files changed
+573
-79
No files matched your search
+2
-1
@@ -1 +1,2 @@
|
||||
.vite
|
||||
.vite
|
||||
.vscode
|
||||
+12
-1
@@ -6,12 +6,23 @@ import Register from "./Pages/Register";
|
||||
import HomeLayout from "./Layouts/HomeLayout";
|
||||
import Demo from "./Pages/Demo/Demo";
|
||||
import PlayGround from "./Pages/PlayGround/PlayGround";
|
||||
import Monitors from "./Pages/Monitors"
|
||||
import Incidents from "./Pages/Incidents";
|
||||
import Status from "./Pages/Status";
|
||||
import Integrations from "./Pages/Integrations";
|
||||
import Settings from "./Pages/Settings";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
<Routes>
|
||||
<Route exact path="/" element={<HomeLayout />} />
|
||||
<Route exact path="/" element={<HomeLayout />} >
|
||||
<Route path="monitors" element={<Monitors />} />
|
||||
<Route path="incidents" element={<Incidents />} />
|
||||
<Route path="status" element={<Status />} />
|
||||
<Route path="integrations" element={<Integrations />} />
|
||||
<Route path="settings" element={<Settings />} />
|
||||
</Route>
|
||||
<Route exact path="/register" element={<Register />} />
|
||||
<Route exact path="/login" element={<Login />} />
|
||||
<Route exact path="/demo" element={<Demo />} />
|
||||
|
||||
@@ -1,10 +1,48 @@
|
||||
import React from 'react'
|
||||
import './index.css'
|
||||
import { useState } from 'react';
|
||||
import './index.css';
|
||||
import Button from '@mui/material/Button';
|
||||
import Menu from '@mui/material/Menu';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
|
||||
const NavBar = () => {
|
||||
return (
|
||||
<div>NavBar Component</div>
|
||||
)
|
||||
}
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const open = Boolean(anchorEl);
|
||||
|
||||
export default NavBar
|
||||
const handleClick = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
id="basic-button"
|
||||
aria-controls={open ? 'basic-menu' : undefined}
|
||||
aria-haspopup="true"
|
||||
aria-expanded={open ? 'true' : undefined}
|
||||
onClick={handleClick}
|
||||
>
|
||||
Jackie Dawn
|
||||
</Button>
|
||||
<Menu
|
||||
id="basic-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
MenuListProps={{
|
||||
'aria-labelledby': 'basic-button',
|
||||
}}
|
||||
>
|
||||
<MenuItem onClick={handleClose}>Profile</MenuItem>
|
||||
<MenuItem onClick={handleClose}>Team</MenuItem>
|
||||
<MenuItem onClick={handleClose}>Invite Colleagues</MenuItem>
|
||||
<MenuItem onClick={handleClose}>Log Out</MenuItem>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavBar;
|
||||
@@ -8,10 +8,6 @@ const Home = () => {
|
||||
return (
|
||||
<>
|
||||
<div>Home</div>
|
||||
<DropdownTeamMember />
|
||||
<Search />
|
||||
<DashboardMenu />
|
||||
<Integrations />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Whitespace-only changes.
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
const Incidents = () => {
|
||||
return (
|
||||
<div>Incidents</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Incidents
|
||||
Whitespace-only changes.
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
const Integrations = () => {
|
||||
return (
|
||||
<div>Integrations</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Integrations
|
||||
Whitespace-only changes.
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
const Monitors = () => {
|
||||
return (
|
||||
<div>Monitors</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Monitors
|
||||
Whitespace-only changes.
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
const Settings = () => {
|
||||
return (
|
||||
<div>Settings</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Settings
|
||||
Whitespace-only changes.
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
const Status = () => {
|
||||
return (
|
||||
<div>Status</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Status
|
||||
@@ -31,7 +31,7 @@ BlueWave uptime monitoring application
|
||||
#### Installation
|
||||
|
||||
1. Change directory to the `Server` directory
|
||||
2. Install all depencies by running `npm install`
|
||||
2. Install all dependencies by running `npm install`
|
||||
|
||||
---
|
||||
|
||||
@@ -39,13 +39,14 @@ BlueWave uptime monitoring application
|
||||
|
||||
Configure the server with the following environmental variables
|
||||
|
||||
| ENV Varialbe Name | Required/Optional | Type | Description | Accepted Values |
|
||||
| -------------------- | ----------------- | ------- | ---------------------------------------------------- | ------------------- |
|
||||
| DB_TYPE | Optional | string | Specify DB to use | `MongoDB \| FakeDB` |
|
||||
| DB_CONNECTION_STRING | Required | string | Specfies URL for MongoDB Database | |
|
||||
| PORT | Optional | Integer | Specifies Port for Server | |
|
||||
| MAILERSEND_API_KEY | Required | string | Specfies API KEY for MailerSend service | |
|
||||
| SYSTEM_EMAIL_ADDRESS | Required | string | Specfies System email to be used in emailing service | |
|
||||
| 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 | |
|
||||
|
||||
---
|
||||
|
||||
@@ -130,9 +131,9 @@ Example:
|
||||
|
||||
##### Response Payload
|
||||
|
||||
> | Type | Notes |
|
||||
> | ------ | ---------- |
|
||||
> | `User` | User model |
|
||||
> | Type | Notes |
|
||||
> | ---- | ---------------------------------- |
|
||||
> | JWT | JSON Web Token containing a `User` |
|
||||
|
||||
##### Sample CURL request
|
||||
|
||||
@@ -153,18 +154,8 @@ curl --request POST \
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"msg": "User created}",
|
||||
"data": {
|
||||
"_id": "6645079aae0b439371913972",
|
||||
"firstname": "User First Name",
|
||||
"lastname": "User Last Name",
|
||||
"email": "user@gmail.com",
|
||||
"isActive": true,
|
||||
"isVerified": false,
|
||||
"updated_at": "2024-05-15T19:06:02.720Z",
|
||||
"created_at": "2024-05-15T19:06:02.720Z",
|
||||
"__v": 0
|
||||
}
|
||||
"msg": "User created",
|
||||
"data": "<encoded_user>"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -191,9 +182,9 @@ curl --request POST \
|
||||
|
||||
##### Response Payload
|
||||
|
||||
> | Type | Notes |
|
||||
> | ------ | ---------- |
|
||||
> | `User` | User model |
|
||||
> | Type | Notes |
|
||||
> | ---- | ---------------------------------- |
|
||||
> | JWT | JSON Web Token Containing a `User` |
|
||||
|
||||
##### Sample CURL request
|
||||
|
||||
@@ -213,17 +204,7 @@ curl --request POST \
|
||||
{
|
||||
"success": true,
|
||||
"msg": "Found user",
|
||||
"data": {
|
||||
"_id": "6644fb9bae0b439371913969",
|
||||
"firstname": "User First Name",
|
||||
"lastname": "User Last Name",
|
||||
"email": "user@gmail.com",
|
||||
"isActive": true,
|
||||
"isVerified": false,
|
||||
"updated_at": "2024-05-15T18:14:51.049Z",
|
||||
"created_at": "2024-05-15T18:14:51.049Z",
|
||||
"__v": 0
|
||||
}
|
||||
"data": "<encoded_user>"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -246,6 +227,49 @@ curl --request POST \
|
||||
> | ---------------- | ----------------- |
|
||||
> | `Array[Monitor]` | Array of monitors |
|
||||
|
||||
###### Sample cURL Request
|
||||
|
||||
```
|
||||
curl --request GET \
|
||||
--url http://localhost:5000/api/v1/monitors \
|
||||
--header '<bearer_token>' \
|
||||
```
|
||||
|
||||
###### 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
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
@@ -265,6 +289,35 @@ curl --request POST \
|
||||
> | --------- | --------------------------------------------------- |
|
||||
> | `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 '<bearer_token>' \
|
||||
```
|
||||
|
||||
###### 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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
@@ -278,16 +331,210 @@ curl --request POST \
|
||||
> | -------------- | ----- |
|
||||
> | Method | GET |
|
||||
|
||||
###### Request Payload
|
||||
###### Response Payload
|
||||
|
||||
> | Type | Notes |
|
||||
> | ---------------- | ------------------------------------------------------------------ |
|
||||
> | `Array[Monitor]` | Array of monitors created by user with userId specified in request |
|
||||
|
||||
###### Sample cURL Request
|
||||
|
||||
```
|
||||
curl --request GET \
|
||||
--url http://localhost:5000/api/v1/monitors/user/6645079aae0b439371913972 \
|
||||
--header '<bearer_token>' \
|
||||
```
|
||||
|
||||
###### 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
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><code>POST</code><b>/api/v1/monitors</b></summary>
|
||||
|
||||
###### Method/Headers
|
||||
|
||||
> | Method/Headers | Value |
|
||||
> | -------------- | ----- |
|
||||
> | Method | POST |
|
||||
|
||||
###### Response Payload
|
||||
|
||||
> | Type | Notes |
|
||||
> | --------- | --------------------------------- |
|
||||
> | `Monitor` | Newly created monitor is returned |
|
||||
|
||||
##### Sample CURL request
|
||||
|
||||
```
|
||||
curl --request POST \
|
||||
--url http://localhost:5000/api/v1/monitors \
|
||||
--header <bearer_token> \
|
||||
--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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><code>POST</code><b>/api/v1/monitors/delete/{monitorId}</b></summary>
|
||||
|
||||
###### 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 '<bearer_token>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
```
|
||||
|
||||
###### Sample Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"msg": "Monitor deleted"
|
||||
}
|
||||
```
|
||||
|
||||
## </details>
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><code>POST</code><b>/api/v1/monitors/edit/{monitorId}</b></summary>
|
||||
|
||||
###### 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 '<bearer_token' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '
|
||||
{
|
||||
"_id": "664e5ccf189c864800debc16",
|
||||
"userId": "6645079aae0b439371913972",
|
||||
"name": "Edited monitor",
|
||||
"description": "Description",
|
||||
"url": "https://monitor0.com",
|
||||
"isActive": true,
|
||||
"interval": 60000
|
||||
}'
|
||||
```
|
||||
|
||||
###### Sample Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"msg": "Monitor edited",
|
||||
"data": {
|
||||
"_id": "664e5ccf189c864800debc16",
|
||||
"userId": "6645079aae0b439371913972",
|
||||
"name": "Edited monitor",
|
||||
"description": "Description",
|
||||
"url": "https://monitor0.com",
|
||||
"isActive": true,
|
||||
"interval": 60000,
|
||||
"createdAt": "2024-05-22T20:59:59.295Z",
|
||||
"updatedAt": "2024-05-22T21:34:33.893Z",
|
||||
"__v": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 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).
|
||||
@@ -1,7 +1,19 @@
|
||||
const express = require("express");
|
||||
const UserModel = require("../models/user");
|
||||
const { registerValidation, loginValidation } = require("../validation/joi");
|
||||
const logger = require("../utils/logger");
|
||||
require("dotenv").config();
|
||||
var jwt = require("jsonwebtoken");
|
||||
const SERVICE_NAME = "auth";
|
||||
|
||||
/**
|
||||
* Creates and returns JWT token with an arbitrary payload
|
||||
* @function
|
||||
* @param {Object} payload
|
||||
* @returns {String}
|
||||
*/
|
||||
const issueToken = (payload) => {
|
||||
return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "1h" });
|
||||
};
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -23,16 +35,16 @@ const registerController = async (req, res) => {
|
||||
try {
|
||||
const isUser = await req.db.getUserByEmail(req, res);
|
||||
if (isUser) {
|
||||
logger.error("User already exists!", {
|
||||
service: "auth",
|
||||
logger.error("User already exists", {
|
||||
service: SERVICE_NAME,
|
||||
userId: isUser._id,
|
||||
});
|
||||
return res
|
||||
.status(400)
|
||||
.json({ success: false, msg: "User already exists!" });
|
||||
.json({ success: false, msg: "User already exists" });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error.message, { service: "auth" });
|
||||
logger.error(error.message, { service: SERVICE_NAME });
|
||||
return res.status(500).json({ success: false, msg: error.message });
|
||||
}
|
||||
|
||||
@@ -41,20 +53,29 @@ const registerController = async (req, res) => {
|
||||
const newUser = await req.db.insertUser(req, res);
|
||||
// TODO: Send an email to user
|
||||
// Will add this later
|
||||
logger.info("New user created!", { service: "auth", userId: newUser._id });
|
||||
logger.info("New user created!", {
|
||||
service: SERVICE_NAME,
|
||||
userId: newUser._id,
|
||||
});
|
||||
const token = issueToken(newUser._doc);
|
||||
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: "User created}", data: newUser });
|
||||
.json({ success: true, msg: "User created", data: token });
|
||||
} catch (error) {
|
||||
logger.error(error.message, { service: "auth" });
|
||||
logger.error(error.message, { service: SERVICE_NAME });
|
||||
return res.status(500).json({ success: false, msg: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
// **************************
|
||||
// Handles logging in a user
|
||||
// Returns a user at the moment, but will likely return a JWT in the future
|
||||
// **************************
|
||||
/**
|
||||
* Returns JWT with User info
|
||||
* @async
|
||||
* @param {Express.Request} req
|
||||
* @param {Express.Response} res
|
||||
* @returns {Promise<Express.Response>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const loginController = async (req, res) => {
|
||||
try {
|
||||
// Validate input
|
||||
@@ -69,25 +90,22 @@ const loginController = async (req, res) => {
|
||||
}
|
||||
// Compare password
|
||||
const match = await user.comparePassword(req.body.password);
|
||||
console.log(user);
|
||||
if (!match) {
|
||||
throw new Error("Password does not match!");
|
||||
}
|
||||
|
||||
// Copy user to remove password. More memory, but better than mutating user?
|
||||
// We can move this to the DB layer if we want
|
||||
// Probably not neccessary at all as we'll likely return a JWT instead of a user
|
||||
// Remove password from user object. Should this be abstracted to DB layer?
|
||||
const userWithoutPassword = { ...user._doc };
|
||||
delete userWithoutPassword.password;
|
||||
|
||||
// Happy path, return user
|
||||
// In the future we'll probably return a JWT instead of a user
|
||||
// Happy path, return token
|
||||
const token = issueToken(userWithoutPassword);
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: "Found user", data: userWithoutPassword });
|
||||
.json({ success: true, msg: "Found user", data: token });
|
||||
} catch (error) {
|
||||
// Anything else should be an error
|
||||
logger.error(error.message, { service: "auth" });
|
||||
logger.error(error.message, { service: SERVICE_NAME });
|
||||
return res.status(500).json({ success: false, msg: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ const {
|
||||
} = require("../validation/joi");
|
||||
|
||||
const logger = require("../utils/logger");
|
||||
const Monitor = require("../models/Monitor");
|
||||
|
||||
/**
|
||||
* Returns all monitors
|
||||
@@ -42,8 +41,7 @@ const getMonitorById = async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const monitorId = req.params.monitorId;
|
||||
const monitor = await req.db.getMonitorById(monitorId);
|
||||
const monitor = await req.db.getMonitorById(req, res);
|
||||
return res.json({ success: true, msg: "Monitor found", data: monitor });
|
||||
} catch (error) {
|
||||
logger.error(error.message, { service: "monitor" });
|
||||
@@ -69,7 +67,7 @@ const getMonitorsByUserId = async (req, res) => {
|
||||
|
||||
try {
|
||||
const userId = req.params.userId;
|
||||
const monitors = await req.db.getMonitorsByUserId(userId);
|
||||
const monitors = await req.db.getMonitorsByUserId(req, res);
|
||||
logger.info(`Monitors for user ${userId} found`, {
|
||||
service: "monitor",
|
||||
userId: userId,
|
||||
@@ -137,7 +135,7 @@ const deleteMonitor = async (req, res) => {
|
||||
* when it is deleted so there is no orphaned data
|
||||
* We also need to make sure to stop all running services for this monitor
|
||||
*/
|
||||
return res.status(204).json({ success: true, msg: "Monitor deleted" });
|
||||
return res.status(200).json({ success: true, msg: "Monitor deleted" });
|
||||
} catch (error) {
|
||||
logger.error(error.message, { service: "monitor" });
|
||||
return res.status(500).json({ success: false, msg: error.message });
|
||||
|
||||
+3
-1
@@ -41,7 +41,9 @@ const insertUser = async (req, res) => {
|
||||
const salt = await bcrypt.genSalt(10); //genSalt is asynchronous, need to wait
|
||||
newUser.password = await bcrypt.hash(newUser.password, salt); // hash is also async, need to eitehr await or use hashSync
|
||||
USERS.push(newUser);
|
||||
return newUser;
|
||||
const userToReturn = { ...newUser._doc };
|
||||
delete userToReturn.password;
|
||||
return userToReturn;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
+3
-2
@@ -6,6 +6,8 @@ const monitorRouter = require("./routes/monitorRoute");
|
||||
const { connectDbAndRunServer } = require("./configs/db");
|
||||
require("dotenv").config();
|
||||
const logger = require("./utils/logger");
|
||||
var { verifyJWT } = require("./middleware/verifyJWT");
|
||||
|
||||
// const { sendEmail } = require('./utils/sendEmail')
|
||||
|
||||
// **************************
|
||||
@@ -58,8 +60,7 @@ app.use((req, res, next) => {
|
||||
|
||||
//routes
|
||||
app.use("/api/v1/auth", authRouter);
|
||||
|
||||
app.use("/api/v1/monitors", monitorRouter);
|
||||
app.use("/api/v1/monitors", verifyJWT, monitorRouter);
|
||||
|
||||
// Testing email service
|
||||
// app.use('/sendEmail', async (req, res) => {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
const jwt = require("jsonwebtoken");
|
||||
const logger = require("../utils/logger");
|
||||
const SERVICE_NAME = "verifyJWT";
|
||||
const TOKEN_PREFIX = "Bearer ";
|
||||
|
||||
/**
|
||||
* Verifies the JWT token
|
||||
* @function
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
* @param {express.NextFunction} next
|
||||
* @returns {express.Response}
|
||||
*/
|
||||
const verifyJWT = (req, res, next) => {
|
||||
const token = req.headers["authorization"];
|
||||
// Make sure a token is provided
|
||||
if (!token) {
|
||||
logger.error("No token provided", { service: SERVICE_NAME });
|
||||
return res.status(401).json({ success: false, msg: "No token provided" });
|
||||
}
|
||||
// Make sure it is properly formatted
|
||||
if (token.startsWith(TOKEN_PREFIX)) {
|
||||
const parsedToken = token.slice(TOKEN_PREFIX.length, token.length);
|
||||
// Verify the token's authenticity
|
||||
jwt.verify(parsedToken, process.env.JWT_SECRET, (err, decoded) => {
|
||||
if (err) {
|
||||
logger.error("Invalid token", { service: SERVICE_NAME });
|
||||
return res.status(401).json({ success: false, msg: "Invalid token" });
|
||||
}
|
||||
//Add the user to the request object for use in the route
|
||||
req.user = decoded;
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
logger.error("Invalid token format", { service: SERVICE_NAME });
|
||||
return res
|
||||
.status(400)
|
||||
.json({ success: false, msg: "Invalid token format" });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { verifyJWT };
|
||||
Generated
+94
@@ -15,6 +15,7 @@
|
||||
"express": "^4.19.2",
|
||||
"helmet": "^7.1.0",
|
||||
"joi": "^17.13.1",
|
||||
"jsonwebtoken": "9.0.2",
|
||||
"mailersend": "^2.2.0",
|
||||
"mongoose": "^8.3.3",
|
||||
"winston": "^3.13.0"
|
||||
@@ -310,6 +311,11 @@
|
||||
"node": ">=16.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
@@ -535,6 +541,14 @@
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
@@ -1073,6 +1087,51 @@
|
||||
"@sideway/pinpoint": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
|
||||
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
|
||||
"dependencies": {
|
||||
"jws": "^3.2.2",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/jws": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
||||
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
||||
"dependencies": {
|
||||
"jwa": "^1.4.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/kareem": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
|
||||
@@ -1086,6 +1145,41 @@
|
||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
||||
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
||||
},
|
||||
"node_modules/lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
|
||||
},
|
||||
"node_modules/lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
|
||||
},
|
||||
"node_modules/lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
|
||||
},
|
||||
"node_modules/lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
|
||||
},
|
||||
"node_modules/lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
|
||||
},
|
||||
"node_modules/logform": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"express": "^4.19.2",
|
||||
"helmet": "^7.1.0",
|
||||
"joi": "^17.13.1",
|
||||
"jsonwebtoken": "9.0.2",
|
||||
"mailersend": "^2.2.0",
|
||||
"mongoose": "^8.3.3",
|
||||
"winston": "^3.13.0"
|
||||
|
||||
Reference in new issue
Block a user