@aikidosec/firewall
Version:
Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks
65 lines (64 loc) • 2.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.wrapRequestHandler = wrapRequestHandler;
const Context_1 = require("../../agent/Context");
const contextFromRequest_1 = require("./contextFromRequest");
const wrap_1 = require("../../helpers/wrap");
function wrapRequestHandler(handler) {
const fn = (0, wrap_1.createWrappedFunction)(handler, function wrap(handler) {
return function wrap() {
if (arguments.length === 0) {
return handler.apply(this);
}
const context = (0, contextFromRequest_1.contextFromRequest)(arguments[0]);
return (0, Context_1.runWithContext)(context, () => {
return handler.apply(this, arguments);
});
};
});
// Some libraries/apps have properties on the handler functions that are not copied by our createWrappedFunction function
// (createWrappedFunction only copies properties when hasOwnProperty is true)
// Let's set up a proxy to forward the property access to the original handler
// e.g. https://github.com/TryGhost/Ghost/blob/fefb9ec395df8695d06442b6ecd3130dae374d94/ghost/core/core/frontend/web/site.js#L192
for (const key in handler) {
if (Object.prototype.hasOwnProperty.call(handler, key)) {
continue;
}
Object.defineProperty(fn, key, {
get() {
// @ts-expect-error Types unknown
return handler[key];
},
set(value) {
// @ts-expect-error Types unknown
handler[key] = value;
},
});
}
// For some libraries/apps it's important to preserve the function name
// e.g. Ghost looks up a middleware function by name in the router stack
preserveLayerName(fn, handler.name);
return fn;
}
/**
* Object.getOwnPropertyDescriptor(function myFunction() {}, "name")
* {
* value: 'myFunction',
* writable: false,
* enumerable: false,
* configurable: true
* }
*/
function preserveLayerName(wrappedFunction, originalName) {
try {
Object.defineProperty(wrappedFunction, "name", {
value: originalName,
writable: false,
enumerable: false,
configurable: true,
});
}
catch {
// Ignore
}
}