Comparing version 2.8.1 to 2.8.2
@@ -5,4 +5,2 @@ # contributing to `cors` | ||
[![build status](https://secure.travis-ci.org/TroyGoode/node-cors.png)](http://travis-ci.org/TroyGoode/node-cors) | ||
## The CORS Spec | ||
@@ -9,0 +7,0 @@ |
@@ -5,2 +5,3 @@ (function () { | ||
var assign = require('object-assign'); | ||
var vary = require('vary'); | ||
@@ -64,8 +65,6 @@ | ||
}]); | ||
if (isAllowed) { | ||
headers.push([{ | ||
key: 'Vary', | ||
value: 'Origin' | ||
}]); | ||
} | ||
headers.push([{ | ||
key: 'Vary', | ||
value: 'Origin' | ||
}]); | ||
} | ||
@@ -77,3 +76,3 @@ | ||
function configureMethods(options) { | ||
var methods = options.methods || defaults.methods; | ||
var methods = options.methods; | ||
if (methods.join) { | ||
@@ -99,15 +98,22 @@ methods = options.methods.join(','); // .methods is an array, so turn it into a string | ||
function configureAllowedHeaders(options, req) { | ||
var headers = options.allowedHeaders || options.headers; | ||
if (!headers) { | ||
headers = req.headers['access-control-request-headers']; // .headers wasn't specified, so reflect the request headers | ||
} else if (headers.join) { | ||
headers = headers.join(','); // .headers is an array, so turn it into a string | ||
var allowedHeaders = options.allowedHeaders || options.headers; | ||
var headers = []; | ||
if (!allowedHeaders) { | ||
allowedHeaders = req.headers['access-control-request-headers']; // .headers wasn't specified, so reflect the request headers | ||
headers.push([{ | ||
key: 'Vary', | ||
value: 'Access-Control-Request-Headers' | ||
}]); | ||
} else if (allowedHeaders.join) { | ||
allowedHeaders = allowedHeaders.join(','); // .headers is an array, so turn it into a string | ||
} | ||
if (headers && headers.length) { | ||
return { | ||
if (allowedHeaders && allowedHeaders.length) { | ||
headers.push([{ | ||
key: 'Access-Control-Allow-Headers', | ||
value: headers | ||
}; | ||
value: allowedHeaders | ||
}]); | ||
} | ||
return null; | ||
return headers; | ||
} | ||
@@ -188,15 +194,5 @@ | ||
function middlewareWrapper(o) { | ||
// if no options were passed in, use the defaults | ||
if (!o || o === true) { | ||
o = {}; | ||
if (typeof o !== 'function') { | ||
o = assign({}, defaults, o); | ||
} | ||
if (o.origin === undefined) { | ||
o.origin = defaults.origin; | ||
} | ||
if (o.methods === undefined) { | ||
o.methods = defaults.methods; | ||
} | ||
if (o.preflightContinue === undefined) { | ||
o.preflightContinue = defaults.preflightContinue; | ||
} | ||
@@ -203,0 +199,0 @@ // if options are static (either via defaults or custom options passed in), wrap in a function |
{ | ||
"name": "cors", | ||
"version": "2.8.1", | ||
"description": "Node.js CORS middleware", | ||
"version": "2.8.2", | ||
"author": "Troy Goode <troygoode@gmail.com> (https://github.com/troygoode/)", | ||
"description": "middleware for dynamically or statically enabling CORS in express/connect applications", | ||
"keywords": ["cors", "express", "connect", "middleware"], | ||
"homepage": "https://github.com/expressjs/cors/", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/expressjs/cors.git" | ||
}, | ||
"contributors": [ | ||
{ | ||
"name": "Troy Goode", | ||
"email": "troygoode@gmail.com", | ||
"web": "https://github.com/troygoode/" | ||
} | ||
], | ||
"license": "MIT", | ||
"bugs": {"url": "https://github.com/expressjs/cors/issues"}, | ||
"repository": "expressjs/cors", | ||
"main": "./lib/index.js", | ||
@@ -26,2 +14,3 @@ "engines": { | ||
"dependencies": { | ||
"object-assign": "^4", | ||
"vary": "^1" | ||
@@ -34,2 +23,3 @@ }, | ||
"express": "^4.12.4", | ||
"istanbul": "^0.4.5", | ||
"mocha": "^2.2.5", | ||
@@ -40,5 +30,5 @@ "should": "^6.0.3", | ||
"scripts": { | ||
"test": "npm run lint && ./node_modules/mocha/bin/mocha", | ||
"lint": "./node_modules/eslint/bin/eslint.js lib test" | ||
"test": "npm run lint && istanbul cover node_modules/mocha/bin/_mocha", | ||
"lint": "eslint lib test" | ||
} | ||
} |
174
README.md
@@ -1,3 +0,8 @@ | ||
# `cors` | ||
# cors | ||
[![NPM Version][npm-image]][npm-url] | ||
[![NPM Downloads][downloads-image]][downloads-url] | ||
[![Build Status][travis-image]][travis-url] | ||
[![Test Coverage][coveralls-image]][coveralls-url] | ||
CORS is a node.js package for providing a [Connect](http://www.senchalabs.org/connect/)/[Express](http://expressjs.com/) middleware that can be used to enable [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) with various options. | ||
@@ -7,5 +12,2 @@ | ||
[![NPM](https://nodei.co/npm/cors.png?downloads=true&stars=true)](https://nodei.co/npm/cors/) | ||
[![build status](https://secure.travis-ci.org/expressjs/cors.svg?branch=master)](http://travis-ci.org/expressjs/cors) | ||
* [Installation](#installation) | ||
@@ -23,5 +25,9 @@ * [Usage](#usage) | ||
## Installation (via [npm](https://npmjs.org/package/cors)) | ||
## Installation | ||
```bash | ||
This is a [Node.js](https://nodejs.org/en/) module available through the | ||
[npm registry](https://www.npmjs.com/). Installation is done using the | ||
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): | ||
```sh | ||
$ npm install cors | ||
@@ -36,14 +42,14 @@ ``` | ||
var express = require('express') | ||
, cors = require('cors') | ||
, app = express(); | ||
var cors = require('cors') | ||
var app = express() | ||
app.use(cors()); | ||
app.use(cors()) | ||
app.get('/products/:id', function(req, res, next){ | ||
res.json({msg: 'This is CORS-enabled for all origins!'}); | ||
}); | ||
app.get('/products/:id', function (req, res, next) { | ||
res.json({msg: 'This is CORS-enabled for all origins!'}) | ||
}) | ||
app.listen(80, function(){ | ||
console.log('CORS-enabled web server listening on port 80'); | ||
}); | ||
app.listen(80, function () { | ||
console.log('CORS-enabled web server listening on port 80') | ||
}) | ||
``` | ||
@@ -55,12 +61,12 @@ | ||
var express = require('express') | ||
, cors = require('cors') | ||
, app = express(); | ||
var cors = require('cors') | ||
var app = express() | ||
app.get('/products/:id', cors(), function(req, res, next){ | ||
res.json({msg: 'This is CORS-enabled for a Single Route'}); | ||
}); | ||
app.get('/products/:id', cors(), function (req, res, next) { | ||
res.json({msg: 'This is CORS-enabled for a Single Route'}) | ||
}) | ||
app.listen(80, function(){ | ||
console.log('CORS-enabled web server listening on port 80'); | ||
}); | ||
app.listen(80, function () { | ||
console.log('CORS-enabled web server listening on port 80') | ||
}) | ||
``` | ||
@@ -72,4 +78,4 @@ | ||
var express = require('express') | ||
, cors = require('cors') | ||
, app = express(); | ||
var cors = require('cors') | ||
var app = express() | ||
@@ -79,11 +85,11 @@ var corsOptions = { | ||
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 | ||
}; | ||
} | ||
app.get('/products/:id', cors(corsOptions), function(req, res, next){ | ||
res.json({msg: 'This is CORS-enabled for only example.com.'}); | ||
}); | ||
app.get('/products/:id', cors(corsOptions), function (req, res, next) { | ||
res.json({msg: 'This is CORS-enabled for only example.com.'}) | ||
}) | ||
app.listen(80, function(){ | ||
console.log('CORS-enabled web server listening on port 80'); | ||
}); | ||
app.listen(80, function () { | ||
console.log('CORS-enabled web server listening on port 80') | ||
}) | ||
``` | ||
@@ -95,20 +101,23 @@ | ||
var express = require('express') | ||
, cors = require('cors') | ||
, app = express(); | ||
var cors = require('cors') | ||
var app = express() | ||
var whitelist = ['http://example1.com', 'http://example2.com']; | ||
var whitelist = ['http://example1.com', 'http://example2.com'] | ||
var corsOptions = { | ||
origin: function(origin, callback){ | ||
var originIsWhitelisted = whitelist.indexOf(origin) !== -1; | ||
callback(originIsWhitelisted ? null : 'Bad Request', originIsWhitelisted); | ||
origin: function (origin, callback) { | ||
if (whitelist.indexOf(origin) !== -1) { | ||
callback(null, true) | ||
} else { | ||
callback(new Error('Not allowed by CORS')) | ||
} | ||
} | ||
}; | ||
} | ||
app.get('/products/:id', cors(corsOptions), function(req, res, next){ | ||
res.json({msg: 'This is CORS-enabled for a whitelisted domain.'}); | ||
}); | ||
app.get('/products/:id', cors(corsOptions), function (req, res, next) { | ||
res.json({msg: 'This is CORS-enabled for a whitelisted domain.'}) | ||
}) | ||
app.listen(80, function(){ | ||
console.log('CORS-enabled web server listening on port 80'); | ||
}); | ||
app.listen(80, function () { | ||
console.log('CORS-enabled web server listening on port 80') | ||
}) | ||
``` | ||
@@ -127,13 +136,13 @@ | ||
var express = require('express') | ||
, cors = require('cors') | ||
, app = express(); | ||
var cors = require('cors') | ||
var app = express() | ||
app.options('/products/:id', cors()); // enable pre-flight request for DELETE request | ||
app.del('/products/:id', cors(), function(req, res, next){ | ||
res.json({msg: 'This is CORS-enabled for all origins!'}); | ||
}); | ||
app.options('/products/:id', cors()) // enable pre-flight request for DELETE request | ||
app.del('/products/:id', cors(), function (req, res, next) { | ||
res.json({msg: 'This is CORS-enabled for all origins!'}) | ||
}) | ||
app.listen(80, function(){ | ||
console.log('CORS-enabled web server listening on port 80'); | ||
}); | ||
app.listen(80, function () { | ||
console.log('CORS-enabled web server listening on port 80') | ||
}) | ||
``` | ||
@@ -143,5 +152,5 @@ | ||
```javascript | ||
app.options('*', cors()) // include before other routes | ||
``` | ||
app.options('*', cors()); // include before other routes | ||
``` | ||
@@ -152,23 +161,23 @@ ### Configuring CORS Asynchronously | ||
var express = require('express') | ||
, cors = require('cors') | ||
, app = express(); | ||
var cors = require('cors') | ||
var app = express() | ||
var whitelist = ['http://example1.com', 'http://example2.com']; | ||
var corsOptionsDelegate = function(req, callback){ | ||
var whitelist = ['http://example1.com', 'http://example2.com'] | ||
var corsOptionsDelegate = function (req, callback) { | ||
var corsOptions; | ||
if(whitelist.indexOf(req.header('Origin')) !== -1){ | ||
corsOptions = { origin: true }; // reflect (enable) the requested origin in the CORS response | ||
if (whitelist.indexOf(req.header('Origin')) !== -1) { | ||
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response | ||
}else{ | ||
corsOptions = { origin: false }; // disable CORS for this request | ||
corsOptions = { origin: false } // disable CORS for this request | ||
} | ||
callback(null, corsOptions); // callback expects two parameters: error and options | ||
}; | ||
callback(null, corsOptions) // callback expects two parameters: error and options | ||
} | ||
app.get('/products/:id', cors(corsOptionsDelegate), function(req, res, next){ | ||
res.json({msg: 'This is CORS-enabled for a whitelisted domain.'}); | ||
}); | ||
app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) { | ||
res.json({msg: 'This is CORS-enabled for a whitelisted domain.'}) | ||
}) | ||
app.listen(80, function(){ | ||
console.log('CORS-enabled web server listening on port 80'); | ||
}); | ||
app.listen(80, function () { | ||
console.log('CORS-enabled web server listening on port 80') | ||
}) | ||
``` | ||
@@ -179,7 +188,7 @@ | ||
* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values: | ||
- `Boolean` - set `origin` to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS. | ||
- `String` - set `origin` to a specific origin. For example if you set it to `"http://example.com"` only requests from "http://example.com" will be allowed. | ||
- `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com". | ||
- `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com". | ||
- `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (which expects the signature `err [object], allow [bool]`) as the second. | ||
- `Boolean` - set `origin` to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS. | ||
- `String` - set `origin` to a specific origin. For example if you set it to `"http://example.com"` only requests from "http://example.com" will be allowed. | ||
- `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com". | ||
- `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com". | ||
- `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (which expects the signature `err [object], allow [bool]`) as the second. | ||
* `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']`). | ||
@@ -191,2 +200,3 @@ * `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. | ||
* `preflightContinue`: Pass the CORS preflight response to the next handler. | ||
* `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`. | ||
@@ -199,3 +209,4 @@ The default configuration is the equivalent of: | ||
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE", | ||
"preflightContinue": false | ||
"preflightContinue": false, | ||
"optionsSuccessStatus": 204 | ||
} | ||
@@ -222,1 +233,10 @@ ``` | ||
[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com)) | ||
[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg | ||
[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master | ||
[downloads-image]: https://img.shields.io/npm/dm/cors.svg | ||
[downloads-url]: https://npmjs.org/package/cors | ||
[npm-image]: https://img.shields.io/npm/v/cors.svg | ||
[npm-url]: https://npmjs.org/package/cors | ||
[travis-image]: https://img.shields.io/travis/expressjs/cors/master.svg | ||
[travis-url]: https://travis-ci.org/expressjs/cors |
@@ -45,2 +45,11 @@ (function () { | ||
describe('cors', function () { | ||
it('does not alter `options` configuration object', function () { | ||
var options = Object.freeze({ | ||
origin: 'custom-origin' | ||
}); | ||
(function () { | ||
cors(options); | ||
}).should.not.throw(); | ||
}); | ||
it('passes control to next middleware', function (done) { | ||
@@ -242,3 +251,4 @@ // arrange | ||
should.not.exist(res.getHeader('Access-Control-Allow-Origin')); | ||
should.not.exist(res.getHeader('Vary')); | ||
should.exist(res.getHeader('Vary')); | ||
res.getHeader('Vary').should.equal('Origin'); | ||
return done(); | ||
@@ -499,2 +509,3 @@ }); | ||
res.getHeader('Access-Control-Allow-Headers').should.equal('header1,header2'); | ||
should.not.exist(res.getHeader('Vary')); | ||
done(); | ||
@@ -518,2 +529,3 @@ }; | ||
should.not.exist(res.getHeader('Access-Control-Allow-Headers')); | ||
should.not.exist(res.getHeader('Vary')); | ||
done(); | ||
@@ -537,2 +549,4 @@ }; | ||
res.getHeader('Access-Control-Allow-Headers').should.equal('requestedHeader1,requestedHeader2'); | ||
should.exist(res.getHeader('Vary')); | ||
res.getHeader('Vary').should.equal('Access-Control-Request-Headers'); | ||
done(); | ||
@@ -563,2 +577,20 @@ }; | ||
it('specifying an empty list or string of exposed headers will result in no response header for exposed headers', function (done) { | ||
// arrange | ||
var req, res, next, options; | ||
options = { | ||
exposedHeaders: [] | ||
}; | ||
req = fakeRequest(); | ||
res = fakeResponse(); | ||
next = function () { | ||
// assert | ||
should.not.exist(res.getHeader('Access-Control-Expose-Headers')); | ||
done(); | ||
}; | ||
// act | ||
cors(options)(req, res, next); | ||
}); | ||
it('includes credentials if explicitly enabled', function (done) { | ||
@@ -565,0 +597,0 @@ // arrange |
@@ -48,3 +48,3 @@ (function () { | ||
res.headers['access-control-allow-origin'].should.eql('*'); | ||
res.text.should.startWith('Error: nope'); | ||
res.text.should.containEql('Error: nope'); | ||
done(); | ||
@@ -51,0 +51,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51823
17
1200
229
2
8
2
1
2
+ Addedobject-assign@^4
+ Addedobject-assign@4.1.1(transitive)