diff -Nru node-cors-2.7.1/CONTRIBUTING.md node-cors-2.8.5/CONTRIBUTING.md --- node-cors-2.7.1/CONTRIBUTING.md 2015-05-28 23:04:14.000000000 +0000 +++ node-cors-2.8.5/CONTRIBUTING.md 2018-11-04 20:56:03.000000000 +0000 @@ -2,8 +2,6 @@ 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. Learn more about the project in [the README](README.md). -[![build status](https://secure.travis-ci.org/TroyGoode/node-cors.png)](http://travis-ci.org/TroyGoode/node-cors) - ## The CORS Spec [http://www.w3.org/TR/cors/](http://www.w3.org/TR/cors/) diff -Nru node-cors-2.7.1/debian/changelog node-cors-2.8.5/debian/changelog --- node-cors-2.7.1/debian/changelog 2016-02-23 18:28:56.000000000 +0000 +++ node-cors-2.8.5/debian/changelog 2020-05-04 09:12:15.000000000 +0000 @@ -1,6 +1,38 @@ +node-cors (2.8.5-1) unstable; urgency=medium + + * Team upload + + [ Debian Janitor ] + * Trim trailing whitespace. + * Use secure copyright file specification URI. + * Use secure URI in debian/watch. + * Bump debhelper from deprecated 9 to 12. + * Set debhelper-compat version in Build-Depends. + * Update renamed lintian tag names in lintian overrides. + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, + Repository-Browse. + * Update Vcs-* headers from URL redirect. + * Use canonical URL in Vcs-Git. + + [ Xavier Guimard ] + * Declare compliance with policy 4.5.0 + * Use pkg-js-tools auto install + * Add "Rules-Requires-Root: no" + * Change section to javascript + * Add debian/gbp.conf + * debian/watch: use github tags + * New upstream version 2.8.5 + * Install upstream changelog + * Update lintian overrides + * Add dependency to node-object-assign + * Add build dependencies to mocha, node-after, node-express, + node-object-assign, node-supertest + * Enable upstream test using mocha + + -- Xavier Guimard Mon, 04 May 2020 11:12:15 +0200 + node-cors (2.7.1-1) unstable; urgency=medium * Initial release -- Thorsten Alteholz Tue, 23 Feb 2016 18:10:04 +0100 - diff -Nru node-cors-2.7.1/debian/compat node-cors-2.8.5/debian/compat --- node-cors-2.7.1/debian/compat 2016-02-23 13:11:53.000000000 +0000 +++ node-cors-2.8.5/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -9 diff -Nru node-cors-2.7.1/debian/control node-cors-2.8.5/debian/control --- node-cors-2.7.1/debian/control 2016-02-23 13:19:50.000000000 +0000 +++ node-cors-2.8.5/debian/control 2020-05-04 09:10:21.000000000 +0000 @@ -1,26 +1,32 @@ Source: node-cors -Section: web +Section: javascript Priority: optional Maintainer: Debian Javascript Maintainers Uploaders: Thorsten Alteholz -Build-Depends: - debhelper (>= 9) - , dh-buildinfo - , nodejs -Standards-Version: 3.9.7 +Build-Depends: debhelper-compat (= 12) + , mocha + , node-after + , node-express + , node-object-assign + , node-supertest + , node-vary + , pkg-js-tools (>= 0.9.20~) +Standards-Version: 4.5.0 +Vcs-Browser: https://salsa.debian.org/js-team/node-cors +Vcs-Git: https://salsa.debian.org/js-team/node-cors.git Homepage: https://github.com/expressjs/cors/ -Vcs-Git: https://anonscm.debian.org/git/pkg-javascript/node-cors.git -Vcs-Browser: https://anonscm.debian.org/gitweb/?p=pkg-javascript/node-cors.git +Testsuite: autopkgtest-pkg-nodejs +Rules-Requires-Root: no Package: node-cors Architecture: all -Depends: - ${misc:Depends} +Depends: ${misc:Depends} + , node-object-assign + , node-vary , nodejs - , node-vary (>= 1.0.0) Description: middleware for enabling CORS in express/connect applications - CORS is a node.js package for providing a Connect/Express middleware - that can be used to dynamically or statically enable CORS with + CORS is a node.js package for providing a Connect/Express middleware + that can be used to dynamically or statically enable CORS with various options. . Node.js is an event-based server-side JavaScript engine. diff -Nru node-cors-2.7.1/debian/copyright node-cors-2.8.5/debian/copyright --- node-cors-2.7.1/debian/copyright 2016-02-23 13:10:05.000000000 +0000 +++ node-cors-2.8.5/debian/copyright 2020-05-04 09:03:34.000000000 +0000 @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: cors Upstream-Contact: https://github.com/expressjs/cors/issues Source: https://github.com/expressjs/cors/ @@ -31,4 +31,3 @@ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff -Nru node-cors-2.7.1/debian/gbp.conf node-cors-2.8.5/debian/gbp.conf --- node-cors-2.7.1/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/debian/gbp.conf 2020-05-04 09:04:56.000000000 +0000 @@ -0,0 +1,5 @@ +[DEFAULT] +pristine-tar = True + +[import-orig] +filter = [ '.gitignore', '.travis.yml', '.git*' ] diff -Nru node-cors-2.7.1/debian/install node-cors-2.8.5/debian/install --- node-cors-2.7.1/debian/install 2016-02-23 13:10:06.000000000 +0000 +++ node-cors-2.8.5/debian/install 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -package.json usr/lib/nodejs/cors/ -lib usr/lib/nodejs/cors/ diff -Nru node-cors-2.7.1/debian/rules node-cors-2.8.5/debian/rules --- node-cors-2.7.1/debian/rules 2016-02-23 13:10:05.000000000 +0000 +++ node-cors-2.8.5/debian/rules 2020-05-04 09:07:55.000000000 +0000 @@ -5,11 +5,7 @@ #export DH_VERBOSE=1 %: - dh $@ - -#override_dh_auto_build: - -#override_dh_auto_test: - - + dh $@ --with nodejs +override_dh_installchangelogs: + dh_installchangelogs -k HISTORY.md diff -Nru node-cors-2.7.1/debian/source/lintian-overrides node-cors-2.8.5/debian/source/lintian-overrides --- node-cors-2.7.1/debian/source/lintian-overrides 2016-02-23 13:21:10.000000000 +0000 +++ node-cors-2.8.5/debian/source/lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -# the line is really that long -node-cors source: insane-line-length-in-source-file test/body-events.js line length is 2894 characters (>512) -node-cors source: source-contains-prebuilt-javascript-object test/body-events.js line length is 2890 characters (>512) -node-cors source: source-is-missing test/body-events.js line length is 2890 characters (>512) diff -Nru node-cors-2.7.1/debian/tests/control node-cors-2.8.5/debian/tests/control --- node-cors-2.7.1/debian/tests/control 2016-02-23 13:11:47.000000000 +0000 +++ node-cors-2.8.5/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Tests: require -Depends: node-cors diff -Nru node-cors-2.7.1/debian/tests/pkg-js/test node-cors-2.8.5/debian/tests/pkg-js/test --- node-cors-2.7.1/debian/tests/pkg-js/test 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/debian/tests/pkg-js/test 2020-05-04 09:08:32.000000000 +0000 @@ -0,0 +1 @@ +mocha diff -Nru node-cors-2.7.1/debian/tests/require node-cors-2.8.5/debian/tests/require --- node-cors-2.7.1/debian/tests/require 2016-02-23 13:11:47.000000000 +0000 +++ node-cors-2.8.5/debian/tests/require 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#!/bin/sh -set -e -nodejs -e "require('cors');" diff -Nru node-cors-2.7.1/debian/upstream/metadata node-cors-2.8.5/debian/upstream/metadata --- node-cors-2.7.1/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/debian/upstream/metadata 2020-05-04 09:03:34.000000000 +0000 @@ -0,0 +1,4 @@ +Bug-Database: https://github.com/expressjs/cors/issues +Bug-Submit: https://github.com/expressjs/cors/issues/new +Repository: https://github.com/expressjs/cors.git +Repository-Browse: https://github.com/expressjs/cors diff -Nru node-cors-2.7.1/debian/watch node-cors-2.8.5/debian/watch --- node-cors-2.7.1/debian/watch 2016-02-23 13:10:08.000000000 +0000 +++ node-cors-2.8.5/debian/watch 2020-05-04 09:05:19.000000000 +0000 @@ -1,9 +1,6 @@ -version=3 -# It is not recommended use fakeupstream. Please investigate more. -# Origin url: https://github.com/expressjs/cors -# Take a look at https://wiki.debian.org/debian/watch/ -# See also fakeupstream: http://anonscm.debian.org/viewvc/qa/trunk/cgi-bin/fakeupstream.cgi?view=markup +version=4 opts=\ -dversionmangle=s/\+(debian|dfsg|ds|deb)(\.\d+)?$//,\ -filenamemangle=s/.*=// \ - http://qa.debian.org/cgi-bin/fakeupstream.cgi?upstream=npmjs/cors .*=cors-(\d.*)\.(?:tgz|tar\.(?:gz|bz2|xz)) +ctype=nodejs,\ +dversionmangle=auto,\ +filenamemangle=s/.*\/v?([\d\.-]+)\.tar\.gz/node-cors-$1.tar.gz/ \ + https://github.com/expressjs/cors/tags .*/archive/v?([\d\.]+).tar.gz diff -Nru node-cors-2.7.1/.eslintrc node-cors-2.8.5/.eslintrc --- node-cors-2.7.1/.eslintrc 2015-05-28 23:03:37.000000000 +0000 +++ node-cors-2.8.5/.eslintrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -{ - "env": { - "node": true - }, - "rules": { - "indent": [2, 2], - "quotes": "single" - } -} diff -Nru node-cors-2.7.1/.eslintrc.yml node-cors-2.8.5/.eslintrc.yml --- node-cors-2.7.1/.eslintrc.yml 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/.eslintrc.yml 2018-11-04 20:56:03.000000000 +0000 @@ -0,0 +1,7 @@ +root: true +env: + node: true +rules: + indent: ["error", 2, { "SwitchCase": 1 }] + quotes: ["error", "single"] + space-in-parens: ["error", "never"] diff -Nru node-cors-2.7.1/.gitignore node-cors-2.8.5/.gitignore --- node-cors-2.7.1/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/.gitignore 2018-11-04 20:56:03.000000000 +0000 @@ -0,0 +1,5 @@ +.nyc_output/ +coverage/ +node_modules/ +npm-debug.log +package-lock.json diff -Nru node-cors-2.7.1/HISTORY.md node-cors-2.8.5/HISTORY.md --- node-cors-2.7.1/HISTORY.md 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/HISTORY.md 2018-11-04 20:56:03.000000000 +0000 @@ -0,0 +1,58 @@ +2.8.5 / 2018-11-04 +================== + + * Fix setting `maxAge` option to `0` + +2.8.4 / 2017-07-12 +================== + + * Work-around Safari bug in default pre-flight response + +2.8.3 / 2017-03-29 +================== + + * Fix error when options delegate missing `methods` option + +2.8.2 / 2017-03-28 +================== + + * Fix error when frozen options are passed + * Send "Vary: Origin" when using regular expressions + * Send "Vary: Access-Control-Request-Headers" when dynamic `allowedHeaders` + +2.8.1 / 2016-09-08 +================== + +This release only changed documentation. + +2.8.0 / 2016-08-23 +================== + + * Add `optionsSuccessStatus` option + +2.7.2 / 2016-08-23 +================== + + * Fix error when Node.js running in strict mode + +2.7.1 / 2015-05-28 +================== + + * Move module into expressjs organization + +2.7.0 / 2015-05-28 +================== + + * Allow array of matching condition as `origin` option + * Allow regular expression as `origin` option + +2.6.1 / 2015-05-28 +================== + + * Update `license` in package.json + +2.6.0 / 2015-04-27 +================== + + * Add `preflightContinue` option + * Fix "Vary: Origin" header added for "*" diff -Nru node-cors-2.7.1/lib/index.js node-cors-2.8.5/lib/index.js --- node-cors-2.7.1/lib/index.js 2015-05-28 23:04:14.000000000 +0000 +++ node-cors-2.8.5/lib/index.js 2018-11-04 20:56:03.000000000 +0000 @@ -2,13 +2,15 @@ 'use strict'; + var assign = require('object-assign'); var vary = require('vary'); var defaults = { - origin: '*', - methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', - preflightContinue: false - }; + origin: '*', + methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', + preflightContinue: false, + optionsSuccessStatus: 204 + }; function isString(s) { return typeof s === 'string' || s instanceof String; @@ -59,19 +61,17 @@ key: 'Access-Control-Allow-Origin', value: isAllowed ? requestOrigin : false }]); - if (isAllowed) { - headers.push([{ - key: 'Vary', - value: 'Origin' - }]); - } + headers.push([{ + key: 'Vary', + value: 'Origin' + }]); } return headers; } function configureMethods(options) { - var methods = options.methods || defaults.methods; + var methods = options.methods; if (methods.join) { methods = options.methods.join(','); // .methods is an array, so turn it into a string } @@ -92,19 +92,26 @@ } 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; } function configureExposedHeaders(options) { @@ -124,7 +131,7 @@ } function configureMaxAge(options) { - var maxAge = options.maxAge && options.maxAge.toString(); + var maxAge = (typeof options.maxAge === 'number' || options.maxAge) && options.maxAge.toString() if (maxAge && maxAge.length) { return { key: 'Access-Control-Max-Age', @@ -163,10 +170,13 @@ headers.push(configureExposedHeaders(options, req)); applyHeaders(headers, res); - if (options.preflightContinue ) { + if (options.preflightContinue) { next(); } else { - res.statusCode = 204; + // Safari (and potentially other browsers) need content-length 0, + // for 204 or they just hang waiting for a body + res.statusCode = options.optionsSuccessStatus; + res.setHeader('Content-Length', '0'); res.end(); } } else { @@ -180,20 +190,6 @@ } function middlewareWrapper(o) { - // if no options were passed in, use the defaults - if (!o) { - 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; - } - // if options are static (either via defaults or custom options passed in), wrap in a function var optionsCallback = null; if (typeof o === 'function') { @@ -204,17 +200,18 @@ }; } - return function (req, res, next) { + return function corsMiddleware(req, res, next) { optionsCallback(req, function (err, options) { if (err) { next(err); } else { + var corsOptions = assign({}, defaults, options); var originCallback = null; - if (options.origin && typeof options.origin === 'function') { - originCallback = options.origin; - } else if (options.origin) { + if (corsOptions.origin && typeof corsOptions.origin === 'function') { + originCallback = corsOptions.origin; + } else if (corsOptions.origin) { originCallback = function (origin, cb) { - cb(null, options.origin); + cb(null, corsOptions.origin); }; } @@ -223,7 +220,6 @@ if (err2 || !origin) { next(err2); } else { - var corsOptions = Object.create(options); corsOptions.origin = origin; cors(corsOptions, req, res, next); } diff -Nru node-cors-2.7.1/LICENSE node-cors-2.8.5/LICENSE --- node-cors-2.7.1/LICENSE 2014-10-23 21:35:18.000000000 +0000 +++ node-cors-2.8.5/LICENSE 2018-11-04 20:56:03.000000000 +0000 @@ -1,9 +1,22 @@ -The MIT License (MIT) +(The MIT License) Copyright (c) 2013 Troy Goode -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nru node-cors-2.7.1/.npmignore node-cors-2.8.5/.npmignore --- node-cors-2.7.1/.npmignore 2014-10-23 21:35:18.000000000 +0000 +++ node-cors-2.8.5/.npmignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -.DS_Store -node_modules -npm-debug.log diff -Nru node-cors-2.7.1/package.json node-cors-2.8.5/package.json --- node-cors-2.7.1/package.json 2015-05-28 23:15:37.000000000 +0000 +++ node-cors-2.8.5/package.json 2018-11-04 20:56:03.000000000 +0000 @@ -1,41 +1,41 @@ { "name": "cors", - "version": "2.7.1", + "description": "Node.js CORS middleware", + "version": "2.8.5", "author": "Troy Goode (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"}, + "keywords": [ + "cors", + "express", + "connect", + "middleware" + ], + "repository": "expressjs/cors", "main": "./lib/index.js", - "engines": { - "node": ">=0.10.0" - }, "dependencies": { + "object-assign": "^4", "vary": "^1" }, "devDependencies": { - "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" + "after": "0.8.2", + "eslint": "2.13.1", + "express": "4.16.3", + "mocha": "5.2.0", + "nyc": "13.1.0", + "supertest": "3.3.0" + }, + "files": [ + "lib/index.js", + "CONTRIBUTING.md", + "HISTORY.md", + "LICENSE", + "README.md" + ], + "engines": { + "node": ">= 0.10" }, "scripts": { - "test": "npm run lint && ./node_modules/mocha/bin/mocha", - "lint": "./node_modules/eslint/bin/eslint.js lib test" + "test": "npm run lint && nyc --reporter=html --reporter=text mocha --require test/support/env", + "lint": "eslint lib test" } } diff -Nru node-cors-2.7.1/README.md node-cors-2.8.5/README.md --- node-cors-2.7.1/README.md 2015-05-28 23:16:24.000000000 +0000 +++ node-cors-2.8.5/README.md 2018-11-04 20:56:03.000000000 +0000 @@ -1,12 +1,14 @@ -# `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. **[Follow me (@troygoode) on Twitter!](https://twitter.com/intent/user?screen_name=troygoode)** -[![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.png)](http://travis-ci.org/expressjs/cors) * [Installation](#installation) * [Usage](#usage) * [Simple Usage](#simple-usage-enable-all-cors-requests) @@ -19,9 +21,13 @@ * [License](#license) * [Author](#author) -## Installation (via [npm](https://npmjs.org/package/cors)) +## Installation + +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): -```bash +```sh $ npm install cors ``` @@ -31,78 +37,97 @@ ```javascript 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.listen(80, function(){ - console.log('CORS-enabled web server listening on port 80'); -}); +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') +}) ``` ### Enable CORS for a Single Route ```javascript 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 all origins!'}); -}); - -app.listen(80, function(){ - console.log('CORS-enabled web server listening on port 80'); -}); +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') +}) ``` ### Configuring CORS ```javascript var express = require('express') - , cors = require('cors') - , app = express(); +var cors = require('cors') +var app = express() var corsOptions = { - origin: 'http://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'); -}); + origin: 'http://example.com', + 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.listen(80, function () { + console.log('CORS-enabled web server listening on port 80') +}) ``` ### Configuring CORS w/ Dynamic Origin ```javascript 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(null, 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') +}) +``` + +If you do not want to block REST tools or server-to-server requests, +add a `!origin` check in the origin function like so: + +```javascript +var corsOptions = { + origin: function (origin, callback) { + if (whitelist.indexOf(origin) !== -1 || !origin) { + callback(null, true) + } else { + callback(new Error('Not allowed by CORS')) + } + } +} ``` ### Enabling CORS Pre-Flight @@ -116,63 +141,80 @@ ```javascript 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.listen(80, function(){ - console.log('CORS-enabled web server listening on port 80'); -}); +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') +}) ``` You can also enable pre-flight across-the-board like so: -``` -app.options('*', cors()); // include before other routes +```javascript +app.options('*', cors()) // include before other routes ``` ### Configuring CORS Asynchronously ```javascript 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 - }else{ - corsOptions = { origin: false }; // disable CORS for this request + 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 } - 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.listen(80, function(){ - console.log('CORS-enabled web server listening on port 80'); -}); +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') +}) ``` ## Configuration Options -* `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. +* `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. * `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']`). * `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. * `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed. * `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted. -* `maxAge`: Configures the **Access-Control-Allow-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted. +* `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted. * `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`. -For details on the effect of each CORS header, [read this article on HTML5 Rocks](http://www.html5rocks.com/en/tutorials/cors/). +The default configuration is the equivalent of: + +```json +{ + "origin": "*", + "methods": "GET,HEAD,PUT,PATCH,POST,DELETE", + "preflightContinue": false, + "optionsSuccessStatus": 204 +} +``` + +For details on the effect of each CORS header, read [this](http://www.html5rocks.com/en/tutorials/cors/) article on HTML5 Rocks. ## Demo @@ -190,3 +232,12 @@ ## Author [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 diff -Nru node-cors-2.7.1/test/basic-auth.js node-cors-2.8.5/test/basic-auth.js --- node-cors-2.7.1/test/basic-auth.js 2015-05-28 23:03:37.000000000 +0000 +++ node-cors-2.8.5/test/basic-auth.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -(function () { - /*global describe, it*/ - - 'use strict'; - - var should = require('should'), - express = require('express'), - supertest = require('supertest'), - basicAuth = require('basic-auth-connect'), - cors = require('../lib'); - - var app; - - /* -------------------------------------------------------------------------- */ - - app = express(); - app.use(basicAuth('username', 'password')); - app.use(cors()); - app.post('/', function (req, res) { - res.send('hello world'); - }); - - /* -------------------------------------------------------------------------- */ - - describe('basic auth', function () { - it('POST works', function (done) { - supertest(app) - .post('/') - .auth('username', 'password') - .expect(200) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - res.text.should.eql('hello world'); - done(); - }); - }); - }); - -}()); diff -Nru node-cors-2.7.1/test/body-events.js node-cors-2.8.5/test/body-events.js --- node-cors-2.7.1/test/body-events.js 2015-05-28 23:03:37.000000000 +0000 +++ node-cors-2.8.5/test/body-events.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -(function () { - /*global describe, it*/ - - 'use strict'; - - var should = require('should'), - express = require('express'), - supertest = require('supertest'), - bodyParser = require('body-parser'), - cors = require('../lib'); - - var dynamicOrigin, - app1, - app2, - text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed justo turpis, tempor id sem fringilla, cursus tristique purus. Mauris a sollicitudin magna. Etiam dui lacus, vehicula non dictum at, cursus vitae libero. Curabitur lorem nulla, sollicitudin id enim ut, vehicula rhoncus felis. Ut nec iaculis velit. Vivamus at augue nulla. Fusce at molestie arcu. Duis at dui at tellus mattis tincidunt. Vestibulum sit amet dictum metus. Curabitur nec pretium ante. Proin vulputate elit ac lorem gravida, sit amet placerat lorem fringilla. Mauris fermentum, diam et volutpat auctor, ante enim imperdiet purus, sit amet tincidunt ipsum nulla nec est. Fusce id ipsum in sem malesuada laoreet vitae non magna. Praesent commodo turpis in nulla egestas, eu posuere magna venenatis. Integer in aliquam sem. Fusce quis lorem tincidunt eros rutrum lobortis.\n\nNam aliquam cursus ipsum, a hendrerit purus. Cras ultrices viverra nunc ac lacinia. Sed sed diam orci. Vestibulum ut orci a nibh scelerisque pretium. Sed suscipit vestibulum metus, ac ultricies leo sodales a. Aliquam erat volutpat. Vestibulum mauris massa, luctus et libero vel, cursus suscipit nulla. Cras sed erat quis massa fermentum congue. Mauris ultrices sem ligula, id malesuada lectus tincidunt eget. Donec sed nisl elit. Aenean ac lobortis massa. Phasellus felis nisl, dictum a dui volutpat, dictum sagittis diam. Vestibulum lacinia tellus vel commodo consequat.\n\nNulla at varius nibh, non posuere enim. Curabitur urna est, ultrices vel sem nec, consequat molestie nisi. Aliquam sed augue sit amet ante viverra pretium. Cras aliquam turpis vitae eros gravida egestas. Etiam quis dolor non quam suscipit iaculis. Sed euismod est libero, ac ullamcorper elit hendrerit vitae. Vivamus sollicitudin nulla dolor, vitae porta lacus suscipit ac.\n\nSed volutpat, magna in scelerisque dapibus, eros ante volutpat nisi, ac condimentum diam sem sed justo. Aenean justo risus, bibendum vitae blandit ac, mattis quis nunc. Quisque non felis nec justo auctor accumsan non id odio. Mauris vel dui feugiat dolor dapibus convallis in et neque. Phasellus fermentum sollicitudin tortor ac pretium. Proin tristique accumsan nulla eu venenatis. Cras porta lorem ac arcu accumsan pulvinar. Sed dignissim leo augue, a pretium ante viverra id. Phasellus blandit at purus a malesuada. Nam et cursus mauris. Vivamus accumsan augue laoreet lectus lacinia eleifend. Fusce sit amet felis nunc. Pellentesque eu turpis nisl.\n\nPellentesque vitae quam feugiat, volutpat lectus et, faucibus massa. Maecenas consectetur quis nisi eu aliquam. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam laoreet condimentum laoreet. Praesent sit amet massa sit amet dui porta condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed volutpat massa nec risus malesuada hendrerit.'; - - /* -------------------------------------------------------------------------- */ - - dynamicOrigin = function (origin, cb) { - setTimeout(function () { - cb(null, true); - }, 200); - }; - - /* -------------------------------------------------------------------------- */ - - app1 = express(); - app1.use(cors({origin: dynamicOrigin})); - app1.use(bodyParser.json()); - app1.post('/', function (req, res) { - res.send(req.body); - }); - - /* -------------------------------------------------------------------------- */ - - app2 = express(); - app2.use(bodyParser.json()); - app2.use(cors({origin: dynamicOrigin})); - app2.post('/', function (req, res) { - res.send(req.body); - }); - - /* -------------------------------------------------------------------------- */ - - describe('body-parser-events', function () { - describe('app1 (cors before bodyparser)', function () { - it('POST works', function (done) { - var body = { - example: text - }; - supertest(app1) - .post('/') - .send(body) - .expect(200) - .end(function (err, res) { - should.not.exist(err); - res.body.should.eql(body); - done(); - }); - }); - }); - - describe('app2 (bodyparser before cors)', function () { - it('POST works', function (done) { - var body = { - example: text - }; - supertest(app2) - .post('/') - .send(body) - .expect(200) - .end(function (err, res) { - should.not.exist(err); - res.body.should.eql(body); - done(); - }); - }); - }); - }); - -}()); diff -Nru node-cors-2.7.1/test/cors.js node-cors-2.8.5/test/cors.js --- node-cors-2.7.1/test/cors.js 2015-05-28 23:04:14.000000000 +0000 +++ node-cors-2.8.5/test/cors.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,652 +0,0 @@ -(function () { - /*global describe, it*/ - - 'use strict'; - - var should = require('should'), - cors = require('../lib'); - - var fakeRequest = function (headers) { - return { - headers: headers || { - 'origin': 'request.com', - 'access-control-request-headers': 'requestedHeader1,requestedHeader2' - }, - pause: function () { - // do nothing - return; - }, - resume: function () { - // do nothing - return; - } - }; - }, - fakeResponse = function () { - var headers = {}; - return { - allHeaders: function () { - return headers; - }, - getHeader: function (key) { - return headers[key]; - }, - setHeader: function (key, value) { - headers[key] = value; - return; - }, - get: function (key) { - return headers[key]; - } - }; - }; - - describe('cors', function () { - it('passes control to next middleware', function (done) { - // arrange - var req, res, next; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - done(); - }; - - // act - cors()(req, res, next); - }); - - it('shortcircuits preflight requests', function (done) { - // arrange - var req, res, next; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.statusCode.should.equal(204); - done(); - }; - next = function () { - // assert - done('should not be called'); - }; - - // act - cors()(req, res, next); - }); - - it('doesn\'t shortcircuit preflight requests with preflightContinue option', function (done) { - // arrange - var req, res, next; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - done('should not be called'); - }; - next = function () { - // assert - done(); - }; - - // act - cors({preflightContinue: true})(req, res, next); - }); - - it('normalizes method names', function (done) { - // arrange - var req, res, next; - req = fakeRequest(); - req.method = 'options'; - res = fakeResponse(); - res.end = function () { - // assert - res.statusCode.should.equal(204); - done(); - }; - next = function () { - // assert - done('should not be called'); - }; - - // act - cors()(req, res, next); - }); - - it('no options enables default CORS to all origins', function (done) { - // arrange - var req, res, next; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - res.getHeader('Access-Control-Allow-Origin').should.equal('*'); - should.not.exist(res.getHeader('Access-Control-Allow-Methods')); - done(); - }; - - // act - cors()(req, res, next); - }); - - it('OPTION call with no options enables default CORS to all origins and methods', function (done) { - // arrange - var req, res, next; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.statusCode.should.equal(204); - done(); - }; - next = function () { - // assert - res.getHeader('Access-Control-Allow-Origin').should.equal('*'); - res.getHeader('Access-Control-Allow-Methods').should.equal('GET,PUT,PATCH,POST,DELETE'); - done(); - }; - - // act - cors()(req, res, next); - }); - - describe('passing static options', function () { - it('overrides defaults', function (done) { - // arrange - var req, res, next, options; - options = { - origin: 'example.com', - methods: ['FOO', 'bar'], - headers: ['FIZZ', 'buzz'], - credentials: true, - maxAge: 123 - }; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.statusCode.should.equal(204); - done(); - }; - next = function () { - // assert - res.getHeader('Access-Control-Allow-Origin').should.equal('example.com'); - res.getHeader('Access-Control-Allow-Methods').should.equal('FOO,bar'); - res.getHeader('Access-Control-Allow-Headers').should.equal('FIZZ,buzz'); - res.getHeader('Access-Control-Allow-Credentials').should.equal('true'); - res.getHeader('Access-Control-Allow-Max-Age').should.equal('123'); - done(); - }; - - // act - cors(options)(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) { - // arrange - var req, res, next, options; - options = { - origin: false, - methods: ['FOO', 'bar'], - headers: ['FIZZ', 'buzz'], - credentials: true, - maxAge: 123 - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - should.not.exist(res.getHeader('Access-Control-Allow-Origin')); - should.not.exist(res.getHeader('Access-Control-Allow-Methods')); - should.not.exist(res.getHeader('Access-Control-Allow-Headers')); - should.not.exist(res.getHeader('Access-Control-Allow-Credentials')); - should.not.exist(res.getHeader('Access-Control-Allow-Max-Age')); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('can override origin', function (done) { - // arrange - var req, res, next, options; - options = { - origin: 'example.com' - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - res.getHeader('Access-Control-Allow-Origin').should.equal('example.com'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('includes Vary header for specific origins', function (done) { - // arrange - var req, res, next, options; - options = { - origin: 'example.com' - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - should.exist(res.getHeader('Vary')); - res.getHeader('Vary').should.equal('Origin'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('appends to an existing Vary header', function (done) { - // arrange - var req, res, next, options; - options = { - origin: 'example.com' - }; - req = fakeRequest(); - res = fakeResponse(); - res.setHeader('Vary', 'Foo'); - next = function () { - // assert - res.getHeader('Vary').should.equal('Foo, Origin'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('origin defaults to *', function (done) { - // arrange - var req, res, next, options; - options = { - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - res.getHeader('Access-Control-Allow-Origin').should.equal('*'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('specifying true for origin reflects requesting origin', function (done) { - // arrange - var req, res, next, options; - options = { - origin: true - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - res.getHeader('Access-Control-Allow-Origin').should.equal('request.com'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('should allow origin when callback returns true', function (done) { - var req, res, next, options; - options = { - origin: function (sentOrigin, cb) { - sentOrigin.should.equal('request.com'); - cb(null, true); - } - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - res.getHeader('Access-Control-Allow-Origin').should.equal('request.com'); - done(); - }; - - cors(options)(req, res, next); - }); - - it('should not allow origin when callback returns false', function (done) { - var req, res, next, options; - options = { - origin: function (sentOrigin, cb) { - sentOrigin.should.equal('request.com'); - cb(null, false); - } - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - should.not.exist(res.getHeader('Access-Control-Allow-Origin')); - should.not.exist(res.getHeader('Access-Control-Allow-Methods')); - should.not.exist(res.getHeader('Access-Control-Allow-Headers')); - should.not.exist(res.getHeader('Access-Control-Allow-Credentials')); - should.not.exist(res.getHeader('Access-Control-Allow-Max-Age')); - done(); - }; - - cors(options)(req, res, next); - }); - - it('should not override options.origin callback', function (done) { - var req, res, next, options; - options = { - origin: function (sentOrigin, cb) { - var isValid = sentOrigin === 'request.com'; - cb(null, isValid); - } - }; - - req = fakeRequest(); - res = fakeResponse(); - next = function () { - res.getHeader('Access-Control-Allow-Origin').should.equal('request.com'); - }; - - cors(options)(req, res, next); - - req = fakeRequest({ - 'origin': 'invalid-request.com' - }); - res = fakeResponse(); - - next = function () { - should.not.exist(res.getHeader('Access-Control-Allow-Origin')); - should.not.exist(res.getHeader('Access-Control-Allow-Methods')); - should.not.exist(res.getHeader('Access-Control-Allow-Headers')); - should.not.exist(res.getHeader('Access-Control-Allow-Credentials')); - should.not.exist(res.getHeader('Access-Control-Allow-Max-Age')); - done(); - }; - - cors(options)(req, res, next); - }); - - - it('can override methods', function (done) { - // arrange - var req, res, next, options; - options = { - methods: ['method1', 'method2'] - }; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.statusCode.should.equal(204); - done(); - }; - next = function () { - // assert - res.getHeader('Access-Control-Allow-Methods').should.equal('method1,method2'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('methods defaults to GET, PUT, PATCH, POST, DELETE', function (done) { - // arrange - var req, res, next, options; - options = { - }; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.statusCode.should.equal(204); - done(); - }; - next = function () { - // assert - res.getHeader('Access-Control-Allow-Methods').should.equal('GET,PUT,PATCH,POST,DELETE'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('can specify allowed headers', function (done) { - // arrange - var req, res, options; - options = { - allowedHeaders: ['header1', 'header2'] - }; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.getHeader('Access-Control-Allow-Headers').should.equal('header1,header2'); - done(); - }; - - // act - cors(options)(req, res, null); - }); - - it('specifying an empty list or string of allowed headers will result in no response header for allowed headers', function (done) { - // arrange - var req, res, next, options; - options = { - allowedHeaders: [] - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - should.not.exist(res.getHeader('Access-Control-Allow-Headers')); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('if no allowed headers are specified, defaults to requested allowed headers', function (done) { - // arrange - var req, res, options; - options = { - }; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.getHeader('Access-Control-Allow-Headers').should.equal('requestedHeader1,requestedHeader2'); - done(); - }; - - // act - cors(options)(req, res, null); - }); - - it('can specify exposed headers', function (done) { - // arrange - var req, res, options, next; - options = { - exposedHeaders: ['custom-header1', 'custom-header2'] - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - res.getHeader('Access-Control-Expose-Headers').should.equal('custom-header1,custom-header2'); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('includes credentials if explicitly enabled', function (done) { - // arrange - var req, res, options; - options = { - credentials: true - }; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.getHeader('Access-Control-Allow-Credentials').should.equal('true'); - done(); - }; - - // act - cors(options)(req, res, null); - }); - - it('does not includes credentials unless explicitly enabled', function (done) { - // arrange - var req, res, next, options; - options = { - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - should.not.exist(res.getHeader('Access-Control-Allow-Credentials')); - done(); - }; - - // act - cors(options)(req, res, next); - }); - - it('includes maxAge when specified', function (done) { - // arrange - var req, res, options; - options = { - maxAge: 456 - }; - req = fakeRequest(); - req.method = 'OPTIONS'; - res = fakeResponse(); - res.end = function () { - // assert - res.getHeader('Access-Control-Max-Age').should.equal('456'); - done(); - }; - - // act - cors(options)(req, res, null); - }); - - it('does not includes maxAge unless specified', function (done) { - // arrange - var req, res, next, options; - options = { - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - should.not.exist(res.getHeader('Access-Control-Allow-Max-Age')); - done(); - }; - - // act - cors(options)(req, res, next); - }); - }); - - describe('passing a function to build options', function () { - it('handles options specified via callback', function (done) { - // arrange - var req, res, next, delegate; - delegate = function (req2, cb) { - cb(null, { - origin: 'delegate.com' - }); - }; - req = fakeRequest(); - res = fakeResponse(); - next = function () { - // assert - res.getHeader('Access-Control-Allow-Origin').should.equal('delegate.com'); - done(); - }; - - // act - cors(delegate)(req, res, next); - }); - - it('handles error specified via callback', function (done) { - // arrange - var req, res, next, delegate; - delegate = function (req2, cb) { - cb('some error'); - }; - req = fakeRequest(); - res = fakeResponse(); - next = function (err) { - // assert - err.should.equal('some error'); - done(); - }; - - // act - cors(delegate)(req, res, next); - }); - }); - }); - -}()); diff -Nru node-cors-2.7.1/test/error-response.js node-cors-2.8.5/test/error-response.js --- node-cors-2.7.1/test/error-response.js 2015-05-28 23:03:37.000000000 +0000 +++ node-cors-2.8.5/test/error-response.js 2018-11-04 20:56:03.000000000 +0000 @@ -1,10 +1,8 @@ (function () { - /*global describe, it*/ 'use strict'; - var should = require('should'), - express = require('express'), + var express = require('express'), supertest = require('supertest'), cors = require('../lib'); @@ -42,35 +40,26 @@ supertest(app) .post('/five-hundred') .expect(500) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - res.text.should.startWith('Error: nope'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .expect(/Error: nope/) + .end(done) }); it('401', function (done) { supertest(app) .post('/four-oh-one') .expect(401) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - res.text.should.eql('unauthorized'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .expect('unauthorized') + .end(done) }); it('404', function (done) { supertest(app) .post('/four-oh-four') .expect(404) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .end(done) }); }); diff -Nru node-cors-2.7.1/test/.eslintrc.yml node-cors-2.8.5/test/.eslintrc.yml --- node-cors-2.7.1/test/.eslintrc.yml 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/test/.eslintrc.yml 2018-11-04 20:56:03.000000000 +0000 @@ -0,0 +1,2 @@ +env: + mocha: true diff -Nru node-cors-2.7.1/test/example-app.js node-cors-2.8.5/test/example-app.js --- node-cors-2.7.1/test/example-app.js 2015-05-28 23:03:37.000000000 +0000 +++ node-cors-2.8.5/test/example-app.js 2018-11-04 20:56:03.000000000 +0000 @@ -1,10 +1,8 @@ (function () { - /*global describe, it*/ 'use strict'; - var should = require('should'), - express = require('express'), + var express = require('express'), supertest = require('supertest'), cors = require('../lib'); @@ -40,33 +38,24 @@ supertest(simpleApp) .get('/') .expect(200) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - res.text.should.eql('Hello World (Get)'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .expect('Hello World (Get)') + .end(done) }); it('HEAD works', function (done) { supertest(simpleApp) .head('/') .expect(204) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .end(done) }); it('POST works', function (done) { supertest(simpleApp) .post('/') .expect(200) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - res.text.should.eql('Hello World (Post)'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .expect('Hello World (Post)') + .end(done) }); }); @@ -75,22 +64,16 @@ supertest(complexApp) .options('/') .expect(204) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .end(done) }); it('DELETE works', function (done) { supertest(complexApp) .del('/') .expect(200) - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - res.text.should.eql('Hello World (Delete)'); - done(); - }); + .expect('Access-Control-Allow-Origin', '*') + .expect('Hello World (Delete)') + .end(done) }); }); }); diff -Nru node-cors-2.7.1/test/issue-2.js node-cors-2.8.5/test/issue-2.js --- node-cors-2.7.1/test/issue-2.js 2015-05-28 23:03:37.000000000 +0000 +++ node-cors-2.8.5/test/issue-2.js 2018-11-04 20:56:03.000000000 +0000 @@ -1,10 +1,8 @@ (function () { - /*global describe, it*/ 'use strict'; - var should = require('should'), - express = require('express'), + var express = require('express'), supertest = require('supertest'), cors = require('../lib'); @@ -31,25 +29,19 @@ it('OPTIONS works', function (done) { supertest(app) .options('/api/login') - .expect(204) .set('Origin', 'http://example.com') - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('http://example.com'); - done(); - }); + .expect(204) + .expect('Access-Control-Allow-Origin', 'http://example.com') + .end(done) }); it('POST works', function (done) { supertest(app) .post('/api/login') - .expect(200) .set('Origin', 'http://example.com') - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('http://example.com'); - res.text.should.eql('LOGIN'); - done(); - }); + .expect(200) + .expect('Access-Control-Allow-Origin', 'http://example.com') + .expect('LOGIN') + .end(done) }); }); diff -Nru node-cors-2.7.1/test/issue-31.js node-cors-2.8.5/test/issue-31.js --- node-cors-2.7.1/test/issue-31.js 2015-05-28 23:03:37.000000000 +0000 +++ node-cors-2.8.5/test/issue-31.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -(function () { - /*global describe, it*/ - - 'use strict'; - - var should = require('should'), - express = require('express'), - supertest = require('supertest'), - cors = require('../lib'); - - var app, - mainRouter, - itemsRouter; - - /* -------------------------------------------------------------------------- */ - - itemsRouter = new express.Router(); - itemsRouter.get('/', function (req, res) { - res.send('hello world'); - }); - - mainRouter = new express.Router(); - mainRouter.use('/items', itemsRouter); - - app = express(); - app.use(cors()); - app.use(mainRouter); - - /* -------------------------------------------------------------------------- */ - - describe('issue #31', function () { - it('OPTIONS works', function (done) { - supertest(app) - .options('/items') - .expect(204) - .set('Origin', 'http://example.com') - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - done(); - }); - }); - - it('GET works', function (done) { - supertest(app) - .get('/items') - .expect(200) - .set('Origin', 'http://example.com') - .end(function (err, res) { - should.not.exist(err); - res.headers['access-control-allow-origin'].should.eql('*'); - res.text.should.eql('hello world'); - done(); - }); - }); - }); - -}()); diff -Nru node-cors-2.7.1/test/mocha.opts node-cors-2.8.5/test/mocha.opts --- node-cors-2.7.1/test/mocha.opts 2014-10-23 21:35:18.000000000 +0000 +++ node-cors-2.8.5/test/mocha.opts 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ ---ui bdd ---reporter spec ---require should diff -Nru node-cors-2.7.1/test/support/env.js node-cors-2.8.5/test/support/env.js --- node-cors-2.7.1/test/support/env.js 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/test/support/env.js 2018-11-04 20:56:03.000000000 +0000 @@ -0,0 +1,2 @@ + +process.env.NODE_ENV = 'test'; diff -Nru node-cors-2.7.1/test/test.js node-cors-2.8.5/test/test.js --- node-cors-2.7.1/test/test.js 1970-01-01 00:00:00.000000000 +0000 +++ node-cors-2.8.5/test/test.js 2018-11-04 20:56:03.000000000 +0000 @@ -0,0 +1,772 @@ +(function () { + + 'use strict'; + + var after = require('after') + var assert = require('assert') + var cors = require('..') + + var fakeRequest = function (method, headers) { + return { + method: method, + headers: headers || { + 'origin': 'request.com', + 'access-control-request-headers': 'requestedHeader1,requestedHeader2' + } + }; + }, + fakeResponse = function () { + var headers = {}; + return { + getHeader: function (key) { + return headers[key]; + }, + setHeader: function (key, value) { + headers[key] = value; + return; + }, + get: function (key) { + return headers[key]; + } + }; + }; + + describe('cors', function () { + it('does not alter `options` configuration object', function () { + var options = Object.freeze({ + origin: 'custom-origin' + }); + assert.doesNotThrow(function () { + cors(options); + }) + }); + + it('passes control to next middleware', function (done) { + // arrange + var req, res, next; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + done(); + }; + + // act + cors()(req, res, next); + }); + + it('shortcircuits preflight requests', function (done) { + // arrange + var cb = after(1, done) + var req, res, next; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.statusCode, 204) + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors()(req, res, next); + }); + + it('can configure preflight success response status code', function (done) { + // arrange + var cb = after(1, done) + var req, res, next; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.statusCode, 200) + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors({optionsSuccessStatus: 200})(req, res, next); + }); + + it('doesn\'t shortcircuit preflight requests with preflightContinue option', function (done) { + // arrange + var cb = after(1, done) + var req, res, next; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + cb(new Error('should not be called')) + }; + next = function () { + // assert + cb() + }; + + // act + cors({preflightContinue: true})(req, res, next); + }); + + it('normalizes method names', function (done) { + // arrange + var cb = after(1, done) + var req, res, next; + req = fakeRequest('options'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.statusCode, 204) + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors()(req, res, next); + }); + + it('includes Content-Length response header', function (done) { + // arrange + var cb = after(1, done) + var req, res, next; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.getHeader('Content-Length'), '0') + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors()(req, res, next); + }); + + it('no options enables default CORS to all origins', function (done) { + // arrange + var req, res, next; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Origin'), '*') + assert.equal(res.getHeader('Access-Control-Allow-Methods'), undefined) + done(); + }; + + // act + cors()(req, res, next); + }); + + it('OPTION call with no options enables default CORS to all origins and methods', function (done) { + // arrange + var cb = after(1, done) + var req, res, next; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.statusCode, 204) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), '*') + assert.equal(res.getHeader('Access-Control-Allow-Methods'), 'GET,HEAD,PUT,PATCH,POST,DELETE') + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors()(req, res, next); + }); + + describe('passing static options', function () { + it('overrides defaults', function (done) { + // arrange + var cb = after(1, done) + var req, res, next, options; + options = { + origin: 'example.com', + methods: ['FOO', 'bar'], + headers: ['FIZZ', 'buzz'], + credentials: true, + maxAge: 123 + }; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.statusCode, 204) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'example.com') + assert.equal(res.getHeader('Access-Control-Allow-Methods'), 'FOO,bar') + assert.equal(res.getHeader('Access-Control-Allow-Headers'), 'FIZZ,buzz') + assert.equal(res.getHeader('Access-Control-Allow-Credentials'), 'true') + assert.equal(res.getHeader('Access-Control-Max-Age'), '123') + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors(options)(req, res, next); + }); + + it('matches request origin against regexp', function(done) { + var req = fakeRequest('GET'); + var res = fakeResponse(); + var options = { origin: /^(.+\.)?request.com$/ }; + cors(options)(req, res, function(err) { + assert.ifError(err) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), req.headers.origin) + assert.equal(res.getHeader('Vary'), 'Origin') + return done(); + }); + }); + + it('matches request origin against array of origin checks', function(done) { + var req = fakeRequest('GET'); + var res = fakeResponse(); + var options = { origin: [ /foo\.com$/, 'request.com' ] }; + cors(options)(req, res, function(err) { + assert.ifError(err) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), req.headers.origin) + assert.equal(res.getHeader('Vary'), 'Origin') + return done(); + }); + }); + + it('doesn\'t match request origin against array of invalid origin checks', function(done) { + var req = fakeRequest('GET'); + var res = fakeResponse(); + var options = { origin: [ /foo\.com$/, 'bar.com' ] }; + cors(options)(req, res, function(err) { + assert.ifError(err) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), undefined) + assert.equal(res.getHeader('Vary'), 'Origin') + return done(); + }); + }); + + it('origin of false disables cors', function (done) { + // arrange + var req, res, next, options; + options = { + origin: false, + methods: ['FOO', 'bar'], + headers: ['FIZZ', 'buzz'], + credentials: true, + maxAge: 123 + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Origin'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Methods'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Headers'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Credentials'), undefined) + assert.equal(res.getHeader('Access-Control-Max-Age'), undefined) + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('can override origin', function (done) { + // arrange + var req, res, next, options; + options = { + origin: 'example.com' + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'example.com') + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('includes Vary header for specific origins', function (done) { + // arrange + var req, res, next, options; + options = { + origin: 'example.com' + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Vary'), 'Origin') + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('appends to an existing Vary header', function (done) { + // arrange + var req, res, next, options; + options = { + origin: 'example.com' + }; + req = fakeRequest('GET'); + res = fakeResponse(); + res.setHeader('Vary', 'Foo'); + next = function () { + // assert + assert.equal(res.getHeader('Vary'), 'Foo, Origin') + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('origin defaults to *', function (done) { + // arrange + var req, res, next; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Origin'), '*') + done(); + }; + + // act + cors()(req, res, next); + }); + + it('specifying true for origin reflects requesting origin', function (done) { + // arrange + var req, res, next, options; + options = { + origin: true + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'request.com') + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('should allow origin when callback returns true', function (done) { + var req, res, next, options; + options = { + origin: function (sentOrigin, cb) { + assert.equal(sentOrigin, 'request.com') + cb(null, true); + } + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'request.com') + done(); + }; + + cors(options)(req, res, next); + }); + + it('should not allow origin when callback returns false', function (done) { + var req, res, next, options; + options = { + origin: function (sentOrigin, cb) { + assert.equal(sentOrigin, 'request.com') + cb(null, false); + } + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + assert.equal(res.getHeader('Access-Control-Allow-Origin'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Methods'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Headers'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Credentials'), undefined) + assert.equal(res.getHeader('Access-Control-Max-Age'), undefined) + done(); + }; + + cors(options)(req, res, next); + }); + + it('should not override options.origin callback', function (done) { + var req, res, next, options; + options = { + origin: function (sentOrigin, cb) { + var isValid = sentOrigin === 'request.com'; + cb(null, isValid); + } + }; + + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'request.com') + }; + + cors(options)(req, res, next); + + req = fakeRequest('GET', { + 'origin': 'invalid-request.com' + }); + res = fakeResponse(); + + next = function () { + assert.equal(res.getHeader('Access-Control-Allow-Origin'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Methods'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Headers'), undefined) + assert.equal(res.getHeader('Access-Control-Allow-Credentials'), undefined) + assert.equal(res.getHeader('Access-Control-Max-Age'), undefined) + done(); + }; + + cors(options)(req, res, next); + }); + + + it('can override methods', function (done) { + // arrange + var cb = after(1, done) + var req, res, next, options; + options = { + methods: ['method1', 'method2'] + }; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.statusCode, 204) + assert.equal(res.getHeader('Access-Control-Allow-Methods'), 'method1,method2') + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors(options)(req, res, next); + }); + + it('methods defaults to GET, HEAD, PUT, PATCH, POST, DELETE', function (done) { + // arrange + var cb = after(1, done) + var req, res, next; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.statusCode, 204) + assert.equal(res.getHeader('Access-Control-Allow-Methods'), 'GET,HEAD,PUT,PATCH,POST,DELETE') + cb() + }; + next = function () { + // assert + cb(new Error('should not be called')) + }; + + // act + cors()(req, res, next); + }); + + it('can specify allowed headers as array', function (done) { + // arrange + var req, res, options; + options = { + allowedHeaders: ['header1', 'header2'] + }; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Headers'), 'header1,header2') + assert.equal(res.getHeader('Vary'), undefined) + done(); + }; + + // act + cors(options)(req, res, null); + }); + + it('can specify allowed headers as string', function (done) { + // arrange + var req, res, options; + options = { + allowedHeaders: 'header1,header2' + }; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Headers'), 'header1,header2') + assert.equal(res.getHeader('Vary'), undefined) + done(); + }; + + // act + cors(options)(req, res, null); + }); + + it('specifying an empty list or string of allowed headers will result in no response header for allowed headers', function (done) { + // arrange + var req, res, next, options; + options = { + allowedHeaders: [] + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Headers'), undefined) + assert.equal(res.getHeader('Vary'), undefined) + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('if no allowed headers are specified, defaults to requested allowed headers', function (done) { + // arrange + var req, res; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Headers'), 'requestedHeader1,requestedHeader2') + assert.equal(res.getHeader('Vary'), 'Access-Control-Request-Headers') + done(); + }; + + // act + cors()(req, res, null); + }); + + it('can specify exposed headers as array', function (done) { + // arrange + var req, res, options, next; + options = { + exposedHeaders: ['custom-header1', 'custom-header2'] + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Expose-Headers'), 'custom-header1,custom-header2') + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('can specify exposed headers as string', function (done) { + // arrange + var req, res, options, next; + options = { + exposedHeaders: 'custom-header1,custom-header2' + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Expose-Headers'), 'custom-header1,custom-header2') + done(); + }; + + // act + cors(options)(req, res, next); + }); + + 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('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Expose-Headers'), undefined) + done(); + }; + + // act + cors(options)(req, res, next); + }); + + it('includes credentials if explicitly enabled', function (done) { + // arrange + var req, res, options; + options = { + credentials: true + }; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Credentials'), 'true') + done(); + }; + + // act + cors(options)(req, res, null); + }); + + it('does not includes credentials unless explicitly enabled', function (done) { + // arrange + var req, res, next; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Credentials'), undefined) + done(); + }; + + // act + cors()(req, res, next); + }); + + it('includes maxAge when specified', function (done) { + // arrange + var req, res, options; + options = { + maxAge: 456 + }; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.getHeader('Access-Control-Max-Age'), '456') + done(); + }; + + // act + cors(options)(req, res, null); + }); + + it('includes maxAge when specified and equals to zero', function (done) { + // arrange + var req, res, options + options = { + maxAge: 0 + } + req = fakeRequest('OPTIONS') + res = fakeResponse() + res.end = function () { + // assert + assert.equal(res.getHeader('Access-Control-Max-Age'), '0') + done() + } + + // act + cors(options)(req, res, null) + }); + + it('does not includes maxAge unless specified', function (done) { + // arrange + var req, res, next; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Max-Age'), undefined) + done(); + }; + + // act + cors()(req, res, next); + }); + }); + + describe('passing a function to build options', function () { + it('handles options specified via callback', function (done) { + // arrange + var req, res, next, delegate; + delegate = function (req2, cb) { + cb(null, { + origin: 'delegate.com' + }); + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'delegate.com') + done(); + }; + + // act + cors(delegate)(req, res, next); + }); + + it('handles options specified via callback for preflight', function (done) { + // arrange + var req, res, delegate; + delegate = function (req2, cb) { + cb(null, { + origin: 'delegate.com', + maxAge: 1000 + }); + }; + req = fakeRequest('OPTIONS'); + res = fakeResponse(); + res.end = function () { + // assert + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'delegate.com') + assert.equal(res.getHeader('Access-Control-Max-Age'), '1000') + done(); + }; + + // act + cors(delegate)(req, res, null); + }); + + it('handles error specified via callback', function (done) { + // arrange + var req, res, next, delegate; + delegate = function (req2, cb) { + cb('some error'); + }; + req = fakeRequest('GET'); + res = fakeResponse(); + next = function (err) { + // assert + assert.equal(err, 'some error') + done(); + }; + + // act + cors(delegate)(req, res, next); + }); + }); + }); + +}()); diff -Nru node-cors-2.7.1/.travis.yml node-cors-2.8.5/.travis.yml --- node-cors-2.7.1/.travis.yml 2014-10-23 21:35:18.000000000 +0000 +++ node-cors-2.8.5/.travis.yml 2018-11-04 20:56:03.000000000 +0000 @@ -1,3 +1,56 @@ language: node_js node_js: - - 0.10 + - "0.10" + - "4.9" + - "6.14" + - "8.12" + - "10.11" +sudo: false +cache: + directories: + - node_modules +before_install: + # Configure npm + - | + # Skip updating shrinkwrap / lock + npm config set shrinkwrap false + # Setup Node.js version-specific dependencies + - | + # mocha for testing + # - use 3.x for Node.js < 6 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + npm install --save-dev mocha@3.5.3 + fi + - | + # nyc for coverage + # - use 10.x for Node.js < 4 + # - use 11.x for Node.js < 6 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + npm install --save-dev nyc@10.3.2 + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + npm install --save-dev nyc@11.9.0 + fi + - | + # supertest for http calls + # - use 2.0.0 for Node.js < 4 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + npm install --save-dev supertest@2.0.0 + fi + # Update Node.js modules + - | + # Prune & rebuild node_modules + if [[ -d node_modules ]]; then + npm prune + npm rebuild + fi +script: + - | + # Run test script + npm test +after_script: + - | + # Upload coverage to coveralls if exists + if [[ -d .nyc_output ]]; then + npm install --save-dev coveralls@2 + nyc report --reporter=text-lcov | coveralls + fi