1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | var __generator = (this && this.__generator) || function (thisArg, body) {
|
12 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
13 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
14 | function verb(n) { return function (v) { return step([n, v]); }; }
|
15 | function step(op) {
|
16 | if (f) throw new TypeError("Generator is already executing.");
|
17 | while (_) try {
|
18 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
19 | if (y = 0, t) op = [op[0] & 2, t.value];
|
20 | switch (op[0]) {
|
21 | case 0: case 1: t = op; break;
|
22 | case 4: _.label++; return { value: op[1], done: false };
|
23 | case 5: _.label++; y = op[1]; op = [0]; continue;
|
24 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
25 | default:
|
26 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
27 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
28 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
29 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
30 | if (t[2]) _.ops.pop();
|
31 | _.trys.pop(); continue;
|
32 | }
|
33 | op = body.call(thisArg, _);
|
34 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
35 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
36 | }
|
37 | };
|
38 | Object.defineProperty(exports, "__esModule", { value: true });
|
39 | var logger_1 = require("@bitblit/ratchet/dist/common/logger");
|
40 | var http = require("http");
|
41 | var web_handler_1 = require("./api-gateway/web-handler");
|
42 | var promise_ratchet_1 = require("@bitblit/ratchet/dist/common/promise-ratchet");
|
43 | var string_ratchet_1 = require("@bitblit/ratchet/dist/common/string-ratchet");
|
44 | var moment = require("moment-timezone");
|
45 | var qs = require("querystring");
|
46 | var simple_role_route_auth_1 = require("./api-gateway/auth/simple-role-route-auth");
|
47 | var router_util_1 = require("./api-gateway/route/router-util");
|
48 | var fs = require("fs");
|
49 | var path = require("path");
|
50 | var built_in_handlers_1 = require("./api-gateway/route/built-in-handlers");
|
51 | var epsilon_constants_1 = require("./epsilon-constants");
|
52 |
|
53 |
|
54 |
|
55 | var LocalServer = (function () {
|
56 | function LocalServer(routerConfig, port) {
|
57 | if (port === void 0) { port = 8888; }
|
58 | this.routerConfig = routerConfig;
|
59 | this.port = port;
|
60 | this.aborted = false;
|
61 | this.webHandler = new web_handler_1.WebHandler(routerConfig);
|
62 | }
|
63 | LocalServer.prototype.runServer = function () {
|
64 | return __awaiter(this, void 0, void 0, function () {
|
65 | var _this = this;
|
66 | return __generator(this, function (_a) {
|
67 | logger_1.Logger.info('Starting Epsilon server on port %d', this.port);
|
68 | this.server = http.createServer(this.requestHandler.bind(this)).listen(this.port);
|
69 | logger_1.Logger.info('Epsilon server is listening');
|
70 |
|
71 | process.on('SIGINT', function () {
|
72 | logger_1.Logger.info('Caught SIGINT - shutting down test server...');
|
73 | _this.aborted = true;
|
74 | });
|
75 | return [2 , this.checkFinished()];
|
76 | });
|
77 | });
|
78 | };
|
79 | LocalServer.prototype.checkFinished = function () {
|
80 | return __awaiter(this, void 0, void 0, function () {
|
81 | var wait;
|
82 | return __generator(this, function (_a) {
|
83 | switch (_a.label) {
|
84 | case 0:
|
85 | if (!this.aborted) return [3 , 1];
|
86 | return [2 , true];
|
87 | case 1: return [4 , promise_ratchet_1.PromiseRatchet.wait(1000)];
|
88 | case 2:
|
89 | wait = _a.sent();
|
90 | return [2 , this.checkFinished()];
|
91 | }
|
92 | });
|
93 | });
|
94 | };
|
95 | LocalServer.prototype.requestHandler = function (request, response) {
|
96 | return __awaiter(this, void 0, void 0, function () {
|
97 | var evt, context, result, written;
|
98 | return __generator(this, function (_a) {
|
99 | switch (_a.label) {
|
100 | case 0: return [4 , this.messageToApiGatewayEvent(request)];
|
101 | case 1:
|
102 | evt = _a.sent();
|
103 | context = {};
|
104 | logger_1.Logger.info('Processing event: %j', evt);
|
105 | if (!(evt.path == '/epsilon-poison-pill')) return [3 , 2];
|
106 | this.aborted = true;
|
107 | return [2 , true];
|
108 | case 2: return [4 , this.webHandler.lambdaHandler(evt, context)];
|
109 | case 3:
|
110 | result = _a.sent();
|
111 | return [4 , this.writeProxyResultToServerResponse(result, response)];
|
112 | case 4:
|
113 | written = _a.sent();
|
114 | return [2 , written];
|
115 | }
|
116 | });
|
117 | });
|
118 | };
|
119 | LocalServer.prototype.bodyAsBase64String = function (request) {
|
120 | return __awaiter(this, void 0, void 0, function () {
|
121 | return __generator(this, function (_a) {
|
122 | return [2 , new Promise(function (res, rej) {
|
123 | var body = [];
|
124 | request.on('data', function (chunk) {
|
125 | body.push(chunk);
|
126 | });
|
127 | request.on('end', function () {
|
128 | var rval = Buffer.concat(body).toString('base64');
|
129 | res(rval);
|
130 | });
|
131 | })];
|
132 | });
|
133 | });
|
134 | };
|
135 | LocalServer.prototype.messageToApiGatewayEvent = function (request) {
|
136 | return __awaiter(this, void 0, void 0, function () {
|
137 | var bodyString, stageIdx, stage, path, reqTime, formattedTime, queryIdx, queryStringParams, headers, rval;
|
138 | return __generator(this, function (_a) {
|
139 | switch (_a.label) {
|
140 | case 0: return [4 , this.bodyAsBase64String(request)];
|
141 | case 1:
|
142 | bodyString = _a.sent();
|
143 | stageIdx = request.url.indexOf('/', 1);
|
144 | stage = request.url.substring(1, stageIdx);
|
145 | path = request.url.substring(stageIdx + 1);
|
146 | reqTime = new Date().getTime();
|
147 | formattedTime = moment.tz(reqTime, 'UTC').format('DD/MMM/YYYY:hh:mm:ss ZZ');
|
148 | queryIdx = request.url.indexOf('?');
|
149 | queryStringParams = (queryIdx > -1) ? qs.parse(request.url.substring(queryIdx + 1)) : {};
|
150 | headers = Object.assign({}, request.headers);
|
151 | headers['X-Forwarded-Proto'] = 'http';
|
152 | rval = {
|
153 | body: bodyString,
|
154 | multiValueHeaders: {},
|
155 | multiValueQueryStringParameters: {},
|
156 | resource: '/{proxy+}',
|
157 | path: request.url,
|
158 | httpMethod: request.method.toLowerCase(),
|
159 | isBase64Encoded: true,
|
160 | queryStringParameters: queryStringParams,
|
161 | pathParameters: {
|
162 | proxy: path
|
163 | },
|
164 | stageVariables: {
|
165 | baz: 'qux'
|
166 | },
|
167 | headers: headers,
|
168 | requestContext: {
|
169 | accountId: '123456789012',
|
170 | resourceId: '123456',
|
171 | stage: stage,
|
172 | requestId: string_ratchet_1.StringRatchet.createType4Guid(),
|
173 | requestTime: formattedTime,
|
174 | requestTimeEpoch: reqTime,
|
175 | identity: null,
|
176 | |
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 | path: request.url,
|
193 | domainName: request.headers['host'],
|
194 | resourcePath: '/{proxy+}',
|
195 | httpMethod: request.method.toLowerCase(),
|
196 | apiId: '1234567890',
|
197 | protocol: 'HTTP/1.1'
|
198 | }
|
199 | };
|
200 | return [2 , rval];
|
201 | }
|
202 | });
|
203 | });
|
204 | };
|
205 | LocalServer.prototype.writeProxyResultToServerResponse = function (proxyResult, response) {
|
206 | return __awaiter(this, void 0, void 0, function () {
|
207 | var isGraphQLSchemaResponse, toWrite;
|
208 | return __generator(this, function (_a) {
|
209 | isGraphQLSchemaResponse = (!!proxyResult && !!proxyResult.body && proxyResult.body.indexOf('{\"data\":{\"__schema\"') > -1);
|
210 | if (!isGraphQLSchemaResponse) {
|
211 | logger_1.Logger.debug('Result: %j', proxyResult);
|
212 | }
|
213 | response.statusCode = proxyResult.statusCode;
|
214 | if (proxyResult.headers) {
|
215 | Object.keys(proxyResult.headers).forEach(function (hk) {
|
216 | response.setHeader(hk, String(proxyResult.headers[hk]));
|
217 | });
|
218 | }
|
219 | toWrite = (proxyResult.isBase64Encoded) ? Buffer.from(proxyResult.body, 'base64') : Buffer.from(proxyResult.body);
|
220 | response.end(toWrite);
|
221 | return [2 , !!proxyResult.body];
|
222 | });
|
223 | });
|
224 | };
|
225 | return LocalServer;
|
226 | }());
|
227 | exports.LocalServer = LocalServer;
|
228 |
|
229 | function createSampleRouterConfig() {
|
230 | var yamlString = loadSampleOpenApiYaml();
|
231 | var authorizers = new Map();
|
232 | var handlers = new Map();
|
233 | var simpleRouteAuth = new simple_role_route_auth_1.SimpleRoleRouteAuth(['USER'], []);
|
234 | authorizers.set('SampleAuthorizer', function (token, event, route) { return simpleRouteAuth.handler(token, event, route); });
|
235 | handlers.set('get /', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
236 | handlers.set('get /meta/server', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
237 | handlers.set('get /meta/user', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
238 | handlers.set('get /meta/item/{itemId}', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
239 | handlers.set('post /secure/access-token', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
240 | handlers.set('get /multi/fixed', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event, 'fixed'); });
|
241 | handlers.set('get /multi/{v}', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event, 'variable'); });
|
242 | handlers.set('get /err/{code}', function (event) { throw new Error('Fake err: ' + JSON.stringify(event)); });
|
243 | var cfg = router_util_1.RouterUtil.openApiYamlToRouterConfig(yamlString, handlers, authorizers);
|
244 | cfg.corsAllowedHeaders = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
|
245 | cfg.corsAllowedOrigins = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
|
246 | cfg.corsAllowedMethods = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
|
247 | return cfg;
|
248 | }
|
249 | exports.createSampleRouterConfig = createSampleRouterConfig;
|
250 | function loadSampleOpenApiYaml() {
|
251 | var yamlString = fs.readFileSync(path.join(__dirname, 'static', 'sample-open-api-doc.yaml')).toString();
|
252 | return yamlString;
|
253 | }
|
254 | exports.loadSampleOpenApiYaml = loadSampleOpenApiYaml;
|
255 |
|
\ | No newline at end of file |