Files
MichilisandCursor a6840ea953 Harden auth, payments, and frontend against review findings.
Close exploitable gaps in booking/payment flows, enforce token versioning and account checks, gate sensitive payment data, and add middleware plus input validation across admin routes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 19:59:02 +00:00

55 lines
1.6 KiB
JavaScript

/** @type {import('next').NextConfig} */
// Backend origin for API/upload proxying. Configurable per environment instead of
// being hardcoded to localhost.
const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:3001';
// Extra image hosts can be allowed via a comma-separated env var (e.g. a CDN).
const extraImageHosts = (process.env.NEXT_PUBLIC_IMAGE_HOSTS || '')
.split(',')
.map((h) => h.trim())
.filter(Boolean)
.map((hostname) => ({ protocol: 'https', hostname }));
const securityHeaders = [
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'X-XSS-Protection', value: '0' },
{ key: 'Permissions-Policy', value: 'camera=(self), microphone=(), geolocation=()' },
];
const nextConfig = {
images: {
// Restrict remote image sources to a known allowlist instead of allowing any
// https host (which let the Next image optimizer be used as an open proxy).
remotePatterns: [
{ protocol: 'https', hostname: 'images.unsplash.com' },
{ protocol: 'http', hostname: 'localhost', port: '3001' },
...extraImageHosts,
],
},
async headers() {
return [
{
source: '/:path*',
headers: securityHeaders,
},
];
},
async rewrites() {
return [
{
source: '/api/:path*',
destination: `${BACKEND_URL}/api/:path*`,
},
{
source: '/uploads/:path*',
destination: `${BACKEND_URL}/uploads/:path*`,
},
];
},
};
module.exports = nextConfig;