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/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/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/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'", ); }); }); 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", },