Skip to content

Commit

Permalink
options.credentials: accept function
Browse files Browse the repository at this point in the history
  • Loading branch information
alxndrsn committed Nov 19, 2024
1 parent 53312a5 commit 86743ce
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ app.listen(80, function () {
* `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.
* `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Possible values:
- `Boolean` - set `credentials` to `true` to pass the header, otherwise it is omitted.
- `Function` - set `credentials` to a function implementing some custom logic. The function takes the request as the only parameter. Return `true` from this function 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`.
Expand Down
9 changes: 5 additions & 4 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@
};
}

function configureCredentials(options) {
if (options.credentials === true) {
function configureCredentials(options, req) {
if (options.credentials === true ||
(typeof options.credentials === 'function' && options.credentials(req) === true)) {
return {
key: 'Access-Control-Allow-Credentials',
value: 'true'
Expand Down Expand Up @@ -163,7 +164,7 @@
if (method === 'OPTIONS') {
// preflight
headers.push(configureOrigin(options, req));
headers.push(configureCredentials(options))
headers.push(configureCredentials(options, req))
headers.push(configureMethods(options))
headers.push(configureAllowedHeaders(options, req));
headers.push(configureMaxAge(options))
Expand All @@ -182,7 +183,7 @@
} else {
// actual response
headers.push(configureOrigin(options, req));
headers.push(configureCredentials(options))
headers.push(configureCredentials(options, req))
headers.push(configureExposedHeaders(options))
applyHeaders(headers, res);
next();
Expand Down
39 changes: 39 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,45 @@ var util = require('util')
cors()(req, res, next);
});

describe('credentials configured with function', function () {
function conditionalCredentials(req) {
console.log('conditionalCredentials()', 'origin:', req.headers.origin);
var match = req.headers.origin === 'http://example.com';
console.log('conditionalCredentials()', 'match:', match);
return match;
}

it('includes credentials if provided function returns true', function (done) {
var cb = after(1, done)
var req = fakeRequest('OPTIONS')
var res = fakeResponse()

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

cors({ credentials: conditionalCredentials })(req, res, function (err) {
cb(err || new Error('should not be called'))
})
});

it('does not include credentials if provided function returns false', function (done) {
var cb = after(1, done)
var req = fakeRequest('OPTIONS', { origin: 'http://unmatched.example.com' });
var res = fakeResponse();

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

cors({ credentials: conditionalCredentials })(req, res, function (err) {
cb(err || new Error('should not be called'))
})
});
});

it('includes maxAge when specified', function (done) {
var cb = after(1, done)
var req = new FakeRequest('OPTIONS')
Expand Down

0 comments on commit 86743ce

Please sign in to comment.