Files
prowler/ui/next.config.js
Chandrapal Badshah b9bfdc1a5a feat: Integrate Prowler MCP to Lighthouse AI (#9255)
Co-authored-by: Chandrapal Badshah <12944530+Chan9390@users.noreply.github.com>
Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
Co-authored-by: Alejandro Bailo <59607668+alejandrobailo@users.noreply.github.com>
Co-authored-by: Alan Buscaglia <gentlemanprogramming@gmail.com>
Co-authored-by: Adrián Jesús Peña Rodríguez <adrianjpr@gmail.com>
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
2025-12-17 10:10:43 +01:00

99 lines
3.1 KiB
JavaScript

const dotenv = require("dotenv");
const dotenvExpand = require("dotenv-expand");
dotenvExpand.expand(dotenv.config({ path: "../.env", quiet: true }));
const { withSentryConfig } = require("@sentry/nextjs");
/** @type {import('next').NextConfig} */
// HTTP Security Headers
// 'unsafe-eval' is configured under `script-src` because it is required by NextJS for development mode
const cspHeader = `
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://www.googletagmanager.com https://browser.sentry-cdn.com;
connect-src 'self' https://api.iconify.design https://api.simplesvg.com https://api.unisvg.com https://js.stripe.com https://www.googletagmanager.com https://*.sentry.io https://*.ingest.sentry.io;
img-src 'self' https://www.google-analytics.com https://www.googletagmanager.com;
font-src 'self';
style-src 'self' 'unsafe-inline';
frame-src 'self' https://js.stripe.com https://www.googletagmanager.com;
frame-ancestors 'none';
report-to csp-endpoint;
`;
// Get Sentry CSP report endpoint if DSN is configured
const getSentryReportEndpoint = () => {
if (!process.env.NEXT_PUBLIC_SENTRY_DSN) return null;
try {
const sentryKey =
process.env.NEXT_PUBLIC_SENTRY_DSN.split("@")[0]?.split("//")[1];
return sentryKey
? `https://o0.ingest.sentry.io/api/0/security/?sentry_key=${sentryKey}`
: null;
} catch {
return null;
}
};
const nextConfig = {
poweredByHeader: false,
// Use standalone only in production deployments, not for CI/testing
...(process.env.NODE_ENV === "production" &&
!process.env.CI && {
output: "standalone",
outputFileTracingRoot: __dirname,
}),
experimental: {
reactCompiler: true,
},
turbopack: {
root: __dirname,
},
async headers() {
const sentryEndpoint = getSentryReportEndpoint();
const headers = [
{
key: "Content-Security-Policy",
value: cspHeader.replace(/\n/g, ""),
},
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "Referrer-Policy",
value: "strict-origin-when-cross-origin",
},
];
// Add Reporting-Endpoints header if Sentry is configured
if (sentryEndpoint) {
headers.push({
key: "Reporting-Endpoints",
value: `csp-endpoint="${sentryEndpoint}"`,
});
}
return [
{
source: "/(.*)",
headers,
},
];
},
};
// Sentry configuration options
const sentryWebpackPluginOptions = {
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
silent: true, // Suppresses all logs
hideSourceMaps: true, // Hides source maps from generated client bundles
disableLogger: true, // Automatically tree-shake Sentry logger statements to reduce bundle size
widenClientFileUpload: true, // Upload a larger set of source maps for prettier stack traces
};
// Export with Sentry only if configuration is available
module.exports = process.env.SENTRY_DSN
? withSentryConfig(nextConfig, sentryWebpackPluginOptions)
: nextConfig;