Skip to content

Commit

Permalink
Merge branch 'release/v0.0.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
rudijs committed Sep 14, 2014
2 parents be52042 + 8ccd96c commit 5bef881
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 29 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
# Changelog
All notable changes to this project will be documented in this file.

## 0.0.3 - 2014-09-14

### Added
- Add URL regular expression exclude list option
- Readme updates.
- Dev dependency updates

### Deprecated
- Nothing.

### Removed
- Nothing.

### Fixed
- Nothing.

## 0.0.2 - 2014-09-14

### Added
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,32 @@ Here's an example of manual catch and re-throw:

app.use(koaJsonApiHeaders());

If you have an API endpoint you wish to not use JSON API headers for you can add jsonapiexclude=true to the URL query string.
*Exclude List*

If you have an API endpoint that you do not want to enforce JSON API headers you can exclude it from the header validations.

There are two methods for excluding:

- Add jsonapiexclude=true to the URL query string.

Example: http://localhost:3000/signin/google?jsonapiexclude=true

If the URL query string key 'jsonapiexclude' exists (any value) the JSON API headers validation will be skipped.

- Pass in an exclude list of URL regular expression patterns when you use `app.use()'

Example:

app.use(koaJsonApiHeaders({whiteList: [
'signin\/google',
'auth\/google\\?code'
]}));

*Note:

- No start or end '/'
- The escaping of the '/' and the double escaping of the '?' as these are regular expression characters.

## Tests with code coverage report in `test/coverage`

Note: Requires nodes at least v0.11.13 (earlier v0.11 versions may work, have not checked for this).
Expand Down
75 changes: 50 additions & 25 deletions lib/koa-jsonapi-headers.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,64 @@
'use strict';

module.exports = function koaJsonApiHeaders() {
module.exports = function koaJsonApiHeaders(options) {

if(!options) {
options = {};
}

if (!options.excludeList) {
options.excludeList = [];
}

function validateJsonApiHeaders(ctx) {

// Content-type: application/vnd.api+json
if (!ctx.header['content-type'] || !/application\/vnd\.api\+json/.test(ctx.header['content-type'])) {
ctx.throw(400, {
message: {
status: 400,
title: 'Bad Request',
detail: 'API requires header "Content-type application/vnd.api+json" for exchanging data.'
}
});
}

// Accept: application/vnd.api+json
if (!ctx.header.accept || !/application\/vnd\.api\+json/.test(ctx.header.accept)) {
ctx.throw(400, {
message: {
status: 400,
title: 'Bad Request',
detail: 'API requires header "Accept application/vnd.api+json" for exchanging data.'
}
});
}

}

return function *jsonApiHeaders(next) {

var ctx = this;

/*
Check for URL query value 'jsonapiexclude=true'
If it exists skip jsaonapi header validation
If it exists skip jsaonapi header validation for this request
*/
var jsonApiExclude = this.query.jsonapiexclude || false;

if (jsonApiExclude === false) {

// Content-type: application/vnd.api+json
if (!this.header['content-type'] || !/application\/vnd\.api\+json/.test(this.header['content-type'])) {
this.throw(400, {
message: {
status: 400,
title: 'Bad Request',
detail: 'API requires header "Content-type application/vnd.api+json" for exchanging data.'
}
});
}
var jsonApiExclude = ctx.query.jsonapiexclude || false;

// Accept: application/vnd.api+json
if (!this.header.accept || !/application\/vnd\.api\+json/.test(this.header.accept)) {
this.throw(400, {
message: {
status: 400,
title: 'Bad Request',
detail: 'API requires header "Accept application/vnd.api+json" for exchanging data.'
}
});
/*
Check if this request is in the excludeList to not validate
If match is found jsonApiExclude to true and skip jsaonapi header validation for this request
*/
options.excludeList.forEach(function (regex) {
var r = new RegExp(regex);
if (r.test(ctx.url)) {
jsonApiExclude = true;
}
});

if (jsonApiExclude === false) {
validateJsonApiHeaders(ctx);
}

yield next;
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koa-jsonapi-headers",
"version": "0.0.2",
"version": "0.0.3",
"description": "KoaJS Validate JSON-API Request Headers Middleware",
"repository": {
"type": "git",
Expand Down Expand Up @@ -29,7 +29,7 @@
"coveralls": "^2.11.1",
"istanbul-harmony": "^0.3.0",
"jshint": "^2.5.4",
"koa": "^0.10.0",
"koa": "^0.11.0",
"mocha": "^1.21.4",
"supertest": "^0.13.0"
}
Expand Down
29 changes: 28 additions & 1 deletion test/koa-jsonapi-headers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('JSON API Headers Middleware', function () {

});

it('should permit exclusions', function (done) {
it('should permit exclusions via URL query', function (done) {

app.use(koaJsonApiHeaders());

Expand All @@ -141,6 +141,33 @@ describe('JSON API Headers Middleware', function () {

});

it('should permit exclusions via regex list', function (done) {

app.use(koaJsonApiHeaders({excludeList: [
'resource\/path',
'excluded\/endpoint\\?id'
]}));

// default route
app.use(function *route1(next) {
this.body = 'Excluded headers request OK';
yield next;
});

request(app.listen())
.get('/excluded/endpoint?id=1')
.expect(200)
.end(function (err, res) {
if (err) {
should.not.exist(err);
return done(err);
}
res.text.should.equal('Excluded headers request OK');
done();
});

});

});

});

0 comments on commit 5bef881

Please sign in to comment.