0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

Improved version match logic (#8922)

closes #8821

- Use semver to do constraint matching
- Use client to generate a caret constraint
- E.g. if the client is 1.1, then the constraint ^1.1.0 will match >=1.1.0 <2.0.0
- Updated tests
This commit is contained in:
Hannah Wolfe 2017-08-22 10:59:01 +01:00 committed by Kevin Ansfield
parent 553c8d50ac
commit b1cfa6e342
3 changed files with 72 additions and 16 deletions

View file

@ -1,13 +1,19 @@
var errors = require('../../errors'),
var semver = require('semver'),
errors = require('../../errors'),
i18n = require('../../i18n');
function checkVersionMatch(req, res, next) {
var requestVersion = req.get('X-Ghost-Version'),
currentVersion = res.locals.safeVersion;
var clientVersion = req.get('X-Ghost-Version'),
serverVersion = res.locals.version,
constraint = '^' + clientVersion + '.0';
if (requestVersion && requestVersion !== currentVersion) {
// no error when client is on an earlier minor version than server
// error when client is on a later minor version than server
// always error when the major version is different
if (clientVersion && !semver.satisfies(serverVersion, constraint)) {
return next(new errors.VersionMismatchError({
message: i18n.t('errors.middleware.api.versionMismatch', {requestVersion: requestVersion, currentVersion: currentVersion})
message: i18n.t('errors.middleware.api.versionMismatch', {clientVersion: clientVersion, serverVersion: serverVersion})
}));
}

View file

@ -66,7 +66,7 @@
},
"middleware": {
"api": {
"versionMismatch": "Request for version {requestVersion} does not match current version {currentVersion}."
"versionMismatch": "Client request for {clientVersion} does not match server version {serverVersion}."
},
"auth": {
"clientAuthenticationFailed": "Client Authentication Failed",

View file

@ -19,30 +19,80 @@ describe('Version Mismatch', function () {
get: getStub
};
res = {
locals: {
safeVersion: '0.7'
}
locals: {}
};
});
function testVersionMatch(serverVersion, clientVersion) {
// Set the server version
res.locals.version = serverVersion;
if (clientVersion) {
// Optionally set the client version
getStub.returns(clientVersion);
}
versionMatch(req, res, nextStub);
}
it('should call next if request does not include a version', function () {
versionMatch(req, res, nextStub);
var server = '1.5.1';
testVersionMatch(server);
nextStub.calledOnce.should.be.true();
nextStub.firstCall.args.should.be.empty();
});
it('should call next if versions match', function () {
getStub.returns('0.7');
versionMatch(req, res, nextStub);
it('should call next if versions are an exact match', function () {
var server = '1.5.0',
client = '1.5';
testVersionMatch(server, client);
nextStub.calledOnce.should.be.true();
nextStub.firstCall.args.should.be.empty();
});
it('should throw VersionMismatchError if request includes incorrect version', function () {
getStub.returns('0.6');
versionMatch(req, res, nextStub);
it('should call next if client version is earlier than server', function () {
var server = '1.5.0',
client = '1.3';
testVersionMatch(server, client);
nextStub.calledOnce.should.be.true();
nextStub.firstCall.args.should.be.empty();
});
it('should throw VersionMismatchError if client version is earlier by a major version', function () {
var server = '2.5.0',
client = '1.3';
testVersionMatch(server, client);
nextStub.calledOnce.should.be.true();
nextStub.firstCall.args.should.have.lengthOf(1);
nextStub.firstCall.args[0].should.have.property('errorType', 'VersionMismatchError');
nextStub.firstCall.args[0].should.have.property('statusCode', 400);
});
it('should throw VersionMismatchError if client version is later than server', function () {
var server = '1.3.0',
client = '1.5';
testVersionMatch(server, client);
nextStub.calledOnce.should.be.true();
nextStub.firstCall.args.should.have.lengthOf(1);
nextStub.firstCall.args[0].should.have.property('errorType', 'VersionMismatchError');
nextStub.firstCall.args[0].should.have.property('statusCode', 400);
});
it('should throw VersionMismatchError if client version is later by a major version', function () {
var server = '1.5.0',
client = '2.3';
testVersionMatch(server, client);
nextStub.calledOnce.should.be.true();
nextStub.firstCall.args.should.have.lengthOf(1);