From 5057d3491ed046de041c9eb758fde4bc2fce4d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miszczyszyn?= Date: Tue, 11 Apr 2023 15:03:50 +0200 Subject: [PATCH] Support comma-delimited x-forwarded-proto (#227) * Support comma-delimited x-forwarded-proto * Changeset --- .changeset/cool-knives-punch.md | 5 +++++ src/headers.ts | 10 +++++++++- src/middleware/with-base-url.test.ts | 30 ++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 .changeset/cool-knives-punch.md diff --git a/.changeset/cool-knives-punch.md b/.changeset/cool-knives-punch.md new file mode 100644 index 00000000..0a19f686 --- /dev/null +++ b/.changeset/cool-knives-punch.md @@ -0,0 +1,5 @@ +--- +"@saleor/app-sdk": patch +--- + +Support comma-delimited x-forwarded-proto diff --git a/src/headers.ts b/src/headers.ts index c0a48edf..c0759fc6 100644 --- a/src/headers.ts +++ b/src/headers.ts @@ -18,6 +18,14 @@ export const getSaleorHeaders = (headers: { [name: string]: string | string[] | }); export const getBaseUrl = (headers: { [name: string]: string | string[] | undefined }): string => { - const { host, "x-forwarded-proto": protocol = "http" } = headers; + const { host, "x-forwarded-proto": xForwardedProto = "http" } = headers; + + const xForwardedProtos = Array.isArray(xForwardedProto) + ? xForwardedProto.join(",") + : xForwardedProto; + const protocols = xForwardedProtos.split(","); + // prefer https over other protocols + const protocol = protocols.find((el) => el === "https") || protocols[0]; + return `${protocol}://${host}`; }; diff --git a/src/middleware/with-base-url.test.ts b/src/middleware/with-base-url.test.ts index 5ba4b8fd..a0f4ea4b 100644 --- a/src/middleware/with-base-url.test.ts +++ b/src/middleware/with-base-url.test.ts @@ -28,5 +28,35 @@ describe("middleware", () => { expect(mockRequest.context.baseURL).toBe("https://my-saleor-env.saleor.cloud"); expect(mockHandlerFn).toHaveBeenCalledOnce(); }); + + it("supports multiple comma-delimited values in x-forwarded-proto", async () => { + const mockRequest = { + context: {}, + headers: { + host: "my-saleor-env.saleor.cloud", + "x-forwarded-proto": "https,http", + }, + } as unknown as Request; + + await withBaseURL(mockHandlerFn)(mockRequest); + + expect(mockRequest.context.baseURL).toBe("https://my-saleor-env.saleor.cloud"); + expect(mockHandlerFn).toHaveBeenCalledOnce(); + }); + + it("supports multiple x-forwarded-proto headers", async () => { + const mockRequest = { + context: {}, + headers: { + host: "my-saleor-env.saleor.cloud", + "x-forwarded-proto": ["http", "ftp,https"], + }, + } as unknown as Request; + + await withBaseURL(mockHandlerFn)(mockRequest); + + expect(mockRequest.context.baseURL).toBe("https://my-saleor-env.saleor.cloud"); + expect(mockHandlerFn).toHaveBeenCalledOnce(); + }); }); });