UNPKG

@webda/aws

Version:

Webda AWS Services implementation

417 lines 16.4 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { suite, test } from "@testdeck/mocha"; import { Bean, getCommonJS, HttpContext, Route, Service, WebdaError } from "@webda/core"; import { TestApplication } from "@webda/core/lib/test.js"; import * as assert from "assert"; import * as fs from "fs"; import { checkLocalStack, WebdaAwsTest } from "../index.spec.js"; import { LambdaServer } from "./lambdaserver.js"; const { __dirname } = getCommonJS(import.meta.url); let ExceptionExecutor = class ExceptionExecutor extends Service { initRoutes() { super.initRoutes(); this.addRoute("/broken/{type}", ["GET"], this._brokenRoute); this.addRoute("/route/string", ["GET"], this.onString); } async _brokenRoute(ctx) { if (ctx.parameters.type === "unauthorized") { throw new WebdaError.Unauthorized("OnPurpose"); } else if (ctx.parameters.type === "401") { throw 401; } else if (ctx.parameters.type === "Error") { throw new Error(); } } async onString(ctx) { ctx.write(`CodeCoverage${ctx.getParameters().test || ""}`); } async onParamString(ctx) { ctx.write(`CodeCoverage${ctx.getParameters().uuid}${ctx.getParameters().test || ""}`); } }; __decorate([ Route("/route/broken/{type}") ], ExceptionExecutor.prototype, "_brokenRoute", null); __decorate([ Route("/route/string{?test}") ], ExceptionExecutor.prototype, "onString", null); __decorate([ Route("/route/param/{uuid}{?test?}") ], ExceptionExecutor.prototype, "onParamString", null); ExceptionExecutor = __decorate([ Bean ], ExceptionExecutor); let LambdaHandlerTest = class LambdaHandlerTest extends WebdaAwsTest { constructor() { super(...arguments); this.context = {}; this.badCheck = false; } async before() { await checkLocalStack(); let app = new TestApplication(this.getTestConfiguration()); app.addService("Test/AWSEvents", (await import("../../test/moddas/awsevents.js")).AWSEventsHandler); await app.load(); this.webda = this.handler = new LambdaServer(app); await this.webda.init(); this.webda.registerRequestFilter({ checkRequest: async () => true }); this.evt = { httpMethod: "GET", headers: { Cookie: "webda=plop;", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, requestContext: { identity: {} }, path: "/prefix/route/string", resource: "/route/string", body: JSON.stringify({}) }; this.debugMailer = this.handler.getService("DebugMailer"); } async checkRequestNoRequestFilter() { await this.handler.init(); // @ts-ignore this.handler._requestFilters = []; this.ensureGoodCSRF(); this.evt.queryStringParameters = { test: "Plop" }; let res = await this.handler.handleRequest(this.evt, this.context); // No filter return ok now assert.strictEqual(res.statusCode, 200); } async checkRequestRefusedRequest() { await this.handler.init(); // @ts-ignore this.handler._requestFilters = []; this.ensureGoodCSRF(); this.evt.queryStringParameters = { test: "Plop" }; this.handler.registerRequestFilter({ checkRequest: async () => false }); let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 403); } async checkRequestRedirect() { await this.handler.init(); // @ts-ignore this.handler._requestFilters = []; this.ensureGoodCSRF(); this.evt.queryStringParameters = { test: "Plop" }; this.handler.registerRequestFilter({ checkRequest: async () => { throw new WebdaError.Redirect("Need Auth", "https://google.com"); } }); let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 302); console.log(res); assert.strictEqual(res.headers.Location, "https://google.com"); } async handleRequestCustomLaunch() { await this.handler.handleRequest({ command: "launch", service: "DebugMailer", method: "send", args: ["test"] }, undefined); assert.strictEqual(this.debugMailer.sent[0], "test"); } async handleRequestCustomLaunchBadService() { await this.handler.handleRequest({ command: "launch", service: "DebugMailers", method: "send", args: ["test"] }, undefined); assert.strictEqual(this.debugMailer.sent.length, 0); } async handleRequestCustomLaunchBadMethod() { await this.handler.handleRequest({ command: "launch", service: "DebugMailer", method: "sends" }, undefined); assert.strictEqual(this.debugMailer.sent.length, 0); } async handleRequestKnownRoute() { this.ensureGoodCSRF(); let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.body, "CodeCoverage"); } async handleRequestIdHeader() { this.ensureGoodCSRF(); this.handler.getConfiguration().parameters.lambdaRequestHeader = "x-webda-request-id"; let res = await this.handler.handleRequest(this.evt, { ...this.context, awsRequestId: "toto" }); assert.strictEqual(res.body, "CodeCoverage"); assert.strictEqual(res.headers["x-webda-request-id"], "toto"); } async handleRequestKnownRouteWithParamAndQuery() { this.ensureGoodCSRF(); this.evt.queryStringParameters = { test: "Plop" }; this.evt.path = "/prefix/route/param/myid"; this.evt.resource = "/route/param/{uuid}"; this.evt.pathParameters = { uuid: "myid" }; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.body, "CodeCoveragemyidPlop"); } async handleRequestKnownRouteWithParam() { this.ensureGoodCSRF(); this.evt.path = "/prefix/route/param/myid"; this.evt.resource = "/route/param/{uuid}"; this.evt.pathParameters = { uuid: "myid" }; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.body, "CodeCoveragemyid"); } async handleRequestKnownRouteWithQuery() { this.ensureGoodCSRF(); this.evt.queryStringParameters = { test: "Plop" }; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.body, "CodeCoveragePlop"); } async handleRequestUnknownRoute() { this.ensureGoodCSRF(); this.evt.path = "/route/unknown"; this.evt.resource = "/route/unknown"; delete this.evt.headers.Cookie; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 404); } async handleRequestThrow401() { this.ensureGoodCSRF(); this.evt.path = "/route/broken/401"; this.evt.resource = "/route/broken/401"; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 401); this.evt.path = "/route/broken/unauthorized"; this.evt.resource = "/route/broken/unauthorized"; res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 401); } async handleRequestThrowError() { this.ensureGoodCSRF(); this.evt.path = "/route/broken/Error"; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 500); } async handleRequestOPTIONS() { this.ensureGoodCSRF(); this.evt.httpMethod = "OPTIONS"; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 204); assert.strictEqual(res.headers["Access-Control-Allow-Methods"], "GET,OPTIONS"); } async handleRequestOPTIONSWith404() { this.ensureGoodCSRF(); this.evt.path = "/route/unknown"; this.evt.httpMethod = "OPTIONS"; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 404); } async cov() { this.ensureGoodCSRF(); this.evt.headers["X-Forwarded-Port"] = "wew"; this.evt.headers["Content-Type"] = "text/plain"; this.evt.body = "{wew''"; // Should fallback on port 443 await this.handler.handleRequest(this.evt, this.context); } async handleRequestQueryParams() { // TODO Check parameter retrieval this.evt.queryStringParameters = { test: "plop" }; this.evt.headers.Origin = "https://test.webda.io"; this.evt.headers.Host = "test.webda.io"; await this.handler.handleRequest(this.evt, this.context); } async handleRequestOrigin() { this.evt.headers.Origin = "https://test.webda.io"; this.evt.headers.Host = "test.webda.io"; let wait = false; this.handler.on("Webda.Result", () => { return new Promise((resolve, reject) => { // Delay 100ms to ensure it waited setTimeout(() => { wait = true; resolve(); }, 100); }); }); let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.headers["Access-Control-Allow-Origin"], this.evt.headers.Origin); assert.strictEqual(wait, true); } async handleRequestOriginCSRF() { this.evt.headers.Origin = "https://test3.webda.io"; this.evt.headers.Host = "test3.webda.io"; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 401); } async handleRequestRefererCSRF() { this.evt.headers.Referer = "https://test3.webda.io"; this.evt.headers.Host = "test3.webda.io"; this.evt.headers.origin = "test3.webda.io"; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 401); } async handleRequestRefererNoCORS() { // No more fallback on referer for CORS // BUt request should be served as no CORS is requested (lack of Origin) this.evt.headers.Referer = "https://test.webda.io"; this.evt.headers.Host = "test.webda.io"; let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.headers["Access-Control-Allow-Origin"], undefined); assert.strictEqual(res.statusCode, 200); } async handleRequestHardStopCheckRequest() { this.evt.headers.Referer = "https://test.webda.io"; this.evt.headers.Host = "test.webda.io"; this.handler.registerRequestFilter(this); let res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 410); this.badCheck = true; res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 500); this.newExcept = true; res = await this.handler.handleRequest(this.evt, this.context); assert.strictEqual(res.statusCode, 429); } async checkRequest() { if (this.newExcept) { throw new WebdaError.TooManyRequests("Too many requests"); } if (this.badCheck) { throw new Error("Unknown"); } throw 410; } ensureGoodCSRF() { this.evt.headers.Origin = "https://test.webda.io"; this.evt.headers.Host = "test.webda.io"; } async awsEvents() { let service = this.handler.getService("awsEvents"); let files = fs.readdirSync(__dirname + "/../../test/aws-events"); for (let f in files) { let file = files[f]; let event = JSON.parse(fs.readFileSync(__dirname + "/../../test/aws-events/" + file).toString()); await this.handler.handleRequest(event, this.context); if (file === "api-gateway-aws-proxy.json") { assert.strictEqual(service.getEvents().length, 0, "API Gateway should go through the normal request handling"); } else { assert.notStrictEqual(service.getEvents().length, 0, "Should have get some events:" + JSON.stringify(event)); } } } /** * Wildcard path from API Gateway were missing the prefix * * @see https://github.com/loopingz/webda.io/issues/193 */ async computePrefix() { let httpContext = new HttpContext("test.webda.io", "GET", "/prefix/static1234/test/subfolder/index.html"); this.handler.computePrefix({ path: "/prefix/static1234/test/subfolder/index.html", resource: "/static1234/{path+}", pathParameters: { path: "test/subfolder/index.html" } }, httpContext); assert.strictEqual(httpContext.getRelativeUri(), "/static1234/test/subfolder/index.html"); assert.strictEqual(httpContext.prefix, "/prefix"); } }; __decorate([ test ], LambdaHandlerTest.prototype, "checkRequestNoRequestFilter", null); __decorate([ test ], LambdaHandlerTest.prototype, "checkRequestRefusedRequest", null); __decorate([ test ], LambdaHandlerTest.prototype, "checkRequestRedirect", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestCustomLaunch", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestCustomLaunchBadService", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestCustomLaunchBadMethod", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestKnownRoute", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestIdHeader", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestKnownRouteWithParamAndQuery", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestKnownRouteWithParam", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestKnownRouteWithQuery", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestUnknownRoute", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestThrow401", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestThrowError", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestOPTIONS", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestOPTIONSWith404", null); __decorate([ test ], LambdaHandlerTest.prototype, "cov", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestQueryParams", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestOrigin", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestOriginCSRF", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestRefererCSRF", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestRefererNoCORS", null); __decorate([ test ], LambdaHandlerTest.prototype, "handleRequestHardStopCheckRequest", null); __decorate([ test ], LambdaHandlerTest.prototype, "awsEvents", null); __decorate([ test ], LambdaHandlerTest.prototype, "computePrefix", null); LambdaHandlerTest = __decorate([ suite ], LambdaHandlerTest); //# sourceMappingURL=lambdaserver.spec.js.map