Added Vary value for CORS in Admin API

refs https://github.com/TryGhost/Toolbox/issues/461

- Having a 'Origin' in vary header value present on each `OPTIONS` allows to correctly bucket "allowed CORS" and "disallowed CORS" responses in shared caches
This commit is contained in:
Naz 2022-11-02 16:09:16 +08:00
parent 2f2aa36c75
commit f581e33400
No known key found for this signature in database
3 changed files with 31 additions and 6 deletions

View File

@ -65,7 +65,7 @@ function getAllowlist() {
* @param {Function} cb callback that configures CORS.
* @return {null}
*/
function handleCORS(req, cb) {
function corsOptionsDelegate(req, cb) {
const origin = req.get('origin');
// Request must have an Origin header
@ -81,4 +81,19 @@ function handleCORS(req, cb) {
return cb(null, DISABLE_CORS);
}
module.exports = cors(handleCORS);
/**
*
* @param {Express.Request} req
* @param {Express.Response} res
* @param {Function} next
*/
const handleCaching = (req, res, next) => {
// @NOTE: try to add native support for dynamic 'vary' header value in 'cors' module
res.vary('Origin');
next();
};
module.exports = [
cors(corsOptionsDelegate),
handleCaching
];

View File

@ -7,7 +7,7 @@ Object {
"content-length": "8",
"content-type": "text/html; charset=utf-8",
"etag": "W/\\"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg\\"",
"vary": "Accept-Version, Accept-Encoding",
"vary": "Accept-Version, Origin, Accept-Encoding",
"x-powered-by": "Express",
}
`;
@ -19,7 +19,7 @@ Object {
"content-length": "8",
"content-type": "text/html; charset=utf-8",
"etag": "W/\\"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg\\"",
"vary": "Accept-Version, Accept-Encoding",
"vary": "Accept-Version, Origin, Accept-Encoding",
"x-powered-by": "Express",
}
`;

View File

@ -3,7 +3,8 @@ const sinon = require('sinon');
const rewire = require('rewire');
const configUtils = require('../../../../../utils/configUtils');
let cors = rewire('../../../../../../core/server/web/api/middleware/cors');
let cors = rewire('../../../../../../core/server/web/api/middleware/cors')[0];
let corsCaching = rewire('../../../../../../core/server/web/api/middleware/cors')[1];
describe('cors', function () {
let res;
@ -22,6 +23,7 @@ describe('cors', function () {
headers: {},
getHeader: function () {
},
vary: sinon.spy(),
setHeader: function (h, v) {
this.headers[h] = v;
}
@ -33,7 +35,7 @@ describe('cors', function () {
afterEach(function () {
sinon.restore();
configUtils.restore();
cors = rewire('../../../../../../core/server/web/api/middleware/cors');
cors = rewire('../../../../../../core/server/web/api/middleware/cors')[0];
});
it('should not be enabled without a request origin header', function (done) {
@ -130,4 +132,12 @@ describe('cors', function () {
done();
});
it('should add origin value to the vary header', function (done) {
corsCaching(req, res, function () {
should.equal(res.vary.called, true);
should.equal(res.vary.args[0], 'Origin');
done();
});
});
});