@stuntman/server 0.1.7 → 0.1.9

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.
Files changed (57) hide show
  1. package/README.md +9 -1
  2. package/dist/api/api.d.ts +25 -0
  3. package/dist/api/api.d.ts.map +1 -0
  4. package/dist/api/api.js +212 -0
  5. package/dist/api/api.js.map +1 -0
  6. package/dist/api/utils.d.ts +5 -0
  7. package/dist/api/utils.d.ts.map +1 -0
  8. package/dist/api/utils.js +61 -0
  9. package/dist/api/utils.js.map +1 -0
  10. package/dist/api/validators.d.ts +4 -0
  11. package/dist/api/validators.d.ts.map +1 -0
  12. package/dist/api/validators.js +125 -0
  13. package/dist/api/validators.js.map +1 -0
  14. package/dist/api/webgui/rules.pug +147 -0
  15. package/dist/api/webgui/style.css +28 -0
  16. package/dist/api/webgui/traffic.pug +38 -0
  17. package/dist/bin/stuntman.d.ts +3 -0
  18. package/dist/bin/stuntman.d.ts.map +1 -0
  19. package/dist/bin/stuntman.js +8 -0
  20. package/dist/bin/stuntman.js.map +1 -0
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +6 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/ipUtils.d.ts +18 -0
  26. package/dist/ipUtils.d.ts.map +1 -0
  27. package/dist/ipUtils.js +102 -0
  28. package/dist/ipUtils.js.map +1 -0
  29. package/dist/mock.d.ts +32 -0
  30. package/dist/mock.d.ts.map +1 -0
  31. package/dist/mock.js +306 -0
  32. package/dist/mock.js.map +1 -0
  33. package/dist/requestContext.d.ts +10 -0
  34. package/dist/requestContext.d.ts.map +1 -0
  35. package/dist/requestContext.js +19 -0
  36. package/dist/requestContext.js.map +1 -0
  37. package/dist/ruleExecutor.d.ts +23 -0
  38. package/dist/ruleExecutor.d.ts.map +1 -0
  39. package/dist/ruleExecutor.js +189 -0
  40. package/dist/ruleExecutor.js.map +1 -0
  41. package/dist/rules/catchAll.d.ts +3 -0
  42. package/dist/rules/catchAll.d.ts.map +1 -0
  43. package/dist/rules/catchAll.js +16 -0
  44. package/dist/rules/catchAll.js.map +1 -0
  45. package/dist/rules/echo.d.ts +3 -0
  46. package/dist/rules/echo.d.ts.map +1 -0
  47. package/dist/rules/echo.js +16 -0
  48. package/dist/rules/echo.js.map +1 -0
  49. package/dist/rules/index.d.ts +4 -0
  50. package/dist/rules/index.d.ts.map +1 -0
  51. package/dist/rules/index.js +71 -0
  52. package/dist/rules/index.js.map +1 -0
  53. package/dist/storage.d.ts +5 -0
  54. package/dist/storage.d.ts.map +1 -0
  55. package/dist/storage.js +43 -0
  56. package/dist/storage.js.map +1 -0
  57. package/package.json +2 -2
