From 2727b74f80b3eacf432bdd2fbc5063c9bda247a4 Mon Sep 17 00:00:00 2001 From: Catherine Smith Date: Sat, 11 Nov 2023 02:53:48 +0100 Subject: [PATCH] Prod 1328 Track more granular consent method (#4419) --- CHANGELOG.md | 1 + .../src/types/api/models/ConsentMethod.ts | 6 +- .../src/components/ConsentButtons.tsx | 17 ++- .../src/components/notices/NoticeOverlay.tsx | 21 +++- .../src/components/tcf/TcfConsentButtons.tsx | 8 +- .../src/components/tcf/TcfOverlay.tsx | 24 ++-- clients/fides-js/src/lib/consent-types.ts | 8 +- clients/fides-js/src/lib/events.ts | 6 +- clients/fides-js/src/lib/preferences.ts | 3 +- clients/fides-js/src/services/api.ts | 3 + .../cypress/e2e/consent-banner-tcf.cy.ts | 103 ++++++++++++------ .../cypress/e2e/consent-banner.cy.ts | 37 ++++++- src/fides/api/models/privacy_preference.py | 6 +- 13 files changed, 174 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38d4319c88..a810979d87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The types of changes are: ### Added - Adds support for custom get experiences fn and custom patch notices served fn [#4410](https://github.com/ethyca/fides/pull/4410) +- Adds more granularity to tracking consent method, updates custom savePreferencesFn and FidesUpdated event to take consent method [#4419](https://github.com/ethyca/fides/pull/4419) ### Changed - Button ordering in fides.js UI [#4407](https://github.com/ethyca/fides/pull/4407) diff --git a/clients/admin-ui/src/types/api/models/ConsentMethod.ts b/clients/admin-ui/src/types/api/models/ConsentMethod.ts index 8d0b4dd52c..359761155a 100644 --- a/clients/admin-ui/src/types/api/models/ConsentMethod.ts +++ b/clients/admin-ui/src/types/api/models/ConsentMethod.ts @@ -6,7 +6,11 @@ * An enumeration. */ export enum ConsentMethod { - BUTTON = "button", + BUTTON = "button", // deprecated- keeping for backwards-compatibility + REJECT = "reject", + ACCEPT = "accept", + SAVE = "save", + DISMISS = "dismiss", GPC = "gpc", INDIVIDUAL_NOTICE = "individual_notice", } diff --git a/clients/fides-js/src/components/ConsentButtons.tsx b/clients/fides-js/src/components/ConsentButtons.tsx index 06e40d9b95..7e9621ccba 100644 --- a/clients/fides-js/src/components/ConsentButtons.tsx +++ b/clients/fides-js/src/components/ConsentButtons.tsx @@ -1,11 +1,12 @@ -import { h, VNode } from "preact"; +import { VNode, h } from "preact"; import Button from "./Button"; import { ButtonType, - PrivacyExperience, ConsentMechanism, - PrivacyNotice, + ConsentMethod, ExperienceConfig, + PrivacyExperience, + PrivacyNotice, } from "../lib/consent-types"; import PrivacyPolicyLink from "./PrivacyPolicyLink"; @@ -66,7 +67,7 @@ type NoticeKeys = Array; interface NoticeConsentButtonProps { experience: PrivacyExperience; - onSave: (noticeKeys: NoticeKeys) => void; + onSave: (consentMethod: ConsentMethod, noticeKeys: NoticeKeys) => void; onManagePreferencesClick?: () => void; enabledKeys: NoticeKeys; isAcknowledge: boolean; @@ -89,11 +90,15 @@ export const NoticeConsentButtons = ({ const { experience_config: config, privacy_notices: notices } = experience; const handleAcceptAll = () => { - onSave(notices.map((n) => n.notice_key)); + onSave( + ConsentMethod.accept, + notices.map((n) => n.notice_key) + ); }; const handleRejectAll = () => { onSave( + ConsentMethod.reject, notices .filter((n) => n.consent_mechanism === ConsentMechanism.NOTICE_ONLY) .map((n) => n.notice_key) @@ -101,7 +106,7 @@ export const NoticeConsentButtons = ({ }; const handleSave = () => { - onSave(enabledKeys); + onSave(ConsentMethod.save, enabledKeys); }; if (isAcknowledge) { diff --git a/clients/fides-js/src/components/notices/NoticeOverlay.tsx b/clients/fides-js/src/components/notices/NoticeOverlay.tsx index 6cfb6a8faa..2980814e64 100644 --- a/clients/fides-js/src/components/notices/NoticeOverlay.tsx +++ b/clients/fides-js/src/components/notices/NoticeOverlay.tsx @@ -86,7 +86,10 @@ const NoticeOverlay: FunctionComponent = ({ }; const handleUpdatePreferences = useCallback( - (enabledPrivacyNoticeKeys: Array) => { + ( + consentMethod: ConsentMethod, + enabledPrivacyNoticeKeys: Array + ) => { const consentPreferencesToSave = createConsentPreferencesToSave( privacyNotices, enabledPrivacyNoticeKeys, @@ -96,7 +99,7 @@ const NoticeOverlay: FunctionComponent = ({ updateConsentPreferences({ consentPreferencesToSave, experience, - consentMethod: ConsentMethod.button, + consentMethod, options, userLocationString: fidesRegionString, cookie, @@ -154,8 +157,11 @@ const NoticeOverlay: FunctionComponent = ({ experience={experience} onManagePreferencesClick={onManagePreferencesClick} enabledKeys={draftEnabledNoticeKeys} - onSave={(keys) => { - handleUpdatePreferences(keys); + onSave={( + consentMethod: ConsentMethod, + keys: Array + ) => { + handleUpdatePreferences(consentMethod, keys); onSave(); }} isAcknowledge={isAllNoticeOnly} @@ -183,8 +189,11 @@ const NoticeOverlay: FunctionComponent = ({ { - handleUpdatePreferences(keys); + onSave={( + consentMethod: ConsentMethod, + keys: Array + ) => { + handleUpdatePreferences(consentMethod, keys); onClose(); }} isInModal diff --git a/clients/fides-js/src/components/tcf/TcfConsentButtons.tsx b/clients/fides-js/src/components/tcf/TcfConsentButtons.tsx index 562a661019..d77eb95d1d 100644 --- a/clients/fides-js/src/components/tcf/TcfConsentButtons.tsx +++ b/clients/fides-js/src/components/tcf/TcfConsentButtons.tsx @@ -1,13 +1,13 @@ import { VNode, h } from "preact"; -import { PrivacyExperience } from "../../lib/consent-types"; +import { ConsentMethod, PrivacyExperience } from "../../lib/consent-types"; import { ConsentButtons } from "../ConsentButtons"; import type { EnabledIds, TcfModels } from "../../lib/tcf/types"; interface TcfConsentButtonProps { experience: PrivacyExperience; onManagePreferencesClick?: () => void; - onSave: (keys: EnabledIds) => void; + onSave: (consentMethod: ConsentMethod, keys: EnabledIds) => void; firstButton?: VNode; isMobile: boolean; includePrivacyPolicy?: boolean; @@ -48,7 +48,7 @@ export const TcfConsentButtons = ({ ...(experience.tcf_system_legitimate_interests || []), ]), }; - onSave(allIds); + onSave(ConsentMethod.accept, allIds); }; const handleRejectAll = () => { const emptyIds: EnabledIds = { @@ -60,7 +60,7 @@ export const TcfConsentButtons = ({ vendorsConsent: [], vendorsLegint: [], }; - onSave(emptyIds); + onSave(ConsentMethod.reject, emptyIds); }; return ( diff --git a/clients/fides-js/src/components/tcf/TcfOverlay.tsx b/clients/fides-js/src/components/tcf/TcfOverlay.tsx index 5d71d7e354..351c0a527c 100644 --- a/clients/fides-js/src/components/tcf/TcfOverlay.tsx +++ b/clients/fides-js/src/components/tcf/TcfOverlay.tsx @@ -1,5 +1,5 @@ -import { h, FunctionComponent, Fragment } from "preact"; -import { useState, useCallback, useMemo } from "preact/hooks"; +import { Fragment, FunctionComponent, h } from "preact"; +import { useCallback, useMemo, useState } from "preact/hooks"; import ConsentBanner from "../ConsentBanner"; import PrivacyPolicyLink from "../PrivacyPolicyLink"; @@ -18,16 +18,16 @@ import type { EnabledIds, TCFFeatureRecord, TCFFeatureSave, + TcfModels, TCFPurposeConsentRecord, TCFPurposeLegitimateInterestsRecord, TCFPurposeSave, + TcfSavePreferences, TCFSpecialFeatureSave, TCFSpecialPurposeSave, - TCFVendorSave, - TcfSavePreferences, TCFVendorConsentRecord, TCFVendorLegitimateInterestsRecord, - TcfModels, + TCFVendorSave, } from "../../lib/tcf/types"; import { updateConsentPreferences } from "../../lib/preferences"; @@ -293,7 +293,7 @@ const TcfOverlay: FunctionComponent = ({ }); const handleUpdateAllPreferences = useCallback( - (enabledIds: EnabledIds) => { + (consentMethod: ConsentMethod, enabledIds: EnabledIds) => { const tcf = createTcfSavePayload({ experience, enabledIds, @@ -302,7 +302,7 @@ const TcfOverlay: FunctionComponent = ({ updateConsentPreferences({ consentPreferencesToSave: [], experience, - consentMethod: ConsentMethod.button, + consentMethod, options, userLocationString: fidesRegionString, cookie, @@ -361,8 +361,8 @@ const TcfOverlay: FunctionComponent = ({ { - handleUpdateAllPreferences(keys); + onSave={(consentMethod: ConsentMethod, keys: EnabledIds) => { + handleUpdateAllPreferences(consentMethod, keys); onSave(); }} isMobile={isMobile} @@ -394,8 +394,8 @@ const TcfOverlay: FunctionComponent = ({ /> )} renderModalFooter={({ onClose, isMobile }) => { - const onSave = (keys: EnabledIds) => { - handleUpdateAllPreferences(keys); + const onSave = (consentMethod: ConsentMethod, keys: EnabledIds) => { + handleUpdateAllPreferences(consentMethod, keys); onClose(); }; return ( @@ -407,7 +407,7 @@ const TcfOverlay: FunctionComponent = ({