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

Added function names to all Express middleware

refs https://github.com/TryGhost/DevOps/issues/68

- without a name, tools such as New Relic report the function as
  `<anonymous>`, which makes it incredible hard to follow the code flow
- this commit adds a function name to all middleware I can find that
  doesn't already have one, which should fill in a lot of those gaps
This commit is contained in:
Daniel Lockyer 2023-08-30 11:33:31 +02:00 committed by Daniel Lockyer
parent eb718276e8
commit cc085bafe9
16 changed files with 33 additions and 33 deletions
ghost
api-framework/lib
core/core
frontend/web
server
services
api-version-compatibility
auth/api-key
members
web
admin
api
endpoints/admin
middleware
parent/middleware
shared/middleware
well-known.js

View file

@ -14,7 +14,7 @@ const headers = require('./headers');
* @return {Function}
*/
const http = (apiImpl) => {
return async (req, res, next) => {
return async function Http(req, res, next) {
debug(`External API request to ${req.url}`);
let apiKey = null;
let integration = null;

View file

@ -60,7 +60,7 @@ function corsOptionsDelegate(req, callback) {
* @param {Express.Response} res
* @param {Function} next
*/
const handleCaching = (req, res, next) => {
const handleCaching = function handleCachingCors(req, res, next) {
const method = req.method && req.method.toUpperCase && req.method.toUpperCase();
if (method === 'OPTIONS') {
// @NOTE: try to add native support for dynamic 'vary' header value in 'cors' module

View file

@ -12,7 +12,7 @@ const FORMAT_PATH_REGEX = /^\/format\/([^./]+)\//;
const TRAILING_SLASH_REGEX = /\/+$/;
module.exports = function (req, res, next) {
module.exports = function handleImageSizes(req, res, next) {
// In admin we need to read images and calculate the average color (blocked by CORS otherwise)
res.setHeader('Access-Control-Allow-Origin', '*');

View file

@ -129,7 +129,7 @@ module.exports = function setupSiteApp(routerConfig) {
siteApp.use(shared.middleware.prettyUrls);
// ### Caching
siteApp.use(function (req, res, next) {
siteApp.use(function frontendCaching(req, res, next) {
// Site frontend is cacheable UNLESS request made by a member or site is in private mode
if (req.member || res.isPrivateBlog) {
return shared.middleware.cacheControl('private')(req, res, next);
@ -138,7 +138,7 @@ module.exports = function setupSiteApp(routerConfig) {
}
});
siteApp.use(function (req, res, next) {
siteApp.use(function memberPageViewMiddleware(req, res, next) {
if (req.member) {
// This event needs memberLastSeenAt to avoid doing un-necessary database queries when updating `last_seen_at`
DomainEvents.dispatch(MemberPageViewEvent.create({url: req.url, memberId: req.member.id, memberLastSeenAt: req.member.last_seen_at}, new Date()));

View file

@ -25,7 +25,7 @@ const init = () => {
});
};
module.exports.errorHandler = (err, req, res, next) => {
module.exports.errorHandler = function apiVersionCompatibilityErrorHandler(err, req, res, next) {
return versionMismatchHandler(serviceInstance)(err, req, res, next);
};
@ -38,7 +38,7 @@ module.exports.errorHandler = (err, req, res, next) => {
* @param {import('express').Response} res
* @param {import('express').NextFunction} next
*/
module.exports.contentVersion = (req, res, next) => {
module.exports.contentVersion = function apiVersionCompatibilityContentVersion(req, res, next) {
res.header('Content-Version', `v${ghostVersion.safe}`);
res.vary('Accept-Version');

View file

@ -8,7 +8,7 @@ const urlUtils = require('../../../shared/url-utils');
* @param {import('express').Response} res
* @param {import('express').NextFunction} next
*/
module.exports = (req, res, next) => {
module.exports = function mwVersionRewrites(req, res, next) {
let {version} = legacyApiPathMatch(req.url);
// If we don't match a valid version, carry on

View file

@ -44,7 +44,7 @@ const _extractTokenFromUrl = function extractTokenFromUrl(reqUrl) {
return query.token;
};
const authenticate = (req, res, next) => {
const authenticate = function apiKeyAdminAuth(req, res, next) {
// CASE: we don't have an Authorization header so allow fallthrough to other
// auth middleware or final "ensure authenticated" check
if (!req.headers || !req.headers.authorization) {
@ -63,7 +63,7 @@ const authenticate = (req, res, next) => {
return authenticateWithToken(req, res, next, {token, JWT_OPTIONS: JWT_OPTIONS_DEFAULTS});
};
const authenticateWithUrl = (req, res, next) => {
const authenticateWithUrl = function apiKeyAuthenticateWithUrl(req, res, next) {
const token = _extractTokenFromUrl(req.originalUrl);
if (!token) {
return next(new errors.UnauthorizedError({
@ -89,7 +89,7 @@ const authenticateWithUrl = (req, res, next) => {
* - the "Audience" claim should match the requested API path
* https://tools.ietf.org/html/rfc7519#section-4.1.3
*/
const authenticateWithToken = async (req, res, next, {token, JWT_OPTIONS}) => {
const authenticateWithToken = async function apiKeyAuthenticateWithToken(req, res, next, {token, JWT_OPTIONS}) {
const decoded = jwt.decode(token, {complete: true});
if (!decoded || !decoded.header) {

View file

@ -16,7 +16,7 @@ const messages = {
// @TODO: This piece of middleware actually belongs to the frontend, not to the member app
// Need to figure a way to separate these things (e.g. frontend actually talks to members API)
const loadMemberSession = async function (req, res, next) {
const loadMemberSession = async function loadMemberSession(req, res, next) {
try {
const member = await membersService.ssr.getMemberDataFromSession(req, res);
Object.assign(req, {member});
@ -32,7 +32,7 @@ const loadMemberSession = async function (req, res, next) {
* Require member authentication, and make it possible to authenticate via uuid.
* You can chain this after loadMemberSession to make it possible to authenticate via both the uuid and the session.
*/
const authMemberByUuid = async function (req, res, next) {
const authMemberByUuid = async function authMemberByUuid(req, res, next) {
try {
const uuid = req.query.uuid;
if (!uuid) {
@ -60,7 +60,7 @@ const authMemberByUuid = async function (req, res, next) {
}
};
const getIdentityToken = async function (req, res) {
const getIdentityToken = async function getIdentityToken(req, res) {
try {
const token = await membersService.ssr.getIdentityTokenForMemberFromSession(req, res);
res.writeHead(200);
@ -71,7 +71,7 @@ const getIdentityToken = async function (req, res) {
}
};
const deleteSession = async function (req, res) {
const deleteSession = async function deleteSession(req, res) {
try {
await membersService.ssr.deleteSession(req, res);
res.writeHead(204);
@ -87,7 +87,7 @@ const deleteSession = async function (req, res) {
}
};
const getMemberData = async function (req, res) {
const getMemberData = async function getMemberData(req, res) {
try {
const member = await membersService.ssr.getMemberDataFromSession(req, res);
if (member) {
@ -101,7 +101,7 @@ const getMemberData = async function (req, res) {
}
};
const deleteSuppression = async function (req, res) {
const deleteSuppression = async function deleteSuppression(req, res) {
try {
const member = await membersService.ssr.getMemberDataFromSession(req, res);
const options = {
@ -123,7 +123,7 @@ const deleteSuppression = async function (req, res) {
}
};
const getMemberNewsletters = async function (req, res) {
const getMemberNewsletters = async function getMemberNewsletters(req, res) {
try {
const memberUuid = req.query.uuid;
@ -151,7 +151,7 @@ const getMemberNewsletters = async function (req, res) {
}
};
const updateMemberNewsletters = async function (req, res) {
const updateMemberNewsletters = async function updateMemberNewsletters(req, res) {
try {
const memberUuid = req.query.uuid;
if (!memberUuid) {
@ -182,7 +182,7 @@ const updateMemberNewsletters = async function (req, res) {
}
};
const updateMemberData = async function (req, res) {
const updateMemberData = async function updateMemberData(req, res) {
try {
const data = _.pick(req.body, 'name', 'expertise', 'subscribed', 'newsletters', 'enable_comment_notifications');
const member = await membersService.ssr.getMemberDataFromSession(req, res);
@ -209,7 +209,7 @@ const updateMemberData = async function (req, res) {
}
};
const createSessionFromMagicLink = async function (req, res, next) {
const createSessionFromMagicLink = async function createSessionFromMagicLink(req, res, next) {
if (!req.url.includes('token=')) {
return next();
}

View file

@ -25,7 +25,7 @@ module.exports = function setupAdminApp() {
adminApp.use('/assets', serveStatic(
path.join(config.get('paths').adminAssets, 'assets'), {
maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : constants.ONE_YEAR_MS,
immutable: true,
immutable: true,
fallthrough: false
}
));
@ -59,7 +59,7 @@ module.exports = function setupAdminApp() {
// Finally, routing
adminApp.get('*', require('./controller'));
adminApp.use((err, req, res, next) => {
adminApp.use(function fourOhFourMw(err, req, res, next) {
if (err.statusCode && err.statusCode === 404) {
// Remove 404 errors for next middleware to inject
next();

View file

@ -8,7 +8,7 @@ const messages = {
notImplemented: 'The server does not support the functionality required to fulfill the request.'
};
const notImplemented = function (req, res, next) {
const notImplemented = function notImplemented(req, res, next) {
// CASE: user is logged in, allow
if (!req.api_key) {
return next();

View file

@ -87,7 +87,7 @@ function corsOptionsDelegate(req, cb) {
* @param {Express.Response} res
* @param {Function} next
*/
const handleCaching = (req, res, next) => {
const handleCaching = function handleCaching(req, res, next) {
const method = req.method && req.method.toUpperCase && req.method.toUpperCase();
if (method === 'OPTIONS') {
// @NOTE: try to add native support for dynamic 'vary' header value in 'cors' module

View file

@ -47,7 +47,7 @@ const upload = multer({dest: os.tmpdir()});
const deleteSingleFile = file => fs.unlink(file.path).catch(err => logging.error(err));
const single = name => (req, res, next) => {
const single = name => function singleUploadFunction(req, res, next) {
const singleUpload = upload.single(name);
singleUpload(req, res, (err) => {
@ -77,7 +77,7 @@ const single = name => (req, res, next) => {
});
};
const media = (fileName, thumbName) => (req, res, next) => {
const media = (fileName, thumbName) => function mediaUploadFunction(req, res, next) {
const mediaUpload = upload.fields([{
name: fileName,
maxCount: 1

View file

@ -3,7 +3,7 @@ const uuid = require('uuid');
/**
* @TODO: move this middleware to Framework monorepo?
*/
module.exports = (req, res, next) => {
module.exports = function requestIdMw(req, res, next) {
const requestId = req.get('X-Request-ID') || uuid.v4();
// Set a value for internal use

View file

@ -21,7 +21,7 @@ const messages = {
pageNotFound: 'Page not found"'
};
const uncapitalise = (req, res, next) => {
const uncapitalise = function uncapitalise(req, res, next) {
let pathToTest = (req.baseUrl ? req.baseUrl : '') + req.path;
let redirectPath;
let decodedURI;

View file

@ -87,7 +87,7 @@ _private.getFrontendRedirectUrl = ({requestedHost, requestedUrl, queryParameters
}
};
_private.redirect = (req, res, next, redirectFn) => {
_private.redirect = function urlRedirectsRedirect(req, res, next, redirectFn) {
const redirectUrl = redirectFn({
requestedHost: req.vhost ? req.vhost.host : req.get('host'),
requestedUrl: url.parse(req.originalUrl || req.url).pathname,
@ -104,11 +104,11 @@ _private.redirect = (req, res, next, redirectFn) => {
next();
};
const frontendRedirect = (req, res, next) => {
const frontendRedirect = function frontendRedirect(req, res, next) {
_private.redirect(req, res, next, _private.getFrontendRedirectUrl);
};
const adminRedirect = (req, res, next) => {
const adminRedirect = function adminRedirect(req, res, next) {
_private.redirect(req, res, next, _private.getAdminRedirectUrl);
};

View file

@ -18,7 +18,7 @@ module.exports = function setupWellKnownApp() {
const cache = cacheControl('public', {maxAge: config.get('caching:wellKnown:maxAge')});
wellKnownApp.get('/jwks.json', cache, async (req, res) => {
wellKnownApp.get('/jwks.json', cache, async function jwksMiddleware(req, res) {
const jwks = await getSafePublicJWKS();
// there's only one key in the store atm