2015-06-10 22:18:31 +03:00
|
|
|
// # uncapitalise Middleware
|
|
|
|
// Usage: uncapitalise(req, res, next)
|
|
|
|
// After:
|
|
|
|
// Before:
|
2017-10-26 19:24:08 +03:00
|
|
|
// App: Admin|Site|API
|
2015-06-10 22:18:31 +03:00
|
|
|
//
|
|
|
|
// Detect upper case in req.path.
|
2016-10-10 22:14:32 +03:00
|
|
|
//
|
|
|
|
// Example req:
|
|
|
|
// req.originalUrl = /blog/ghost/signin/?asdAD=asdAS
|
|
|
|
// req.url = /ghost/signin/?asdAD=asdAS
|
|
|
|
// req.baseUrl = /blog
|
|
|
|
// req.path = /ghost/signin/
|
2015-06-10 22:18:31 +03:00
|
|
|
|
2020-04-09 21:40:00 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
2019-06-18 16:13:55 +03:00
|
|
|
const urlUtils = require('../../../lib/url-utils');
|
2020-04-09 21:40:00 +03:00
|
|
|
const {i18n} = require('../../../lib/common');
|
2018-09-20 16:03:33 +03:00
|
|
|
const localUtils = require('../utils');
|
2018-09-10 15:07:57 +03:00
|
|
|
|
2018-09-20 16:03:33 +03:00
|
|
|
const uncapitalise = (req, res, next) => {
|
|
|
|
let pathToTest = (req.baseUrl ? req.baseUrl : '') + req.path;
|
|
|
|
let redirectPath;
|
|
|
|
let decodedURI;
|
2018-09-10 15:07:57 +03:00
|
|
|
|
|
|
|
const isSignupOrReset = pathToTest.match(/^(.*\/ghost\/(signup|reset)\/)/i),
|
2019-08-09 17:15:13 +03:00
|
|
|
isAPI = pathToTest.match(/^(.*\/ghost\/api\/(v[\d.]+|canary)\/.*?\/)/i);
|
2015-06-10 22:18:31 +03:00
|
|
|
|
|
|
|
if (isSignupOrReset) {
|
|
|
|
pathToTest = isSignupOrReset[1];
|
|
|
|
}
|
|
|
|
|
2019-09-12 20:17:35 +03:00
|
|
|
// Do not lowercase anything after e.g. /api/v{X}/ to protect :key/:slug
|
2015-06-10 22:18:31 +03:00
|
|
|
if (isAPI) {
|
|
|
|
pathToTest = isAPI[1];
|
|
|
|
}
|
|
|
|
|
2017-11-28 14:39:38 +03:00
|
|
|
try {
|
|
|
|
decodedURI = decodeURIComponent(pathToTest);
|
|
|
|
} catch (err) {
|
2020-04-09 21:40:00 +03:00
|
|
|
return next(new errors.NotFoundError({
|
|
|
|
message: i18n.t('errors.errors.pageNotFound'),
|
2017-11-28 14:39:38 +03:00
|
|
|
err: err
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2015-09-24 16:40:48 +03:00
|
|
|
/**
|
|
|
|
* In node < 0.11.1 req.path is not encoded, afterwards, it is always encoded such that | becomes %7C etc.
|
|
|
|
* That encoding isn't useful here, as it triggers an extra uncapitalise redirect, so we decode the path first
|
|
|
|
*/
|
2017-11-28 14:39:38 +03:00
|
|
|
if (/[A-Z]/.test(decodedURI)) {
|
2017-12-14 00:06:31 +03:00
|
|
|
redirectPath = (localUtils.removeOpenRedirectFromUrl((req.originalUrl || req.url).replace(pathToTest, pathToTest.toLowerCase())));
|
2019-06-18 16:13:55 +03:00
|
|
|
return urlUtils.redirect301(res, redirectPath);
|
2015-06-10 22:18:31 +03:00
|
|
|
}
|
2017-11-01 16:44:54 +03:00
|
|
|
|
|
|
|
next();
|
2015-06-10 22:18:31 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = uncapitalise;
|