Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1086/security issues verified #1521

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading