Introduces the Go photo-api service, nginx/systemd deploy wiring, and Next.js gallery/lightbox pages so event photos can be managed and browsed. Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
2.1 KiB
JavaScript
66 lines
2.1 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';
|
|
|
|
// The standalone photo gallery service (photo-api/). Must be rewritten
|
|
// before the generic /api rule below — Next rewrites are order-sensitive.
|
|
const PHOTO_API_URL = process.env.PHOTO_API_URL || 'http://localhost:3003';
|
|
|
|
// 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 = {
|
|
// Overridable so a production build can run while `next dev` holds .next
|
|
// (e.g. NEXT_DIST_DIR=.next-build npm run build).
|
|
distDir: process.env.NEXT_DIST_DIR || '.next',
|
|
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/photos/:path*',
|
|
destination: `${PHOTO_API_URL}/api/photos/:path*`,
|
|
},
|
|
{
|
|
source: '/api/:path*',
|
|
destination: `${BACKEND_URL}/api/:path*`,
|
|
},
|
|
{
|
|
source: '/uploads/:path*',
|
|
destination: `${BACKEND_URL}/uploads/:path*`,
|
|
},
|
|
];
|
|
},
|
|
};
|
|
|
|
module.exports = nextConfig;
|