New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

hyperswitch

Package Overview
Dependencies
Maintainers
4
Versions
75
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hyperswitch - npm Package Compare versions

Comparing version 0.3.5 to 0.4.0

lib/filters/http.js

30

lib/filters/header_match.js
"use strict";
var utils = require('../utils');
var HTTPError = require('../exports').HTTPError;
/**
* From a list of uri Regex and values, constructs a regex to check if the
* request URI is in the white-list.
*/
var CACHE = new Map();
function constructInternalRequestRegex(variants) {
if (CACHE.has(variants)) {
return CACHE.get(variants);
}
var regex = (variants || []).map(function(regexString) {
if (/^\/.+\/$/.test(regexString)) {
return '(:?' + regexString.substring(1, regexString.length - 1) + ')';
} else {
// Instead of comparing strings
return '(:?^'
+ regexString.replace(/[\-\[\]\/\{}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
+ '$)';
}
}).join('|');
regex = regex && regex.length > 0 ? new RegExp(regex) : undefined;
CACHE.set(variants, regex);
return regex;
}
module.exports = function(hyper, req, next, options) {

@@ -35,6 +12,7 @@ var errorMessage = options.error_message

Object.keys(options.whitelist).forEach(function(headerName) {
var valueRegex = constructInternalRequestRegex(options.whitelist[headerName]);
options._cache[headerName] = options._cache[headerName]
|| utils.constructRegex(options.whitelist[headerName]);
var headerValue = req.headers && req.headers[headerName]
|| hyper._rootReq.headers && hyper._rootReq.headers[headerName];
if (!valueRegex.test(headerValue)) {
if (!options._cache[headerName].test(headerValue)) {
throw new HTTPError({

@@ -41,0 +19,0 @@ status: options.error_status || 403,

@@ -38,2 +38,2 @@ "use strict";

});
};
};

@@ -12,3 +12,2 @@ 'use strict';

var swaggerUI = require('./swaggerUI');
var AuthService = require('./auth');

@@ -56,4 +55,5 @@

this._rootReq = par._rootReq || req;
this._forwardedHeaders = par._forwardedHeaders || this._rootReq.headers;
this._authService = par._authService ? new AuthService(par._authService) : null;
this._requestFilters = par._requestFilters;
this._subRequestFilters = par._subRequestFilters;
this.ctx = par.ctx || {};
} else {

@@ -82,4 +82,5 @@ // Brand new instance

this._rootReq = null;
this._forwardedHeaders = null;
this._authService = null;
this._requestFilters = [];
this._subRequestFilters = [];
this.ctx = parOptions && parOptions.ctx || null;
}

@@ -170,26 +171,2 @@ }

// Special handling for external web requests
HyperSwitch.prototype.defaultWebRequestHandler = function(req) {
// Enforce the usage of UA
req.headers = req.headers || {};
req.headers['user-agent'] = req.headers['user-agent'] || this.config.user_agent;
if (this._authService) {
this._authService.prepareRequest(this, req);
}
this.setRequestId(req);
this.log('trace/webrequest', {
req: req,
request_id: req.headers['x-request-id']
});
// Make sure we have a string
req.uri = '' + req.uri;
return preq(req)
.then(function(res) {
if (res && res.headers) {
utils.removeHopToHopHeaders(res.headers, true);
}
return res;
});
};
HyperSwitch.prototype._isSysRequest = function(req) {

@@ -248,2 +225,29 @@ return ((req.uri.params && req.uri.params.api === 'sys')

HyperSwitch.prototype._createFilteredHandler = function(handler, filters, specInfo) {
if (!filters || !filters.length) {
return handler;
}
var filterIdx = 0;
return function handlerWrapper(hyper, req) {
if (filters && filterIdx < filters.length) {
var filter = filters[filterIdx];
filterIdx++;
if (typeof filter === 'function') {
return filter(hyper, req, handlerWrapper, filter.options, specInfo);
}
if (filter.method
&& filter.method !== req.method
&& !(filter.method === 'get' && req.method === 'head')) {
return handlerWrapper(hyper, req);
}
return filter.filter(hyper, req, handlerWrapper, filter.options, specInfo);
} else {
return P.method(handler)(hyper, req);
}
};
};
HyperSwitch.prototype.request = function(req, options) {

@@ -253,31 +257,9 @@ if (req.method) {

}
return this._request(req, options);
return this._filteredRequest(req, options);
};
HyperSwitch.prototype._wrapInAccessCheck = function(handlerPromise, match, childReq) {
var self = this;
// Don't need to check access restrictions on /sys requests,
// as these endpoints are internal, so can be accessed only
// within HyperSwitch. (See HyperSwitch.prototype.request) All required
// checks should be added and made at the root of the request chain,
// at /v1 level
if (!this._isSysRequest(childReq)
&& match.permissions
&& Array.isArray(match.permissions)
&& match.permissions.length) {
self._authService = self._authService || new AuthService(match.value.specRoot);
self._authService.addRequirements(match.permissions);
if (childReq.method === 'get' || childReq.method === 'head') {
return P.all([
handlerPromise,
self._authService.checkPermissions(self, childReq)
])
.then(function(res) { return res[0]; });
} else {
return self._authService.checkPermissions(self, childReq)
.then(function() { return handlerPromise; });
}
} else {
return handlerPromise;
}
HyperSwitch.prototype._filteredRequest = function(req, options) {
return this._createFilteredHandler(function(hyper, req) {
return hyper._request(req, options);
}, this._recursionDepth === 0 ? this._requestFilters : this._subRequestFilters)(this, req);
};

@@ -288,9 +270,2 @@

var self = this;
// Special handling for https? requests
var host = req.uri.constructor === String ? req.uri : req.uri.protoHost;
if (/^https?:\/\//.test(host)) {
return self.defaultWebRequestHandler(req);
}
self._checkMaxRecursionDepth(req);

@@ -333,25 +308,6 @@

var childHyperSwitch = this.makeChild(childReq, options);
var specInfo = {
var reqHandler = childHyperSwitch._createFilteredHandler(handler, match.filters, {
path: match.value.path,
spec: handler.spec
};
var filterIdx = 0;
var reqHandler = function handlerWrapper(hyper, req) {
if (filterIdx < match.filters.length) {
var filter = match.filters[filterIdx];
filterIdx++;
if (filter.method
&& filter.method !== req.method
&& !(filter.method === 'get' && req.method === 'head')) {
return handlerWrapper(hyper, req);
}
return filter.filter(hyper, req, handlerWrapper, filter.options, specInfo);
} else {
return P.method(handler)(hyper, req);
}
};
});
// This is a hack. Pure P.try get's executed on this tick, but we wanna

@@ -365,3 +321,3 @@ // wrap it in metrics and access checks and start execution only afterwards.

reqHandlerPromise = reqHandlerPromise
return reqHandlerPromise
.then(function(res) {

@@ -393,4 +349,2 @@ childHyperSwitch.log('trace/hyper/response', {

});
return childHyperSwitch._wrapInAccessCheck(reqHandlerPromise, match, childReq);
} else {

@@ -442,3 +396,3 @@ // No handler found.

HyperSwitch.prototype[method] = function(uri, req) {
return this._request(makeRequest(uri, req, method));
return this._filteredRequest(makeRequest(uri, req, method));
};

@@ -445,0 +399,0 @@ });

@@ -120,3 +120,3 @@ "use strict";

Router.prototype._loadRouteFilter = function(filterDef, globals, method) {
Router.prototype._loadFilter = function(filterDef, globals, method) {
if (filterDef.type === 'default') {

@@ -126,5 +126,8 @@ filterDef.path = __dirname + '/filters/' + filterDef.name + '.js';

var options = this._expandOptions(filterDef, globals);
options._cache = {};
return {
filter: this._requireModule(filterDef.path),
options: this._expandOptions(filterDef, globals),
options: options,
method: method

@@ -139,3 +142,3 @@ };

var filters = filtersDef.map(function(filterDef) {
return self._loadRouteFilter(filterDef, scope.globals, method);
return self._loadFilter(filterDef, scope.globals, method);
});

@@ -588,2 +591,10 @@ node.value = node.value || {};

.then(function() {
(spec['x-request-filters'] || []).forEach(function(filterDef) {
hyper._requestFilters = hyper._requestFilters || [];
hyper._requestFilters.push(self._loadFilter(filterDef, { options: hyper.config }));
});
(spec['x-sub-request-filters'] || []).forEach(function(filterDef) {
hyper._subRequestFilters = hyper._subRequestFilters || [];
hyper._subRequestFilters.push(self._loadFilter(filterDef, { options: hyper.config }));
});
// Only set the tree after loading everything

@@ -590,0 +601,0 @@ self.tree = rootNode;

@@ -103,3 +103,4 @@ "use strict";

function logResponse(opts, response) {
function logResponse(opts, response, startTime) {
var latency = Date.now() - startTime;
var logLevel = 'trace/request';

@@ -110,2 +111,4 @@ if (response.status >= 500) {

logLevel = 'info/request';
} else if (latency > 5000) {
logLevel = 'trace/request/slow';
}

@@ -115,3 +118,4 @@ opts.log(logLevel, {

res: response,
stack: response.stack
stack: response.stack,
latency: latency,
});

@@ -154,3 +158,3 @@ }

logResponse(opts, response);
logResponse(opts, response, opts.startTime);

@@ -188,3 +192,3 @@ var body;

if (req.method === 'head') {
delete response.body;
response.body = null;
}

@@ -191,0 +195,0 @@

@@ -48,2 +48,22 @@ "use strict";

/**
* From a list of uri Regex and values, constructs a regex to check if the
* request URI is in the white-list.
*/
utils.constructRegex = function(variants) {
var regex = (variants || []).map(function(regexString) {
regexString = regexString.trim();
if (/^\/.+\/$/.test(regexString)) {
return '(:?' + regexString.substring(1, regexString.length - 1) + ')';
} else {
// Instead of comparing strings
return '(:?^'
+ regexString.replace(/[\-\[\]\/\{}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
+ ')';
}
}).join('|');
regex = regex && regex.length > 0 ? new RegExp(regex) : undefined;
return regex;
};
module.exports = utils;
{
"name": "hyperswitch",
"version": "0.3.5",
"version": "0.4.0",
"description": "REST API creation framework",

@@ -36,3 +36,4 @@ "main": "index.js",

"json-stable-stringify": "git+https://github.com/wikimedia/json-stable-stringify#master",
"ajv": "^3.7.2"
"ajv": "^3.7.2",
"regexp-utils": "^0.3.2"
},

@@ -39,0 +40,0 @@ "devDependencies": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc