Skip to content

Commit 37e44be

Browse files
ivasilovalaister
andauthored
feat: Add GTM (supabase#35567)
* Add third-parties dependency for GTM. Reexport the GTM from the common package. * Add the TelemetryTagManager to four of the production apps. * Add the GOOGLE_TAG_MANAGER_ID env var as a turbo dependency to the 4 apps. * Skip rendering the tag manager if the env var is not set or not running on the platform. * Fix the prop type to be extracted from the component. * Add default values for consent to GTM. * Another try to mimic gtag function. * Fix a link in www. * Try another approach. * try. * Remove the data-redaction flag. * Remove extra code. * Send a sign-up event if GTM is enabled. * Send only the email to GTM. * Minor fixes. * Remove third-parties from pnpm lockfile. * Lets try to make studio work again. * Add CSP rules for img loading for GTM. * Add event for testing. * Add www.googletagmanager.com to the CSP rules. * Add Stape to CSP rules. * Fix stape CSP. * Clean up the code. * Remove extra console.log. * Fix the stape urls for CORS. * Fix the wrong category for Stape URL. * Add google ads urls. * Bump the timeout. * Add google.com to the img-src for google ads. * update csp * remove comment * update to use google analytics without signals * add stape to default-src in csp * move csp to middleware * add google ads support and fix middleware base path * remove google tag manager / google ads references from csp. load via stape proxy instead * add double click url to image src * add Google Tag Manager URL to CSP configuration * add ga4 urls to csp * remove google urls from CSP --------- Co-authored-by: Alaister Young <[email protected]>
1 parent c62c275 commit 37e44be

File tree

15 files changed

+920
-426
lines changed

15 files changed

+920
-426
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
/docker/ @supabase/dev-workflows
1616

17-
/apps/studio/next.config.js @supabase/security
17+
/apps/studio/csp.js @supabase/security
1818
/apps/studio/components/interfaces/Billing/Payment @supabase/security
1919
/apps/studio/components/interfaces/Organization/BillingSettings/ @supabase/security
2020
/apps/studio/components/interfaces/Organization/Documents/ @supabase/security

apps/docs/app/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { genFaviconData } from 'common/MetaFavicons/app-router'
1111
import { GlobalProviders } from '~/features/app.providers'
1212
import { TopNavSkeleton } from '~/layouts/MainSkeleton'
1313
import { BASE_PATH, IS_PRODUCTION } from '~/lib/constants'
14+
import { TelemetryTagManager } from 'common'
1415

1516
const metadata: Metadata = {
1617
applicationName: 'Supabase Docs',
@@ -47,6 +48,7 @@ const RootLayout = ({ children }: { children: React.ReactNode }) => {
4748
return (
4849
<html lang="en">
4950
<body>
51+
<TelemetryTagManager />
5052
<GlobalProviders>
5153
<TopNavSkeleton>{children}</TopNavSkeleton>
5254
</GlobalProviders>

apps/docs/turbo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"NEXT_PUBLIC_AUTH_PERSISTED_KEY",
3434
"NEXT_PUBLIC_AUTH_NAVIGATOR_LOCK_KEY",
3535
"NEXT_PUBLIC_AUTH_DETECT_SESSION_IN_URL",
36+
"NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID",
3637
"NEXT_PUBLIC_GOTRUE_URL",
3738
"NEXT_PUBLIC_SUPABASE_ANON_KEY",
3839
// These envs are technically passthrough env vars because they're only used on the server side of Nextjs

apps/studio/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ yarn-error.log*
3737
/public/dashboard
3838
# Sentry Auth Token
3939
.sentryclirc
40+
41+
certificates

apps/studio/components/ui/GroupsTelemetry.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { useSendGroupsIdentifyMutation } from 'data/telemetry/send-groups-identi
88
import { useSendGroupsResetMutation } from 'data/telemetry/send-groups-reset-mutation'
99
import { usePrevious } from 'hooks/deprecated'
1010
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
11-
import { useAppStateSnapshot } from 'state/app-state'
1211
import { IS_PLATFORM } from 'lib/constants'
1312

1413
const getAnonId = async (id: string) => {

apps/studio/csp.js

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
const API_URL = process.env.NEXT_PUBLIC_API_URL
2+
? new URL(process.env.NEXT_PUBLIC_API_URL).origin
3+
: ''
4+
const SUPABASE_URL = process.env.SUPABASE_URL ? new URL(process.env.SUPABASE_URL).origin : ''
5+
const GOTRUE_URL = process.env.NEXT_PUBLIC_GOTRUE_URL
6+
? new URL(process.env.NEXT_PUBLIC_GOTRUE_URL).origin
7+
: ''
8+
const SUPABASE_PROJECTS_URL = 'https://*.supabase.co'
9+
const SUPABASE_PROJECTS_URL_WS = 'wss://*.supabase.co'
10+
11+
// construct the URL for the Websocket Local URLs
12+
let SUPABASE_LOCAL_PROJECTS_URL_WS = ''
13+
if (SUPABASE_URL) {
14+
const url = new URL(SUPABASE_URL)
15+
const wsUrl = `${url.hostname}:${url.port}`
16+
SUPABASE_LOCAL_PROJECTS_URL_WS = `ws://${wsUrl} wss://${wsUrl}`
17+
}
18+
19+
// Needed to test docs search in local dev
20+
const SUPABASE_DOCS_PROJECT_URL = process.env.NEXT_PUBLIC_SUPABASE_URL
21+
? new URL(process.env.NEXT_PUBLIC_SUPABASE_URL).origin
22+
: ''
23+
24+
// Needed to test docs content API in local dev
25+
const SUPABASE_CONTENT_API_URL = process.env.NEXT_PUBLIC_CONTENT_API_URL
26+
? new URL(process.env.NEXT_PUBLIC_CONTENT_API_URL).origin
27+
: ''
28+
29+
const SUPABASE_STAGING_PROJECTS_URL = 'https://*.supabase.red'
30+
const SUPABASE_STAGING_PROJECTS_URL_WS = 'wss://*.supabase.red'
31+
const SUPABASE_COM_URL = 'https://supabase.com'
32+
const CLOUDFLARE_CDN_URL = 'https://cdnjs.cloudflare.com'
33+
const HCAPTCHA_SUBDOMAINS_URL = 'https://*.hcaptcha.com'
34+
const HCAPTCHA_ASSET_URL = 'https://newassets.hcaptcha.com'
35+
const HCAPTCHA_JS_URL = 'https://js.hcaptcha.com'
36+
const CONFIGCAT_URL = 'https://cdn-global.configcat.com'
37+
const CONFIGCAT_PROXY_URL = ['staging', 'local'].includes(process.env.NEXT_PUBLIC_ENVIRONMENT ?? '')
38+
? 'https://configcat.supabase.green'
39+
: 'https://configcat.supabase.com'
40+
const STRIPE_SUBDOMAINS_URL = 'https://*.stripe.com'
41+
const STRIPE_JS_URL = 'https://js.stripe.com'
42+
const STRIPE_NETWORK_URL = 'https://*.stripe.network'
43+
const CLOUDFLARE_URL = 'https://www.cloudflare.com'
44+
const ONE_ONE_ONE_ONE_URL = 'https://one.one.one.one'
45+
const VERCEL_URL = 'https://vercel.com'
46+
const VERCEL_INSIGHTS_URL = 'https://*.vercel-insights.com'
47+
const GITHUB_API_URL = 'https://api.github.com'
48+
const GITHUB_USER_CONTENT_URL = 'https://raw.githubusercontent.com'
49+
const GITHUB_USER_AVATAR_URL = 'https://avatars.githubusercontent.com'
50+
const GOOGLE_USER_AVATAR_URL = 'https://lh3.googleusercontent.com'
51+
52+
// This is a custom domain for Stape, which isused for GTM servers
53+
const STAPE_URL = 'https://ss.supabase.com'
54+
55+
const VERCEL_LIVE_URL = 'https://vercel.live'
56+
const SENTRY_URL =
57+
'https://*.ingest.sentry.io https://*.ingest.us.sentry.io https://*.ingest.de.sentry.io'
58+
const SUPABASE_ASSETS_URL =
59+
process.env.NEXT_PUBLIC_ENVIRONMENT === 'staging'
60+
? 'https://frontend-assets.supabase.green'
61+
: 'https://frontend-assets.supabase.com'
62+
63+
const USERCENTRICS_URLS = 'https://*.usercentrics.eu'
64+
const USERCENTRICS_APP_URL = 'https://app.usercentrics.eu'
65+
66+
// used by vercel live preview
67+
const PUSHER_URL = 'https://*.pusher.com'
68+
const PUSHER_URL_WS = 'wss://*.pusher.com'
69+
70+
module.exports.getCSP = function getCSP() {
71+
const DEFAULT_SRC_URLS = [
72+
API_URL,
73+
SUPABASE_URL,
74+
GOTRUE_URL,
75+
SUPABASE_LOCAL_PROJECTS_URL_WS,
76+
SUPABASE_PROJECTS_URL,
77+
SUPABASE_PROJECTS_URL_WS,
78+
HCAPTCHA_SUBDOMAINS_URL,
79+
CONFIGCAT_URL,
80+
CONFIGCAT_PROXY_URL,
81+
STRIPE_SUBDOMAINS_URL,
82+
STRIPE_NETWORK_URL,
83+
CLOUDFLARE_URL,
84+
ONE_ONE_ONE_ONE_URL,
85+
VERCEL_INSIGHTS_URL,
86+
GITHUB_API_URL,
87+
GITHUB_USER_CONTENT_URL,
88+
SUPABASE_ASSETS_URL,
89+
USERCENTRICS_URLS,
90+
STAPE_URL,
91+
]
92+
const SCRIPT_SRC_URLS = [
93+
CLOUDFLARE_CDN_URL,
94+
HCAPTCHA_JS_URL,
95+
STRIPE_JS_URL,
96+
SUPABASE_ASSETS_URL,
97+
STAPE_URL,
98+
]
99+
const FRAME_SRC_URLS = [HCAPTCHA_ASSET_URL, STRIPE_JS_URL, STAPE_URL]
100+
const IMG_SRC_URLS = [
101+
SUPABASE_URL,
102+
SUPABASE_COM_URL,
103+
SUPABASE_PROJECTS_URL,
104+
GITHUB_USER_AVATAR_URL,
105+
GOOGLE_USER_AVATAR_URL,
106+
SUPABASE_ASSETS_URL,
107+
USERCENTRICS_APP_URL,
108+
STAPE_URL,
109+
]
110+
const STYLE_SRC_URLS = [CLOUDFLARE_CDN_URL, SUPABASE_ASSETS_URL]
111+
const FONT_SRC_URLS = [CLOUDFLARE_CDN_URL, SUPABASE_ASSETS_URL]
112+
113+
const isDevOrStaging =
114+
process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' ||
115+
process.env.NEXT_PUBLIC_ENVIRONMENT === 'local' ||
116+
process.env.NEXT_PUBLIC_ENVIRONMENT === 'staging'
117+
118+
const defaultSrcDirective = [
119+
`default-src 'self'`,
120+
...DEFAULT_SRC_URLS,
121+
...(isDevOrStaging
122+
? [
123+
SUPABASE_STAGING_PROJECTS_URL,
124+
SUPABASE_STAGING_PROJECTS_URL_WS,
125+
VERCEL_LIVE_URL,
126+
SUPABASE_DOCS_PROJECT_URL,
127+
SUPABASE_CONTENT_API_URL,
128+
]
129+
: []),
130+
PUSHER_URL_WS,
131+
SENTRY_URL,
132+
].join(' ')
133+
134+
const imgSrcDirective = [
135+
`img-src 'self'`,
136+
`blob:`,
137+
`data:`,
138+
...IMG_SRC_URLS,
139+
...(isDevOrStaging ? [SUPABASE_STAGING_PROJECTS_URL, VERCEL_URL] : []),
140+
].join(' ')
141+
142+
const scriptSrcDirective = [
143+
`script-src 'self'`,
144+
`'unsafe-eval'`,
145+
`'unsafe-inline'`,
146+
...SCRIPT_SRC_URLS,
147+
VERCEL_LIVE_URL,
148+
PUSHER_URL,
149+
].join(' ')
150+
151+
const frameSrcDirective = [`frame-src 'self'`, ...FRAME_SRC_URLS, VERCEL_LIVE_URL].join(' ')
152+
153+
const styleSrcDirective = [
154+
`style-src 'self'`,
155+
`'unsafe-inline'`,
156+
...STYLE_SRC_URLS,
157+
VERCEL_LIVE_URL,
158+
].join(' ')
159+
160+
const fontSrcDirective = [`font-src 'self'`, ...FONT_SRC_URLS, VERCEL_LIVE_URL].join(' ')
161+
162+
const workerSrcDirective = [`worker-src 'self'`, `blob:`, `data:`].join(' ')
163+
164+
const cspDirectives = [
165+
defaultSrcDirective,
166+
imgSrcDirective,
167+
scriptSrcDirective,
168+
frameSrcDirective,
169+
styleSrcDirective,
170+
fontSrcDirective,
171+
workerSrcDirective,
172+
`object-src 'none'`,
173+
`base-uri 'self'`,
174+
`form-action 'self'`,
175+
`frame-ancestors 'none'`,
176+
`block-all-mixed-content`,
177+
...(process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' &&
178+
process.env.NEXT_PUBLIC_ENVIRONMENT === 'prod'
179+
? [`upgrade-insecure-requests`]
180+
: []),
181+
]
182+
183+
const csp = cspDirectives.join('; ') + ';'
184+
185+
// Replace newline characters and spaces
186+
return csp.replace(/\s{2,}/g, ' ').trim()
187+
}

apps/studio/lib/profile.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as Sentry from '@sentry/nextjs'
2-
import { useIsLoggedIn } from 'common'
2+
import { useIsLoggedIn, useUser } from 'common'
33
import { useRouter } from 'next/router'
44
import { PropsWithChildren, createContext, useContext, useMemo } from 'react'
55
import { toast } from 'sonner'
@@ -30,6 +30,7 @@ export const ProfileContext = createContext<ProfileContextType>({
3030
})
3131

3232
export const ProfileProvider = ({ children }: PropsWithChildren<{}>) => {
33+
const user = useUser()
3334
const isLoggedIn = useIsLoggedIn()
3435
const router = useRouter()
3536
const signOut = useSignOut()
@@ -38,6 +39,16 @@ export const ProfileProvider = ({ children }: PropsWithChildren<{}>) => {
3839
const { mutate: createProfile, isLoading: isCreatingProfile } = useProfileCreateMutation({
3940
onSuccess: () => {
4041
sendEvent({ action: 'sign_up', properties: { category: 'conversion' } })
42+
43+
if (user) {
44+
// Send an event to GTM, will do nothing if GTM is not enabled
45+
const thisWindow = window as any
46+
thisWindow.dataLayer = thisWindow.dataLayer || []
47+
thisWindow.dataLayer.push({
48+
event: 'sign_up',
49+
email: user.email,
50+
})
51+
}
4152
},
4253
onError: (error) => {
4354
if (error.code === 409) {

apps/studio/next.config.js

Lines changed: 3 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -2,115 +2,11 @@ const { withSentryConfig } = require('@sentry/nextjs')
22
const withBundleAnalyzer = require('@next/bundle-analyzer')({
33
enabled: process.env.ANALYZE === 'true',
44
})
5+
const { getCSP } = require('./csp')
56

67
// Required for nextjs standalone build
78
const path = require('path')
89

9-
const API_URL = process.env.NEXT_PUBLIC_API_URL
10-
? new URL(process.env.NEXT_PUBLIC_API_URL).origin
11-
: ''
12-
const SUPABASE_URL = process.env.SUPABASE_URL ? new URL(process.env.SUPABASE_URL).origin : ''
13-
const GOTRUE_URL = process.env.NEXT_PUBLIC_GOTRUE_URL
14-
? new URL(process.env.NEXT_PUBLIC_GOTRUE_URL).origin
15-
: ''
16-
const SUPABASE_PROJECTS_URL = 'https://*.supabase.co'
17-
const SUPABASE_PROJECTS_URL_WS = 'wss://*.supabase.co'
18-
19-
// construct the URL for the Websocket Local URLs
20-
let SUPABASE_LOCAL_PROJECTS_URL_WS = ''
21-
if (SUPABASE_URL) {
22-
const url = new URL(SUPABASE_URL)
23-
const wsUrl = `${url.hostname}:${url.port}`
24-
SUPABASE_LOCAL_PROJECTS_URL_WS = `ws://${wsUrl} wss://${wsUrl}`
25-
}
26-
27-
// Needed to test docs search in local dev
28-
const SUPABASE_DOCS_PROJECT_URL = process.env.NEXT_PUBLIC_SUPABASE_URL
29-
? new URL(process.env.NEXT_PUBLIC_SUPABASE_URL).origin
30-
: ''
31-
32-
// Needed to test docs content API in local dev
33-
const SUPABASE_CONTENT_API_URL = process.env.NEXT_PUBLIC_CONTENT_API_URL
34-
? new URL(process.env.NEXT_PUBLIC_CONTENT_API_URL).origin
35-
: ''
36-
37-
const SUPABASE_STAGING_PROJECTS_URL = 'https://*.supabase.red'
38-
const SUPABASE_STAGING_PROJECTS_URL_WS = 'wss://*.supabase.red'
39-
const SUPABASE_COM_URL = 'https://supabase.com'
40-
const CLOUDFLARE_CDN_URL = 'https://cdnjs.cloudflare.com'
41-
const HCAPTCHA_SUBDOMAINS_URL = 'https://*.hcaptcha.com'
42-
const HCAPTCHA_ASSET_URL = 'https://newassets.hcaptcha.com'
43-
const HCAPTCHA_JS_URL = 'https://js.hcaptcha.com'
44-
const CONFIGCAT_URL = 'https://cdn-global.configcat.com'
45-
const CONFIGCAT_PROXY_URL = ['staging', 'local'].includes(process.env.NEXT_PUBLIC_ENVIRONMENT)
46-
? 'https://configcat.supabase.green'
47-
: 'https://configcat.supabase.com'
48-
const STRIPE_SUBDOMAINS_URL = 'https://*.stripe.com'
49-
const STRIPE_JS_URL = 'https://js.stripe.com'
50-
const STRIPE_NETWORK_URL = 'https://*.stripe.network'
51-
const CLOUDFLARE_URL = 'https://www.cloudflare.com'
52-
const ONE_ONE_ONE_ONE_URL = 'https://one.one.one.one'
53-
const VERCEL_URL = 'https://vercel.com'
54-
const VERCEL_INSIGHTS_URL = 'https://*.vercel-insights.com'
55-
const GITHUB_API_URL = 'https://api.github.com'
56-
const GITHUB_USER_CONTENT_URL = 'https://raw.githubusercontent.com'
57-
const GITHUB_USER_AVATAR_URL = 'https://avatars.githubusercontent.com'
58-
const GOOGLE_USER_AVATAR_URL = 'https://lh3.googleusercontent.com'
59-
const VERCEL_LIVE_URL = 'https://vercel.live'
60-
const SENTRY_URL =
61-
'https://*.ingest.sentry.io https://*.ingest.us.sentry.io https://*.ingest.de.sentry.io'
62-
const SUPABASE_ASSETS_URL =
63-
process.env.NEXT_PUBLIC_ENVIRONMENT === 'staging'
64-
? 'https://frontend-assets.supabase.green'
65-
: 'https://frontend-assets.supabase.com'
66-
67-
const USERCENTRICS_URLS = 'https://*.usercentrics.eu'
68-
const USERCENTRICS_APP_URL = 'https://app.usercentrics.eu'
69-
70-
// used by vercel live preview
71-
const PUSHER_URL = 'https://*.pusher.com'
72-
const PUSHER_URL_WS = 'wss://*.pusher.com'
73-
74-
const DEFAULT_SRC_URLS = `${API_URL} ${SUPABASE_URL} ${GOTRUE_URL} ${SUPABASE_LOCAL_PROJECTS_URL_WS} ${SUPABASE_PROJECTS_URL} ${SUPABASE_PROJECTS_URL_WS} ${HCAPTCHA_SUBDOMAINS_URL} ${CONFIGCAT_URL} ${CONFIGCAT_PROXY_URL} ${STRIPE_SUBDOMAINS_URL} ${STRIPE_NETWORK_URL} ${CLOUDFLARE_URL} ${ONE_ONE_ONE_ONE_URL} ${VERCEL_INSIGHTS_URL} ${GITHUB_API_URL} ${GITHUB_USER_CONTENT_URL} ${SUPABASE_ASSETS_URL} ${USERCENTRICS_URLS}`
75-
const SCRIPT_SRC_URLS = `${CLOUDFLARE_CDN_URL} ${HCAPTCHA_JS_URL} ${STRIPE_JS_URL} ${SUPABASE_ASSETS_URL}`
76-
const FRAME_SRC_URLS = `${HCAPTCHA_ASSET_URL} ${STRIPE_JS_URL}`
77-
const IMG_SRC_URLS = `${SUPABASE_URL} ${SUPABASE_COM_URL} ${SUPABASE_PROJECTS_URL} ${GITHUB_USER_AVATAR_URL} ${GOOGLE_USER_AVATAR_URL} ${SUPABASE_ASSETS_URL} ${USERCENTRICS_APP_URL}`
78-
const STYLE_SRC_URLS = `${CLOUDFLARE_CDN_URL} ${SUPABASE_ASSETS_URL}`
79-
const FONT_SRC_URLS = `${CLOUDFLARE_CDN_URL} ${SUPABASE_ASSETS_URL}`
80-
81-
const csp = [
82-
...(process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' ||
83-
process.env.NEXT_PUBLIC_ENVIRONMENT === 'local' ||
84-
process.env.NEXT_PUBLIC_ENVIRONMENT === 'staging'
85-
? [
86-
`default-src 'self' ${DEFAULT_SRC_URLS} ${SUPABASE_STAGING_PROJECTS_URL} ${SUPABASE_STAGING_PROJECTS_URL_WS} ${VERCEL_LIVE_URL} ${PUSHER_URL_WS} ${SUPABASE_DOCS_PROJECT_URL} ${SUPABASE_CONTENT_API_URL} ${SENTRY_URL};`,
87-
`script-src 'self' 'unsafe-eval' 'unsafe-inline' ${SCRIPT_SRC_URLS} ${VERCEL_LIVE_URL} ${PUSHER_URL};`,
88-
`frame-src 'self' ${FRAME_SRC_URLS} ${VERCEL_LIVE_URL};`,
89-
`img-src 'self' blob: data: ${IMG_SRC_URLS} ${SUPABASE_STAGING_PROJECTS_URL} ${VERCEL_URL};`,
90-
`style-src 'self' 'unsafe-inline' ${STYLE_SRC_URLS} ${VERCEL_LIVE_URL};`,
91-
`font-src 'self' ${FONT_SRC_URLS} ${VERCEL_LIVE_URL};`,
92-
`worker-src 'self' blob: data:;`,
93-
]
94-
: [
95-
`default-src 'self' ${DEFAULT_SRC_URLS} ${PUSHER_URL_WS} ${SENTRY_URL};`,
96-
`script-src 'self' 'unsafe-eval' 'unsafe-inline' ${SCRIPT_SRC_URLS} ${VERCEL_LIVE_URL} ${PUSHER_URL};`,
97-
`frame-src 'self' ${FRAME_SRC_URLS} ${VERCEL_LIVE_URL};`,
98-
`img-src 'self' blob: data: ${IMG_SRC_URLS} ;`,
99-
`style-src 'self' 'unsafe-inline' ${STYLE_SRC_URLS} ${VERCEL_LIVE_URL};`,
100-
`font-src 'self' ${FONT_SRC_URLS} ${VERCEL_LIVE_URL};`,
101-
`worker-src 'self' blob: data:;`,
102-
]),
103-
`object-src 'none';`,
104-
`base-uri 'self';`,
105-
`form-action 'self';`,
106-
`frame-ancestors 'none';`,
107-
`block-all-mixed-content;`,
108-
...(process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' &&
109-
process.env.NEXT_PUBLIC_ENVIRONMENT === 'prod'
110-
? [`upgrade-insecure-requests;`]
111-
: []),
112-
].join(' ')
113-
11410
function getAssetPrefix() {
11511
// If not force enabled, but not production env, disable CDN
11612
if (process.env.FORCE_ASSET_CDN !== '1' && process.env.VERCEL_ENV !== 'production') {
@@ -511,7 +407,8 @@ const nextConfig = {
511407
},
512408
{
513409
key: 'Content-Security-Policy',
514-
value: process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' ? csp : "frame-ancestors 'none';",
410+
value:
411+
process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' ? getCSP() : "frame-ancestors 'none';",
515412
},
516413
{
517414
key: 'Referrer-Policy',

0 commit comments

Comments
 (0)