Skip to content

Commit

Permalink
feat(secure): secure all routes
Browse files Browse the repository at this point in the history
  • Loading branch information
sojida committed Apr 4, 2019
1 parent 79f5bc5 commit 34d5673
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 12 deletions.
6 changes: 5 additions & 1 deletion server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ app.get('/', (req, res) => {
});

app.use('/api/v1', routes);

app.all('*', (req, res) => {
res.status(404).json({
error: 'This route does not exist yet!',
});
});
app.listen(port, () => {
// eslint-disable-next-line no-console
console.log(`App is listen on Port ${port}`);
Expand Down
6 changes: 6 additions & 0 deletions server/controllers/profile.controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ const controller = {
error: 'id not valid',
});
}
const { userObj } = req.user;
if (!validations.compareFieldWithToken(userObj.id, req.params.id)) {
return res.status(403).json({
error: 'User does not own this account',
});
}

const updateBody = req.body;

Expand Down
20 changes: 12 additions & 8 deletions server/helpers/validations.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,16 @@ const validations = {
return valid;
},
verifyAuthHeader(req) {
if (!req.headers.authorization) {
return { error: 'error' };
}
const token = req.headers.authorization;
const payload = Authenticate.decode(token);
if (!payload) {
try {
if (!req.headers.authorization) {
return { error: 'error' };
}
const token = req.headers.authorization;
const payload = Authenticate.decode(token);
return payload;
} catch (err) {
return { error: 'Invalid token' };
}
return payload;
},

/**
Expand All @@ -74,7 +75,7 @@ const validations = {
const payload = validations.verifyAuthHeader(req);
let error;
let status;
if (!payload || payload === 'error') {
if (!payload || payload.error === 'error') {
status = 401;
error = 'You are not authorized';
}
Expand Down Expand Up @@ -142,6 +143,9 @@ const validations = {
next();
}
},
compareFieldWithToken(field, token) {
return field === token;
},
};

export default validations;
7 changes: 6 additions & 1 deletion server/routes/article.routes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import express from 'express';
import controllers from '../controllers';
import validations from '../helpers/validations';

const { articleController } = controllers;

const router = express.Router();

router.get('/article/:id', articleController.getOneArticle);
router.get(
'/article/:id',
validations.verifyUser,
articleController.getOneArticle
);

export default router;
14 changes: 12 additions & 2 deletions server/routes/profile.routes.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import express from 'express';
import controllers from '../controllers';
import middlewares from '../middlewares';
import validations from '../helpers/validations';

const { profileController } = controllers;
const { profileMiddleware } = middlewares;

const router = express.Router();

router.get('/profile/:id', profileController.getUserProfile);
router.get('/profile', profileController.getProfileByField);
router.get(
'/profile/:id',
validations.verifyUser,
profileController.getUserProfile
);
router.get(
'/profile',
validations.verifyUser,
profileController.getProfileByField
);

router.patch(
'/profile/:id',
validations.verifyUser,
profileMiddleware.validateUpdateProfile,
profileController.patchProfile
);
Expand Down
34 changes: 34 additions & 0 deletions tests/article.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,43 @@ import app from '../server/app';

chai.use(chaiHttp);

let userAToken;
let userBToken;

before('login admin', done => {
chai
.request(app)
.post('/api/v1/auth/login')
.send({
email: 'anayo@mail.com',
password: '12345678',
})
.end((err, res) => {
userAToken = res.body.user.token;
done();
});
});

before('login user', done => {
chai
.request(app)
.post('/api/v1/auth/login')
.send({
email: 'ameachichuks@gmail.com',
password: '12345678',
})
.end((err, res) => {
userBToken = res.body.user.token;
done();
});
});

describe('ARTICLE', () => {
it('should respond with the article', done => {
chai
.request(app)
.get('/api/v1/article/7139d3af-b8b4-44f6-a49f-9305791700f4')
.set('Authorization', userBToken)
.end((err, res) => {
expect(res).to.have.status(200);
const {
Expand Down Expand Up @@ -48,6 +80,7 @@ describe('ARTICLE', () => {
chai
.request(app)
.get(`/api/v1/article/7139d3af-b8b4-44f6-a49f-9305791700f4*`)
.set('Authorization', userAToken)
.end((err, res) => {
expect(res).to.have.status(400);
expect(res.body.error).to.equal('id not valid');
Expand All @@ -59,6 +92,7 @@ describe('ARTICLE', () => {
chai
.request(app)
.get(`/api/v1/article/4139d3af-b8b4-44f6-a49f-9305791700f4`)
.set('Authorization', userAToken)
.end((err, res) => {
expect(res).to.have.status(404);
expect(res.body.error).to.equal('Article not found');
Expand Down
10 changes: 10 additions & 0 deletions tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ describe('HOMEPAGE', () => {
done();
});
});

it('should respond with invalid route error', done => {
chai
.request(app)
.get('/thisisaninvalidroute')
.end((err, res) => {
expect(res).to.have.status(404);
done();
});
});
});
77 changes: 77 additions & 0 deletions tests/profile.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,43 @@ import app from '../server/app';

chai.use(chaiHttp);

let userAToken;
let userBToken;

before('login admin', done => {
chai
.request(app)
.post('/api/v1/auth/login')
.send({
email: 'anayo@mail.com',
password: '12345678',
})
.end((err, res) => {
userAToken = res.body.user.token;
done();
});
});

before('login user', done => {
chai
.request(app)
.post('/api/v1/auth/login')
.send({
email: 'ameachichuks@gmail.com',
password: '12345678',
})
.end((err, res) => {
userBToken = res.body.user.token;
done();
});
});

describe('PROFILE', () => {
it('should respond with the user profile', done => {
chai
.request(app)
.get('/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c')
.set('Authorization', userAToken)
.end((err, res) => {
expect(res).to.have.status(200);
const {
Expand Down Expand Up @@ -44,6 +76,7 @@ describe('PROFILE', () => {
chai
.request(app)
.get(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099*`)
.set('Authorization', userBToken)
.end((err, res) => {
expect(res).to.have.status(400);
expect(res.body.error).to.equal('id not valid');
Expand All @@ -55,6 +88,7 @@ describe('PROFILE', () => {
chai
.request(app)
.get(`/api/v1/profile?first_name=Ameachi`)
.set('Authorization', userAToken)
.end((err, res) => {
expect(res).to.have.status(200);
const { first_name: firstname } = res.body.data[0];
Expand All @@ -67,6 +101,7 @@ describe('PROFILE', () => {
chai
.request(app)
.get(`/api/v1/profile?firstname=Ameachi`)
.set('Authorization', userAToken)
.end((err, res) => {
expect(res).to.have.status(400);
expect(res.body.error).to.equal('invalid query sring');
Expand All @@ -78,6 +113,7 @@ describe('PROFILE', () => {
chai
.request(app)
.patch(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c`)
.set('Authorization', userAToken)
.send({ first_name: 'Sammy' })
.end((err, res) => {
expect(res).to.have.status(200);
Expand All @@ -88,10 +124,49 @@ describe('PROFILE', () => {
});
});

it('should respond with error for updating wrong users profile', done => {
chai
.request(app)
.patch(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c`)
.set('Authorization', userBToken)
.send({ first_name: 'Sammy' })
.end((err, res) => {
expect(res).to.have.status(403);
expect(res.body.error).to.equal('User does not own this account');
done();
});
});

it('should respond with error for no authorization', done => {
chai
.request(app)
.patch(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c`)
.send({ first_name: 'Sammy' })
.end((err, res) => {
expect(res).to.have.status(401);
expect(res.body.error).to.equal('You are not authorized');
done();
});
});

it('should respond with error for bad token', done => {
chai
.request(app)
.patch(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c`)
.set('Authorization', 'fakeToken')
.send({ first_name: 'Sammy' })
.end((err, res) => {
expect(res).to.have.status(403);
expect(res.body.error).to.equal('Forbidden');
done();
});
});

it('should respond with error for invalid editable field', done => {
chai
.request(app)
.patch(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c`)
.set('Authorization', userAToken)
.send({ firstname: 'Sammy' })
.end((err, res) => {
expect(res).to.have.status(400);
Expand All @@ -104,6 +179,7 @@ describe('PROFILE', () => {
chai
.request(app)
.patch(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c`)
.set('Authorization', userAToken)
.send({})
.end((err, res) => {
expect(res).to.have.status(400);
Expand All @@ -116,6 +192,7 @@ describe('PROFILE', () => {
chai
.request(app)
.patch(`/api/v1/profile/6517a6ea-662b-4eef-ab9f-20f89bd7099c`)
.set('Authorization', userAToken)
.send({ email: 'Sammy' })
.end((err, res) => {
expect(res).to.have.status(400);
Expand Down

0 comments on commit 34d5673

Please sign in to comment.