Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: handle private network requests #274

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -202,6 +202,7 @@ app.listen(80, function () {
* `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-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
* `allowPrivateNetworkAccess`: Configures the **Access-Control-Allow-Private-Network**. Set to `false` to disable Private Network Requests, otherwise it is allowed.
* `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`.

Expand Down
16 changes: 16 additions & 0 deletions lib/index.js
Expand Up @@ -141,6 +141,21 @@
return null;
}

function configurePrivateNetworkAccess(options, req) {
if (!options.hasOwnProperty('allowPrivateNetworkAccess')) {
joostdebruijn marked this conversation as resolved.
Show resolved Hide resolved
// Allow Private Network Requests by default.
options.allowPrivateNetworkAccess = true;
}

if (req.headers['access-control-request-private-network'] === 'true' && options.allowPrivateNetworkAccess) {
return {
key: 'Access-Control-Allow-Private-Network',
value: 'true'
};
}
return null;
}

function applyHeaders(headers, res) {
for (var i = 0, n = headers.length; i < n; i++) {
var header = headers[i];
Expand Down Expand Up @@ -168,6 +183,7 @@
headers.push(configureAllowedHeaders(options, req));
headers.push(configureMaxAge(options))
headers.push(configureExposedHeaders(options))
headers.push(configurePrivateNetworkAccess(options, req))
applyHeaders(headers, res);

if (options.preflightContinue) {
Expand Down
61 changes: 61 additions & 0 deletions test/test.js
Expand Up @@ -630,6 +630,67 @@ var util = require('util')
// act
cors()(req, res, next);
});

it('allows private network requests when allowPrivateNetworkAccess is true', function (done) {
// arrange
var req, res, options, cb;
options = {
allowPrivateNetworkAccess: true,
};
req = fakeRequest('OPTIONS', {'access-control-request-private-network': 'true'});
res = fakeResponse();
cb = after(1, done)

res.on('finish', function () {
assert.equal(res.getHeader('Access-Control-Allow-Private-Network'), 'true')
cb()
})

// act
cors(options)(req, res, function (err) {
cb(err || new Error('should not be called'))
});
});

it('denies private network requests when allowPrivateNetworkAccess is false', function (done) {
// arrange
var req, res, options, cb;
options = {
allowPrivateNetworkAccess: false,
};
req = fakeRequest('OPTIONS', {'access-control-request-private-network': 'true'});
res = fakeResponse();
cb = after(1, done)

res.on('finish', function () {
assert.equal(res.getHeader('Access-Control-Allow-Private-Network'), undefined)
cb()
})

// act
cors(options)(req, res, function (err) {
cb(err || new Error('should not be called'))
});
});

it('allows private network requests when no options are set', function (done) {
// arrange
var req, res, options, cb;
options = {};
req = fakeRequest('OPTIONS', {'access-control-request-private-network': 'true'});
res = fakeResponse();
cb = after(1, done)

res.on('finish', function () {
assert.equal(res.getHeader('Access-Control-Allow-Private-Network'), 'true')
cb()
})

// act
cors(options)(req, res, function (err) {
cb(err || new Error('should not be called'))
});
});
});

describe('passing a function to build options', function () {
Expand Down