0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

Added validation to redirects config

refs https://linear.app/tryghost/issue/CORE-86/fix-failing-site-instance-when-redirects-file-is-invalid
refs 260a47da83

- Added validation logic to catch redirects files having invalid RegEx expressions when they are introduced into the system (on upload)
- This way the error happening in the refed commit would have not happened as the validator would not have passed it through
- Moved up the "Router" declaration in custom-redirects as it needs to happen before any other bit of logic has a chance to throw
This commit is contained in:
Naz 2021-10-04 18:32:40 +02:00
parent 8f5186995d
commit 5066e65e03
4 changed files with 59 additions and 3 deletions

View file

@ -4,6 +4,7 @@ const errors = require('@tryghost/errors');
const messages = {
redirectsWrongFormat: 'Incorrect redirects file format.',
invalidRedirectsFromRegex: 'Incorrect RegEx in redirects file.',
redirectsHelp: 'https://ghost.org/docs/themes/routing/#redirects'
};
/**
@ -26,6 +27,17 @@ const validate = (redirects) => {
help: tpl(messages.redirectsHelp)
});
}
try {
// each 'from' property should be a valid RegExp string
new RegExp(redirect.from);
} catch (error) {
throw new errors.ValidationError({
message: tpl(messages.invalidRedirectsFromRegex),
context: redirect,
help: tpl(messages.redirectsHelp)
});
}
});
};

View file

@ -96,11 +96,11 @@ _private.registerRoutes = (router, redirects) => {
const loadRoutes = () => {
try {
customRedirectsRouter = express.Router('redirects');
const redirects = redirectsService.loadRedirectsFile();
redirectsService.validate(redirects);
customRedirectsRouter = express.Router('redirects');
_private.registerRoutes(customRedirectsRouter, redirects);
} catch (err) {
if (errors.utils.isIgnitionError(err)) {

View file

@ -0,0 +1,44 @@
const should = require('should');
const {validate} = require('../../../../core/server/services/redirects/validation');
describe('UNIT: custom redirects validation', function () {
it('passes validation for a valid redirects config', function () {
const config = [{
permanent: true,
from: '/test-params',
to: '/result?q=abc'
}];
validate(config);
});
it('throws for an invalid redirects config format missing from parameter', function () {
const config = [{
permanent: true,
to: '/'
}];
try {
validate(config);
should.fail('should have thrown');
} catch (err) {
err.message.should.equal('Incorrect redirects file format.');
}
});
it('throws for an invalid redirects config having invalid RegExp in from field', function () {
const config = [{
permanent: true,
from: '/invalid_regex/(/size/[a-zA-Z0-9_-.]*/[a-zA-Z0-9_-.]*/[0-9]*/[0-9]*/)([a-zA-Z0-9_-.]*)',
to: '/'
}];
try {
validate(config);
should.fail('should have thrown');
} catch (err) {
err.message.should.equal('Incorrect RegEx in redirects file.');
}
});
});

View file

@ -2,10 +2,10 @@ const should = require('should');
const sinon = require('sinon');
const rewire = require('rewire');
const express = require('express');
const supertest = require('supertest');
const customRedirects = rewire('../../../../../core/server/web/shared/middlewares/custom-redirects');
const registerRoutes = customRedirects.__get__('_private.registerRoutes');
const supertest = require('supertest');
describe('UNIT: custom redirects', function () {
let res;