Comparing version 2.6.1 to 2.7.0
@@ -22,3 +22,2 @@ # contributing to `cors` | ||
$ npm test | ||
$ npm run lint | ||
``` | ||
@@ -25,0 +24,0 @@ |
@@ -1,4 +0,1 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true*/ | ||
(function () { | ||
@@ -8,4 +5,5 @@ | ||
var vary = require('vary'), | ||
defaults = { | ||
var vary = require('vary'); | ||
var defaults = { | ||
origin: '*', | ||
@@ -16,20 +14,60 @@ methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', | ||
function isString(s) { | ||
return typeof s === 'string' || s instanceof String; | ||
} | ||
function isOriginAllowed(origin, allowedOrigin) { | ||
if (Array.isArray(allowedOrigin)) { | ||
for (var i = 0; i < allowedOrigin.length; ++i) { | ||
if (isOriginAllowed(origin, allowedOrigin[i])) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} else if (isString(allowedOrigin)) { | ||
return origin === allowedOrigin; | ||
} else if (allowedOrigin instanceof RegExp) { | ||
return allowedOrigin.test(origin); | ||
} else { | ||
return !!allowedOrigin; | ||
} | ||
} | ||
function configureOrigin(options, req) { | ||
var requestOrigin = req.headers.origin, | ||
headers = [], | ||
isAllowed; | ||
if (!options.origin || options.origin === '*') { | ||
return { | ||
// allow any origin | ||
headers.push([{ | ||
key: 'Access-Control-Allow-Origin', | ||
value: '*' | ||
}; | ||
}]); | ||
} else if (isString(options.origin)) { | ||
// fixed origin | ||
headers.push([{ | ||
key: 'Access-Control-Allow-Origin', | ||
value: options.origin | ||
}]); | ||
headers.push([{ | ||
key: 'Vary', | ||
value: 'Origin' | ||
}]); | ||
} else { | ||
return [ | ||
{ | ||
key: 'Access-Control-Allow-Origin', | ||
value: options.origin === true ? req.headers.origin : options.origin | ||
}, | ||
{ | ||
isAllowed = isOriginAllowed(requestOrigin, options.origin); | ||
// reflect origin | ||
headers.push([{ | ||
key: 'Access-Control-Allow-Origin', | ||
value: isAllowed ? requestOrigin : false | ||
}]); | ||
if (isAllowed) { | ||
headers.push([{ | ||
key: 'Vary', | ||
value: 'Origin' | ||
} | ||
]; | ||
}]); | ||
} | ||
} | ||
return headers; | ||
} | ||
@@ -74,3 +112,3 @@ | ||
function configureExposedHeaders(options, req) { | ||
function configureExposedHeaders(options) { | ||
var headers = options.exposedHeaders; | ||
@@ -167,7 +205,5 @@ if (!headers) { | ||
} else { | ||
/*jslint unparam: true*/ // `req` is part of the signature, but isn't used for this stub | ||
optionsCallback = function (req, cb) { | ||
cb(null, o); | ||
}; | ||
/*jslint unparam: false*/ | ||
} | ||
@@ -184,13 +220,11 @@ | ||
} else if (options.origin) { | ||
/*jslint unparam: true*/ // `origin` is part of the signature, but isn't used for this stub | ||
originCallback = function (origin, cb) { | ||
cb(null, options.origin); | ||
}; | ||
/*jslint unparam: false*/ | ||
} | ||
if (originCallback) { | ||
originCallback(req.headers.origin, function (err, origin) { | ||
if (err || !origin) { | ||
next(err); | ||
originCallback(req.headers.origin, function (err2, origin) { | ||
if (err2 || !origin) { | ||
next(err2); | ||
} else { | ||
@@ -197,0 +231,0 @@ var corsOptions = Object.create(options); |
{ | ||
"name": "cors", | ||
"version": "2.6.1", | ||
"version": "2.7.0", | ||
"author": "Troy Goode <troygoode@gmail.com> (https://github.com/troygoode/)", | ||
@@ -29,14 +29,14 @@ "description": "middleware for dynamically or statically enabling CORS in express/connect applications", | ||
"devDependencies": { | ||
"basic-auth-connect": "^1", | ||
"body-parser": "^1.4.3", | ||
"express": "^4", | ||
"lint": "^1.1.2", | ||
"mocha": "^1.18.2", | ||
"should": "^3.3.1", | ||
"supertest": "^0.12" | ||
"basic-auth-connect": "^1.0.0", | ||
"body-parser": "^1.12.4", | ||
"eslint": "^0.21.2", | ||
"express": "^4.12.4", | ||
"mocha": "^2.2.5", | ||
"should": "^6.0.3", | ||
"supertest": "^1.0.1" | ||
}, | ||
"scripts": { | ||
"test": "./node_modules/mocha/bin/mocha", | ||
"lint": "./node_modules/lint/bin/node-lint lib test" | ||
"test": "npm run lint && ./node_modules/mocha/bin/mocha", | ||
"lint": "./node_modules/eslint/bin/eslint.js lib test" | ||
} | ||
} |
@@ -167,3 +167,3 @@ # `cors` | ||
* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Expects a string (ex: "http://example.com"). Set to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as defined by `req.header('Origin')`. Set to `false` to disable CORS. Can also be set to a function, which takes the request origin as the first parameter and a callback (which expects the signature `err [object], allow [bool]`) as the second. | ||
* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Expects a string (ex: "http://example.com"). Set to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as defined by `req.header('Origin')`. Set to `false` to disable CORS. Can also be set to a function, which takes the request origin as the first parameter and a callback (which expects the signature `err [object], allow [bool]`) as the second. Finally, it can also be a regular expression (`/example\.com$/`) or an array of regular expressions and/or strings to match against. | ||
* `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`). | ||
@@ -170,0 +170,0 @@ * `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header. |
@@ -1,5 +0,3 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true, describe: true, it: true, setTimeout: true*/ | ||
(function () { | ||
/*global describe, it*/ | ||
@@ -12,5 +10,6 @@ 'use strict'; | ||
basicAuth = require('basic-auth-connect'), | ||
cors = require('../lib'), | ||
app; | ||
cors = require('../lib'); | ||
var app; | ||
/* -------------------------------------------------------------------------- */ | ||
@@ -21,7 +20,5 @@ | ||
app.use(cors()); | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
app.post('/', function (req, res) { | ||
res.send('hello world'); | ||
}); | ||
/*jslint unparam: false*/ | ||
@@ -46,2 +43,1 @@ /* -------------------------------------------------------------------------- */ | ||
}()); | ||
@@ -1,5 +0,3 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true, describe: true, it: true, setTimeout: true*/ | ||
(function () { | ||
/*global describe, it*/ | ||
@@ -12,4 +10,5 @@ 'use strict'; | ||
bodyParser = require('body-parser'), | ||
cors = require('../lib'), | ||
dynamicOrigin, | ||
cors = require('../lib'); | ||
var dynamicOrigin, | ||
app1, | ||
@@ -32,7 +31,5 @@ app2, | ||
app1.use(bodyParser.json()); | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
app1.post('/', function (req, res) { | ||
res.send(req.body); | ||
}); | ||
/*jslint unparam: false*/ | ||
@@ -44,7 +41,5 @@ /* -------------------------------------------------------------------------- */ | ||
app2.use(cors({origin: dynamicOrigin})); | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
app2.post('/', function (req, res) { | ||
res.send(req.body); | ||
}); | ||
/*jslint unparam: false*/ | ||
@@ -90,2 +85,1 @@ /* -------------------------------------------------------------------------- */ | ||
}()); | ||
@@ -1,5 +0,3 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true, describe: true, it: true*/ | ||
(function () { | ||
/*global describe, it*/ | ||
@@ -9,4 +7,5 @@ 'use strict'; | ||
var should = require('should'), | ||
cors = require('../lib'), | ||
fakeRequest = function (headers) { | ||
cors = require('../lib'); | ||
var fakeRequest = function (headers) { | ||
return { | ||
@@ -80,3 +79,3 @@ headers: headers || { | ||
it('don\'t shortcircuits preflight requests with preflightContinue option', function (done) { | ||
it('doesn\'t shortcircuit preflight requests with preflightContinue option', function (done) { | ||
// arrange | ||
@@ -191,2 +190,40 @@ var req, res, next; | ||
it('matches request origin against regexp', function(done) { | ||
var req = fakeRequest(); | ||
var res = fakeResponse(); | ||
var options = { origin: /^(.+\.)?request.com$/ }; | ||
cors(options)(req, res, function(err) { | ||
should.not.exist(err); | ||
res.getHeader('Access-Control-Allow-Origin').should.equal(req.headers.origin); | ||
should.exist(res.getHeader('Vary')); | ||
res.getHeader('Vary').should.equal('Origin'); | ||
return done(); | ||
}); | ||
}); | ||
it('matches request origin against array of origin checks', function(done) { | ||
var req = fakeRequest(); | ||
var res = fakeResponse(); | ||
var options = { origin: [ /foo\.com$/, 'request.com' ] }; | ||
cors(options)(req, res, function(err) { | ||
should.not.exist(err); | ||
res.getHeader('Access-Control-Allow-Origin').should.equal(req.headers.origin); | ||
should.exist(res.getHeader('Vary')); | ||
res.getHeader('Vary').should.equal('Origin'); | ||
return done(); | ||
}); | ||
}); | ||
it('doesn\'t match request origin against array of invalid origin checks', function(done) { | ||
var req = fakeRequest(); | ||
var res = fakeResponse(); | ||
var options = { origin: [ /foo\.com$/, 'bar.com' ] }; | ||
cors(options)(req, res, function(err) { | ||
should.not.exist(err); | ||
should.not.exist(res.getHeader('Access-Control-Allow-Origin')); | ||
should.not.exist(res.getHeader('Vary')); | ||
return done(); | ||
}); | ||
}); | ||
it('origin of false disables cors', function (done) { | ||
@@ -246,2 +283,3 @@ // arrange | ||
// assert | ||
should.exist(res.getHeader('Vary')); | ||
res.getHeader('Vary').should.equal('Origin'); | ||
@@ -581,4 +619,3 @@ done(); | ||
var req, res, next, delegate; | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in this route | ||
delegate = function (req, cb) { | ||
delegate = function (req2, cb) { | ||
cb(null, { | ||
@@ -588,3 +625,2 @@ origin: 'delegate.com' | ||
}; | ||
/*jslint unparam: false*/ | ||
req = fakeRequest(); | ||
@@ -605,7 +641,5 @@ res = fakeResponse(); | ||
var req, res, next, delegate; | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in this route | ||
delegate = function (req, cb) { | ||
delegate = function (req2, cb) { | ||
cb('some error'); | ||
}; | ||
/*jslint unparam: false*/ | ||
req = fakeRequest(); | ||
@@ -626,2 +660,1 @@ res = fakeResponse(); | ||
}()); | ||
@@ -1,5 +0,3 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true, describe: true, it: true, setTimeout: true*/ | ||
(function () { | ||
/*global describe, it*/ | ||
@@ -11,5 +9,6 @@ 'use strict'; | ||
supertest = require('supertest'), | ||
cors = require('../lib'), | ||
app; | ||
cors = require('../lib'); | ||
var app; | ||
/* -------------------------------------------------------------------------- */ | ||
@@ -20,21 +19,14 @@ | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
app.post('/five-hundred', function (req, res, next) { | ||
next(new Error('nope')); | ||
}); | ||
/*jslint unparam: false*/ | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
app.post('/four-oh-one', function (req, res, next) { | ||
next(new Error('401')); | ||
}); | ||
/*jslint unparam: false*/ | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
app.post('/four-oh-four', function (req, res, next) { | ||
next(); | ||
}); | ||
/*jslint unparam: false*/ | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
app.use(function (err, req, res, next) { | ||
@@ -47,3 +39,2 @@ if (err.message === '401') { | ||
}); | ||
/*jslint unparam: false*/ | ||
@@ -90,2 +81,1 @@ /* -------------------------------------------------------------------------- */ | ||
}()); | ||
@@ -1,5 +0,3 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true, describe: true, it: true*/ | ||
(function () { | ||
/*global describe, it*/ | ||
@@ -11,4 +9,5 @@ 'use strict'; | ||
supertest = require('supertest'), | ||
cors = require('../lib'), | ||
simpleApp, | ||
cors = require('../lib'); | ||
var simpleApp, | ||
complexApp; | ||
@@ -19,3 +18,2 @@ | ||
simpleApp = express(); | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in these routes | ||
simpleApp.head('/', cors(), function (req, res) { | ||
@@ -30,3 +28,2 @@ res.status(204).send(); | ||
}); | ||
/*jslint unparam: false*/ | ||
@@ -37,7 +34,5 @@ /* -------------------------------------------------------------------------- */ | ||
complexApp.options('/', cors()); | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in this route | ||
complexApp.delete('/', cors(), function (req, res) { | ||
res.send('Hello World (Delete)'); | ||
}); | ||
/*jslint unparam: false*/ | ||
@@ -108,2 +103,1 @@ /* -------------------------------------------------------------------------- */ | ||
}()); | ||
@@ -1,5 +0,3 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true, describe: true, it: true*/ | ||
(function () { | ||
/*global describe, it*/ | ||
@@ -11,4 +9,5 @@ 'use strict'; | ||
supertest = require('supertest'), | ||
cors = require('../lib'), | ||
app, | ||
cors = require('../lib'); | ||
var app, | ||
corsOptions; | ||
@@ -26,7 +25,5 @@ | ||
app.options('/api/login', cors(corsOptions)); | ||
/*jslint unparam: true*/ // `req` is part of the signature, but not used in this route | ||
app.post('/api/login', cors(corsOptions), function (req, res) { | ||
res.send('LOGIN'); | ||
}); | ||
/*jslint unparam: false*/ | ||
@@ -62,2 +59,1 @@ /* -------------------------------------------------------------------------- */ | ||
}()); | ||
@@ -1,5 +0,3 @@ | ||
/*jslint indent: 2*/ | ||
/*global require: true, module: true, describe: true, it: true*/ | ||
(function () { | ||
/*global describe, it*/ | ||
@@ -11,4 +9,5 @@ 'use strict'; | ||
supertest = require('supertest'), | ||
cors = require('../lib'), | ||
app, | ||
cors = require('../lib'); | ||
var app, | ||
mainRouter, | ||
@@ -19,3 +18,3 @@ itemsRouter; | ||
itemsRouter = express.Router(); | ||
itemsRouter = new express.Router(); | ||
itemsRouter.get('/', function (req, res) { | ||
@@ -25,3 +24,3 @@ res.send('hello world'); | ||
mainRouter = express.Router(); | ||
mainRouter = new express.Router(); | ||
mainRouter.use('/items', itemsRouter); | ||
@@ -63,2 +62,1 @@ | ||
}()); | ||
48838
16
1157