From 19565349755d7c5cf97391e9d79f530f6b249e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20K?= <51174697+DanCodernaut@users.noreply.github.com> Date: Tue, 13 May 2025 17:20:13 +0200 Subject: [PATCH 1/3] fix: Display opengraph correctly --- next.config.ts | 135 ++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 62 deletions(-) diff --git a/next.config.ts b/next.config.ts index ca8677c..0e6dfc0 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,97 +1,107 @@ import { withSentryConfig } from "@sentry/nextjs"; -// Helper function to build the CSP header string. Keeps things tidy. +// Build Content Security Policy (CSP) header dynamically const getCspHeader = () => { - const nonce = process.env.NODE_ENV === "production" ? "${process.env.CSP_NONCE}" : ""; - const policies = { - // Default policy for anything not explicitly defined. 'self' means our own domain. + // Only allow resources from our own domain "default-src": ["'self'"], + + // Script sources "script-src": [ - "'self'", // Allow scripts from our own domain. - // For Next.js development (HMR, etc.), 'unsafe-eval' is often needed. + "'self'", + // Allow eval in development for Next.js hot reloading process.env.NODE_ENV === "development" ? "'unsafe-eval'" : "", - // Use CSP nonce in production instead of unsafe-inline - process.env.NODE_ENV === "development" ? "'unsafe-inline'" : nonce ? `'nonce-${nonce}'` : "", - // Sentry's CDN for browser error tracking. + // Allow inline scripts (consider removing this for better security) + "'unsafe-inline'", + // Sentry error tracking CDN "https://browser.sentry-cdn.com", - // Add any other trusted script CDNs or domains here. - ].filter(Boolean), // This nifty trick removes empty strings + ].filter(Boolean), + + // CSS style sources "style-src": [ - "'self'", // Allow stylesheets from our own domain. - // Style nonce is challenging with many CSS-in-JS solutions, so keeping unsafe-inline - // but you could consider using hashes for critical CSS if possible + "'self'", + // Allow inline styles "'unsafe-inline'", ], + + // Image sources - Allow any HTTPS source to prevent blocking OG crawlers "img-src": [ - "'self'", // Allow images from our own domain. - "data:", // Allows base64 encoded images (often used for small icons or placeholders). - // Replace broad https: with specific domains you need - "https://via.placeholder.com", - // Add other specific image domains you use + "'self'", + "data:", // Base64 encoded images + "https:", // Allow all HTTPS images for OG crawlers + "https://via.placeholder.com", // Placeholder images ], + + // Font sources "font-src": [ - "'self'", // Allow fonts from our own domain. - "data:", // Allows base64 encoded fonts. + "'self'", + "data:", // Base64 encoded fonts ], + + // API and WebSocket connections "connect-src": [ - "'self'", // Allow connections (API calls, WebSockets) to our own domain. - // Sentry's endpoint for sending error data - more specific than wildcard - "https://o4505758147321856.ingest.sentry.io", - // Arcjet's domains for its services - specific endpoints + "'self'", + // Sentry error reporting (update with your actual Sentry DSN) + "https://o4509210060587008.ingest.de.sentry.io", + // Arcjet security service "https://api.arcjet.com", "wss://realtime.arcjet.com", - // Add your specific API endpoints if on different domains ], - // For web workers. Next.js might use blob workers. + + // Web workers "worker-src": ["'self'", "blob:"], - // Domains that are allowed to embed this page in an iframe. + + // Embedding in frames - Allow same origin for better compatibility "frame-src": ["'self'"], - // Disables , , and elements. Generally a good idea. + + // Block all objects/embeds "object-src": ["'none'"], - // URLs where forms on your site can submit data. + + // Form submission "form-action": ["'self'"], - // Prevents clickjacking by controlling which sites can embed yours. - "frame-ancestors": ["'none'"], - // Tells browsers to upgrade HTTP requests to HTTPS. - "upgrade-insecure-requests": [], - // Enable reporting to help debug CSP issues - uncomment and set up endpoint + + // Don't block iframe embedding by crawlers - remove this restriction + // "frame-ancestors": ["'none'"], // Commented out to allow OG crawlers + + // Force HTTPS (only in production) + ...(process.env.NODE_ENV === "production" ? { "upgrade-insecure-requests": [] } : {}), + + // CSP violation reporting "report-to": ["default"], "report-uri": ["/api/csp-report"], }; - // This part just turns the 'policies' object into a valid CSP string. + // Convert policies object to CSP string return Object.entries(policies) - .map(([key, valueArray]) => { - if (valueArray.length === 0) { - return key; // For directives like 'upgrade-insecure-requests' that don't have values. + .map(([directive, sources]) => { + if (sources.length === 0) { + return directive; } - return `${key} ${valueArray.join(" ")}`; + return `${directive} ${sources.join(" ")}`; }) .join("; "); }; -// Generate the CSP header value once. -const cspHeaderValue = getCspHeader(); - /** @type {import('next').NextConfig} */ const nextConfig = { - // reactStrictMode: false, // User's setting. Note: `true` is generally recommended for catching issues early. + // Environment variables for client-side env: { MONGODB_URI: process.env.MONGODB_URI, JWT_SECRET: process.env.JWT_SECRET, JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN, ARCJET_KEY: process.env.ARCJET_KEY, SENTRY_AUTH_TOKEN: process.env.SENTRY_AUTH_TOKEN, - CSP_NONCE: process.env.NODE_ENV === "production" ? `${Date.now().toString(36)}` : "", }, + + // Image optimization settings images: { formats: ["image/webp"], contentDispositionType: "attachment", - // This CSP is specific to images served by Next.js Image Optimization. - // It's separate from the global CSP header we're setting below. - contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;", + // Relaxed CSP for Next.js image optimization + contentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self' data: https:;", }, + + // URL redirects async rewrites() { return [ { @@ -100,49 +110,50 @@ const nextConfig = { }, ]; }, - // This function lets us add custom HTTP headers to responses. + + // HTTP headers for all responses async headers() { return [ { - // Apply these headers to all routes in the application. source: "/:path*", headers: [ { key: "Content-Security-Policy", - // Use the CSP string we generated. The replace just cleans up extra spaces. - value: cspHeaderValue.replace(/\s{2,}/g, " ").trim(), + value: getCspHeader() + .replace(/\s{2,}/g, " ") + .trim(), }, - // Some extra security headers. Good to have! { - // Prevents browsers from MIME-sniffing the content type. + // Block MIME type sniffing key: "X-Content-Type-Options", value: "nosniff", }, { - // Controls if your site can be displayed in a ,