import type { Handle } from '@sveltejs/kit' import { sequence } from '@sveltejs/kit/hooks' import { site } from '$lib/config/site' 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 } 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 ${PUBLIC_SITE_DOMAIN}), 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 } export const langHandle: Handle = async ({ event, resolve }) => await resolve(event, { transformPageChunk: ({ html }) => html.replace('', ``) }) // If you have custom handlers, make sure to place them after `sentryHandle()` in the `sequence` function. export const handle: Handle = sequence(sentryHandle(), cspHandle, langHandle) // 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/