Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

unexpected-mitm

Package Overview
Dependencies
Maintainers
5
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unexpected-mitm - npm Package Compare versions

Comparing version 9.0.3 to 9.1.0

177

lib/unexpectedMitm.js

@@ -1,2 +0,2 @@

/* global setImmediate, after, console */
/* global setImmediate, process, after, console */
var messy = require('messy'),

@@ -17,2 +17,6 @@ createMitm = require('mitm'),

function checkEnvFlag(varName) {
return process.env[varName] === 'true';
}
function isRegExp(obj) {

@@ -22,2 +26,6 @@ return Object.prototype.toString.call(obj) === '[object RegExp]';

function isTextualBody(message, content) {
return message.hasTextualContentType && bufferCanBeInterpretedAsUtf8(content);
}
function formatHeaderObj(headerObj) {

@@ -58,2 +66,9 @@ var result = {};

function trimHeaders(message) {
delete message.headers['Content-Length'];
delete message.headers['Transfer-Encoding'];
delete message.headers.Connection;
delete message.headers.Date;
}
function trimMessage(message) {

@@ -63,3 +78,3 @@ if (typeof message.body !== 'undefined') {

delete message.body;
} else if (new messy.Message({headers: {'Content-Type': message.headers['Content-Type']}}).hasTextualContentType && bufferCanBeInterpretedAsUtf8(message.body)) {
} else if (isTextualBody(new messy.Message({headers: {'Content-Type': message.headers['Content-Type']}}), message.body)) {
message.body = message.body.toString('utf-8');

@@ -80,6 +95,3 @@ }

if (message.headers) {
delete message.headers['Content-Length'];
delete message.headers['Transfer-Encoding'];
delete message.headers.Connection;
delete message.headers.Date;
trimHeaders(message);
if (Object.keys(message.headers).length === 0) {

@@ -104,2 +116,18 @@ delete message.headers;

function trimMockResponse(mockResponse) {
var responseProperties = {};
responseProperties.statusCode = mockResponse.statusCode;
responseProperties.statusMessage = mockResponse.statusMessage;
responseProperties.protocolName = mockResponse.protocolName;
responseProperties.protocolVersion = mockResponse.protocolVersion;
responseProperties.headers = formatHeaderObj(mockResponse.headers.valuesByName);
if (mockResponse.body) {
// read out the messy decoded body
responseProperties.body = mockResponse.body;
}
return responseProperties;
}
function trimRecordedExchange(recordedExchange) {

@@ -299,3 +327,32 @@ return {

function responseForVerification(response, validationBlock) {
// arrange to use formatted headers
response.headers = formatHeaderObj(response.headers);
// remove superfluous headers from the response
trimHeaders(response);
// call messy for decoding of text values
var messyMessage = new messy.Message({headers: {'Content-Type': response.headers['Content-Type']}, unchunkedBody: response.body});
if (response.body.length === 0) {
// remove an empty body from the comparison
delete response.body;
} else if (messyMessage.hasTextualContentType) {
// read a messy decoded version of the body
response.body = messyMessage.body;
}
if (validationBlock) {
if (validationBlock.ignoreHeaders) {
validationBlock.ignoreHeaders.forEach(function (headerKey) {
delete response.headers[messy.formatHeaderName(headerKey)];
});
}
}
return response;
}
module.exports = {

@@ -495,2 +552,55 @@ name: 'unexpected-mitm',

function createVerifier(expect, verifyBlocks) {
return function (fulfilmentValue, httpConversation, httpConversationSatisfySpec) {
var httpExchanges = httpConversation.exchanges.slice(0);
var httpVerificationSatisfySpec = {
exchanges: []
};
function nextItem() {
var exchange = httpExchanges.shift();
var verifyOptions = verifyBlocks.shift();
var request;
if (exchange) {
request = exchange.request;
return performRequest({
encrypted: request.encrypted,
headers: request.headers.toJSON(),
method: request.method,
host: request.host,
port: request.port,
path: request.url,
body: request.body
}).then(function (responseResult) {
httpVerificationSatisfySpec.exchanges.push({
request: {},
response: responseForVerification(responseResult, verifyOptions.response)
});
return nextItem();
});
} else {
return httpVerificationSatisfySpec;
}
}
return expect.promise(function (resolve, reject) {
resolve(nextItem());
}).then(function (httpVerificationSatisfySpec) {
expect.withError(function () {
return expect(httpConversation, 'to satisfy', httpVerificationSatisfySpec);
}, function (e) {
expect.errorMode = 'bubble';
expect.fail({
diff: function (output) {
return output.text('The mock and service have diverged.\n\n').append(e.getErrorMessage(output));
}
});
});
});
};
}
function executeMitm(expect, subject) {

@@ -617,18 +727,26 @@ var mitm = createMitm(),

})
.addAssertion('<any> with http mocked out [with extra info] <array|object> <assertion>', function (expect, subject, requestDescriptions) { // ...
.addAssertion('<any> with http mocked out [and verified] [with extra info] <array|object> <assertion>', function (expect, subject, requestDescriptions) { // ...
expect.errorMode = 'nested';
var mitm = createMitm();
var shouldBeVerified = checkEnvFlag('UNEXPECTED_MITM_VERIFY') || expect.flags['and verified'];
var shouldReturnExtraInfo = expect.flags['with extra info'];
return expect.promise(function (resolve, reject) {
if (!Array.isArray(requestDescriptions)) {
if (typeof requestDescriptions === 'undefined') {
requestDescriptions = [];
} else {
requestDescriptions = [requestDescriptions];
}
if (!Array.isArray(requestDescriptions)) {
if (typeof requestDescriptions === 'undefined') {
requestDescriptions = [];
} else {
// duplicate descriptions to allow array consumption
requestDescriptions = requestDescriptions.slice(0);
requestDescriptions = [requestDescriptions];
}
} else {
// duplicate descriptions to allow array consumption
requestDescriptions = requestDescriptions.slice(0);
}
var verifyBlocks = requestDescriptions.map(function (description) {
var verifyBlock = description.verify || {};
delete description.verify;
return verifyBlock;
});
var assertionPromise = expect.promise(function (resolve, reject) {
var httpConversation = new messy.HttpConversation(),

@@ -745,4 +863,5 @@ httpConversationSatisfySpec = {exchanges: []},

* assertion is reject()ed, we have already
* resolve()d which is effectively ignored
* thus we proceed with our output.
* resolve()d thus the rejection of the former
* is effectively ignored and we proceed with
* our output.
*/

@@ -832,3 +951,3 @@

request: expectedRequestProperties,
response: mockResponseError || mockResponse
response: mockResponseError || trimMockResponse(mockResponse)
});

@@ -849,3 +968,3 @@

return expect(httpConversation, 'to satisfy', httpConversationSatisfySpec).then(function () {
if (expect.flags['with extra info']) {
if (shouldBeVerified || shouldReturnExtraInfo) {
return [fulfilmentValue, httpConversation, httpConversationSatisfySpec];

@@ -859,4 +978,22 @@ } else {

});
if (shouldBeVerified) {
expect.errorMode = 'default';
var verifier = createVerifier(expect, verifyBlocks);
return assertionPromise.spread(function (fulfilmentValue, httpConversation, httpConversationSatisfySpec) {
return verifier(fulfilmentValue, httpConversation, httpConversationSatisfySpec).then(function () {
if (shouldReturnExtraInfo) {
return [fulfilmentValue, httpConversation, httpConversationSatisfySpec];
} else {
return fulfilmentValue;
}
});
});
}
return assertionPromise;
});
}
};

2

package.json
{
"name": "unexpected-mitm",
"version": "9.0.3",
"version": "9.1.0",
"description": "Unexpected plugin for the mitm library",

@@ -5,0 +5,0 @@ "author": "Andreas Lind <andreas@one.com>",

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