import type { Handle } from '@sveltejs/kit'; import { sequence } from '@sveltejs/kit/hooks'; import { handleErrorWithSentry, sentryHandle } from '@sentry/sveltekit'; import * as Sentry from '@sentry/sveltekit'; import { PUBLIC_SENTRY_KEY, PUBLIC_SENTRY_PROJECT_ID, PUBLIC_SENTRY_ORG_ID } from '$env/static/public'; import { csp, rootDomain } from './cspDirectives'; Sentry.init({ dsn: `https://${PUBLIC_SENTRY_KEY}@${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/${PUBLIC_SENTRY_PROJECT_ID}`, tracesSampleRate: 1.0 }); export const cspHandle: Handle = async ({ event, resolve }) => { if (!csp) { throw new Error('csp is undefined'); } const response = await resolve(event); // Permission fullscreen necessary for maps fullscreen const headers = { 'X-Frame-Options': 'SAMEORIGIN', 'Referrer-Policy': 'no-referrer', 'Permissions-Policy': `accelerometer=(), autoplay=(), camera=(), document-domain=(self, 'js-profiling'), encrypted-media=(), fullscreen=(self ${rootDomain}), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), geolocation=()`, 'X-Content-Type-Options': 'nosniff', // 'Content-Security-Policy-Report-Only': csp, 'Content-Security-Policy': csp, 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'Expect-CT': `max-age=86400, report-uri="https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}"`, 'Report-To': `{group: "csp-endpoint", "max_age": 10886400, "endpoints": [{"url": "https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}"}]}` }; Object.entries(headers).forEach(([key, value]) => { response.headers.set(key, value); }); return response; }; // If you have custom handlers, make sure to place them after `sentryHandle()` in the `sequence` function. export const handle: Handle = sequence(sentryHandle(), cspHandle); // If you have a custom error handler, pass it to `handleErrorWithSentry` export const handleError = handleErrorWithSentry(); // https://gist.github.com/acoyfellow/d8e86979c66ebea25e1643594e38be73 // https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP // https://scotthelme.co.uk/content-security-policy-an-introduction/ // scanner: https://securityheaders.com/