From 4881704486bf95e72fb1ba8a0f862353424eab72 Mon Sep 17 00:00:00 2001 From: eastandwestwind Date: Mon, 18 Sep 2023 18:51:00 -0400 Subject: [PATCH] account for TCF not using notices --- clients/fides-js/src/fides.ts | 9 ++++---- clients/fides-js/src/lib/consent-types.ts | 4 +++- clients/fides-js/src/lib/consent-utils.ts | 27 ++++++++++++++--------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/clients/fides-js/src/fides.ts b/clients/fides-js/src/fides.ts index bc23cc74e8..6d25d5089f 100644 --- a/clients/fides-js/src/fides.ts +++ b/clients/fides-js/src/fides.ts @@ -72,10 +72,11 @@ import { import { constructFidesRegionString, debugLog, - experienceIsValidAndHasNotices, + experienceIsValid, experienceHasNotices, transformConsentToFidesUserPreference, validateOptions, + isEmptyExperience, } from "./lib/consent-utils"; import { dispatchFidesEvent } from "./lib/events"; import { fetchExperience } from "./services/fides/api"; @@ -217,7 +218,7 @@ const init = async ({ _Fides.geolocation = geolocation; _Fides.options = options; _Fides.initialized = true; - if (experienceHasNotices(experience)) { + if (experience && !isEmptyExperience(experience)) { // at this point, pre-fetched experience contains no user consent, so we populate with the Fides cookie updateExperienceFromCookieConsent( experience as PrivacyExperience, @@ -254,7 +255,7 @@ const init = async ({ `User location could not be obtained. Skipping overlay initialization.` ); shouldInitOverlay = false; - } else if (!experienceHasNotices(experience)) { + } else if (!experience || isEmptyExperience(experience)) { effectiveExperience = await fetchExperience( fidesRegionString, options.fidesApiUrl, @@ -263,7 +264,7 @@ const init = async ({ ); } - if (experienceIsValidAndHasNotices(effectiveExperience, options)) { + if (experienceIsValid(effectiveExperience, options)) { // Overwrite cookie consent with experience-based consent values cookie.consent = buildCookieConsentForExperiences( effectiveExperience as PrivacyExperience, diff --git a/clients/fides-js/src/lib/consent-types.ts b/clients/fides-js/src/lib/consent-types.ts index c4af06b1a7..9f238b2434 100644 --- a/clients/fides-js/src/lib/consent-types.ts +++ b/clients/fides-js/src/lib/consent-types.ts @@ -1,10 +1,12 @@ +export type EmptyExperience = {}; + export interface FidesConfig { // Set the consent defaults from a "legacy" Privacy Center config.json. consent?: LegacyConsentConfig; // Set the "experience" to be used for this Fides.js instance -- overrides the "legacy" config. // If set, Fides.js will fetch neither experience config nor user geolocation. // If not set or is empty, Fides.js will attempt to fetch its own experience config. - experience?: PrivacyExperience | {}; + experience?: PrivacyExperience | EmptyExperience; // Set the geolocation for this Fides.js instance. If *not* set, Fides.js will fetch its own geolocation. geolocation?: UserGeolocation; // Global options for this Fides.js instance. Fides provides defaults for all props except privacyCenterUrl diff --git a/clients/fides-js/src/lib/consent-utils.ts b/clients/fides-js/src/lib/consent-utils.ts index d89c74a69e..6c2a393431 100644 --- a/clients/fides-js/src/lib/consent-utils.ts +++ b/clients/fides-js/src/lib/consent-utils.ts @@ -2,6 +2,7 @@ import { ConsentContext } from "./consent-context"; import { ComponentType, ConsentMechanism, + EmptyExperience, FidesOptions, GpcStatus, PrivacyExperience, @@ -26,21 +27,25 @@ export const debugLog = ( } }; +/** + * Returns true if privacy experience is null or empty + */ +export const isEmptyExperience = (obj: unknown): obj is EmptyExperience => + typeof obj === "object" && obj != null && Object.keys(obj).length === 0; + /** * Returns true if privacy experience has notices */ export const experienceHasNotices = ( experience: PrivacyExperience | undefined | {} -): boolean => { - if (experience && Object.keys(experience).length >= 0) { - const privacyExperience = experience as PrivacyExperience; - return Boolean( - privacyExperience.privacy_notices && - privacyExperience.privacy_notices.length > 0 - ); - } - return false; -}; +): boolean => + Boolean( + experience && + !isEmptyExperience(experience) && + // fixme: how to tell ts that privacy_notices exists on experience? + experience.privacy_notices && + experience.privacy_notices.length > 0 + ); /** * Construct user location str to be ingested by Fides API @@ -155,7 +160,7 @@ export const validateOptions = (options: FidesOptions): boolean => { /** * Determines whether experience is valid and relevant notices exist within the experience */ -export const experienceIsValidAndHasNotices = ( +export const experienceIsValid = ( effectiveExperience: PrivacyExperience | undefined | {}, options: FidesOptions ): boolean => {