diff --git a/src/utils/internal/cors.ts b/src/utils/internal/cors.ts index 4648e440..e47e26a1 100644 --- a/src/utils/internal/cors.ts +++ b/src/utils/internal/cors.ts @@ -79,17 +79,19 @@ export function createOriginHeaders( const { origin: originOption } = options; const origin = event.request.headers.get("origin"); - if (!origin || !originOption || originOption === "*") { + if (!originOption || originOption === "*") { return { "access-control-allow-origin": "*" }; } - if (typeof originOption === "string") { - return { "access-control-allow-origin": originOption, vary: "origin" }; + if (originOption === "null") { + return { "access-control-allow-origin": "null", vary: "origin" }; } - return isCorsOriginAllowed(origin, options) - ? { "access-control-allow-origin": origin, vary: "origin" } - : {}; + if (origin && isCorsOriginAllowed(origin, options)) { + return { "access-control-allow-origin": origin, vary: "origin" }; + } + + return {}; } /** diff --git a/test/unit/cors.test.ts b/test/unit/cors.test.ts index ebe85e7e..24b493f6 100644 --- a/test/unit/cors.test.ts +++ b/test/unit/cors.test.ts @@ -180,33 +180,35 @@ describe("cors (unit)", () => { describe("createOriginHeaders", () => { it('returns an object whose `access-control-allow-origin` is `"*"` if `origin` option is not defined, or `"*"`', () => { - const eventMock = mockEvent("/", { + const hasOriginEventMock = mockEvent("/", { method: "OPTIONS", headers: { origin: "https://example.com", }, }); - const options1: H3CorsOptions = {}; - const options2: H3CorsOptions = { + const noOriginEventMock = mockEvent("/", { + method: "OPTIONS", + headers: {}, + }); + const defaultOptions: H3CorsOptions = {}; + const originWildcardOptions: H3CorsOptions = { origin: "*", }; - expect(createOriginHeaders(eventMock, options1)).toEqual({ + expect(createOriginHeaders(hasOriginEventMock, defaultOptions)).toEqual({ "access-control-allow-origin": "*", }); - expect(createOriginHeaders(eventMock, options2)).toEqual({ + expect( + createOriginHeaders(hasOriginEventMock, originWildcardOptions), + ).toEqual({ "access-control-allow-origin": "*", }); - }); - - it('returns an object whose `access-control-allow-origin` is `"*"` if `origin` header is not defined', () => { - const eventMock = mockEvent("/", { - method: "OPTIONS", - headers: {}, + expect(createOriginHeaders(noOriginEventMock, defaultOptions)).toEqual({ + "access-control-allow-origin": "*", }); - const options: H3CorsOptions = {}; - - expect(createOriginHeaders(eventMock, options)).toEqual({ + expect( + createOriginHeaders(noOriginEventMock, originWildcardOptions), + ).toEqual({ "access-control-allow-origin": "*", }); }); @@ -235,6 +237,12 @@ describe("cors (unit)", () => { origin: "http://example.com", }, }); + const noMatchEventMock = mockEvent("/", { + method: "OPTIONS", + headers: { + origin: "http://example.test", + }, + }); const options1: H3CorsOptions = { origin: ["http://example.com"], }; @@ -246,10 +254,12 @@ describe("cors (unit)", () => { "access-control-allow-origin": "http://example.com", vary: "origin", }); + expect(createOriginHeaders(noMatchEventMock, options1)).toEqual({}); expect(createOriginHeaders(eventMock, options2)).toEqual({ "access-control-allow-origin": "http://example.com", vary: "origin", }); + expect(createOriginHeaders(noMatchEventMock, options2)).toEqual({}); }); it("returns an empty object if `origin` option is one that is not allowed", () => { @@ -269,6 +279,22 @@ describe("cors (unit)", () => { expect(createOriginHeaders(eventMock, options1)).toEqual({}); expect(createOriginHeaders(eventMock, options2)).toEqual({}); }); + + it("returns an empty object if `origin` option is not wildcard and `origin` header is not defined", () => { + const eventMock = mockEvent("/", { + method: "OPTIONS", + headers: {}, + }); + const options1: H3CorsOptions = { + origin: ["http://example.com"], + }; + const options2: H3CorsOptions = { + origin: () => false, + }; + + expect(createOriginHeaders(eventMock, options1)).toEqual({}); + expect(createOriginHeaders(eventMock, options2)).toEqual({}); + }); }); describe("createMethodsHeaders", () => {