@mbtest/mountebank 2.9.2-beta.9050
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +94 -0
- package/bin/mb +136 -0
- package/package.json +71 -0
- package/releases.json +52 -0
- package/src/cli/api.js +112 -0
- package/src/cli/cli.js +420 -0
- package/src/controllers/configController.js +64 -0
- package/src/controllers/feedController.js +115 -0
- package/src/controllers/homeController.js +58 -0
- package/src/controllers/imposterController.js +328 -0
- package/src/controllers/impostersController.js +215 -0
- package/src/controllers/logsController.js +52 -0
- package/src/models/behaviors.js +553 -0
- package/src/models/behaviorsValidator.js +186 -0
- package/src/models/compatibility.js +133 -0
- package/src/models/dryRunValidator.js +261 -0
- package/src/models/filesystemBackedImpostersRepository.js +908 -0
- package/src/models/http/baseHttpServer.js +207 -0
- package/src/models/http/headersMap.js +87 -0
- package/src/models/http/httpProxy.js +230 -0
- package/src/models/http/httpRequest.js +82 -0
- package/src/models/http/httpServer.js +18 -0
- package/src/models/http/index.js +18 -0
- package/src/models/https/cert/mb-cert.pem +20 -0
- package/src/models/https/cert/mb-csr.pem +16 -0
- package/src/models/https/cert/mb-key.pem +27 -0
- package/src/models/https/httpsServer.js +42 -0
- package/src/models/https/index.js +18 -0
- package/src/models/imposter.js +243 -0
- package/src/models/imposterPrinter.js +120 -0
- package/src/models/impostersRepository.js +49 -0
- package/src/models/inMemoryImpostersRepository.js +418 -0
- package/src/models/jsonpath.js +44 -0
- package/src/models/mbConnection.js +107 -0
- package/src/models/predicates.js +438 -0
- package/src/models/protocols.js +242 -0
- package/src/models/responseResolver.js +398 -0
- package/src/models/smtp/index.js +16 -0
- package/src/models/smtp/smtpRequest.js +60 -0
- package/src/models/smtp/smtpServer.js +109 -0
- package/src/models/tcp/index.js +18 -0
- package/src/models/tcp/tcpProxy.js +110 -0
- package/src/models/tcp/tcpRequest.js +23 -0
- package/src/models/tcp/tcpServer.js +156 -0
- package/src/models/tcp/tcpValidator.js +19 -0
- package/src/models/xpath.js +95 -0
- package/src/mountebank.js +245 -0
- package/src/public/images/arrow_down.png +0 -0
- package/src/public/images/arrow_up.png +0 -0
- package/src/public/images/book.jpg +0 -0
- package/src/public/images/dataflow.png +0 -0
- package/src/public/images/favicon.ico +0 -0
- package/src/public/images/forkme_right_orange_ff7600.png +0 -0
- package/src/public/images/mountebank.png +0 -0
- package/src/public/images/overview.gif +0 -0
- package/src/public/images/quote.png +0 -0
- package/src/public/images/tw-logo.png +0 -0
- package/src/public/scripts/jquery/jquery-3.6.1.min.js +2 -0
- package/src/public/scripts/urlHashHandler.js +31 -0
- package/src/public/stylesheets/application.css +424 -0
- package/src/public/stylesheets/ie.css +14 -0
- package/src/public/stylesheets/imposters.css +121 -0
- package/src/public/stylesheets/jqueryui/1.10.4/themes/smoothness/jquery-ui.css +1178 -0
- package/src/util/combinators.js +68 -0
- package/src/util/date.js +51 -0
- package/src/util/errors.js +55 -0
- package/src/util/helpers.js +131 -0
- package/src/util/inherit.js +28 -0
- package/src/util/ip.js +54 -0
- package/src/util/logger.js +83 -0
- package/src/util/middleware.js +256 -0
- package/src/util/scopedLogger.js +47 -0
- package/src/views/_footer.ejs +20 -0
- package/src/views/_header.ejs +113 -0
- package/src/views/_imposter.ejs +8 -0
- package/src/views/config.ejs +71 -0
- package/src/views/docs/api/behaviors/copy.ejs +427 -0
- package/src/views/docs/api/behaviors/decorate.ejs +182 -0
- package/src/views/docs/api/behaviors/lookup.ejs +220 -0
- package/src/views/docs/api/behaviors/shellTransform.ejs +153 -0
- package/src/views/docs/api/behaviors/wait.ejs +121 -0
- package/src/views/docs/api/behaviors.ejs +141 -0
- package/src/views/docs/api/contracts/addStub-description.ejs +10 -0
- package/src/views/docs/api/contracts/addStub.ejs +10 -0
- package/src/views/docs/api/contracts/config-description.ejs +32 -0
- package/src/views/docs/api/contracts/config.ejs +23 -0
- package/src/views/docs/api/contracts/home-description.ejs +18 -0
- package/src/views/docs/api/contracts/home.ejs +13 -0
- package/src/views/docs/api/contracts/imposter-description.ejs +439 -0
- package/src/views/docs/api/contracts/imposter.ejs +182 -0
- package/src/views/docs/api/contracts/imposters-description.ejs +13 -0
- package/src/views/docs/api/contracts/imposters.ejs +13 -0
- package/src/views/docs/api/contracts/logs-description.ejs +3 -0
- package/src/views/docs/api/contracts/logs.ejs +14 -0
- package/src/views/docs/api/contracts/stub-description.ejs +4 -0
- package/src/views/docs/api/contracts/stub.ejs +7 -0
- package/src/views/docs/api/contracts/stubs-description.ejs +4 -0
- package/src/views/docs/api/contracts/stubs.ejs +11 -0
- package/src/views/docs/api/contracts.ejs +133 -0
- package/src/views/docs/api/errors.ejs +64 -0
- package/src/views/docs/api/fault/connectionReset.ejs +31 -0
- package/src/views/docs/api/fault/randomDataThenClose.ejs +31 -0
- package/src/views/docs/api/faults.ejs +57 -0
- package/src/views/docs/api/injection.ejs +426 -0
- package/src/views/docs/api/json.ejs +205 -0
- package/src/views/docs/api/jsonpath.ejs +210 -0
- package/src/views/docs/api/mocks.ejs +130 -0
- package/src/views/docs/api/overview.ejs +968 -0
- package/src/views/docs/api/predicates/and.ejs +62 -0
- package/src/views/docs/api/predicates/contains.ejs +64 -0
- package/src/views/docs/api/predicates/deepEquals.ejs +114 -0
- package/src/views/docs/api/predicates/endsWith.ejs +66 -0
- package/src/views/docs/api/predicates/equals.ejs +125 -0
- package/src/views/docs/api/predicates/exists.ejs +118 -0
- package/src/views/docs/api/predicates/inject.ejs +67 -0
- package/src/views/docs/api/predicates/matches.ejs +66 -0
- package/src/views/docs/api/predicates/not.ejs +52 -0
- package/src/views/docs/api/predicates/or.ejs +79 -0
- package/src/views/docs/api/predicates/startsWith.ejs +62 -0
- package/src/views/docs/api/predicates.ejs +382 -0
- package/src/views/docs/api/proxies.ejs +191 -0
- package/src/views/docs/api/proxy/addDecorateBehavior.ejs +115 -0
- package/src/views/docs/api/proxy/addWaitBehavior.ejs +96 -0
- package/src/views/docs/api/proxy/injectHeaders.ejs +91 -0
- package/src/views/docs/api/proxy/predicateGenerators.ejs +600 -0
- package/src/views/docs/api/proxy/proxyModes.ejs +495 -0
- package/src/views/docs/api/stubs.ejs +391 -0
- package/src/views/docs/api/xpath.ejs +281 -0
- package/src/views/docs/cli/configFiles.ejs +133 -0
- package/src/views/docs/cli/customFormatters.ejs +53 -0
- package/src/views/docs/cli/help.ejs +6 -0
- package/src/views/docs/cli/replay.ejs +42 -0
- package/src/views/docs/cli/restart.ejs +10 -0
- package/src/views/docs/cli/save.ejs +68 -0
- package/src/views/docs/cli/start.ejs +234 -0
- package/src/views/docs/cli/stop.ejs +32 -0
- package/src/views/docs/commandLine.ejs +93 -0
- package/src/views/docs/communityExtensions.ejs +233 -0
- package/src/views/docs/gettingStarted.ejs +146 -0
- package/src/views/docs/mentalModel.ejs +51 -0
- package/src/views/docs/protocols/custom.ejs +231 -0
- package/src/views/docs/protocols/http.ejs +238 -0
- package/src/views/docs/protocols/https.ejs +246 -0
- package/src/views/docs/protocols/smtp.ejs +142 -0
- package/src/views/docs/protocols/tcp.ejs +431 -0
- package/src/views/docs/security.ejs +38 -0
- package/src/views/faqs.ejs +65 -0
- package/src/views/feed.ejs +33 -0
- package/src/views/imposter.ejs +22 -0
- package/src/views/imposters.ejs +33 -0
- package/src/views/index.ejs +89 -0
- package/src/views/license.ejs +30 -0
- package/src/views/logs.ejs +77 -0
- package/src/views/releases/v1.1.0.ejs +55 -0
- package/src/views/releases/v1.1.36.ejs +84 -0
- package/src/views/releases/v1.1.72.ejs +92 -0
- package/src/views/releases/v1.10.0.ejs +108 -0
- package/src/views/releases/v1.11.0.ejs +109 -0
- package/src/views/releases/v1.12.0.ejs +96 -0
- package/src/views/releases/v1.13.0.ejs +118 -0
- package/src/views/releases/v1.14.0.ejs +107 -0
- package/src/views/releases/v1.14.1.ejs +94 -0
- package/src/views/releases/v1.15.0.ejs +113 -0
- package/src/views/releases/v1.16.0.ejs +104 -0
- package/src/views/releases/v1.2.0.ejs +78 -0
- package/src/views/releases/v1.2.103.ejs +86 -0
- package/src/views/releases/v1.2.122.ejs +86 -0
- package/src/views/releases/v1.2.30.ejs +84 -0
- package/src/views/releases/v1.2.45.ejs +84 -0
- package/src/views/releases/v1.2.56.ejs +79 -0
- package/src/views/releases/v1.3.0.ejs +86 -0
- package/src/views/releases/v1.3.1.ejs +100 -0
- package/src/views/releases/v1.4.0.ejs +96 -0
- package/src/views/releases/v1.4.1.ejs +103 -0
- package/src/views/releases/v1.4.2.ejs +100 -0
- package/src/views/releases/v1.4.3.ejs +113 -0
- package/src/views/releases/v1.5.0.ejs +104 -0
- package/src/views/releases/v1.5.1.ejs +91 -0
- package/src/views/releases/v1.6.0.ejs +109 -0
- package/src/views/releases/v1.7.0.ejs +113 -0
- package/src/views/releases/v1.7.1.ejs +90 -0
- package/src/views/releases/v1.7.2.ejs +96 -0
- package/src/views/releases/v1.8.0.ejs +121 -0
- package/src/views/releases/v1.9.0.ejs +111 -0
- package/src/views/releases/v2.0.0.ejs +159 -0
- package/src/views/releases/v2.1.0.ejs +121 -0
- package/src/views/releases/v2.1.1.ejs +106 -0
- package/src/views/releases/v2.1.2.ejs +84 -0
- package/src/views/releases/v2.2.0.ejs +115 -0
- package/src/views/releases/v2.2.1.ejs +102 -0
- package/src/views/releases/v2.3.0.ejs +121 -0
- package/src/views/releases/v2.3.1.ejs +100 -0
- package/src/views/releases/v2.3.2.ejs +102 -0
- package/src/views/releases/v2.3.3.ejs +97 -0
- package/src/views/releases/v2.4.0.ejs +114 -0
- package/src/views/releases/v2.5.0.ejs +51 -0
- package/src/views/releases/v2.6.0.ejs +35 -0
- package/src/views/releases/v2.7.0.ejs +32 -0
- package/src/views/releases/v2.8.0.ejs +36 -0
- package/src/views/releases/v2.8.1.ejs +7 -0
- package/src/views/releases/v2.8.2.ejs +26 -0
- package/src/views/releases/v2.9.0.ejs +32 -0
- package/src/views/releases/v2.9.1.ejs +10 -0
- package/src/views/releases.ejs +26 -0
- package/src/views/sitemap.ejs +36 -0
- package/src/views/support.ejs +14 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const helpers = require('../util/helpers.js'),
|
|
4
|
+
errors = require('./errors.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Express middleware functions to inject into the HTTP processing
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns a middleware function to transforms all outgoing relative links in the response body
|
|
13
|
+
* to absolute URLs, incorporating the current host name and port
|
|
14
|
+
* @param {number} port - The port of the current instance
|
|
15
|
+
* @returns {Function}
|
|
16
|
+
*/
|
|
17
|
+
function useAbsoluteUrls (port) {
|
|
18
|
+
return function (request, response, next) {
|
|
19
|
+
const setHeaderOriginal = response.setHeader,
|
|
20
|
+
sendOriginal = response.send,
|
|
21
|
+
host = request.headers.host || `localhost:${port}`,
|
|
22
|
+
absolutize = link => `http://${host}${link}`,
|
|
23
|
+
isObject = helpers.isObject;
|
|
24
|
+
|
|
25
|
+
response.setHeader = function () {
|
|
26
|
+
const args = Array.prototype.slice.call(arguments);
|
|
27
|
+
|
|
28
|
+
if (args[0] && args[0].toLowerCase() === 'location') {
|
|
29
|
+
args[1] = absolutize(args[1]);
|
|
30
|
+
}
|
|
31
|
+
setHeaderOriginal.apply(this, args);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
response.send = function () {
|
|
35
|
+
const args = Array.prototype.slice.call(arguments),
|
|
36
|
+
body = args[0],
|
|
37
|
+
changeLinks = function (obj) {
|
|
38
|
+
if (obj._links) {
|
|
39
|
+
Object.keys(obj._links).forEach(function (rel) {
|
|
40
|
+
if (obj._links[rel].href) {
|
|
41
|
+
obj._links[rel].href = absolutize(obj._links[rel].href);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
traverse = function (obj, fn, parent) {
|
|
47
|
+
if (parent === 'stubs' || parent === 'response') {
|
|
48
|
+
// Don't change _links within stubs or within the response
|
|
49
|
+
// sent back to protocol implementations
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
fn(obj);
|
|
53
|
+
Object.keys(obj).forEach(key => {
|
|
54
|
+
if (obj[key] && isObject(obj[key])) {
|
|
55
|
+
traverse(obj[key], fn, key);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if (isObject(body)) {
|
|
61
|
+
traverse(body, changeLinks);
|
|
62
|
+
|
|
63
|
+
// Special case stubs _links. Hard to manage in the traverse function because stubs is an array
|
|
64
|
+
// and we want to change stubs[]._links but not stubs[]._responses.is.body._links
|
|
65
|
+
if (Array.isArray(body.stubs)) {
|
|
66
|
+
body.stubs.forEach(changeLinks);
|
|
67
|
+
}
|
|
68
|
+
else if (Array.isArray(body.imposters)) {
|
|
69
|
+
body.imposters.forEach(imposter => {
|
|
70
|
+
if (Array.isArray(imposter.stubs)) {
|
|
71
|
+
imposter.stubs.forEach(changeLinks);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
sendOriginal.apply(this, args);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
next();
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns a middleware function to return a 404 if the imposter does not exist
|
|
85
|
+
* @param {Object} imposters - The imposters repository
|
|
86
|
+
* @returns {Function}
|
|
87
|
+
*/
|
|
88
|
+
function createImposterValidator (imposters) {
|
|
89
|
+
return async function validateImposterExists (request, response, next) {
|
|
90
|
+
const exists = await imposters.exists(request.params.id);
|
|
91
|
+
|
|
92
|
+
if (exists) {
|
|
93
|
+
next();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
response.statusCode = 404;
|
|
97
|
+
response.send({
|
|
98
|
+
errors: [errors.MissingResourceError('Try POSTing to /imposters first?')]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Returns a middleware function that logs the requests made to the server
|
|
106
|
+
* @param {Object} log - The logger
|
|
107
|
+
* @param {string} format - The log format
|
|
108
|
+
* @returns {Function}
|
|
109
|
+
*/
|
|
110
|
+
function logger (log, format) {
|
|
111
|
+
function shouldLog (request) {
|
|
112
|
+
const isStaticAsset = (['.js', '.css', '.gif', '.png', '.ico'].some(function (fileType) {
|
|
113
|
+
return request.url.indexOf(fileType) >= 0;
|
|
114
|
+
})),
|
|
115
|
+
isHtmlRequest = (request.headers.accept || '').indexOf('html') >= 0,
|
|
116
|
+
isXHR = request.headers['x-requested-with'] === 'XMLHttpRequest';
|
|
117
|
+
|
|
118
|
+
return !(isStaticAsset || isHtmlRequest || isXHR);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return function (request, response, next) {
|
|
122
|
+
if (shouldLog(request)) {
|
|
123
|
+
const message = format.replace(':method', request.method).replace(':url', request.url);
|
|
124
|
+
if (request.url.indexOf('_requests') > 0) {
|
|
125
|
+
// Protocol implementations communicating with mountebank
|
|
126
|
+
log.debug(message);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
log.info(message);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
next();
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Returns a middleware function that passes global variables to all render calls without
|
|
138
|
+
* having to pass them explicitly
|
|
139
|
+
* @param {Object} vars - the global variables to pass
|
|
140
|
+
* @returns {Function}
|
|
141
|
+
*/
|
|
142
|
+
function globals (vars) {
|
|
143
|
+
return function (request, response, next) {
|
|
144
|
+
const originalRender = response.render;
|
|
145
|
+
response.render = function () {
|
|
146
|
+
const args = Array.prototype.slice.call(arguments),
|
|
147
|
+
variables = args[1] || {};
|
|
148
|
+
|
|
149
|
+
Object.keys(vars).forEach(function (name) {
|
|
150
|
+
variables[name] = vars[name];
|
|
151
|
+
});
|
|
152
|
+
args[1] = variables;
|
|
153
|
+
originalRender.apply(this, args);
|
|
154
|
+
};
|
|
155
|
+
next();
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The mountebank server uses header-based content negotiation to return either HTML or JSON
|
|
161
|
+
* for each URL. This breaks down on IE browsers as they fail to send the correct Accept header,
|
|
162
|
+
* and since we default to JSON (to make the API easier to use), that leads to a poor experience
|
|
163
|
+
* for IE users. We special case IE to html by inspecting the user agent, making sure not to
|
|
164
|
+
* interfere with XHR requests that do add the Accept header
|
|
165
|
+
* @param {Object} request - The http request
|
|
166
|
+
* @param {Object} response - The http response
|
|
167
|
+
* @param {Function} next - The next middleware function to call
|
|
168
|
+
*/
|
|
169
|
+
function defaultIEtoHTML (request, response, next) {
|
|
170
|
+
// IE has inconsistent Accept headers, often defaulting to */*
|
|
171
|
+
// Our default is JSON, which fails to render in the browser on content-negotiated pages
|
|
172
|
+
if (request.headers['user-agent'] && request.headers['user-agent'].indexOf('MSIE') >= 0) {
|
|
173
|
+
if (!(request.headers.accept && request.headers.accept.match(/application\/json/))) {
|
|
174
|
+
request.headers.accept = 'text/html';
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
next();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Returns a middleware function that defaults the content type to JSON if not set to make
|
|
182
|
+
* command line testing easier (e.g. you don't have to set the Accept header with curl) and
|
|
183
|
+
* parses the JSON before reaching a controller, handling errors gracefully.
|
|
184
|
+
* @param {Object} log - The logger
|
|
185
|
+
* @returns {Function}
|
|
186
|
+
*/
|
|
187
|
+
function json (log) {
|
|
188
|
+
return function (request, response, next) {
|
|
189
|
+
// Disable body parsing, if already parsed
|
|
190
|
+
if (request.headers['content-type'] === 'application/json' && helpers.isObject(request.body)) {
|
|
191
|
+
next();
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
request.body = '';
|
|
196
|
+
request.setEncoding('utf8');
|
|
197
|
+
request.on('data', chunk => {
|
|
198
|
+
request.body += chunk;
|
|
199
|
+
});
|
|
200
|
+
request.on('end', function () {
|
|
201
|
+
if (request.body === '') {
|
|
202
|
+
next();
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
try {
|
|
206
|
+
request.body = JSON.parse(request.body);
|
|
207
|
+
request.headers['content-type'] = 'application/json';
|
|
208
|
+
next();
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
log.error('Invalid JSON: ' + request.body);
|
|
212
|
+
response.statusCode = 400;
|
|
213
|
+
response.send({
|
|
214
|
+
errors: [errors.InvalidJSONError({ source: request.body })]
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function validateApiKey (expectedApiKey, log) {
|
|
223
|
+
return function (request, response, next) {
|
|
224
|
+
if (!expectedApiKey) {
|
|
225
|
+
next();
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!request.headers['x-api-key']) {
|
|
230
|
+
log.error('The x-api-key header is required but was not provided');
|
|
231
|
+
response.statusCode = 401;
|
|
232
|
+
response.send({
|
|
233
|
+
errors: [errors.UnauthorizedError()]
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const crypto = require('crypto');
|
|
239
|
+
const hash = crypto.createHash('sha512');
|
|
240
|
+
if (crypto.timingSafeEqual(
|
|
241
|
+
hash.copy().update(request.headers['x-api-key']).digest(),
|
|
242
|
+
hash.copy().update(expectedApiKey).digest()
|
|
243
|
+
)) {
|
|
244
|
+
next();
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
log.error('The x-api-key header value does not match the expected API key');
|
|
248
|
+
response.statusCode = 401;
|
|
249
|
+
response.send({
|
|
250
|
+
errors: [errors.UnauthorizedError()]
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
module.exports = { useAbsoluteUrls, createImposterValidator, logger, globals, defaultIEtoHTML, json, validateApiKey };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** @module */
|
|
4
|
+
|
|
5
|
+
const inherit = require('./inherit.js'),
|
|
6
|
+
util = require('util');
|
|
7
|
+
|
|
8
|
+
function wrap (wrappedLogger, logger) {
|
|
9
|
+
['debug', 'info', 'warn', 'error'].forEach(level => {
|
|
10
|
+
wrappedLogger[level] = function () {
|
|
11
|
+
const args = Array.prototype.slice.call(arguments);
|
|
12
|
+
args[0] = wrappedLogger.scopePrefix + args[0];
|
|
13
|
+
|
|
14
|
+
// Format here rather than use winston's splat formatter
|
|
15
|
+
// to get rid of inconsistent "meta" log elements
|
|
16
|
+
const message = util.format.apply(null, args);
|
|
17
|
+
logger[level](message);
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
wrappedLogger.baseLogger = logger;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns a logger that prefixes each message of the given logger with a given scope
|
|
25
|
+
* @param {Object} logger - The logger to add a scope to
|
|
26
|
+
* @param {string} scope - The prefix for all log messages
|
|
27
|
+
* @returns {Object}
|
|
28
|
+
*/
|
|
29
|
+
function create (logger, scope) {
|
|
30
|
+
function formatScope (scopeText) {
|
|
31
|
+
return scopeText.indexOf('[') === 0 ? scopeText : `[${scopeText}] `;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const wrappedLogger = inherit.from(logger, {
|
|
35
|
+
scopePrefix: formatScope(scope),
|
|
36
|
+
withScope: nestedScopePrefix => create(logger, `${wrappedLogger.scopePrefix}${nestedScopePrefix} `),
|
|
37
|
+
changeScope: newScope => {
|
|
38
|
+
wrappedLogger.scopePrefix = formatScope(newScope);
|
|
39
|
+
wrap(wrappedLogger, logger);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
wrap(wrappedLogger, logger);
|
|
44
|
+
return wrappedLogger;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = { create };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
</div>
|
|
2
|
+
</div>
|
|
3
|
+
|
|
4
|
+
<hr />
|
|
5
|
+
|
|
6
|
+
<footer>
|
|
7
|
+
<nav class='horizontal'>
|
|
8
|
+
<ul>
|
|
9
|
+
<li> </li>
|
|
10
|
+
<li><a href='/releases'>releases</a></li>
|
|
11
|
+
<li><a href='https://github.com/mountebank-testing/mountebank/blob/master/CONTRIBUTING.md'>contributing</a></li>
|
|
12
|
+
<li><a href='/license'>license</a></li>
|
|
13
|
+
<li><a href='https://github.com/mountebank-testing/mountebank'>source</a></li>
|
|
14
|
+
<li><a href='https://github.com/mountebank-testing/mountebank/issues'>issues</a></li>
|
|
15
|
+
</ul>
|
|
16
|
+
</nav>
|
|
17
|
+
</footer>
|
|
18
|
+
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>mountebank - <%= title %></title>
|
|
5
|
+
<meta charset='utf-8'>
|
|
6
|
+
<meta name='description' content='<%= description %>' />
|
|
7
|
+
<meta name='author' content='Brandon Byars' />
|
|
8
|
+
|
|
9
|
+
<link rel='stylesheet' href='/stylesheets/jqueryui/1.10.4/themes/smoothness/jquery-ui.css' />
|
|
10
|
+
<link rel='stylesheet' type='text/css' href='/stylesheets/application.css' />
|
|
11
|
+
<!--[if IE]>
|
|
12
|
+
<link rel='stylesheet' type='text/css' href='/stylesheets/ie.css' />
|
|
13
|
+
<![endif]-->
|
|
14
|
+
|
|
15
|
+
<link rel='shortcut icon' href='/images/favicon.ico' type='image/x-icon' />
|
|
16
|
+
|
|
17
|
+
<script src='/scripts/jquery/jquery-3.6.1.min.js'></script>
|
|
18
|
+
<script src='/scripts/urlHashHandler.js'></script>
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
<div id='main'>
|
|
22
|
+
<header>
|
|
23
|
+
<a href='/'><img src='/images/mountebank.png' alt='mountebank' /></a>
|
|
24
|
+
<p>mountebank - over the wire test doubles</p>
|
|
25
|
+
|
|
26
|
+
<form method='GET' action='http://www.google.com/search'>
|
|
27
|
+
<input type='hidden' name='domains' value='www.mbtest.dev' />
|
|
28
|
+
<input type='hidden' name='sitesearch' value='www.mbtest.dev' />
|
|
29
|
+
<input type='search' name='q' id='q' results='5' autosave='mb' placeholder='Search...'/>
|
|
30
|
+
<input type='submit' value='Search...' id='searchButton' />
|
|
31
|
+
</form>
|
|
32
|
+
|
|
33
|
+
<nav class='horizontal'>
|
|
34
|
+
<ul>
|
|
35
|
+
<li><a href='/'>home</a></li>
|
|
36
|
+
<li><a href='/imposters'>imposters</a></li>
|
|
37
|
+
<li><a href='/logs'>logs</a></li>
|
|
38
|
+
<li><a href='/config'>config</a></li>
|
|
39
|
+
<li><a href='/metrics' title='Prometheus metrics'>metrics</a></li>
|
|
40
|
+
<li><a href='/feed' class='feed-icon' title='subscribe for release updates'></a></li>
|
|
41
|
+
</ul>
|
|
42
|
+
</nav>
|
|
43
|
+
</header>
|
|
44
|
+
|
|
45
|
+
<hr />
|
|
46
|
+
|
|
47
|
+
<div id='sidenav'>
|
|
48
|
+
<h3>the apothecary</h3>
|
|
49
|
+
<nav class='vertical'>
|
|
50
|
+
<ul>
|
|
51
|
+
<li><a href='/docs/gettingStarted'>getting started</a></li>
|
|
52
|
+
<li><a href='/docs/mentalModel'>mental model</a></li>
|
|
53
|
+
<li><a href='/docs/communityExtensions'>3rd party plugins</a></li>
|
|
54
|
+
<li><a href='/docs/commandLine'>command line</a></li>
|
|
55
|
+
<li><a href='/docs/security'>security</a></li>
|
|
56
|
+
<li><a href='/faqs'>faqs</a></li>
|
|
57
|
+
<li><a href='/support'>support</a></li>
|
|
58
|
+
</ul>
|
|
59
|
+
|
|
60
|
+
<p>api:</p>
|
|
61
|
+
<ul>
|
|
62
|
+
<li><a href='/docs/api/overview'>overview</a></li>
|
|
63
|
+
<li><a href='/docs/api/contracts'>contracts</a></li>
|
|
64
|
+
<li><a href='/docs/api/mocks'>mock verification</a></li>
|
|
65
|
+
<li><a href='/docs/api/stubs'>stub responses</a></li>
|
|
66
|
+
<li>
|
|
67
|
+
<ul>
|
|
68
|
+
<li><a href='/docs/api/proxies'>proxies</a></li>
|
|
69
|
+
<li><a href='/docs/api/injection'>injection</a></li>
|
|
70
|
+
<li><a href='/docs/api/behaviors'>behaviors</a></li>
|
|
71
|
+
<li><a href='/docs/api/faults'>faults</a></li>
|
|
72
|
+
</ul>
|
|
73
|
+
</li>
|
|
74
|
+
<li><a href='/docs/api/predicates'>stub predicates</a></li>
|
|
75
|
+
<li>
|
|
76
|
+
<ul>
|
|
77
|
+
<li><a href='/docs/api/xpath'>xpath</a></li>
|
|
78
|
+
<li><a href='/docs/api/json'>json</a></li>
|
|
79
|
+
<li><a href='/docs/api/jsonpath'>jsonpath</a></li>
|
|
80
|
+
</ul>
|
|
81
|
+
</li>
|
|
82
|
+
<li><a href='/docs/api/errors'>errors</a></li>
|
|
83
|
+
</ul>
|
|
84
|
+
|
|
85
|
+
<p>builtin protocols:</p>
|
|
86
|
+
<ul>
|
|
87
|
+
<li><a href='/docs/protocols/http'>http</a></li>
|
|
88
|
+
<li><a href='/docs/protocols/https'>https</a></li>
|
|
89
|
+
<li><a href='/docs/protocols/tcp'>tcp</a></li>
|
|
90
|
+
<li><a href='/docs/protocols/smtp'>smtp</a></li>
|
|
91
|
+
</ul>
|
|
92
|
+
|
|
93
|
+
<p>community plugins:</p>
|
|
94
|
+
<ul>
|
|
95
|
+
<li><a href='https://gitlab.com/dAnjou/mountebank-ldap'>ldap</a></li>
|
|
96
|
+
<li><a href='https://github.com/vamsib/mountebank-ws'>websockets</a></li>
|
|
97
|
+
<li><a href='https://github.com/bashj79/mb-graphql'>graphql</a></li>
|
|
98
|
+
<li><a href='https://github.com/telekom/mb-netmgmt'>snmp</a></li>
|
|
99
|
+
<li><a href='https://github.com/telekom/mb-netmgmt'>telnet</a></li>
|
|
100
|
+
<li><a href='https://github.com/telekom/mb-netmgmt'>ssh</a></li>
|
|
101
|
+
<li><a href='https://github.com/telekom/mb-netmgmt'>netconf</a></li>
|
|
102
|
+
<li><a href='/docs/protocols/custom'>create your own</a></li>
|
|
103
|
+
</ul>
|
|
104
|
+
|
|
105
|
+
<p>the book:<br /><br />
|
|
106
|
+
<a href='https://www.manning.com/books/testing-microservices-with-mountebank?utm_source=mb&utm_medium=affiliate&utm_campaign=book_byars_testing_12_20_18&a_aid=mb&a_bid=ee3288f4'>
|
|
107
|
+
<img src='/images/book.jpg' alt='Testing Microservices with Mountebank' width='130' height='163' />
|
|
108
|
+
</a>
|
|
109
|
+
</p>
|
|
110
|
+
</nav>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<div id='content'>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<tr id='imposter-<%= imposter.port %>'>
|
|
2
|
+
<td style='width: 15em;'><a href='<%= imposter._links.self.href %>'>
|
|
3
|
+
<%= imposter.name || imposter.protocol + ':' + imposter.port %>
|
|
4
|
+
</a></td>
|
|
5
|
+
<td style='width: 6em;'><%= imposter.protocol %></td>
|
|
6
|
+
<td style='width: 5em;'><%= imposter.port %></td>
|
|
7
|
+
<td style='width: 6em;'><%= imposter.numberOfRequests %></td>
|
|
8
|
+
</tr>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<%
|
|
2
|
+
title = 'configuration'
|
|
3
|
+
description = 'The version, command line parameters, and process information about this running mb process'
|
|
4
|
+
%>
|
|
5
|
+
|
|
6
|
+
<%- include('_header') -%>
|
|
7
|
+
|
|
8
|
+
<%
|
|
9
|
+
function isJSONObject (value) {
|
|
10
|
+
return typeof value === 'object' && !Array.isArray(value);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function prettyPrint (value) {
|
|
14
|
+
return isJSONObject(value) ? JSON.stringify(value, null, 2) : value;
|
|
15
|
+
}
|
|
16
|
+
%>
|
|
17
|
+
|
|
18
|
+
<h1>Config</h1>
|
|
19
|
+
|
|
20
|
+
<table>
|
|
21
|
+
<tr>
|
|
22
|
+
<td>version</td>
|
|
23
|
+
<td><%= version %></td>
|
|
24
|
+
</tr>
|
|
25
|
+
<% Object.keys(options).forEach(key =>{ %>
|
|
26
|
+
<tr>
|
|
27
|
+
<td><%= key %></td>
|
|
28
|
+
<td><% if (isJSONObject(options[key])) { -%><pre><code><% } -%><%= prettyPrint(options[key]) %><% if (isJSONObject(options[key])) { -%></code></pre><% } -%>
|
|
29
|
+
</td>
|
|
30
|
+
</tr>
|
|
31
|
+
<% }); -%>
|
|
32
|
+
</table>
|
|
33
|
+
|
|
34
|
+
<h2>Process Information</h2>
|
|
35
|
+
|
|
36
|
+
<table>
|
|
37
|
+
<tr>
|
|
38
|
+
<td>node version</td>
|
|
39
|
+
<td><%= process.nodeVersion %></td>
|
|
40
|
+
</tr>
|
|
41
|
+
<tr>
|
|
42
|
+
<td>architecture</td>
|
|
43
|
+
<td><%= process.architecture %></td>
|
|
44
|
+
</tr>
|
|
45
|
+
<tr>
|
|
46
|
+
<td>platform</td>
|
|
47
|
+
<td><%= process.platform %></td>
|
|
48
|
+
</tr>
|
|
49
|
+
<tr>
|
|
50
|
+
<td>rss</td>
|
|
51
|
+
<td><%= process.rss %></td>
|
|
52
|
+
</tr>
|
|
53
|
+
<tr>
|
|
54
|
+
<td>heapTotal</td>
|
|
55
|
+
<td><%= process.heapTotal %></td>
|
|
56
|
+
</tr>
|
|
57
|
+
<tr>
|
|
58
|
+
<td>heapUsed</td>
|
|
59
|
+
<td><%= process.heapUsed %></td>
|
|
60
|
+
</tr>
|
|
61
|
+
<tr>
|
|
62
|
+
<td>uptime</td>
|
|
63
|
+
<td><%= process.uptime %></td>
|
|
64
|
+
</tr>
|
|
65
|
+
<tr>
|
|
66
|
+
<td>cwd</td>
|
|
67
|
+
<td><%= process.cwd %></td>
|
|
68
|
+
</tr>
|
|
69
|
+
</table>
|
|
70
|
+
|
|
71
|
+
<%- include('_footer') -%>
|