From dd64dffa4d2efc21d24ff70c030234846fd9e057 Mon Sep 17 00:00:00 2001
From: Jay Malhotra <5047192+SapiensAnatis@users.noreply.github.com>
Date: Sat, 18 Jan 2025 13:28:32 +0000
Subject: [PATCH] Add Content-Security-Policy (#1229)
The mode-watcher bug causing a flash of light mode has been fixed so we
can now add a CSP.
Still need to add an additional directive due to a Svelte bug
---
Website/playwright.config.ts | 3 ++-
Website/src/app.html | 3 +++
Website/src/hooks.server.ts | 18 +++++++++++++++++-
Website/src/routes/(main)/+layout.svelte | 2 +-
Website/src/routes/csp/+server.ts | 9 +++++++++
Website/svelte.config.js | 22 ++++++++++++++++------
6 files changed, 48 insertions(+), 9 deletions(-)
create mode 100644 Website/src/routes/csp/+server.ts
diff --git a/Website/playwright.config.ts b/Website/playwright.config.ts
index b0061f824..9d053cfa1 100644
--- a/Website/playwright.config.ts
+++ b/Website/playwright.config.ts
@@ -9,7 +9,8 @@ const config: PlaywrightTestConfig = {
timeout: 120000
},
use: {
- baseURL: 'http://localhost:3001'
+ baseURL: 'http://localhost:3001',
+ bypassCSP: true
},
updateSnapshots: process.env.UPDATE_SNAPSHOTS ? 'all' : 'missing',
ignoreSnapshots: !process.env.CI,
diff --git a/Website/src/app.html b/Website/src/app.html
index 4133ffafd..dd4f33e3a 100644
--- a/Website/src/app.html
+++ b/Website/src/app.html
@@ -11,6 +11,9 @@
Dawnshard
%sveltekit.head%
+
%sveltekit.body%
diff --git a/Website/src/hooks.server.ts b/Website/src/hooks.server.ts
index 9d8e4e27f..1156ea760 100644
--- a/Website/src/hooks.server.ts
+++ b/Website/src/hooks.server.ts
@@ -1,6 +1,8 @@
import { randomUUID } from 'node:crypto';
import type { Handle, HandleFetch, HandleServerError } from '@sveltejs/kit';
+import { sequence } from '@sveltejs/kit/hooks';
+import { generateSetInitialModeExpression } from 'mode-watcher';
import { env } from '$env/dynamic/private';
import { PUBLIC_ENABLE_MSW } from '$env/static/public';
@@ -50,12 +52,24 @@ export const handleFetch: HandleFetch = ({ request, event, fetch }) => {
return fetch(request);
};
-export const handle: Handle = ({ event, resolve }) => {
+const handleHeadScript: Handle = ({ event, resolve }) => {
+ return resolve(event, {
+ transformPageChunk: ({ html }) => {
+ return html.replace('%modewatcher.snippet%', generateSetInitialModeExpression({}));
+ }
+ });
+};
+
+const handleLogger: Handle = ({ event, resolve }) => {
event.locals.logger = createLogger({
requestPath: new URL(event.request.url).pathname,
requestId: randomUUID()
});
+ return resolve(event);
+};
+
+const handleAuth: Handle = ({ event, resolve }) => {
const idToken = event.cookies.get(Cookies.IdToken);
if (!idToken) {
@@ -77,6 +91,8 @@ export const handle: Handle = ({ event, resolve }) => {
return resolve(event);
};
+export const handle = sequence(handleHeadScript, handleLogger, handleAuth);
+
export const handleError: HandleServerError = ({ error, event, status, message }) => {
event.locals.logger.error({ error, status, message }, 'Unhandled error occurred: {message}');
};
diff --git a/Website/src/routes/(main)/+layout.svelte b/Website/src/routes/(main)/+layout.svelte
index c281de385..9501c6ed8 100644
--- a/Website/src/routes/(main)/+layout.svelte
+++ b/Website/src/routes/(main)/+layout.svelte
@@ -14,7 +14,7 @@
-
+
diff --git a/Website/src/routes/csp/+server.ts b/Website/src/routes/csp/+server.ts
new file mode 100644
index 000000000..759be0504
--- /dev/null
+++ b/Website/src/routes/csp/+server.ts
@@ -0,0 +1,9 @@
+import type { RequestHandler } from './$types';
+
+export const POST: RequestHandler = async ({ locals, request }) => {
+ const violation = await request.json();
+
+ locals.logger.error({ violation }, 'CSP violation reported: {violation}');
+
+ return new Response(null, { status: 200 });
+};
diff --git a/Website/svelte.config.js b/Website/svelte.config.js
index 0f8797ad7..a440cd302 100644
--- a/Website/svelte.config.js
+++ b/Website/svelte.config.js
@@ -1,6 +1,13 @@
import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
+const scriptCsp = [
+ 'self',
+ // https://github.com/sveltejs/svelte/issues/14014
+ 'unsafe-hashes',
+ 'sha256-7dQwUgLau1NFCCGjfn9FsYptB6ZtWxJin6VohGIu20I='
+];
+
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
@@ -13,13 +20,16 @@ const config = {
$shadcn: './src/lib/shadcn',
$static: './static',
$main: './src/routes/(main)'
+ },
+ csp: {
+ directives: {
+ 'script-src': scriptCsp
+ },
+ reportOnly: {
+ 'script-src': scriptCsp,
+ 'report-uri': ['/csp']
+ }
}
- // Blocked by https://github.com/svecosystem/mode-watcher/issues/92
- // csp: {
- // directives: {
- // 'script-src': ['self']
- // }
- // }
}
};