Skip to content

Commit 7cb303e

Browse files
authored
fix(redirects): move redirects for terms/privacy to client-side redirects (#1418)
1 parent 8eaa83f commit 7cb303e

File tree

5 files changed

+56
-33
lines changed

5 files changed

+56
-33
lines changed

apps/sim/app/(landing)/privacy/page.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
'use client'
22

3+
import { useEffect } from 'react'
34
import Link from 'next/link'
5+
import { getEnv } from '@/lib/env'
46
import { LegalLayout } from '@/app/(landing)/components'
57

68
export default function PrivacyPolicy() {
9+
useEffect(() => {
10+
const privacyUrl = getEnv('NEXT_PUBLIC_PRIVACY_URL')
11+
if (privacyUrl?.startsWith('http')) {
12+
window.location.href = privacyUrl
13+
}
14+
}, [])
715
return (
816
<LegalLayout title='Privacy Policy'>
917
<section>

apps/sim/app/(landing)/terms/page.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
'use client'
22

3+
import { useEffect } from 'react'
34
import Link from 'next/link'
5+
import { getEnv } from '@/lib/env'
46
import { LegalLayout } from '@/app/(landing)/components'
57

68
export default function TermsOfService() {
9+
useEffect(() => {
10+
const termsUrl = getEnv('NEXT_PUBLIC_TERMS_URL')
11+
if (termsUrl?.startsWith('http')) {
12+
window.location.href = termsUrl
13+
}
14+
}, [])
715
return (
816
<LegalLayout title='Terms of Service'>
917
<section>

apps/sim/lib/security/csp.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const buildTimeCSPDirectives: CSPDirectives = {
7474
'https://*.amazonaws.com',
7575
'https://*.blob.core.windows.net',
7676
...getHostnameFromUrl(env.NEXT_PUBLIC_BRAND_LOGO_URL),
77+
...getHostnameFromUrl(env.NEXT_PUBLIC_BRAND_FAVICON_URL),
7778
],
7879

7980
'media-src': ["'self'", 'blob:'],
@@ -146,19 +147,26 @@ export function generateRuntimeCSP(): string {
146147
const ollamaUrl = getEnv('OLLAMA_URL') || 'http://localhost:11434'
147148

148149
const brandLogoDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_BRAND_LOGO_URL'))
150+
const brandFaviconDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_BRAND_FAVICON_URL'))
149151
const privacyDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_PRIVACY_URL'))
150152
const termsDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_TERMS_URL'))
151153

152-
const allDynamicDomains = [...brandLogoDomains, ...privacyDomains, ...termsDomains]
154+
const allDynamicDomains = [
155+
...brandLogoDomains,
156+
...brandFaviconDomains,
157+
...privacyDomains,
158+
...termsDomains,
159+
]
153160
const uniqueDynamicDomains = Array.from(new Set(allDynamicDomains))
154161
const dynamicDomainsStr = uniqueDynamicDomains.join(' ')
155162
const brandLogoDomain = brandLogoDomains[0] || ''
163+
const brandFaviconDomain = brandFaviconDomains[0] || ''
156164

157165
return `
158166
default-src 'self';
159167
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;
160168
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
161-
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};
169+
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};
162170
media-src 'self' blob:;
163171
font-src 'self' https://fonts.gstatic.com;
164172
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};

apps/sim/middleware.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -93,37 +93,6 @@ export async function middleware(request: NextRequest) {
9393
}
9494
}
9595

96-
// Handle whitelabel redirects for terms and privacy pages
97-
if (url.pathname === '/terms') {
98-
const termsUrl = process.env.NEXT_PUBLIC_TERMS_URL
99-
if (termsUrl?.startsWith('http')) {
100-
return NextResponse.redirect(termsUrl)
101-
}
102-
}
103-
104-
if (url.pathname === '/privacy') {
105-
const privacyUrl = process.env.NEXT_PUBLIC_PRIVACY_URL
106-
if (privacyUrl?.startsWith('http')) {
107-
return NextResponse.redirect(privacyUrl)
108-
}
109-
}
110-
111-
// Legacy redirect: /w -> /workspace (will be handled by workspace layout)
112-
if (url.pathname === '/w' || url.pathname.startsWith('/w/')) {
113-
// Extract workflow ID if present
114-
const pathParts = url.pathname.split('/')
115-
if (pathParts.length >= 3 && pathParts[1] === 'w') {
116-
const workflowId = pathParts[2]
117-
// Redirect old workflow URLs to new format
118-
// We'll need to resolve the workspace ID for this workflow
119-
return NextResponse.redirect(
120-
new URL(`/workspace?redirect_workflow=${workflowId}`, request.url)
121-
)
122-
}
123-
// Simple /w redirect to workspace root
124-
return NextResponse.redirect(new URL('/workspace', request.url))
125-
}
126-
12796
// Handle login page - redirect authenticated users to workspace
12897
if (url.pathname === '/login' || url.pathname === '/signup') {
12998
if (hasActiveSession) {

apps/sim/next.config.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,36 @@ const nextConfig: NextConfig = {
4343
},
4444
]
4545
: []),
46+
// Brand logo domain if configured
47+
...(env.NEXT_PUBLIC_BRAND_LOGO_URL
48+
? (() => {
49+
try {
50+
return [
51+
{
52+
protocol: 'https' as const,
53+
hostname: new URL(env.NEXT_PUBLIC_BRAND_LOGO_URL).hostname,
54+
},
55+
]
56+
} catch {
57+
return []
58+
}
59+
})()
60+
: []),
61+
// Brand favicon domain if configured
62+
...(env.NEXT_PUBLIC_BRAND_FAVICON_URL
63+
? (() => {
64+
try {
65+
return [
66+
{
67+
protocol: 'https' as const,
68+
hostname: new URL(env.NEXT_PUBLIC_BRAND_FAVICON_URL).hostname,
69+
},
70+
]
71+
} catch {
72+
return []
73+
}
74+
})()
75+
: []),
4676
],
4777
},
4878
typescript: {

0 commit comments

Comments
 (0)