@@ -43,7 +43,6 @@ export const buildTimeCSPDirectives: CSPDirectives = {
4343 'style-src' : [ "'self'" , "'unsafe-inline'" , 'https://fonts.googleapis.com' ] ,
4444
4545 'img-src' : [
46- 'https://agentics.epiqglobal.com' ,
4746 "'self'" ,
4847 'data:' ,
4948 'blob:' ,
@@ -66,6 +65,16 @@ export const buildTimeCSPDirectives: CSPDirectives = {
6665 : [ ] ) ,
6766 'https://*.amazonaws.com' ,
6867 'https://*.blob.core.windows.net' ,
68+ ...( env . NEXT_PUBLIC_BRAND_LOGO_URL
69+ ? ( ( ) => {
70+ try {
71+ const url = new URL ( env . NEXT_PUBLIC_BRAND_LOGO_URL )
72+ return [ `https://${ url . hostname } ` ]
73+ } catch {
74+ return [ ]
75+ }
76+ } ) ( )
77+ : [ ] ) ,
6978 ] ,
7079
7180 'media-src' : [ "'self'" , 'blob:' ] ,
@@ -98,6 +107,36 @@ export const buildTimeCSPDirectives: CSPDirectives = {
98107 'https://*.vercel.app' ,
99108 'wss://*.vercel.app' ,
100109 'https://pro.ip-api.com' ,
110+ ...( env . NEXT_PUBLIC_BRAND_LOGO_URL
111+ ? ( ( ) => {
112+ try {
113+ const url = new URL ( env . NEXT_PUBLIC_BRAND_LOGO_URL )
114+ return [ `https://${ url . hostname } ` ]
115+ } catch {
116+ return [ ]
117+ }
118+ } ) ( )
119+ : [ ] ) ,
120+ ...( env . NEXT_PUBLIC_PRIVACY_URL
121+ ? ( ( ) => {
122+ try {
123+ const url = new URL ( env . NEXT_PUBLIC_PRIVACY_URL )
124+ return [ `https://${ url . hostname } ` ]
125+ } catch {
126+ return [ ]
127+ }
128+ } ) ( )
129+ : [ ] ) ,
130+ ...( env . NEXT_PUBLIC_TERMS_URL
131+ ? ( ( ) => {
132+ try {
133+ const url = new URL ( env . NEXT_PUBLIC_TERMS_URL )
134+ return [ `https://${ url . hostname } ` ]
135+ } catch {
136+ return [ ]
137+ }
138+ } ) ( )
139+ : [ ] ) ,
101140 ] ,
102141
103142 // Google Picker and Drive integration
@@ -140,14 +179,46 @@ export function generateRuntimeCSP(): string {
140179 const appUrl = getEnv ( 'NEXT_PUBLIC_APP_URL' ) || ''
141180 const ollamaUrl = getEnv ( 'OLLAMA_URL' ) || 'http://localhost:11434'
142181
182+ const brandLogoDomain = ( ( ) => {
183+ try {
184+ const url = getEnv ( 'NEXT_PUBLIC_BRAND_LOGO_URL' )
185+ return url ? `https://${ new URL ( url ) . hostname } ` : ''
186+ } catch {
187+ return ''
188+ }
189+ } ) ( )
190+
191+ const privacyDomain = ( ( ) => {
192+ try {
193+ const url = getEnv ( 'NEXT_PUBLIC_PRIVACY_URL' )
194+ return url ? `https://${ new URL ( url ) . hostname } ` : ''
195+ } catch {
196+ return ''
197+ }
198+ } ) ( )
199+
200+ const termsDomain = ( ( ) => {
201+ try {
202+ const url = getEnv ( 'NEXT_PUBLIC_TERMS_URL' )
203+ return url ? `https://${ new URL ( url ) . hostname } ` : ''
204+ } catch {
205+ return ''
206+ }
207+ } ) ( )
208+
209+ const dynamicDomains = Array . from (
210+ new Set ( [ brandLogoDomain , privacyDomain , termsDomain ] . filter ( Boolean ) )
211+ )
212+ const dynamicDomainsStr = dynamicDomains . join ( ' ' )
213+
143214 return `
144215 default-src 'self';
145216 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;
146217 style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
147- 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;
218+ 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 } ;
148219 media-src 'self' blob:;
149220 font-src 'self' https://fonts.gstatic.com;
150- 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;
221+ 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 } ;
151222 frame-src https://drive.google.com https://docs.google.com https://*.google.com;
152223 frame-ancestors 'self';
153224 form-action 'self';
0 commit comments