Skip to content

Commit

Permalink
1086/security issues verified (#1521)
Browse files Browse the repository at this point in the history
* add verification check before mutations

* remove log

* cleanup unused imports

* update tests

* update Update and Read tests

* move vble to env file

* undo secret removal

---------

Co-authored-by: Brad <[email protected]>
Co-authored-by: Trillium S <[email protected]>
  • Loading branch information
3 people authored Oct 10, 2023
1 parent 942b871 commit 3556bae
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 19 deletions.
2 changes: 1 addition & 1 deletion backend/middleware/user.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function isAdminByEmail(req, res, next) {
return res.sendStatus(400);
} else {
const role = user.accessLevel;
if (req.get('origin').includes('3001') || role === 'admin' || user.managedProjects.length > 0) {
if (role === 'admin' || user.managedProjects.length > 0) {
next();
} else {
next(res.sendStatus(401));
Expand Down
7 changes: 4 additions & 3 deletions backend/routers/projects.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ const express = require("express");
const router = express.Router();

const { ProjectController } = require('../controllers');
const { AuthUtil } = require("../middleware");

// The base is /api/projects
router.get('/', ProjectController.project_list);

router.post('/', ProjectController.create);
router.post('/', AuthUtil.verifyCookie, ProjectController.create);

router.get('/:ProjectId', ProjectController.project_by_id);

router.put('/:ProjectId', ProjectController.update);
router.put('/:ProjectId', AuthUtil.verifyCookie, ProjectController.update);

router.patch('/:ProjectId', ProjectController.update);
router.patch('/:ProjectId', AuthUtil.verifyCookie, ProjectController.update);


module.exports = router;
148 changes: 142 additions & 6 deletions backend/routers/projects.router.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,58 @@
const supertest = require('supertest');
const app = require('../app');
const request = supertest(app);
const jwt = require('jsonwebtoken');
const { CONFIG_AUTH } = require('../config');


const { setupDB } = require('../setup-test');
setupDB('api-projects');

const { Project } = require('../models');
const { Project, User } = require('../models');
const CONFIG = require('../config/auth.config');

const headers = {};
headers['x-customrequired-header'] = CONFIG.CUSTOM_REQUEST_HEADER;
headers.Accept = 'application/json';
headers.authorization = 'Bearer sometoken';

let token;


describe('CREATE', () => {
beforeAll( async () => {
const submittedData = {
name: {
firstName: 'test',
lastName: 'user',
},
email: '[email protected]',
};
const user = await User.create(submittedData);
const auth_origin = 'TEST';
token = jwt.sign(
{ id: user.id, role: user.accessLevel, auth_origin },
CONFIG_AUTH.SECRET,
{
expiresIn: `${CONFIG_AUTH.TOKEN_EXPIRATION_SEC}s`,
},
);
})
test('Create a Project with POST to /api/projects/ without token', async (done) => {
// Test Data
const submittedData = {
name: 'projectName',
};

// Submit a project
const res = await request
.post('/api/projects/')
.set(headers)
.send(submittedData);
expect(res.status).toBe(401);
done();
});

test('Create a Project with POST to /api/projects/', async (done) => {
// Test Data
const submittedData = {
Expand All @@ -23,6 +63,7 @@ describe('CREATE', () => {
const res = await request
.post('/api/projects/')
.set(headers)
.set('Cookie', [`token=${token}`] )
.send(submittedData);
expect(res.status).toBe(201);
done();
Expand All @@ -40,6 +81,7 @@ describe('READ', () => {
const res = await request
.post('/api/projects/')
.set(headers)
.set('Cookie', [`token=${token}`])
.send(submittedData);
expect(res.status).toBe(201);

Expand All @@ -54,7 +96,25 @@ describe('READ', () => {
});

describe('UPDATE', () => {
test('Update a project with PATCH to /api/projects/:id', async (done) => {
beforeAll(async () => {
const submittedData = {
name: {
firstName: 'test',
lastName: 'user',
},
email: '[email protected]',
};
const user = await User.create(submittedData);
const auth_origin = 'TEST';
token = jwt.sign(
{ id: user.id, role: user.accessLevel, auth_origin },
CONFIG_AUTH.SECRET,
{
expiresIn: `${CONFIG_AUTH.TOKEN_EXPIRATION_SEC}s`,
},
);
})
test('Update a project with PATCH to /api/projects/:id without a token', async (done) => {
// Test Data
const submittedData = {
name: 'projectName',
Expand All @@ -64,6 +124,7 @@ describe('UPDATE', () => {
const res = await request
.post('/api/projects/')
.set(headers)
.set('Cookie', [`token=${token}`])
.send(submittedData);
expect(res.status).toBe(201);

Expand All @@ -76,10 +137,44 @@ describe('UPDATE', () => {
.put(`/api/projects/${res.body._id}`)
.set(headers)
.send(updatedDataPayload);
expect(res2.status).toBe(200);
expect(res2.status).toBe(401);

// Get project
const res3 = await request.get(`/api/projects/${res.body._id}`)
.set(headers);
expect(res3.status).toBe(200);
done();
});
test('Update a project with PATCH to /api/projects/:id with a token', async (done) => {
// Test Data
const submittedData = {
name: 'projectName',
};

// Submit a project
const res = await request
.post('/api/projects/')
.set(headers)
.set('Cookie', [`token=${token}`])
.send(submittedData);
expect(res.status).toBe(201);

const updatedDataPayload = {
name: 'updatedProjectName',
};

// Update project
const res2 = await request
.put(`/api/projects/${res.body._id}`)
.set(headers)
.set('Cookie', [`token=${token}`])
.send(updatedDataPayload);
expect(res2.status).toBe(200)

// Get project
const res3 = await request.get(`/api/projects/${res.body._id}`).set(headers);
const res3 = await request.get(`/api/projects/${res.body._id}`)
.set(headers)
.set('Cookie', [`token=${token}`])
expect(res3.status).toBe(200);

const APIData = res3.body;
Expand All @@ -89,7 +184,45 @@ describe('UPDATE', () => {
});

describe('DELETE', () => {
test('Delete a project with POST to /api/projects/:id', async (done) => {
beforeAll(async () => {
const submittedData = {
name: {
firstName: 'test',
lastName: 'user',
},
email: '[email protected]',
};
const user = await User.create(submittedData);
const auth_origin = 'TEST';
token = jwt.sign(
{ id: user.id, role: user.accessLevel, auth_origin },
CONFIG_AUTH.SECRET,
{
expiresIn: `${CONFIG_AUTH.TOKEN_EXPIRATION_SEC}s`,
},
);
})
test('Delete a project with POST to /api/projects/:id without a token', async (done) => {
// Test Data
const submittedData = {
name: 'projectName',
};

// Submit a project
const res = await request
.post('/api/projects/')
.set(headers)
.set('Cookie', [`token=${token}`])
.send(submittedData);
expect(res.status).toBe(201);

// Delete project
const res2 = await request.patch(`/api/projects/${res.body._id}`)
.set(headers);
expect(res2.status).toBe(401);
done();
});
test('Delete a project with POST to /api/projects/:id with a token', async (done) => {
// Test Data
const submittedData = {
name: 'projectName',
Expand All @@ -99,11 +232,14 @@ describe('DELETE', () => {
const res = await request
.post('/api/projects/')
.set(headers)
.set('Cookie', [`token=${token}`])
.send(submittedData);
expect(res.status).toBe(201);

// Delete project
const res2 = await request.patch(`/api/projects/${res.body._id}`).set(headers);
const res2 = await request.patch(`/api/projects/${res.body._id}`)
.set(headers)
.set('Cookie', [`token=${token}`])
expect(res2.status).toBe(200);
done();
});
Expand Down
7 changes: 4 additions & 3 deletions backend/routers/recurringEvents.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const cors = require('cors');

const { RecurringEvent } = require('../models/recurringEvent.model');
const { RecurringEventController } = require('../controllers/');
const { AuthUtil } = require('../middleware');

// GET /api/recurringevents/
router.get('/', cors(), (req, res) => {
Expand Down Expand Up @@ -34,10 +35,10 @@ router.get('/:id', (req, res) => {
});
});

router.post('/', RecurringEventController.create);
router.post('/', AuthUtil.verifyCookie, RecurringEventController.create);

router.patch('/:RecurringEventId', RecurringEventController.update);
router.patch('/:RecurringEventId', AuthUtil.verifyCookie, RecurringEventController.update);

router.delete('/:RecurringEventId', RecurringEventController.destroy);
router.delete('/:RecurringEventId', AuthUtil.verifyCookie, RecurringEventController.destroy);

module.exports = router;
2 changes: 0 additions & 2 deletions client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import HealthCheck from './pages/HealthCheck';
import SecretPassword from './pages/SecretPassword';
import UserWelcome from './pages/UserWelcome';

import ProjectForm from './components/ProjectForm';

import { ThemeProvider } from '@mui/material';
import theme from './theme';

Expand Down
1 change: 0 additions & 1 deletion client/src/components/ProjectForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Redirect } from 'react-router-dom';
import {
Typography,
Box,
Divider,
Button,
Grid,
Radio,
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/manageProjects/editProject.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import TitledBox from '../parts/boxes/TitledBox';
import { ReactComponent as EditIcon } from '../../svg/Icon_Edit.svg';
import { ReactComponent as PlusIcon } from '../../svg/PlusIcon.svg';

import { Typography, Box, Divider } from '@mui/material';
import { Typography, Box } from '@mui/material';

// Need to hold user state to check which type of user they are and conditionally render editing fields in this component
// for user level block access to all except for the ones checked
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import validator from 'validator';
import { isWordInArrayInString } from './../../../utils/stringUtils.js';
import { el } from 'date-fns/locale';

const validateEventForm = (vals, projectToEdit) => {
let newErrors = {};
Expand Down
1 change: 0 additions & 1 deletion client/src/pages/ProjectList.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
Box,
CircularProgress,
Typography,
Divider,
Button,
} from '@mui/material';
import { Link } from 'react-router-dom';
Expand Down

0 comments on commit 3556bae

Please sign in to comment.