Skip to content

Commit

Permalink
Prod 1328 Track more granular consent method (#4419)
Browse files Browse the repository at this point in the history
  • Loading branch information
eastandwestwind committed Nov 12, 2023
1 parent 79a24bb commit 2727b74
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 69 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion clients/admin-ui/src/types/api/models/ConsentMethod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}
17 changes: 11 additions & 6 deletions clients/fides-js/src/components/ConsentButtons.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand Down Expand Up @@ -66,7 +67,7 @@ type NoticeKeys = Array<PrivacyNotice["notice_key"]>;

interface NoticeConsentButtonProps {
experience: PrivacyExperience;
onSave: (noticeKeys: NoticeKeys) => void;
onSave: (consentMethod: ConsentMethod, noticeKeys: NoticeKeys) => void;
onManagePreferencesClick?: () => void;
enabledKeys: NoticeKeys;
isAcknowledge: boolean;
Expand All @@ -89,19 +90,23 @@ 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)
);
};

const handleSave = () => {
onSave(enabledKeys);
onSave(ConsentMethod.save, enabledKeys);
};

if (isAcknowledge) {
Expand Down
21 changes: 15 additions & 6 deletions clients/fides-js/src/components/notices/NoticeOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
};

const handleUpdatePreferences = useCallback(
(enabledPrivacyNoticeKeys: Array<PrivacyNotice["notice_key"]>) => {
(
consentMethod: ConsentMethod,
enabledPrivacyNoticeKeys: Array<PrivacyNotice["notice_key"]>
) => {
const consentPreferencesToSave = createConsentPreferencesToSave(
privacyNotices,
enabledPrivacyNoticeKeys,
Expand All @@ -96,7 +99,7 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
updateConsentPreferences({
consentPreferencesToSave,
experience,
consentMethod: ConsentMethod.button,
consentMethod,
options,
userLocationString: fidesRegionString,
cookie,
Expand Down Expand Up @@ -154,8 +157,11 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
experience={experience}
onManagePreferencesClick={onManagePreferencesClick}
enabledKeys={draftEnabledNoticeKeys}
onSave={(keys) => {
handleUpdatePreferences(keys);
onSave={(
consentMethod: ConsentMethod,
keys: Array<PrivacyNotice["notice_key"]>
) => {
handleUpdatePreferences(consentMethod, keys);
onSave();
}}
isAcknowledge={isAllNoticeOnly}
Expand Down Expand Up @@ -183,8 +189,11 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
<NoticeConsentButtons
experience={experience}
enabledKeys={draftEnabledNoticeKeys}
onSave={(keys) => {
handleUpdatePreferences(keys);
onSave={(
consentMethod: ConsentMethod,
keys: Array<PrivacyNotice["notice_key"]>
) => {
handleUpdatePreferences(consentMethod, keys);
onClose();
}}
isInModal
Expand Down
8 changes: 4 additions & 4 deletions clients/fides-js/src/components/tcf/TcfConsentButtons.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -48,7 +48,7 @@ export const TcfConsentButtons = ({
...(experience.tcf_system_legitimate_interests || []),
]),
};
onSave(allIds);
onSave(ConsentMethod.accept, allIds);
};
const handleRejectAll = () => {
const emptyIds: EnabledIds = {
Expand All @@ -60,7 +60,7 @@ export const TcfConsentButtons = ({
vendorsConsent: [],
vendorsLegint: [],
};
onSave(emptyIds);
onSave(ConsentMethod.reject, emptyIds);
};

return (
Expand Down
24 changes: 12 additions & 12 deletions clients/fides-js/src/components/tcf/TcfOverlay.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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";
Expand Down Expand Up @@ -293,7 +293,7 @@ const TcfOverlay: FunctionComponent<OverlayProps> = ({
});

const handleUpdateAllPreferences = useCallback(
(enabledIds: EnabledIds) => {
(consentMethod: ConsentMethod, enabledIds: EnabledIds) => {
const tcf = createTcfSavePayload({
experience,
enabledIds,
Expand All @@ -302,7 +302,7 @@ const TcfOverlay: FunctionComponent<OverlayProps> = ({
updateConsentPreferences({
consentPreferencesToSave: [],
experience,
consentMethod: ConsentMethod.button,
consentMethod,
options,
userLocationString: fidesRegionString,
cookie,
Expand Down Expand Up @@ -361,8 +361,8 @@ const TcfOverlay: FunctionComponent<OverlayProps> = ({
<TcfConsentButtons
experience={experience}
onManagePreferencesClick={onManagePreferencesClick}
onSave={(keys) => {
handleUpdateAllPreferences(keys);
onSave={(consentMethod: ConsentMethod, keys: EnabledIds) => {
handleUpdateAllPreferences(consentMethod, keys);
onSave();
}}
isMobile={isMobile}
Expand Down Expand Up @@ -394,8 +394,8 @@ const TcfOverlay: FunctionComponent<OverlayProps> = ({
/>
)}
renderModalFooter={({ onClose, isMobile }) => {
const onSave = (keys: EnabledIds) => {
handleUpdateAllPreferences(keys);
const onSave = (consentMethod: ConsentMethod, keys: EnabledIds) => {
handleUpdateAllPreferences(consentMethod, keys);
onClose();
};
return (
Expand All @@ -407,7 +407,7 @@ const TcfOverlay: FunctionComponent<OverlayProps> = ({
<Button
buttonType={ButtonType.SECONDARY}
label={experience.experience_config?.save_button_label}
onClick={() => onSave(draftIds)}
onClick={() => onSave(ConsentMethod.save, draftIds)}
className="fides-save-button"
/>
}
Expand Down
8 changes: 7 additions & 1 deletion clients/fides-js/src/lib/consent-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ export type FidesApiOptions = {
/**
* Intake a custom function that is called instead of the internal Fides API to save user preferences.
*
* @param {object} consentMethod - method that was used to obtain consent
* @param {object} consent - updated version of Fides.consent with the user's saved preferences for Fides notices
* @param {string} fides_string - updated version of Fides.fides_string with the user's saved preferences for TC/AC/etc notices
* @param {object} experience - current version of the privacy experience that was shown to the user
*/
savePreferencesFn?: (
consentMethod: ConsentMethod,
consent: CookieKeyConsent,
fides_string: string | undefined,
experience: PrivacyExperience
Expand Down Expand Up @@ -398,7 +400,11 @@ export enum ButtonType {
}

export enum ConsentMethod {
button = "button",
button = "button", // deprecated- keeping for backwards-compatibility
reject = "reject",
accept = "accept",
save = "save",
dismiss = "dismiss",
gpc = "gpc",
individual_notice = "api",
}
Expand Down
6 changes: 5 additions & 1 deletion clients/fides-js/src/lib/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ export const dispatchFidesEvent = (
extraDetails?.servingComponent
? `from ${extraDetails.servingComponent} `
: ""
}with cookie ${JSON.stringify(cookie)}`
}with cookie ${JSON.stringify(cookie)} ${
extraDetails?.consentMethod
? `using consent method ${extraDetails.consentMethod} `
: ""
}`
);
window.dispatchEvent(event);
}
Expand Down
3 changes: 2 additions & 1 deletion clients/fides-js/src/lib/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ async function savePreferencesApi(
...(tcf ?? []),
};
await patchUserPreference(
consentMethod,
privacyPreferenceCreate,
options,
cookie,
Expand Down Expand Up @@ -130,5 +131,5 @@ export const updateConsentPreferences = async ({
}

// 6. Dispatch a "FidesUpdated" event
dispatchFidesEvent("FidesUpdated", cookie, options.debug);
dispatchFidesEvent("FidesUpdated", cookie, options.debug, { consentMethod });
};
3 changes: 3 additions & 0 deletions clients/fides-js/src/services/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
ComponentType,
ConsentMethod,
EmptyExperience,
FidesApiOptions,
FidesOptions,
Expand Down Expand Up @@ -114,6 +115,7 @@ const PATCH_FETCH_OPTIONS: RequestInit = {
* Sends user consent preference downstream to Fides or custom API
*/
export const patchUserPreference = async (
consentMethod: ConsentMethod,
preferences: PrivacyPreferencesRequest,
options: FidesOptions,
cookie: FidesCookie,
Expand All @@ -124,6 +126,7 @@ export const patchUserPreference = async (
debugLog(options.debug, "Calling custom save preferences fn");
try {
await options.apiOptions.savePreferencesFn(
consentMethod,
cookie.consent,
cookie.fides_string,
experience
Expand Down
Loading

0 comments on commit 2727b74

Please sign in to comment.