From 05b8884e0af0e72a71c15a7049bc4aac3260884a Mon Sep 17 00:00:00 2001 From: Lee Cheneler Date: Tue, 11 Feb 2025 17:26:18 +0000 Subject: [PATCH 1/3] ci: version bump --- deno.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deno.json b/deno.json index 8fffe95..72fa8f4 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@mage/server", - "version": "0.14.1", + "version": "0.14.2", "license": "MIT", "exports": "./mod.ts", "tasks": { From e9423ad8d181a90b71e03e571d4538112efe6bd2 Mon Sep 17 00:00:00 2001 From: Lee Cheneler Date: Tue, 11 Feb 2025 17:33:46 +0000 Subject: [PATCH 2/3] ci: fix serve files middleware --- README.md | 5 +---- deno.json | 2 +- src/middleware/serve-files.ts | 2 +- tests/middleware/serve-files.test.ts | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3cd8778..bd5cdaa 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,9 @@ ## Installation ```sh -deno add jsr:@mage/server npm:preact@10.22.1 +deno add jsr:@mage/server npm:preact ``` -**NB: its important we're in sync with the version of Preact that we're using or -Context API won't work.** - ## Getting started Minimum TypeScript compiler options: diff --git a/deno.json b/deno.json index 72fa8f4..94ff673 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@mage/server", - "version": "0.14.2", + "version": "0.14.3", "license": "MIT", "exports": "./mod.ts", "tasks": { diff --git a/src/middleware/serve-files.ts b/src/middleware/serve-files.ts index c7c3328..7ba3fa2 100644 --- a/src/middleware/serve-files.ts +++ b/src/middleware/serve-files.ts @@ -55,7 +55,7 @@ export const useServeFiles = ( // Resolve filepath and remove the buildId from the path if it exists let filepath = resolve(options.directory, context.wildcard).replace( - `.${context.buildId}`, + `-${context.buildId}`, "", ); diff --git a/tests/middleware/serve-files.test.ts b/tests/middleware/serve-files.test.ts index 8bbf8c6..8b85111 100644 --- a/tests/middleware/serve-files.test.ts +++ b/tests/middleware/serve-files.test.ts @@ -146,7 +146,7 @@ describe("middleware - serve file", () => { describe("cache busting with build id", () => { it("should return file when it exists with build id suffixed", async () => { const response = await fetch( - server.url(`/public/image.png.${server.app.buildId}`), + server.url(`/public/image-${server.app.buildId}.png`), { method: "GET", }, From c227cd1effbc268493f04210ddea6c8cf000442c Mon Sep 17 00:00:00 2001 From: Lee Cheneler Date: Tue, 11 Feb 2025 17:38:26 +0000 Subject: [PATCH 3/3] fix: applying default safe csp options --- src/headers/content-security-policy.ts | 19 ++++++++++++++++++- tests/headers/content-security-policy.test.ts | 6 +++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/headers/content-security-policy.ts b/src/headers/content-security-policy.ts index 481e8fd..8a69f96 100644 --- a/src/headers/content-security-policy.ts +++ b/src/headers/content-security-policy.ts @@ -69,7 +69,24 @@ export const contentSecurityPolicy = ( context: MageContext, options: ContentSecurityPolicyOptions, ): void => { - const header = Object.entries(options.directives) + const defaultDirectives = { + defaultSrc: ["'self'"], + baseUri: ["'self'"], + fontSrc: ["'self'", "https:", "data:"], + formAction: ["'self'"], + frameAncestors: ["'self'"], + imgSrc: ["'self'", "data:"], + objectSrc: ["'none'"], + scriptSrc: ["'self'"], + scriptSrcAttr: ["'none'"], + styleSrc: ["'self'", "https:", "'unsafe-inline'"], + upgradeInsecureRequests: true, + }; + + const header = Object.entries({ + ...defaultDirectives, + ...options.directives, + }) .map(([key, value]) => { const directive = directiveKeyMap[ key as keyof ContentSecurityPolicyOptions["directives"] diff --git a/tests/headers/content-security-policy.test.ts b/tests/headers/content-security-policy.test.ts index 52593dc..25be9fe 100644 --- a/tests/headers/content-security-policy.test.ts +++ b/tests/headers/content-security-policy.test.ts @@ -58,7 +58,7 @@ describe("headers - content-security-policy", () => { await response.text(); expect(response.headers.get("Content-Security-Policy")).toEqual( - "default-src 'self';script-src 'self' https://example.com", + "default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self' https://example.com;script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests", ); }); @@ -74,7 +74,7 @@ describe("headers - content-security-policy", () => { await response.text(); expect(response.headers.get("Content-Security-Policy")).toEqual( - "default-src 'self';upgrade-insecure-requests", + "default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests", ); }); @@ -90,7 +90,7 @@ describe("headers - content-security-policy", () => { await response.text(); expect(response.headers.get("Content-Security-Policy")).toEqual( - "default-src 'self'", + "default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline'", ); }); });