package/README.md CHANGED
@@ -1,4 +1,12 @@
1
- # Stuntman
1
+ # Stuntman server
2
+
3
+ [![npm](https://img.shields.io/npm/v/@stuntman/server.svg)][npmjs]
4
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/andrzej-woof/stuntman/ci.yaml)][build]
5
+ [![Coverage Status](https://coveralls.io/repos/github/andrzej-woof/stuntman/badge.svg)][coverage]
6
+
7
+ [npmjs]: https://www.npmjs.com/package/@stuntman/server
8
+ [build]: https://github.com/andrzej-woof/stuntman/actions/workflows/ci.yaml
9
+ [coverage]: https://coveralls.io/github/andrzej-woof/stuntman
2
10
 
3
11
  Stuntman is a proxy/mock server that can be deployed remotely together with your application under test, working as either pass-through proxy allowing you to inspect traffic or proxy/mock which can intercept requests/responses and modify them or stub with predefined ones.
4
12
 
@@ -0,0 +1,25 @@
1
+ /// <reference types="node" />
2
+ import http from 'http';
3
+ import { NextFunction, Request, Response, Express as ExpressServer } from 'express';
4
+ import type * as Stuntman from '@stuntman/shared';
5
+ import LRUCache from 'lru-cache';
6
+ type ApiOptions = Stuntman.ApiConfig & {
7
+ mockUuid: string;
8
+ };
9
+ export declare class API {
10
+ protected options: Required<ApiOptions>;
11
+ protected webGuiOptions: Stuntman.WebGuiConfig;
12
+ protected apiApp: ExpressServer | null;
13
+ trafficStore: LRUCache<string, Stuntman.LogEntry>;
14
+ server: http.Server | null;
15
+ constructor(options: ApiOptions, webGuiOptions?: Stuntman.WebGuiConfig);
16
+ private auth;
17
+ protected authReadOnly(req: Request, _res: Response, next: NextFunction): void;
18
+ protected authReadWrite(req: Request, _res: Response, next: NextFunction): void;
19
+ private initApi;
20
+ private initWebGui;
21
+ start(): void;
22
+ stop(): void;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api/api.ts"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAgB,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7F,OAAO,KAAK,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAGlD,OAAO,QAAQ,MAAM,WAAW,CAAC;AAIjC,KAAK,UAAU,GAAG,QAAQ,CAAC,SAAS,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF,qBAAa,GAAG;IACZ,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,YAAY,CAAC;IAC/C,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAQ;IAC9C,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAQ;gBAEtB,OAAO,EAAE,UAAU,EAAE,aAAa,GAAE,QAAQ,CAAC,YAAkC;IAa3F,OAAO,CAAC,IAAI;IAaZ,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAK9E,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAK/E,OAAO,CAAC,OAAO;IA+Gf,OAAO,CAAC,UAAU;IAwDX,KAAK;IAaL,IAAI;CASd"}
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.API = void 0;
7
+ const express_1 = __importDefault(require("express"));
8
+ const uuid_1 = require("uuid");
9
+ const storage_1 = require("../storage");
10
+ const ruleExecutor_1 = require("../ruleExecutor");
11
+ const shared_1 = require("@stuntman/shared");
12
+ const requestContext_1 = __importDefault(require("../requestContext"));
13
+ const serialize_javascript_1 = __importDefault(require("serialize-javascript"));
14
+ const validators_1 = require("./validators");
15
+ const utils_1 = require("./utils");
16
+ const API_KEY_HEADER = 'x-api-key';
17
+ class API {
18
+ constructor(options, webGuiOptions = { disabled: false }) {
19
+ this.apiApp = null;
20
+ this.server = null;
21
+ if (!options.apiKeyReadOnly !== !options.apiKeyReadWrite) {
22
+ throw new Error('apiKeyReadOnly and apiKeyReadWrite options need to be set either both or none');
23
+ }
24
+ this.options = options;
25
+ this.webGuiOptions = webGuiOptions;
26
+ this.trafficStore = (0, storage_1.getTrafficStore)(this.options.mockUuid);
27
+ this.auth = this.auth.bind(this);
28
+ this.authReadOnly = this.authReadOnly.bind(this);
29
+ this.authReadWrite = this.authReadWrite.bind(this);
30
+ }
31
+ auth(req, type) {
32
+ if (!this.options.apiKeyReadOnly && !this.options.apiKeyReadWrite) {
33
+ return;
34
+ }
35
+ const hasValidReadKey = req.header(API_KEY_HEADER) === this.options.apiKeyReadOnly;
36
+ const hasValidWriteKey = req.header(API_KEY_HEADER) === this.options.apiKeyReadWrite;
37
+ const hasValidKey = type === 'read' ? hasValidReadKey || hasValidWriteKey : hasValidWriteKey;
38
+ if (!hasValidKey) {
39
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.UNAUTHORIZED, message: 'unauthorized' });
40
+ }
41
+ return;
42
+ }
43
+ authReadOnly(req, _res, next) {
44
+ this.auth(req, 'read');
45
+ next();
46
+ }
47
+ authReadWrite(req, _res, next) {
48
+ this.auth(req, 'write');
49
+ next();
50
+ }
51
+ initApi() {
52
+ this.apiApp = (0, express_1.default)();
53
+ this.apiApp.use(express_1.default.json());
54
+ this.apiApp.use(express_1.default.text());
55
+ this.apiApp.use((req, _res, next) => {
56
+ requestContext_1.default.bind(req, this.options.mockUuid);
57
+ next();
58
+ });
59
+ this.apiApp.get('/rule', this.authReadOnly.bind, async (_req, res) => {
60
+ res.send((0, shared_1.stringify)(await (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).getRules()));
61
+ });
62
+ this.apiApp.get('/rule/:ruleId', this.authReadOnly, async (req, res) => {
63
+ if (!req.params.ruleId) {
64
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'missing ruleId' });
65
+ }
66
+ res.send((0, shared_1.stringify)(await (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).getRule(req.params.ruleId)));
67
+ });
68
+ this.apiApp.get('/rule/:ruleId/disable', this.authReadWrite, (req, res) => {
69
+ if (!req.params.ruleId) {
70
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'missing ruleId' });
71
+ }
72
+ (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).disableRule(req.params.ruleId);
73
+ res.send();
74
+ });
75
+ this.apiApp.get('/rule/:ruleId/enable', this.authReadWrite, (req, res) => {
76
+ if (!req.params.ruleId) {
77
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'missing ruleId' });
78
+ }
79
+ (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).enableRule(req.params.ruleId);
80
+ res.send();
81
+ });
82
+ this.apiApp.post('/rule', this.authReadWrite, async (req, res) => {
83
+ const deserializedRule = (0, utils_1.deserializeRule)(req.body);
84
+ (0, validators_1.validateDeserializedRule)(deserializedRule);
85
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
86
+ // @ts-ignore
87
+ const rule = await (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).addRule(deserializedRule);
88
+ res.send((0, shared_1.stringify)(rule));
89
+ });
90
+ this.apiApp.get('/rule/:ruleId/remove', this.authReadWrite, async (req, res) => {
91
+ if (!req.params.ruleId) {
92
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'missing ruleId' });
93
+ }
94
+ await (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).removeRule(req.params.ruleId);
95
+ res.send();
96
+ });
97
+ this.apiApp.get('/traffic', this.authReadOnly, (_req, res) => {
98
+ const serializedTraffic = [];
99
+ for (const value of this.trafficStore.values()) {
100
+ serializedTraffic.push(value);
101
+ }
102
+ res.json(serializedTraffic);
103
+ });
104
+ this.apiApp.get('/traffic/:ruleIdOrLabel', this.authReadOnly, (req, res) => {
105
+ if (!req.params.ruleIdOrLabel) {
106
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'missing ruleIdOrLabel' });
107
+ }
108
+ const serializedTraffic = [];
109
+ for (const value of this.trafficStore.values()) {
110
+ if (value.mockRuleId === req.params.ruleIdOrLabel || (value.labels || []).includes(req.params.ruleIdOrLabel)) {
111
+ serializedTraffic.push(value);
112
+ }
113
+ }
114
+ res.json(serializedTraffic);
115
+ });
116
+ if (!this.webGuiOptions.disabled) {
117
+ this.apiApp.set('views', __dirname + '/webgui');
118
+ this.apiApp.set('view engine', 'pug');
119
+ this.initWebGui();
120
+ }
121
+ this.apiApp.all(/.*/, (_req, res) => res.status(404).send());
122
+ this.apiApp.use((error, req, res) => {
123
+ const ctx = requestContext_1.default.get(req);
124
+ const uuid = (ctx === null || ctx === void 0 ? void 0 : ctx.uuid) || (0, uuid_1.v4)();
125
+ if (error instanceof shared_1.AppError && error.isOperational && res) {
126
+ shared_1.logger.error(error);
127
+ res.status(error.httpCode).json({
128
+ error: { message: error.message, httpCode: error.httpCode, stack: error.stack },
129
+ });
130
+ return;
131
+ }
132
+ shared_1.logger.error({ message: error.message, stack: error.stack, name: error.name, uuid }, 'unexpected error');
133
+ if (res) {
134
+ res.status(shared_1.HttpCode.INTERNAL_SERVER_ERROR).json({
135
+ error: { message: error.message, httpCode: shared_1.HttpCode.INTERNAL_SERVER_ERROR, uuid },
136
+ });
137
+ return;
138
+ }
139
+ // eslint-disable-next-line no-console
140
+ console.log('API server encountered a critical error. Exiting');
141
+ process.exit(1);
142
+ });
143
+ }
144
+ initWebGui() {
145
+ if (!this.apiApp) {
146
+ throw new Error('initialization error');
147
+ }
148
+ this.apiApp.get('/webgui/rules', this.authReadOnly, async (_req, res) => {
149
+ const rules = {};
150
+ for (const rule of await (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).getRules()) {
151
+ rules[rule.id] = (0, serialize_javascript_1.default)((0, utils_1.liveRuleToRule)(rule), { unsafe: true });
152
+ }
153
+ res.render('rules', { rules: (0, utils_1.escapedSerialize)(rules), INDEX_DTS: shared_1.INDEX_DTS, ruleKeys: Object.keys(rules) });
154
+ });
155
+ this.apiApp.get('/webgui/traffic', this.authReadOnly, async (_req, res) => {
156
+ const serializedTraffic = [];
157
+ for (const value of this.trafficStore.values()) {
158
+ serializedTraffic.push(value);
159
+ }
160
+ res.render('traffic', {
161
+ traffic: JSON.stringify(serializedTraffic.sort((a, b) => b.originalRequest.timestamp - a.originalRequest.timestamp)),
162
+ });
163
+ });
164
+ // TODO make webui way better and safer, nicer formatting, eslint/prettier, blackjack and hookers
165
+ this.apiApp.post('/webgui/rules/unsafesave', this.authReadWrite, async (req, res) => {
166
+ const rule = new Function(req.body)();
167
+ if (!rule ||
168
+ !rule.id ||
169
+ typeof rule.matches !== 'function' ||
170
+ typeof rule.ttlSeconds !== 'number' ||
171
+ rule.ttlSeconds > shared_1.MAX_RULE_TTL_SECONDS) {
172
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'Invalid rule' });
173
+ }
174
+ await (0, ruleExecutor_1.getRuleExecutor)(this.options.mockUuid).addRule({
175
+ id: rule.id,
176
+ matches: rule.matches,
177
+ ttlSeconds: rule.ttlSeconds,
178
+ actions: rule.actions,
179
+ ...(rule.disableAfterUse !== undefined && { disableAfterUse: rule.disableAfterUse }),
180
+ ...(rule.isEnabled !== undefined && { isEnabled: rule.isEnabled }),
181
+ ...(rule.labels !== undefined && { labels: rule.labels }),
182
+ ...(rule.priority !== undefined && { priority: rule.priority }),
183
+ ...(rule.removeAfterUse !== undefined && { removeAfterUse: rule.removeAfterUse }),
184
+ ...(rule.storeTraffic !== undefined && { storeTraffic: rule.storeTraffic }),
185
+ }, true);
186
+ res.send();
187
+ });
188
+ }
189
+ start() {
190
+ if (this.server) {
191
+ throw new Error('mock server already started');
192
+ }
193
+ this.initApi();
194
+ if (!this.apiApp) {
195
+ throw new Error('initialization error');
196
+ }
197
+ this.server = this.apiApp.listen(this.options.port, () => {
198
+ shared_1.logger.info(`API listening on ${this.options.port}`);
199
+ });
200
+ }
201
+ stop() {
202
+ if (!this.server) {
203
+ throw new Error('mock server not started');
204
+ }
205
+ this.server.close((error) => {
206
+ shared_1.logger.warn(error, 'problem closing server');
207
+ this.server = null;
208
+ });
209
+ }
210
+ }
211
+ exports.API = API;
212
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/api/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type * as Stuntman from '@stuntman/shared';
2
+ export declare const deserializeRule: (serializedRule: Stuntman.SerializedRule) => Stuntman.Rule;
3
+ export declare const escapedSerialize: (obj: any) => string;
4
+ export declare const liveRuleToRule: (liveRule: Stuntman.LiveRule) => Stuntman.Rule;
5
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/api/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAKlD,eAAO,MAAM,eAAe,mBAAoB,SAAS,cAAc,KAAG,SAAS,IAgDlF,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAS,GAAG,WAC2D,CAAC;AAErG,eAAO,MAAM,cAAc,aAAc,SAAS,QAAQ,kBASzD,CAAC"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.liveRuleToRule = exports.escapedSerialize = exports.deserializeRule = void 0;
7
+ const serialize_javascript_1 = __importDefault(require("serialize-javascript"));
8
+ const shared_1 = require("@stuntman/shared");
9
+ const validators_1 = require("./validators");
10
+ // TODO
11
+ const deserializeRule = (serializedRule) => {
12
+ shared_1.logger.debug(serializedRule, 'attempt to deserialize rule');
13
+ (0, validators_1.validateSerializedRuleProperties)(serializedRule);
14
+ const rule = {
15
+ id: serializedRule.id,
16
+ matches: (req) => new Function('____arg0', serializedRule.matches.remoteFn)(req),
17
+ ttlSeconds: serializedRule.ttlSeconds,
18
+ actions: { mockResponse: { status: 200 } },
19
+ ...(serializedRule.disableAfterUse !== undefined && { disableAfterUse: serializedRule.disableAfterUse }),
20
+ ...(serializedRule.removeAfterUse !== undefined && { removeAfterUse: serializedRule.removeAfterUse }),
21
+ ...(serializedRule.labels !== undefined && { labels: serializedRule.labels }),
22
+ ...(serializedRule.priority !== undefined && { priority: serializedRule.priority }),
23
+ ...(serializedRule.isEnabled !== undefined && { isEnabled: serializedRule.isEnabled }),
24
+ ...(serializedRule.storeTraffic !== undefined && { storeTraffic: serializedRule.storeTraffic }),
25
+ };
26
+ // TODO store the original localFn and variables sent from client for web UI editing maybe
27
+ if (serializedRule.actions.mockResponse) {
28
+ rule.actions = {
29
+ mockResponse: 'remoteFn' in serializedRule.actions.mockResponse
30
+ ? (req) => new Function('____arg0', serializedRule.actions.mockResponse.remoteFn)(req)
31
+ : serializedRule.actions.mockResponse,
32
+ };
33
+ }
34
+ else {
35
+ rule.actions = {
36
+ ...(serializedRule.actions.modifyRequest && {
37
+ modifyRequest: ((req) => new Function('____arg0', serializedRule.actions.modifyRequest.remoteFn)(req)),
38
+ }),
39
+ ...(serializedRule.actions.modifyResponse && {
40
+ modifyResponse: ((req, res) => new Function('____arg0', '____arg1', serializedRule.actions.modifyResponse.remoteFn)(req, res)),
41
+ }),
42
+ };
43
+ }
44
+ shared_1.logger.debug(rule, 'deserialized rule');
45
+ return rule;
46
+ };
47
+ exports.deserializeRule = deserializeRule;
48
+ const escapedSerialize = (obj) => (0, serialize_javascript_1.default)(obj).replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, "\\n'\n+ '");
49
+ exports.escapedSerialize = escapedSerialize;
50
+ const liveRuleToRule = (liveRule) => {
51
+ const ruleClone = { ...liveRule };
52
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
53
+ // @ts-ignore
54
+ delete ruleClone.counter;
55
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
56
+ // @ts-ignore
57
+ delete ruleClone.createdTimestamp;
58
+ return ruleClone;
59
+ };
60
+ exports.liveRuleToRule = liveRuleToRule;
61
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/api/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type * as Stuntman from '@stuntman/shared';
2
+ export declare const validateSerializedRuleProperties: (rule: Stuntman.SerializedRule) => void;
3
+ export declare const validateDeserializedRule: (deserializedRule: Stuntman.Rule) => void;
4
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/api/validators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,gCAAgC,SAAU,SAAS,cAAc,KAAG,IAmGhF,CAAC;AAEF,eAAO,MAAM,wBAAwB,qBAAsB,SAAS,IAAI,SA2BvE,CAAC"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateDeserializedRule = exports.validateSerializedRuleProperties = void 0;
4
+ const shared_1 = require("@stuntman/shared");
5
+ const validateSerializedRuleProperties = (rule) => {
6
+ if (!rule) {
7
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid serialized rule' });
8
+ }
9
+ if (typeof rule.id !== 'string') {
10
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.id' });
11
+ }
12
+ if (typeof rule.matches !== 'object' || !('remoteFn' in rule.matches) || typeof rule.matches.remoteFn !== 'string') {
13
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.matches' });
14
+ }
15
+ if (rule.priority && typeof rule.priority !== 'number') {
16
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.priority' });
17
+ }
18
+ if (typeof rule.actions !== 'object') {
19
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.actions - not an object' });
20
+ }
21
+ if (rule.actions.proxyPass !== true &&
22
+ typeof rule.actions.mockResponse !== 'object' &&
23
+ typeof rule.actions.modifyRequest !== 'object' &&
24
+ typeof rule.actions.modifyResponse !== 'object') {
25
+ throw new shared_1.AppError({
26
+ httpCode: shared_1.HttpCode.BAD_REQUEST,
27
+ message: 'invalid rule.actions - missing one of: proxyPass, mockResponse, modifyRequest, modifyResponse',
28
+ });
29
+ }
30
+ if (typeof rule.actions.mockResponse !== 'undefined') {
31
+ if (typeof rule.actions.mockResponse !== 'object') {
32
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.actions.mockResponse' });
33
+ }
34
+ if ('remoteFn' in rule.actions.mockResponse && typeof rule.actions.mockResponse.remoteFn !== 'string') {
35
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.actions.mockResponse' });
36
+ }
37
+ else if ('status' in rule.actions.mockResponse) {
38
+ if (typeof rule.actions.mockResponse.status !== 'number') {
39
+ throw new shared_1.AppError({
40
+ httpCode: shared_1.HttpCode.BAD_REQUEST,
41
+ message: 'invalid rule.actions.mockResponse.status',
42
+ });
43
+ }
44
+ if (typeof rule.actions.mockResponse.rawHeaders !== 'undefined' &&
45
+ (!Array.isArray(rule.actions.mockResponse.rawHeaders) ||
46
+ rule.actions.mockResponse.rawHeaders.some((header) => typeof header !== 'string'))) {
47
+ throw new shared_1.AppError({
48
+ httpCode: shared_1.HttpCode.BAD_REQUEST,
49
+ message: 'invalid rule.actions.mockResponse.rawHeaders',
50
+ });
51
+ }
52
+ if (typeof rule.actions.mockResponse.body !== 'undefined' && typeof rule.actions.mockResponse.body !== 'string') {
53
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.actions.mockResponse.body' });
54
+ }
55
+ }
56
+ }
57
+ if (typeof rule.actions.modifyRequest !== 'undefined' && typeof rule.actions.modifyRequest.remoteFn !== 'string') {
58
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.actions.modifyRequest' });
59
+ }
60
+ if (typeof rule.actions.modifyResponse !== 'undefined' && typeof rule.actions.modifyResponse.remoteFn !== 'string') {
61
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.actions.modifyResponse' });
62
+ }
63
+ if (typeof rule.disableAfterUse !== 'undefined' &&
64
+ typeof rule.disableAfterUse !== 'boolean' &&
65
+ (typeof rule.disableAfterUse !== 'number' || rule.disableAfterUse < 0)) {
66
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.disableAfterUse' });
67
+ }
68
+ if (typeof rule.removeAfterUse !== 'undefined' &&
69
+ typeof rule.removeAfterUse !== 'boolean' &&
70
+ (typeof rule.removeAfterUse !== 'number' || rule.removeAfterUse < 0)) {
71
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.removeAfterUse' });
72
+ }
73
+ if (typeof rule.labels !== 'undefined' &&
74
+ (!Array.isArray(rule.labels) || rule.labels.some((label) => typeof label !== 'string'))) {
75
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.labels' });
76
+ }
77
+ if (rule.actions.mockResponse && rule.actions.modifyResponse) {
78
+ throw new shared_1.AppError({
79
+ httpCode: shared_1.HttpCode.BAD_REQUEST,
80
+ message: 'rule.actions.mockResponse and rule.actions.modifyResponse are mutually exclusive',
81
+ });
82
+ }
83
+ if (!rule.ttlSeconds || rule.ttlSeconds < shared_1.MIN_RULE_TTL_SECONDS || rule.ttlSeconds > shared_1.MAX_RULE_TTL_SECONDS) {
84
+ throw new shared_1.AppError({
85
+ httpCode: shared_1.HttpCode.BAD_REQUEST,
86
+ message: `rule.ttlSeconds should be within ${shared_1.MIN_RULE_TTL_SECONDS} and ${shared_1.MAX_RULE_TTL_SECONDS}`,
87
+ });
88
+ }
89
+ if (typeof rule.isEnabled !== 'undefined' && typeof rule.isEnabled !== 'boolean') {
90
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.isEnabled' });
91
+ }
92
+ if (typeof rule.storeTraffic !== 'undefined' && typeof rule.storeTraffic !== 'boolean') {
93
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.BAD_REQUEST, message: 'invalid rule.storeTraffic' });
94
+ }
95
+ };
96
+ exports.validateSerializedRuleProperties = validateSerializedRuleProperties;
97
+ const validateDeserializedRule = (deserializedRule) => {
98
+ // TODO validate other functions ?
99
+ let matchValidationResult;
100
+ try {
101
+ matchValidationResult = deserializedRule.matches({
102
+ id: 'validation',
103
+ method: 'GET',
104
+ rawHeaders: new shared_1.RawHeaders(),
105
+ timestamp: Date.now(),
106
+ url: 'http://dummy.invalid/',
107
+ });
108
+ }
109
+ catch (error) {
110
+ shared_1.logger.error({ ruleId: deserializedRule.id }, error);
111
+ throw new shared_1.AppError({
112
+ httpCode: shared_1.HttpCode.UNPROCESSABLE_ENTITY,
113
+ message: 'match function threw an error',
114
+ });
115
+ }
116
+ if (matchValidationResult !== true &&
117
+ matchValidationResult !== false &&
118
+ matchValidationResult.result !== true &&
119
+ matchValidationResult.result !== false) {
120
+ shared_1.logger.error({ ruleId: deserializedRule.id, matchValidationResult }, 'match function retruned invalid value');
121
+ throw new shared_1.AppError({ httpCode: shared_1.HttpCode.UNPROCESSABLE_ENTITY, message: 'match function returned invalid value' });
122
+ }
123
+ };
124
+ exports.validateDeserializedRule = validateDeserializedRule;
125
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/api/validators.ts"],"names":[],"mappings":"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"}