darkmode toggle
This commit is contained in:
2
node_modules/corser/.npmignore
generated
vendored
Normal file
2
node_modules/corser/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
example/
|
||||
test/
|
4
node_modules/corser/.travis.yml
generated
vendored
Normal file
4
node_modules/corser/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "node"
|
||||
sudo: false
|
19
node_modules/corser/LICENSE
generated
vendored
Normal file
19
node_modules/corser/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2012 Alexander Grüneberg
|
||||
|
||||
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 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.
|
202
node_modules/corser/README.md
generated
vendored
Normal file
202
node_modules/corser/README.md
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Corser
|
||||
=======
|
||||
|
||||
[](http://www.repostatus.org/#active)
|
||||
[](http://travis-ci.org/agrueneberg/Corser)
|
||||
|
||||
A highly configurable, middleware compatible implementation of [CORS](http://www.w3.org/TR/cors/) for [Node.js](http://nodejs.org/).
|
||||
|
||||
|
||||
Changelog
|
||||
---------
|
||||
|
||||
### 2.0.1 (August 16, 2016)
|
||||
|
||||
* Add workaround for [Chrome 52 sending empty `Access-Control-Request-Headers` header](https://bugs.chromium.org/p/chromium/issues/detail?id=633729).
|
||||
|
||||
### 2.0.0 (March 22, 2014)
|
||||
|
||||
* Preflight requests are automatically closed. If there is a need for handling `OPTIONS` requests, check the `endPreflightRequests` option.
|
||||
* The parameters of the callback function in dynamic origin checking are now `(err, matches)` instead of just `(matches)`.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
### How to use Corser as a middleware in Express
|
||||
|
||||
See `example/express/` for a working example.
|
||||
|
||||
var express, corser, app;
|
||||
|
||||
express = require("express");
|
||||
corser = require("corser");
|
||||
|
||||
app = express();
|
||||
|
||||
app.use(corser.create());
|
||||
|
||||
app.get("/", function (req, res) {
|
||||
res.writeHead(200);
|
||||
res.end("Nice weather today, huh?");
|
||||
});
|
||||
|
||||
app.listen(1337);
|
||||
|
||||
### How to use Corser as a middleware in Connect
|
||||
|
||||
See `example/connect/` for a working example.
|
||||
|
||||
var connect, corser, app;
|
||||
|
||||
connect = require("connect");
|
||||
corser = require("corser");
|
||||
|
||||
app = connect();
|
||||
|
||||
app.use(corser.create());
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.writeHead(200);
|
||||
res.end("Nice weather today, huh?");
|
||||
});
|
||||
|
||||
app.listen(1337);
|
||||
|
||||
### How to use Corser with plain `http`
|
||||
|
||||
var http, corser, corserRequestListener;
|
||||
|
||||
http = require("http");
|
||||
corser = require("corser");
|
||||
|
||||
// Create Corser request listener.
|
||||
corserRequestListener = corser.create();
|
||||
|
||||
http.createServer(function (req, res) {
|
||||
// Route req and res through the request listener.
|
||||
corserRequestListener(req, res, function () {
|
||||
res.writeHead(200);
|
||||
res.end("Nice weather today, huh?");
|
||||
});
|
||||
}).listen(1337);
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
### Creating a Corser request listener
|
||||
|
||||
Creating a Corser request listener that generates the appropriate response headers to enable CORS is as simple as:
|
||||
|
||||
corser.create()
|
||||
|
||||
This is the equivalent of setting a response header of `Access-Control-Allow-Origin: *`. If you want to restrict the origins, or allow more sophisticated request or response headers, you have to pass a configuration object to `corser.create`.
|
||||
|
||||
Corser will automatically end preflight requests for you. A preflight request is a special `OPTIONS` request that the browser sends under certain conditions to negotiate with the server what methods, request headers and response headers are allowed for a CORS request. If you need to use the `OPTIONS` method for other stuff, just set `endPreflightRequests` to `false` and terminate those requests yourself:
|
||||
|
||||
var corserRequestListener;
|
||||
|
||||
corserRequestListener = corser.create({
|
||||
endPreflightRequests: false
|
||||
});
|
||||
|
||||
corserRequestListener(req, res, function () {
|
||||
if (req.method === "OPTIONS") {
|
||||
// End CORS preflight request.
|
||||
res.writeHead(204);
|
||||
res.end();
|
||||
} else {
|
||||
// Implement other HTTP methods.
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
#### Configuration Object
|
||||
|
||||
A configuration object with the following properties can be passed to `corser.create`.
|
||||
|
||||
##### `origins`
|
||||
|
||||
A case-sensitive whitelist of origins. Unless unbound, if the request comes from an origin that is not in this list, it will not be handled by CORS.
|
||||
|
||||
To allow for dynamic origin checking, a function `(origin, callback)` can be passed instead of an array. `origin` is the Origin header, `callback` is a function `(err, matches)`, where `matches` is a boolean flag that indicates whether the given Origin header matches or not.
|
||||
|
||||
Default: unbound, i.e. every origin is accepted.
|
||||
|
||||
##### `methods`
|
||||
|
||||
An uppercase whitelist of methods. If the request uses a method that is not in this list, it will not be handled by CORS.
|
||||
|
||||
Setting a value here will overwrite the list of default simple methods. To not lose them, concat the methods you want to add with `corser.simpleMethods`: `corser.simpleMethods.concat(["PUT", "DELETE"])`.
|
||||
|
||||
Default: simple methods (`GET`, `HEAD`, `POST`).
|
||||
|
||||
##### `requestHeaders`
|
||||
|
||||
A case-insensitive whitelist of request headers. If the request uses a request header that is not in this list, it will not be handled by CORS.
|
||||
|
||||
Setting a value here will overwrite the list of default simple request headers. To not lose them, concat the request headers you want to add with `corser.simpleRequestHeaders`: `corser.simpleRequestHeaders.concat(["Authorization"])`.
|
||||
|
||||
Default: simple request headers (`Accept`, `Accept-Language`, `Content-Language`, `Content-Type`, `Last-Event-ID`).
|
||||
|
||||
##### `responseHeaders`
|
||||
|
||||
A case-insensitive whitelist of response headers. Any response header that is not in this list will be filtered out by the user-agent (the browser).
|
||||
|
||||
Setting a value here will overwrite the list of default simple response headers. To not lose them, concat the response headers you want to add with `corser.simpleResponseHeaders`: `corser.simpleResponseHeaders.concat(["ETag"])`.
|
||||
|
||||
Default: simple response headers (`Cache-Control`, `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, `Pragma`).
|
||||
|
||||
##### `supportsCredentials`
|
||||
|
||||
A boolean that indicates if cookie credentials can be transferred as part of a CORS request. Currently, only a few HTML5 elements can benefit from this setting.
|
||||
|
||||
Default: `false`.
|
||||
|
||||
##### `maxAge`
|
||||
|
||||
An integer that indicates the maximum amount of time in seconds that a preflight request is kept in the client-side preflight result cache.
|
||||
|
||||
Default: not set.
|
||||
|
||||
##### `endPreflightRequests`
|
||||
|
||||
A boolean that indicates if CORS preflight requests should be automatically closed.
|
||||
|
||||
Default: `true`.
|
||||
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
### Ajax call returns `Origin X is not allowed by Access-Control-Allow-Origin`
|
||||
|
||||
Check if the `Origin` header of your request matches one of the origins provided in the `origins` property of the configuration object. If you didn't set any `origins` property, jump to the next question.
|
||||
|
||||
|
||||
### Ajax call still returns `Origin X is not allowed by Access-Control-Allow-Origin`
|
||||
|
||||
Your request might use a non-simple method or one or more non-simple headers. According to the specification, the set of simple methods is `GET`, `HEAD`, and `POST`, and the set of simple request headers is `Accept`, `Accept-Language`, `Content-Language`, `Content-Type`, and `Last-Event-ID`. If your request uses **any** other method or header, you have to explicitly list them in the `methods` or `requestHeaders` property of the configuration object.
|
||||
|
||||
|
||||
#### Example
|
||||
|
||||
You want to allow requests that use an `X-Requested-With` header. Pass the following configuration object to `corser.create`:
|
||||
|
||||
corser.create({
|
||||
requestHeaders: corser.simpleRequestHeaders.concat(["X-Requested-With"])
|
||||
});
|
||||
|
||||
|
||||
### Getting a response header returns `Refused to get unsafe header "X"`
|
||||
|
||||
Your browser blocks every non-simple response headers that was not explicitly allowed in the preflight request. The set of simple response headers is `Cache-Control`, `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, `Pragma`. If you want to access **any** other response header, you have to explicitly list them in the `responseHeaders` property of the configuration object.
|
||||
|
||||
#### Example
|
||||
|
||||
You want to allow clients to read the `ETag` header of a response. Pass the following configuration object to `corser.create`:
|
||||
|
||||
corser.create({
|
||||
responseHeaders: corser.simpleResponseHeaders.concat(["ETag"])
|
||||
});
|
228
node_modules/corser/lib/corser.js
generated
vendored
Normal file
228
node_modules/corser/lib/corser.js
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* Specification: http://www.w3.org/TR/2012/WD-cors-20120403/
|
||||
* W3C Working Draft 3 April 2012
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
/*jshint node:true */
|
||||
|
||||
var simpleMethods, simpleRequestHeaders, simpleResponseHeaders, toLowerCase, checkOriginMatch;
|
||||
|
||||
// A method is said to be a simple method if it is a case-sensitive match for one of the following:
|
||||
Object.defineProperty(exports, "simpleMethods", {
|
||||
get: function () {
|
||||
return [
|
||||
"GET",
|
||||
"HEAD",
|
||||
"POST"
|
||||
];
|
||||
}
|
||||
});
|
||||
simpleMethods = exports.simpleMethods;
|
||||
|
||||
// A header is said to be a simple header if the header field name is an ASCII case-insensitive match for one of
|
||||
// the following:
|
||||
Object.defineProperty(exports, "simpleRequestHeaders", {
|
||||
get: function () {
|
||||
return [
|
||||
"accept",
|
||||
"accept-language",
|
||||
"content-language",
|
||||
"content-type"
|
||||
];
|
||||
}
|
||||
});
|
||||
simpleRequestHeaders = exports.simpleRequestHeaders;
|
||||
|
||||
// A header is said to be a simple response header if the header field name is an ASCII case-insensitive
|
||||
// match for one of the following:
|
||||
Object.defineProperty(exports, "simpleResponseHeaders", {
|
||||
get: function () {
|
||||
return [
|
||||
"cache-control",
|
||||
"content-language",
|
||||
"content-type",
|
||||
"expires",
|
||||
"last-modified",
|
||||
"pragma"
|
||||
];
|
||||
}
|
||||
});
|
||||
simpleResponseHeaders = exports.simpleResponseHeaders;
|
||||
|
||||
toLowerCase = function (array) {
|
||||
return array.map(function (el) {
|
||||
return el.toLowerCase();
|
||||
});
|
||||
};
|
||||
|
||||
checkOriginMatch = function (originHeader, origins, callback) {
|
||||
if (typeof origins === "function") {
|
||||
origins(originHeader, function (err, allow) {
|
||||
callback(err, allow);
|
||||
});
|
||||
} else if (origins.length > 0) {
|
||||
callback(null, origins.some(function (origin) {
|
||||
return origin === originHeader;
|
||||
}));
|
||||
} else {
|
||||
// Always matching is acceptable since the list of origins can be unbounded.
|
||||
callback(null, true);
|
||||
}
|
||||
};
|
||||
|
||||
exports.create = function (options) {
|
||||
options = options || {};
|
||||
options.origins = options.origins || [];
|
||||
options.methods = options.methods || simpleMethods;
|
||||
if (options.hasOwnProperty("requestHeaders") === true) {
|
||||
options.requestHeaders = toLowerCase(options.requestHeaders);
|
||||
} else {
|
||||
options.requestHeaders = simpleRequestHeaders;
|
||||
}
|
||||
if (options.hasOwnProperty("responseHeaders") === true) {
|
||||
options.responseHeaders = toLowerCase(options.responseHeaders);
|
||||
} else {
|
||||
options.responseHeaders = simpleResponseHeaders;
|
||||
}
|
||||
options.maxAge = options.maxAge || null;
|
||||
options.supportsCredentials = options.supportsCredentials || false;
|
||||
if (options.hasOwnProperty("endPreflightRequests") === false) {
|
||||
options.endPreflightRequests = true;
|
||||
}
|
||||
return function (req, res, next) {
|
||||
var methodMatches, headersMatch, requestMethod, requestHeaders, exposedHeaders, endPreflight;
|
||||
// If the Origin header is not present terminate this set of steps.
|
||||
if (!req.headers.hasOwnProperty("origin")) {
|
||||
// The request is outside the scope of the CORS specification. If there is no Origin header,
|
||||
// it could be a same-origin request. Let's let the user-agent handle this situation.
|
||||
next();
|
||||
} else {
|
||||
// If the value of the Origin header is not a case-sensitive match for any of the values in
|
||||
// list of origins, do not set any additional headers and terminate this set of steps.
|
||||
checkOriginMatch(req.headers.origin, options.origins, function (err, originMatches) {
|
||||
if (err !== null) {
|
||||
next(err);
|
||||
} else {
|
||||
if (typeof originMatches !== "boolean" || originMatches === false) {
|
||||
next();
|
||||
} else {
|
||||
// Respond to preflight request.
|
||||
if (req.method === "OPTIONS") {
|
||||
endPreflight = function () {
|
||||
if (options.endPreflightRequests === true) {
|
||||
res.writeHead(204);
|
||||
res.end();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
// If there is no Access-Control-Request-Method header or if parsing failed, do not set
|
||||
// any additional headers and terminate this set of steps.
|
||||
if (!req.headers.hasOwnProperty("access-control-request-method")) {
|
||||
endPreflight();
|
||||
} else {
|
||||
requestMethod = req.headers["access-control-request-method"];
|
||||
// If there are no Access-Control-Request-Headers headers let header field-names be the
|
||||
// empty list. If parsing failed do not set any additional headers and terminate this set
|
||||
// of steps.
|
||||
// Checking for an empty header is a workaround for a bug Chrome 52:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=633729
|
||||
if (req.headers.hasOwnProperty("access-control-request-headers") && req.headers["access-control-request-headers"] !== "") {
|
||||
requestHeaders = toLowerCase(req.headers["access-control-request-headers"].split(/,\s*/));
|
||||
} else {
|
||||
requestHeaders = [];
|
||||
}
|
||||
// If method is not a case-sensitive match for any of the values in list of methods do not
|
||||
// set any additional headers and terminate this set of steps.
|
||||
methodMatches = options.methods.indexOf(requestMethod) !== -1;
|
||||
if (methodMatches === false) {
|
||||
endPreflight();
|
||||
} else {
|
||||
// If any of the header field-names is not a ASCII case-insensitive match for any of
|
||||
// the values in list of headers do not set any additional headers and terminate this
|
||||
// set of steps.
|
||||
headersMatch = requestHeaders.every(function (requestHeader) {
|
||||
// Browsers automatically add Origin to Access-Control-Request-Headers. However,
|
||||
// Origin is not one of the simple request headers. Therefore, the header is
|
||||
// accepted even if it is not in the list of request headers because CORS would
|
||||
// not work without it.
|
||||
if (requestHeader === "origin") {
|
||||
return true;
|
||||
} else {
|
||||
if (options.requestHeaders.indexOf(requestHeader) !== -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (headersMatch === false) {
|
||||
endPreflight();
|
||||
} else {
|
||||
if (options.supportsCredentials === true) {
|
||||
// If the resource supports credentials add a single Access-Control-Allow-Origin
|
||||
// header, with the value of the Origin header as value, and add a single
|
||||
// Access-Control-Allow-Credentials header with the literal string "true"
|
||||
// as value.
|
||||
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
|
||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
} else {
|
||||
// Otherwise, add a single Access-Control-Allow-Origin header, with either the
|
||||
// value of the Origin header or the string "*" as value.
|
||||
if (options.origins.length > 0 || typeof options.origins === "function") {
|
||||
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
|
||||
} else {
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
}
|
||||
}
|
||||
// Optionally add a single Access-Control-Max-Age header with as value the amount
|
||||
// of seconds the user agent is allowed to cache the result of the request.
|
||||
if (options.maxAge !== null) {
|
||||
res.setHeader("Access-Control-Max-Age", options.maxAge);
|
||||
}
|
||||
// Add one or more Access-Control-Allow-Methods headers consisting of (a subset
|
||||
// of) the list of methods.
|
||||
res.setHeader("Access-Control-Allow-Methods", options.methods.join(","));
|
||||
// Add one or more Access-Control-Allow-Headers headers consisting of (a subset
|
||||
// of) the list of headers.
|
||||
res.setHeader("Access-Control-Allow-Headers", options.requestHeaders.join(","));
|
||||
// And out.
|
||||
endPreflight();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (options.supportsCredentials === true) {
|
||||
// If the resource supports credentials add a single Access-Control-Allow-Origin header,
|
||||
// with the value of the Origin header as value, and add a single
|
||||
// Access-Control-Allow-Credentials header with the literal string "true" as value.
|
||||
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
|
||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
} else {
|
||||
// Otherwise, add a single Access-Control-Allow-Origin header, with either the value of
|
||||
// the Origin header or the literal string "*" as value.
|
||||
// If the list of origins is empty, use "*" as value.
|
||||
if (options.origins.length > 0 || typeof options.origins === "function") {
|
||||
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
|
||||
} else {
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
}
|
||||
}
|
||||
// If the list of exposed headers is not empty add one or more Access-Control-Expose-Headers
|
||||
// headers, with as values the header field names given in the list of exposed headers.
|
||||
exposedHeaders = options.responseHeaders.filter(function (optionsResponseHeader) {
|
||||
return simpleResponseHeaders.indexOf(optionsResponseHeader) === -1;
|
||||
});
|
||||
if (exposedHeaders.length > 0) {
|
||||
res.setHeader("Access-Control-Expose-Headers", exposedHeaders.join(","));
|
||||
}
|
||||
// And out.
|
||||
next();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
24
node_modules/corser/package.json
generated
vendored
Normal file
24
node_modules/corser/package.json
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "corser",
|
||||
"version": "2.0.1",
|
||||
"description": "A highly configurable, middleware compatible implementation of CORS.",
|
||||
"keywords": ["cors", "cross-origin resource sharing", "connect", "express", "middleware"],
|
||||
"bugs": "https://github.com/agrueneberg/Corser/issues",
|
||||
"license": "MIT",
|
||||
"author": "Alexander Grüneberg <alexander.grueneberg@googlemail.com>",
|
||||
"main": "./lib/corser.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/agrueneberg/Corser.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "1.3.x",
|
||||
"expect.js": "0.1.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user