mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(redirects): move redirects for terms/privacy to client-side redirects (#1418)
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { getEnv } from '@/lib/env'
|
||||
import { LegalLayout } from '@/app/(landing)/components'
|
||||
|
||||
export default function PrivacyPolicy() {
|
||||
useEffect(() => {
|
||||
const privacyUrl = getEnv('NEXT_PUBLIC_PRIVACY_URL')
|
||||
if (privacyUrl?.startsWith('http')) {
|
||||
window.location.href = privacyUrl
|
||||
}
|
||||
}, [])
|
||||
return (
|
||||
<LegalLayout title='Privacy Policy'>
|
||||
<section>
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { getEnv } from '@/lib/env'
|
||||
import { LegalLayout } from '@/app/(landing)/components'
|
||||
|
||||
export default function TermsOfService() {
|
||||
useEffect(() => {
|
||||
const termsUrl = getEnv('NEXT_PUBLIC_TERMS_URL')
|
||||
if (termsUrl?.startsWith('http')) {
|
||||
window.location.href = termsUrl
|
||||
}
|
||||
}, [])
|
||||
return (
|
||||
<LegalLayout title='Terms of Service'>
|
||||
<section>
|
||||
|
||||
@@ -74,6 +74,7 @@ export const buildTimeCSPDirectives: CSPDirectives = {
|
||||
'https://*.amazonaws.com',
|
||||
'https://*.blob.core.windows.net',
|
||||
...getHostnameFromUrl(env.NEXT_PUBLIC_BRAND_LOGO_URL),
|
||||
...getHostnameFromUrl(env.NEXT_PUBLIC_BRAND_FAVICON_URL),
|
||||
],
|
||||
|
||||
'media-src': ["'self'", 'blob:'],
|
||||
@@ -146,19 +147,26 @@ export function generateRuntimeCSP(): string {
|
||||
const ollamaUrl = getEnv('OLLAMA_URL') || 'http://localhost:11434'
|
||||
|
||||
const brandLogoDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_BRAND_LOGO_URL'))
|
||||
const brandFaviconDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_BRAND_FAVICON_URL'))
|
||||
const privacyDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_PRIVACY_URL'))
|
||||
const termsDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_TERMS_URL'))
|
||||
|
||||
const allDynamicDomains = [...brandLogoDomains, ...privacyDomains, ...termsDomains]
|
||||
const allDynamicDomains = [
|
||||
...brandLogoDomains,
|
||||
...brandFaviconDomains,
|
||||
...privacyDomains,
|
||||
...termsDomains,
|
||||
]
|
||||
const uniqueDynamicDomains = Array.from(new Set(allDynamicDomains))
|
||||
const dynamicDomainsStr = uniqueDynamicDomains.join(' ')
|
||||
const brandLogoDomain = brandLogoDomains[0] || ''
|
||||
const brandFaviconDomain = brandFaviconDomains[0] || ''
|
||||
|
||||
return `
|
||||
default-src 'self';
|
||||
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.google.com https://apis.google.com https://*.vercel-scripts.com https://*.vercel-insights.com https://vercel.live https://*.vercel.live https://vercel.com https://*.vercel.app https://vitals.vercel-insights.com https://b2bjsstore.s3.us-west-2.amazonaws.com;
|
||||
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
|
||||
img-src 'self' data: blob: https://*.googleusercontent.com https://*.google.com https://*.atlassian.com https://cdn.discordapp.com https://*.githubusercontent.com https://*.public.blob.vercel-storage.com ${brandLogoDomain};
|
||||
img-src 'self' data: blob: https://*.googleusercontent.com https://*.google.com https://*.atlassian.com https://cdn.discordapp.com https://*.githubusercontent.com https://*.public.blob.vercel-storage.com ${brandLogoDomain} ${brandFaviconDomain};
|
||||
media-src 'self' blob:;
|
||||
font-src 'self' https://fonts.gstatic.com;
|
||||
connect-src 'self' ${appUrl} ${ollamaUrl} ${socketUrl} ${socketWsUrl} https://*.up.railway.app wss://*.up.railway.app https://api.browser-use.com https://api.exa.ai https://api.firecrawl.dev https://*.googleapis.com https://*.amazonaws.com https://*.s3.amazonaws.com https://*.blob.core.windows.net https://*.vercel-insights.com https://vitals.vercel-insights.com https://*.atlassian.com https://*.supabase.co https://vercel.live https://*.vercel.live https://vercel.com https://*.vercel.app wss://*.vercel.app https://pro.ip-api.com ${dynamicDomainsStr};
|
||||
|
||||
@@ -93,37 +93,6 @@ export async function middleware(request: NextRequest) {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle whitelabel redirects for terms and privacy pages
|
||||
if (url.pathname === '/terms') {
|
||||
const termsUrl = process.env.NEXT_PUBLIC_TERMS_URL
|
||||
if (termsUrl?.startsWith('http')) {
|
||||
return NextResponse.redirect(termsUrl)
|
||||
}
|
||||
}
|
||||
|
||||
if (url.pathname === '/privacy') {
|
||||
const privacyUrl = process.env.NEXT_PUBLIC_PRIVACY_URL
|
||||
if (privacyUrl?.startsWith('http')) {
|
||||
return NextResponse.redirect(privacyUrl)
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy redirect: /w -> /workspace (will be handled by workspace layout)
|
||||
if (url.pathname === '/w' || url.pathname.startsWith('/w/')) {
|
||||
// Extract workflow ID if present
|
||||
const pathParts = url.pathname.split('/')
|
||||
if (pathParts.length >= 3 && pathParts[1] === 'w') {
|
||||
const workflowId = pathParts[2]
|
||||
// Redirect old workflow URLs to new format
|
||||
// We'll need to resolve the workspace ID for this workflow
|
||||
return NextResponse.redirect(
|
||||
new URL(`/workspace?redirect_workflow=${workflowId}`, request.url)
|
||||
)
|
||||
}
|
||||
// Simple /w redirect to workspace root
|
||||
return NextResponse.redirect(new URL('/workspace', request.url))
|
||||
}
|
||||
|
||||
// Handle login page - redirect authenticated users to workspace
|
||||
if (url.pathname === '/login' || url.pathname === '/signup') {
|
||||
if (hasActiveSession) {
|
||||
|
||||
@@ -43,6 +43,36 @@ const nextConfig: NextConfig = {
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// 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: {
|
||||
|
||||
Reference in New Issue
Block a user