Skip to content

Commit 227b0a3

Browse files
committed
feat: handle Chrome CORS preflight private network header
1 parent f038e77 commit 227b0a3

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ app.listen(80, function () {
204204
* `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
205205
* `preflightContinue`: Pass the CORS preflight response to the next handler.
206206
* `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
207+
* `allowPrivateNetwork`: Provides **Access-Control-Allow-Private-Network: true** if **Access-Control-Request-Private-Network: true** is presented.
207208

208209
The default configuration is the equivalent of:
209210

lib/index.js

+15
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,20 @@
156156
}
157157
}
158158

159+
function configureAllowPrivateNetwork(options, req) {
160+
var reqHeader = req.headers['access-control-request-private-network'];
161+
if (
162+
options.allowPrivateNetwork &&
163+
reqHeader && reqHeader === 'true'
164+
) {
165+
return {
166+
key: 'Access-Control-Allow-Private-Network',
167+
value: 'true',
168+
};
169+
}
170+
return null;
171+
}
172+
159173
function cors(options, req, res, next) {
160174
var headers = [],
161175
method = req.method && req.method.toUpperCase && req.method.toUpperCase();
@@ -168,6 +182,7 @@
168182
headers.push(configureAllowedHeaders(options, req));
169183
headers.push(configureMaxAge(options))
170184
headers.push(configureExposedHeaders(options))
185+
headers.push(configureAllowPrivateNetwork(options, req));
171186
applyHeaders(headers, res);
172187

173188
if (options.preflightContinue) {

test/test.js

+33
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,39 @@ var util = require('util')
571571
})
572572
});
573573

574+
it('allows private network if explicitly enabled', function (done) {
575+
var cb = after(1, done)
576+
var req = new FakeRequest('OPTIONS', {
577+
'access-control-request-private-network': 'true'
578+
})
579+
var res = new FakeResponse()
580+
581+
res.on('finish', function () {
582+
assert.equal(res.getHeader('Access-Control-Allow-Private-Network'), 'true')
583+
cb()
584+
})
585+
586+
cors({ allowPrivateNetwork: true })(req, res, function (err) {
587+
cb(err || new Error('should not be called'))
588+
})
589+
});
590+
591+
592+
it('not allows private network if explicitly enabled but access-control-request-private-network is missing', function (done) {
593+
var cb = after(1, done)
594+
var req = new FakeRequest('OPTIONS')
595+
var res = new FakeResponse()
596+
597+
res.on('finish', function () {
598+
assert.equal(res.getHeader('Access-Control-Allow-Private-Network'), undefined)
599+
cb()
600+
})
601+
602+
cors({ allowPrivateNetwork: true })(req, res, function (err) {
603+
cb(err || new Error('should not be called'))
604+
})
605+
});
606+
574607
it('does not includes credentials unless explicitly enabled', function (done) {
575608
// arrange
576609
var req, res, next;

0 commit comments

Comments
 (0)