Skip to content

Commit

Permalink
add fides_accept_all override option
Browse files Browse the repository at this point in the history
  • Loading branch information
gilluminate committed Nov 27, 2024
1 parent c126f4e commit 7e5a316
Show file tree
Hide file tree
Showing 16 changed files with 217 additions and 125 deletions.
13 changes: 13 additions & 0 deletions clients/fides-js/docs/interfaces/FidesOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,16 @@ context (e.g. a native app, another website, etc.) and you want to ensure
that those preferences are respected.

Defaults to `false`.

***

### fides\_accept\_all

> **fides\_accept\_all**: `boolean`
Similar to `fides_reject_all`, when `true`, FidesJS will automatically opt
in to all consent and only show the consent modal upon user request. These 2
options are mutually exclusive, and `fides_accept_all` will take precedence
if both are set to `true`.

Defaults to `false`.
2 changes: 1 addition & 1 deletion clients/fides-js/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const GZIP_SIZE_ERROR_KB = 45; // fail build if bundle size exceeds this
const GZIP_SIZE_WARN_KB = 35; // log a warning if bundle size exceeds this

// TCF
const GZIP_SIZE_TCF_ERROR_KB = 85;
const GZIP_SIZE_TCF_ERROR_KB = 85.5;
const GZIP_SIZE_TCF_WARN_KB = 75;

const preactAliases = {
Expand Down
25 changes: 6 additions & 19 deletions clients/fides-js/src/components/ConsentButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useEffect, useState } from "preact/hooks";

