mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
* Remove turbopack * Fix ci errors * Sim agent import fix * Lint * Ci orchestration * Lint * Ci updates * Tdz fix for generate * Remove logger * Fix imports * Lint
244 lines
6.8 KiB
TypeScript
244 lines
6.8 KiB
TypeScript
import type { NextConfig } from 'next'
|
|
import { env, isTruthy } from './lib/env'
|
|
import { isDev, isHosted } from './lib/environment'
|
|
import { getMainCSPPolicy, getWorkflowExecutionCSPPolicy } from './lib/security/csp'
|
|
|
|
const nextConfig: NextConfig = {
|
|
devIndicators: false,
|
|
images: {
|
|
remotePatterns: [
|
|
{
|
|
protocol: 'https',
|
|
hostname: 'avatars.githubusercontent.com',
|
|
},
|
|
{
|
|
protocol: 'https',
|
|
hostname: 'api.stability.ai',
|
|
},
|
|
// Azure Blob Storage
|
|
{
|
|
protocol: 'https',
|
|
hostname: '*.blob.core.windows.net',
|
|
},
|
|
// AWS S3 - various regions and bucket configurations
|
|
{
|
|
protocol: 'https',
|
|
hostname: '*.s3.amazonaws.com',
|
|
},
|
|
{
|
|
protocol: 'https',
|
|
hostname: '*.s3.*.amazonaws.com',
|
|
},
|
|
{
|
|
protocol: 'https',
|
|
hostname: 'lh3.googleusercontent.com',
|
|
},
|
|
// Custom domain for file storage if configured
|
|
...(env.NEXT_PUBLIC_BLOB_BASE_URL
|
|
? [
|
|
{
|
|
protocol: 'https' as const,
|
|
hostname: new URL(env.NEXT_PUBLIC_BLOB_BASE_URL).hostname,
|
|
},
|
|
]
|
|
: []),
|
|
// Brand logo domain if configured
|
|
...(env.NEXT_PUBLIC_BRAND_LOGO_URL
|
|
? (() => {
|
|
try {
|
|
return [
|
|
{
|
|
protocol: 'https' as const,
|
|
hostname: new URL(env.NEXT_PUBLIC_BRAND_LOGO_URL).hostname,
|
|
},
|
|
]
|
|
} catch {
|
|
return []
|
|
}
|
|
})()
|
|
: []),
|
|
// Brand favicon domain if configured
|
|
...(env.NEXT_PUBLIC_BRAND_FAVICON_URL
|
|
? (() => {
|
|
try {
|
|
return [
|
|
{
|
|
protocol: 'https' as const,
|
|
hostname: new URL(env.NEXT_PUBLIC_BRAND_FAVICON_URL).hostname,
|
|
},
|
|
]
|
|
} catch {
|
|
return []
|
|
}
|
|
})()
|
|
: []),
|
|
],
|
|
},
|
|
typescript: {
|
|
ignoreBuildErrors: isTruthy(env.DOCKER_BUILD),
|
|
},
|
|
eslint: {
|
|
ignoreDuringBuilds: isTruthy(env.DOCKER_BUILD),
|
|
},
|
|
output: isTruthy(env.DOCKER_BUILD) ? 'standalone' : undefined,
|
|
turbopack: {
|
|
resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.json'],
|
|
},
|
|
serverExternalPackages: ['pdf-parse', '@azure/storage-blob'],
|
|
experimental: {
|
|
optimizeCss: true,
|
|
turbopackSourceMaps: false,
|
|
},
|
|
...(isDev && {
|
|
allowedDevOrigins: [
|
|
...(env.NEXT_PUBLIC_APP_URL
|
|
? (() => {
|
|
try {
|
|
return [new URL(env.NEXT_PUBLIC_APP_URL).host]
|
|
} catch {
|
|
return []
|
|
}
|
|
})()
|
|
: []),
|
|
'localhost:3000',
|
|
'localhost:3001',
|
|
],
|
|
}),
|
|
transpilePackages: [
|
|
'prettier',
|
|
'@react-email/components',
|
|
'@react-email/render',
|
|
'@t3-oss/env-nextjs',
|
|
'@t3-oss/env-core',
|
|
'@sim/db',
|
|
],
|
|
async headers() {
|
|
return [
|
|
{
|
|
// API routes CORS headers
|
|
source: '/api/:path*',
|
|
headers: [
|
|
{ key: 'Access-Control-Allow-Credentials', value: 'true' },
|
|
{
|
|
key: 'Access-Control-Allow-Origin',
|
|
value: env.NEXT_PUBLIC_APP_URL || 'http://localhost:3001',
|
|
},
|
|
{
|
|
key: 'Access-Control-Allow-Methods',
|
|
value: 'GET,POST,OPTIONS,PUT,DELETE',
|
|
},
|
|
{
|
|
key: 'Access-Control-Allow-Headers',
|
|
value:
|
|
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key',
|
|
},
|
|
],
|
|
},
|
|
// For workflow execution API endpoints
|
|
{
|
|
source: '/api/workflows/:id/execute',
|
|
headers: [
|
|
{ key: 'Access-Control-Allow-Origin', value: '*' },
|
|
{
|
|
key: 'Access-Control-Allow-Methods',
|
|
value: 'GET,POST,OPTIONS,PUT',
|
|
},
|
|
{
|
|
key: 'Access-Control-Allow-Headers',
|
|
value:
|
|
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key',
|
|
},
|
|
{ key: 'Cross-Origin-Embedder-Policy', value: 'unsafe-none' },
|
|
{ key: 'Cross-Origin-Opener-Policy', value: 'unsafe-none' },
|
|
{
|
|
key: 'Content-Security-Policy',
|
|
value: getWorkflowExecutionCSPPolicy(),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
// Exclude Vercel internal resources and static assets from strict COEP, Google Drive Picker to prevent 'refused to connect' issue
|
|
source: '/((?!_next|_vercel|api|favicon.ico|w/.*|workspace/.*|api/tools/drive).*)',
|
|
headers: [
|
|
{
|
|
key: 'Cross-Origin-Embedder-Policy',
|
|
value: 'credentialless',
|
|
},
|
|
{
|
|
key: 'Cross-Origin-Opener-Policy',
|
|
value: 'same-origin',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
// For main app routes, Google Drive Picker, and Vercel resources - use permissive policies
|
|
source: '/(w/.*|workspace/.*|api/tools/drive|_next/.*|_vercel/.*)',
|
|
headers: [
|
|
{
|
|
key: 'Cross-Origin-Embedder-Policy',
|
|
value: 'unsafe-none',
|
|
},
|
|
{
|
|
key: 'Cross-Origin-Opener-Policy',
|
|
value: 'same-origin-allow-popups',
|
|
},
|
|
],
|
|
},
|
|
// Block access to sourcemap files (defense in depth)
|
|
{
|
|
source: '/(.*)\\.map$',
|
|
headers: [
|
|
{
|
|
key: 'x-robots-tag',
|
|
value: 'noindex',
|
|
},
|
|
],
|
|
},
|
|
// Apply security headers to routes not handled by middleware runtime CSP
|
|
// Middleware handles: /, /workspace/*, /chat/*
|
|
{
|
|
source: '/((?!workspace|chat$).*)',
|
|
headers: [
|
|
{
|
|
key: 'X-Content-Type-Options',
|
|
value: 'nosniff',
|
|
},
|
|
{
|
|
key: 'X-Frame-Options',
|
|
value: 'SAMEORIGIN',
|
|
},
|
|
{
|
|
key: 'Content-Security-Policy',
|
|
value: getMainCSPPolicy(),
|
|
},
|
|
],
|
|
},
|
|
]
|
|
},
|
|
async redirects() {
|
|
const redirects = []
|
|
|
|
// Only enable domain redirects for the hosted version
|
|
if (isHosted) {
|
|
redirects.push(
|
|
{
|
|
source: '/((?!api|_next|_vercel|favicon|static|.*\\..*).*)',
|
|
destination: 'https://www.sim.ai/$1',
|
|
permanent: true,
|
|
has: [{ type: 'host' as const, value: 'simstudio.ai' }],
|
|
},
|
|
{
|
|
source: '/((?!api|_next|_vercel|favicon|static|.*\\..*).*)',
|
|
destination: 'https://www.sim.ai/$1',
|
|
permanent: true,
|
|
has: [{ type: 'host' as const, value: 'www.simstudio.ai' }],
|
|
}
|
|
)
|
|
}
|
|
|
|
return redirects
|
|
},
|
|
}
|
|
|
|
export default nextConfig
|