Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render new TCF fields in the overlay using the data map #4286

Merged
merged 24 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e7f51d8
Update various TS types with latest compass changes
allisonking Oct 16, 2023
e8c5a75
Simplify some code now that vendor relationships contain _all_ vendors
allisonking Oct 16, 2023
678ad16
Merge branch 'main' into aking/4255/tcf-fields
allisonking Oct 16, 2023
6aa9ee3
Use cookie data from TCFVendorRelationships instead of GVL
allisonking Oct 16, 2023
5dc270a
Add privacy_policy_url to TCFVendorRelationships
allisonking Oct 16, 2023
5601de7
Render privacy policy url from vendor
allisonking Oct 16, 2023
2e46ef9
Add retention period field
allisonking Oct 16, 2023
cd898b1
Actually put retention period on embedded data
allisonking Oct 16, 2023
287d4a9
Update TS types again
allisonking Oct 16, 2023
057f4a8
Add retention period to special purpose records
allisonking Oct 16, 2023
5f83cb5
Derive retention from privacy experience response
allisonking Oct 16, 2023
b3ae247
Update changelog
allisonking Oct 16, 2023
3c9131a
Make sure test data fills in relationship arrays
allisonking Oct 16, 2023
7feace9
Update cypress tests
allisonking Oct 17, 2023
c748ef5
Specify "day(s)" for retention period
allisonking Oct 17, 2023
08a7375
Add retention period only in EmbeddedPurpose
allisonking Oct 17, 2023
e2f0d5e
Merge branch 'main' into aking/4255/tcf-fields
allisonking Oct 17, 2023
07403ed
Merge branch 'main' into aking/4255/tcf-fields
allisonking Oct 19, 2023
cd1acff
Remove setting retention period on top level Purposes
allisonking Oct 19, 2023
38be263
Add test for two vendors with same purpose, different retention periods
allisonking Oct 19, 2023
11f0cf2
Remove references to top level purpose retention_period
allisonking Oct 19, 2023
0d98375
Handle empty states a little better
allisonking Oct 19, 2023
c49d5e5
Handle empty retention period string
allisonking Oct 19, 2023
d2e3511
Try to make test less flaky
allisonking Oct 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ The types of changes are:
### Added
- Added a `FidesPreferenceToggled` event to Fides.js to track when user preferences change without being saved [#4253](https://github.com/ethyca/fides/pull/4253)

### Changed
- Derive cookie storage info, privacy policy and legitimate interest disclosure URLs, and data retention data from the data map instead of directly from gvl.json [#4286](https://github.com/ethyca/fides/pull/4286)

## [2.22.0](https://github.com/ethyca/fides/compare/2.21.0...2.22.0)

### Added
Expand Down
1 change: 1 addition & 0 deletions clients/admin-ui/src/types/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export type { DynamoDBDocsSchema } from "./models/DynamoDBDocsSchema";
export { EdgeDirection } from "./models/EdgeDirection";
export type { EmailDocsSchema } from "./models/EmailDocsSchema";
export type { EmbeddedLineItem } from "./models/EmbeddedLineItem";
export type { EmbeddedPurpose } from "./models/EmbeddedPurpose";
export type { EmbeddedVendor } from "./models/EmbeddedVendor";
export type { Endpoint } from "./models/Endpoint";
export { EnforcementLevel } from "./models/EnforcementLevel";
Expand Down
12 changes: 12 additions & 0 deletions clients/admin-ui/src/types/api/models/EmbeddedPurpose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

/**
* Sparse details for an embedded purpose beneath a system or vendor section. Read-only.
*/
export type EmbeddedPurpose = {
id: number;
name: string;
retention_period?: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { UserConsentPreference } from "./UserConsentPreference";
* Schema for a TCF Purpose with Consent Legal Basis returned in the TCF Overlay Experience
*/
export type TCFPurposeConsentRecord = {
retention_period?: string;
allisonking marked this conversation as resolved.
Show resolved Hide resolved
/**
* Official GVL purpose ID. Used for linking with other records, e.g. vendors, cookies, etc.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { UserConsentPreference } from "./UserConsentPreference";
* Schema for a TCF Purpose with Legitimate Interests Legal Basis returned in the TCF Overlay Experience
*/
export type TCFPurposeLegitimateInterestsRecord = {
retention_period?: string;
/**
* Official GVL purpose ID. Used for linking with other records, e.g. vendors, cookies, etc.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { UserConsentPreference } from "./UserConsentPreference";
* records where consent was previously served if applicable.
*/
export type TCFSpecialPurposeRecord = {
retention_period?: string;
/**
* Official GVL purpose ID. Used for linking with other records, e.g. vendors, cookies, etc.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* tslint:disable */
/* eslint-disable */

import type { EmbeddedLineItem } from "./EmbeddedLineItem";
import type { EmbeddedPurpose } from "./EmbeddedPurpose";
import type { UserConsentPreference } from "./UserConsentPreference";

/**
Expand All @@ -18,5 +18,5 @@ export type TCFVendorConsentRecord = {
outdated_preference?: UserConsentPreference;
current_served?: boolean;
outdated_served?: boolean;
purpose_consents?: Array<EmbeddedLineItem>;
purpose_consents?: Array<EmbeddedPurpose>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* tslint:disable */
/* eslint-disable */

import type { EmbeddedLineItem } from "./EmbeddedLineItem";
import type { EmbeddedPurpose } from "./EmbeddedPurpose";
import type { UserConsentPreference } from "./UserConsentPreference";

/**
Expand All @@ -18,5 +18,5 @@ export type TCFVendorLegitimateInterestsRecord = {
outdated_preference?: UserConsentPreference;
current_served?: boolean;
outdated_served?: boolean;
purpose_legitimate_interests?: Array<EmbeddedLineItem>;
purpose_legitimate_interests?: Array<EmbeddedPurpose>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/* eslint-disable */

import type { EmbeddedLineItem } from "./EmbeddedLineItem";
import type { EmbeddedPurpose } from "./EmbeddedPurpose";

/**
* Collects the other relationships for a given vendor - no preferences are saved here
Expand All @@ -12,12 +13,13 @@ export type TCFVendorRelationships = {
has_vendor_id?: boolean;
name?: string;
description?: string;
special_purposes?: Array<EmbeddedLineItem>;
special_purposes?: Array<EmbeddedPurpose>;
features?: Array<EmbeddedLineItem>;
special_features?: Array<EmbeddedLineItem>;
cookie_max_age_seconds?: number;
uses_cookies?: boolean;
cookie_refresh?: boolean;
uses_non_cookie_access?: boolean;
legitimate_interest_disclosure_url?: string;
privacy_policy_url?: string;
};
118 changes: 51 additions & 67 deletions clients/fides-js/src/components/tcf/TcfVendors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import { VNode, h } from "preact";
import { useMemo, useState } from "preact/hooks";
import { Vendor } from "@iabtechlabtcf/core";
import {
GvlDataRetention,
EmbeddedLineItem,
GvlDataCategories,
GvlVendorUrl,
GvlDataDeclarations,
VendorRecord,
EmbeddedPurpose,
} from "../../lib/tcf/types";
import { PrivacyExperience } from "../../lib/consent-types";
import { UpdateEnabledIds } from "./TcfOverlay";
Expand All @@ -21,53 +19,42 @@ import DoubleToggleTable from "./DoubleToggleTable";

const FILTERS = [{ name: "All vendors" }, { name: "IAB TCF vendors" }];

interface Retention {
mapping: Record<number, number>;
default: number;
}

const VendorDetails = ({
label,
lineItems,
dataRetention,
}: {
label: string;
lineItems: EmbeddedLineItem[] | undefined;
dataRetention?: Retention;
lineItems: EmbeddedPurpose[] | undefined;
}) => {
if (!lineItems || lineItems.length === 0) {
return null;
}

const hasRetentionInfo = lineItems.some((li) => li.retention_period);

return (
<table className="fides-vendor-details-table">
<thead>
<tr>
<th width="80%">{label}</th>
{dataRetention ? (
{hasRetentionInfo ? (
<th width="20%" style={{ textAlign: "right" }}>
Retention
</th>
) : null}
</tr>
</thead>
<tbody>
{lineItems.map((item) => {
let retention: string | number = "N/A";
if (dataRetention) {
retention = dataRetention.mapping[item.id] ?? dataRetention.default;
}
return (
<tr key={item.id}>
<td>{item.name}</td>
{dataRetention ? (
<td style={{ textAlign: "right" }}>
{retention == null ? "N/A" : `${retention} day(s)`}
</td>
) : null}
</tr>
);
})}
{lineItems.map((item) => (
<tr key={item.id}>
<td>{item.name}</td>
{hasRetentionInfo ? (
<td style={{ textAlign: "right" }}>
{item.retention_period ?? "N/A"}
</td>
) : null}
</tr>
))}
</tbody>
</table>
);
Expand All @@ -76,11 +63,9 @@ const VendorDetails = ({
const PurposeVendorDetails = ({
purposes,
specialPurposes,
gvlVendor,
}: {
purposes: EmbeddedLineItem[] | undefined;
specialPurposes: EmbeddedLineItem[] | undefined;
gvlVendor: Vendor | undefined;
purposes: EmbeddedPurpose[] | undefined;
specialPurposes: EmbeddedPurpose[] | undefined;
}) => {
const emptyPurposes = purposes ? purposes.length === 0 : true;
const emptySpecialPurposes = specialPurposes
Expand All @@ -90,34 +75,34 @@ const PurposeVendorDetails = ({
if (emptyPurposes && emptySpecialPurposes) {
return null;
}
// @ts-ignore our TCF lib does not have GVL v3 types yet
const dataRetention: GvlDataRetention | undefined = gvlVendor?.dataRetention;
// // @ts-ignore our TCF lib does not have GVL v3 types yet
// const dataRetention: GvlDataRetention | undefined = gvlVendor?.dataRetention;

return (
<div>
<VendorDetails
label="Purposes"
lineItems={purposes as EmbeddedLineItem[]}
dataRetention={
dataRetention
? {
mapping: dataRetention.purposes,
default: dataRetention.stdRetention,
}
: undefined
}
lineItems={purposes}
// dataRetention={
// dataRetention
// ? {
// mapping: dataRetention.purposes,
// default: dataRetention.stdRetention,
// }
// : undefined
// }
allisonking marked this conversation as resolved.
Show resolved Hide resolved
/>
<VendorDetails
label="Special purposes"
lineItems={specialPurposes as EmbeddedLineItem[]}
dataRetention={
dataRetention
? {
mapping: dataRetention.specialPurposes,
default: dataRetention.stdRetention,
}
: undefined
}
lineItems={specialPurposes}
// dataRetention={
// dataRetention
// ? {
// mapping: dataRetention.specialPurposes,
// default: dataRetention.stdRetention,
// }
// : undefined
// }
/>
</div>
);
Expand Down Expand Up @@ -158,13 +143,13 @@ const DataCategories = ({
);
};

const StorageDisclosure = ({ vendor }: { vendor: Vendor }) => {
const StorageDisclosure = ({ vendor }: { vendor: VendorRecord }) => {
const {
name,
usesCookies,
usesNonCookieAccess,
cookieMaxAgeSeconds,
cookieRefresh,
uses_cookies: usesCookies,
uses_non_cookie_access: usesNonCookieAccess,
cookie_max_age_seconds: cookieMaxAgeSeconds,
allisonking marked this conversation as resolved.
Show resolved Hide resolved
cookie_refresh: cookieRefresh,
} = vendor;
let disclosure = "";
if (usesCookies) {
allisonking marked this conversation as resolved.
Show resolved Hide resolved
pattisdr marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -238,22 +223,22 @@ const TcfVendors = ({
}
renderToggleChild={(vendor) => {
const gvlVendor = vendorGvlEntry(vendor.id, experience.gvl);
// @ts-ignore the IAB-TCF lib doesn't support GVL v3 types yet
const url: GvlVendorUrl | undefined = gvlVendor?.urls.find(
(u: GvlVendorUrl) => u.langId === "en"
);
const dataCategories: GvlDataCategories | undefined =
// @ts-ignore the IAB-TCF lib doesn't support GVL v3 types yet
experience.gvl?.dataCategories;
return (
<div>
{gvlVendor ? <StorageDisclosure vendor={gvlVendor} /> : null}
<StorageDisclosure vendor={vendor} />
<div style={{ marginBottom: "1.1em" }}>
{url?.privacy ? (
<ExternalLink href={url.privacy}>Privacy policy</ExternalLink>
{vendor?.privacy_policy_url ? (
<ExternalLink href={vendor.privacy_policy_url}>
Privacy policy
</ExternalLink>
) : null}
{url?.legIntClaim ? (
<ExternalLink href={url.legIntClaim}>
{vendor.legitimate_interest_disclosure_url ? (
<ExternalLink
href={vendor.legitimate_interest_disclosure_url}
>
Legitimate interest disclosure
</ExternalLink>
) : null}
Expand All @@ -264,7 +249,6 @@ const TcfVendors = ({
...(vendor.purpose_legitimate_interests || []),
]}
specialPurposes={vendor.special_purposes}
gvlVendor={gvlVendor}
/>
<VendorDetails label="Features" lineItems={vendor.features} />
<VendorDetails
Expand Down
2 changes: 1 addition & 1 deletion clients/fides-js/src/lib/consent-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export enum ConsentMethod {
export type PrivacyPreferencesRequest = {
browser_identity: Identity;
code?: string;
tc_string?: string;
fides_string?: string;
preferences?: Array<ConsentOptionCreate>;
purpose_consent_preferences?: Array<TCFPurposeSave>;
purpose_legitimate_interests_preferences?: Array<TCFPurposeSave>;
Expand Down
Loading
Loading