import {
ButtonType,
ConsentMechanism,
ConsentMethod,
FidesInitOptions,
PrivacyExperience,
Expand Down Expand Up @@ -139,6 +138,8 @@ type NoticeKeys = Array<PrivacyNotice["notice_key"]>;

interface NoticeConsentButtonProps {
experience: PrivacyExperience;
onAcceptAll: () => void;
onRejectAll: () => void;
onSave: (consentMethod: ConsentMethod, noticeKeys: NoticeKeys) => void;
onManagePreferencesClick?: () => void;
enabledKeys: NoticeKeys;
Expand All @@ -150,6 +151,8 @@ interface NoticeConsentButtonProps {

export const NoticeConsentButtons = ({
experience,
onAcceptAll,
onRejectAll,
onSave,
onManagePreferencesClick,
enabledKeys,
Expand All @@ -164,29 +167,13 @@ export const NoticeConsentButtons = ({
}
const { privacy_notices: notices } = experience;

const handleAcceptAll = () => {
onSave(
ConsentMethod.ACCEPT,
notices.map((n) => n.notice_key),
);
};

const handleAcknowledgeNotices = () => {
onSave(
ConsentMethod.ACKNOWLEDGE,
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(ConsentMethod.SAVE, enabledKeys);
};
Expand Down Expand Up @@ -219,8 +206,8 @@ export const NoticeConsentButtons = ({
<ConsentButtons
availableLocales={experience.available_locales}
onManagePreferencesClick={onManagePreferencesClick}
onAcceptAll={handleAcceptAll}
onRejectAll={handleRejectAll}
onAcceptAll={onAcceptAll}
onRejectAll={onRejectAll}
isInModal={isInModal}
renderFirstButton={renderFirstButton}
hideOptInOut={hideOptInOut}
Expand Down
9 changes: 3 additions & 6 deletions clients/fides-js/src/components/Overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ interface RenderBannerProps {
isOpen: boolean;
isEmbedded: boolean;
onClose: () => void;
onSave: () => void;
onManagePreferencesClick: () => void;
}

Expand Down Expand Up @@ -72,14 +71,15 @@ const Overlay: FunctionComponent<Props> = ({
const delayBannerMilliseconds = 100;
const delayModalLinkMilliseconds = 200;
const hasMounted = useHasMounted();
const isAutoConsented = options.fidesAcceptAll || options.fidesRejectAll;

const showBanner = useMemo(
() =>
!options.fidesRejectAll &&
!isAutoConsented &&
!options.fidesDisableBanner &&
experience.experience_config?.component !== ComponentType.MODAL &&
shouldResurfaceConsent(experience, cookie, savedConsent),
[cookie, savedConsent, experience, options],
[cookie, savedConsent, experience, options, isAutoConsented],
);

const [bannerIsOpen, setBannerIsOpen] = useState(
Expand Down Expand Up @@ -238,9 +238,6 @@ const Overlay: FunctionComponent<Props> = ({
onClose: () => {
setBannerIsOpen(false);
},
onSave: () => {
setBannerIsOpen(false);
},
onManagePreferencesClick: handleManagePreferencesClick,
})
: null}
Expand Down
65 changes: 52 additions & 13 deletions clients/fides-js/src/components/notices/NoticeOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,26 +229,50 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
],
);

const handleAcceptAll = useCallback(() => {
handleUpdatePreferences(
ConsentMethod.ACCEPT,
privacyNoticeItems.map((n) => n.notice.notice_key),
);
}, [handleUpdatePreferences, privacyNoticeItems]);

const handleRejectAll = useCallback(() => {
handleUpdatePreferences(
ConsentMethod.REJECT,
privacyNoticeItems
.filter(
(n) => n.notice.consent_mechanism === ConsentMechanism.NOTICE_ONLY,
)
.map((n) => n.notice.notice_key),
);
}, [handleUpdatePreferences, privacyNoticeItems]);

useEffect(() => {
if (
handleUpdatePreferences &&
options.fidesRejectAll &&
((handleAcceptAll && options.fidesRejectAll) ||
(handleRejectAll && options.fidesAcceptAll)) &&
experience.privacy_notices
) {
fidesDebugger(
"Consent automatically rejected by fides_reject_all override!",
);
handleUpdatePreferences(
ConsentMethod.REJECT,
experience.privacy_notices
.filter((n) => n.consent_mechanism === ConsentMechanism.NOTICE_ONLY)
.map((n) => n.notice_key),
);
if (options.fidesAcceptAll) {
// fidesAcceptAll takes precedence over fidesRejectAll
fidesDebugger(
"Consent automatically accepted by fides_accept_all override!",
);
handleAcceptAll();
} else if (options.fidesRejectAll) {
fidesDebugger(
"Consent automatically rejected by fides_reject_all override!",
);
handleRejectAll();
}
}
}, [
experience.privacy_notices,
handleUpdatePreferences,
options.fidesRejectAll,
options.fidesAcceptAll,
handleAcceptAll,
handleRejectAll,
]);

const dispatchOpenBannerEvent = useCallback(() => {
Expand Down Expand Up @@ -290,7 +314,6 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
isEmbedded,
isOpen,
onClose,
onSave,
onManagePreferencesClick,
}) => {
const isAcknowledge =
Expand All @@ -312,12 +335,20 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
experience={experience}
onManagePreferencesClick={onManagePreferencesClick}
enabledKeys={draftEnabledNoticeKeys}
onAcceptAll={() => {
handleAcceptAll();
onClose();
}}
onRejectAll={() => {
handleRejectAll();
onClose();
}}
onSave={(
consentMethod: ConsentMethod,
keys: Array<PrivacyNotice["notice_key"]>,
) => {
handleUpdatePreferences(consentMethod, keys);
onSave();
onClose();
}}
isAcknowledge={isAcknowledge}
hideOptInOut={isAcknowledge}
Expand Down Expand Up @@ -345,6 +376,14 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
<NoticeConsentButtons
experience={experience}
enabledKeys={draftEnabledNoticeKeys}
onAcceptAll={() => {
handleAcceptAll();
onClose();
}}
onRejectAll={() => {
handleRejectAll();
onClose();
}}
onSave={(
consentMethod: ConsentMethod,
keys: Array<PrivacyNotice["notice_key"]>,
Expand Down
72 changes: 6 additions & 66 deletions clients/fides-js/src/components/tcf/TcfConsentButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,27 @@
import { h, VNode } from "preact";

import {
ConsentMethod,
FidesInitOptions,
PrivacyExperience,
PrivacyExperienceMinimal,
} from "../../lib/consent-types";
import { EMPTY_ENABLED_IDS } from "../../lib/tcf/constants";
import type { EnabledIds, TcfModels } from "../../lib/tcf/types";
import { ConsentButtons } from "../ConsentButtons";

interface TcfConsentButtonProps {
experience: PrivacyExperience | PrivacyExperienceMinimal;
options: FidesInitOptions;
onManagePreferencesClick?: () => void;
onSave: (consentMethod: ConsentMethod, keys: EnabledIds) => void;
onRejectAll: () => void;
onAcceptAll: () => void;
renderFirstButton?: () => VNode;
isInModal?: boolean;
}

const getAllIds = (modelList: TcfModels) => {
if (!modelList) {
return [];
}
return modelList.map((m) => `${m.id}`);
};

export const TcfConsentButtons = ({
experience,
onManagePreferencesClick,
onSave,
onRejectAll,
onAcceptAll,
renderFirstButton,
isInModal,
options,
Expand All @@ -40,64 +32,12 @@ export const TcfConsentButtons = ({

const isGVLLoading = Object.keys(experience.gvl || {}).length === 0;

const handleAcceptAll = () => {
let allIds: EnabledIds;
if (!experience.minimal_tcf) {
// eslint-disable-next-line no-param-reassign
experience = experience as PrivacyExperience;
allIds = {
purposesConsent: getAllIds(experience.tcf_purpose_consents),
purposesLegint: getAllIds(experience.tcf_purpose_legitimate_interests),
specialPurposes: getAllIds(experience.tcf_special_purposes),
features: getAllIds(experience.tcf_features),
specialFeatures: getAllIds(experience.tcf_special_features),
vendorsConsent: getAllIds([
...(experience.tcf_vendor_consents || []),
...(experience.tcf_system_consents || []),
]),
vendorsLegint: getAllIds([
...(experience.tcf_vendor_legitimate_interests || []),
...(experience.tcf_system_legitimate_interests || []),
]),
};
} else {
// eslint-disable-next-line no-param-reassign
experience = experience as PrivacyExperienceMinimal;
allIds = {
purposesConsent:
experience.tcf_purpose_consent_ids?.map((id) => `${id}`) || [],
purposesLegint:
experience.tcf_purpose_legitimate_interest_ids?.map(
(id) => `${id}`,
) || [],
specialPurposes:
experience.tcf_special_purpose_ids?.map((id) => `${id}`) || [],
features: experience.tcf_feature_ids?.map((id) => `${id}`) || [],
specialFeatures:
experience.tcf_special_feature_ids?.map((id) => `${id}`) || [],
vendorsConsent: [
...(experience.tcf_vendor_consent_ids || []),
...(experience.tcf_system_consent_ids || []),
],
vendorsLegint: [
...(experience.tcf_vendor_legitimate_interest_ids || []),
...(experience.tcf_system_legitimate_interest_ids || []),
],
};
}
onSave(ConsentMethod.ACCEPT, allIds);
};
const handleRejectAll = () => {
const emptyIds: EnabledIds = EMPTY_ENABLED_IDS;
onSave(ConsentMethod.REJECT, emptyIds);
};

return (
<ConsentButtons
availableLocales={experience.available_locales}
onManagePreferencesClick={onManagePreferencesClick}
onAcceptAll={handleAcceptAll}
onRejectAll={handleRejectAll}
onAcceptAll={onAcceptAll}
onRejectAll={onRejectAll}
renderFirstButton={renderFirstButton}
isInModal={isInModal}
options={options}
Expand Down
Loading

0 comments on commit 7e5a316

Please sign in to comment.