Files
supabase/packages/common/consent-state.ts
Igor Mytyuk fa2c766aea fix(consent-state): add IS_PLATFORM check in initUserCentrics() (#35805)
- The check on IS_PLATFORM should skip the usercentrics initialization in self-hosted environment and prevent the dashboard errors
2025-05-26 20:15:54 +08:00

111 lines
3.3 KiB
TypeScript

import type Usercentrics from '@usercentrics/cmp-browser-sdk'
import type { BaseCategory, UserDecision } from '@usercentrics/cmp-browser-sdk'
import { proxy, snapshot, useSnapshot } from 'valtio'
import { LOCAL_STORAGE_KEYS, IS_PLATFORM } from './constants'
export const consentState = proxy({
// Usercentrics state
UC: null as Usercentrics | null,
categories: null as BaseCategory[] | null,
// Our state
showConsentToast: false,
hasConsented: false,
acceptAll: () => {
if (!consentState.UC) return
const previousConsentValue = consentState.hasConsented
consentState.hasConsented = true
consentState.showConsentToast = false
consentState.UC.acceptAllServices()
.then(() => {
consentState.categories = consentState.UC?.getCategoriesBaseInfo() ?? null
})
.catch(() => {
consentState.hasConsented = previousConsentValue
consentState.showConsentToast = true
})
},
denyAll: () => {
if (!consentState.UC) return
const previousConsentValue = consentState.hasConsented
consentState.hasConsented = false
consentState.showConsentToast = false
consentState.UC.denyAllServices()
.then(() => {
consentState.categories = consentState.UC?.getCategoriesBaseInfo() ?? null
})
.catch(() => {
consentState.showConsentToast = previousConsentValue
})
},
updateServices: (decisions: UserDecision[]) => {
if (!consentState.UC) return
consentState.showConsentToast = false
consentState.UC.updateServices(decisions)
.then(() => {
consentState.hasConsented = consentState.UC?.areAllConsentsAccepted() ?? false
consentState.categories = consentState.UC?.getCategoriesBaseInfo() ?? null
})
.catch(() => {
consentState.showConsentToast = true
})
},
})
async function initUserCentrics() {
if (process.env.NODE_ENV === 'test') return
if (!IS_PLATFORM) return
const { default: Usercentrics } = await import('@usercentrics/cmp-browser-sdk')
const UC = new Usercentrics(process.env.NEXT_PUBLIC_USERCENTRICS_RULESET_ID!, {
rulesetId: process.env.NEXT_PUBLIC_USERCENTRICS_RULESET_ID,
useRulesetId: true,
})
const initialUIValues = await UC.init()
consentState.UC = UC
const hasConsented = UC.areAllConsentsAccepted()
// 0 = first layer, aka show consent toast
consentState.showConsentToast = initialUIValues.initialLayer === 0
consentState.hasConsented = hasConsented
consentState.categories = UC.getCategoriesBaseInfo()
// If the user has previously consented (before usercentrics), accept all services
if (!hasConsented && localStorage?.getItem(LOCAL_STORAGE_KEYS.TELEMETRY_CONSENT) === 'true') {
consentState.acceptAll()
localStorage.removeItem(LOCAL_STORAGE_KEYS.TELEMETRY_CONSENT)
}
}
// Usercentrics is not available on the server
if (typeof window !== 'undefined') {
initUserCentrics()
}
// Public API for consent
export function hasConsented() {
return snapshot(consentState).hasConsented
}
export function useConsentState() {
const snap = useSnapshot(consentState)
return {
hasAccepted: snap.hasConsented,
categories: snap.categories as BaseCategory[] | null,
acceptAll: snap.acceptAll,
denyAll: snap.denyAll,
updateServices: snap.updateServices,
}
}