From 07b3289ed2e41c6c51afc67cd3c64fec01f01e97 Mon Sep 17 00:00:00 2001 From: Tom Van Dort Date: Thu, 15 Aug 2024 15:26:40 -0400 Subject: [PATCH 1/5] Update command with required quotes. (#5196) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1b0a769f69..734d23a46c 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ In order to get started quickly with Fides, a sample project is bundled within t > [!TIP] > We highly recommend setting up a Python virtual environment such as `venv` to install Fides into. For example: -> +> > ```sh > mkdir ~/fides > cd ~/fides @@ -131,7 +131,7 @@ Fides is created and sponsored by Ethyca: a developer tools company building the By default, running `pip install ethyca-fides` locally will not install the optional Python libraries needed for Microsoft SQL Server, since these rely on additional system dependencies (`freetds`)! However, if you *do* want to connect to MSSQL, you have two options: 1. Use our pre-built Docker images which install these optional dependencies automatically: [`ethyca/fides`](https://hub.docker.com/r/ethyca/fides). See our [Deployment Guide](https://ethyca.com/docs/dev-docs/configuration/deployment) for more! -2. Install the required dependencies on your local development machine and run `pip install ethyca-fides[all]` to include "all" the optional libraries. Keep reading to learn more about this! +2. Install the required dependencies on your local development machine and run `pip install "ethyca-fides[all]"` to include "all" the optional libraries. Keep reading to learn more about this! For local development setup on macOS, follow these steps: 1. Install the required development libraries from Homebrew: From d739aad92591d49e57e05631297e5b7a3070dbf8 Mon Sep 17 00:00:00 2001 From: Adrian Galvan Date: Thu, 15 Aug 2024 14:38:26 -0700 Subject: [PATCH 2/5] Fixing downgrade for OpenID provider migration (#5205) --- .../migrations/versions/ffee79245c9a_add_openid_provider.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/fides/api/alembic/migrations/versions/ffee79245c9a_add_openid_provider.py b/src/fides/api/alembic/migrations/versions/ffee79245c9a_add_openid_provider.py index 3449628827..7e247246e4 100644 --- a/src/fides/api/alembic/migrations/versions/ffee79245c9a_add_openid_provider.py +++ b/src/fides/api/alembic/migrations/versions/ffee79245c9a_add_openid_provider.py @@ -18,7 +18,6 @@ def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### op.create_table( "openid_provider", sa.Column("id", sa.String(length=255), nullable=False), @@ -66,12 +65,10 @@ def upgrade(): ["identifier"], unique=True, ) - # ### end Alembic commands ### def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### op.drop_index(op.f("ix_openid_provider_identifier"), table_name="openid_provider") op.drop_index(op.f("ix_openid_provider_id"), table_name="openid_provider") op.drop_table("openid_provider") - # ### end Alembic commands ### + op.execute("DROP TYPE providerenum") From 876ae7ebbae1c3313cacaed81376b4aabfff9571 Mon Sep 17 00:00:00 2001 From: Robert Keyser <39230492+RobertKeyser@users.noreply.github.com> Date: Fri, 16 Aug 2024 09:15:39 -0500 Subject: [PATCH 3/5] Oracle Responsys: ignore `404`s on delete endpoint (#5203) --- CHANGELOG.md | 2 ++ data/saas/config/oracle_responsys_config.yml | 2 +- .../oracle_responsys_request_overrides.py | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6311552560..dbbb4d94d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ The types of changes are: ## [Unreleased](https://github.com/ethyca/fides/compare/2.43.0...main) +### Fixed +- Ignore `404` errors on Oracle Responsys deletions [#5203](https://github.com/ethyca/fides/pull/5203) ## [2.43.0](https://github.com/ethyca/fides/compare/2.42.1...2.43.0) diff --git a/data/saas/config/oracle_responsys_config.yml b/data/saas/config/oracle_responsys_config.yml index 7660ed9780..819e867949 100644 --- a/data/saas/config/oracle_responsys_config.yml +++ b/data/saas/config/oracle_responsys_config.yml @@ -3,7 +3,7 @@ saas_config: name: Oracle Responsys type: oracle_responsys description: A sample schema representing the Oracle Responsys connector for Fides - version: 0.0.2 + version: 0.0.3 connector_params: - name: domain diff --git a/src/fides/api/service/saas_request/override_implementations/oracle_responsys_request_overrides.py b/src/fides/api/service/saas_request/override_implementations/oracle_responsys_request_overrides.py index e9d5e8dd8a..a091fee0d3 100644 --- a/src/fides/api/service/saas_request/override_implementations/oracle_responsys_request_overrides.py +++ b/src/fides/api/service/saas_request/override_implementations/oracle_responsys_request_overrides.py @@ -272,7 +272,8 @@ def oracle_responsys_profile_list_recipients_delete( SaaSRequestParams( method=HTTPMethod.DELETE, path=f"/rest/api/v1.3/lists/{list_id}/members/{responsys_id}", - ) + ), + [404], ) rows_deleted += 1 From 667b2ddfc66ee92ad257d083a5a7b28fb4e3013f Mon Sep 17 00:00:00 2001 From: Jason Gill Date: Fri, 16 Aug 2024 13:59:47 -0600 Subject: [PATCH 4/5] update TCF banner button layout/split tcf styles (#5204) --- CHANGELOG.md | 1 + .../fides-js/src/components/ConsentBanner.tsx | 5 +- .../src/components/ConsentButtons.tsx | 10 +- clients/fides-js/src/components/fides.css | 308 ++++++------------ .../src/components/tcf/TcfOverlay.tsx | 1 + .../fides-js/src/components/tcf/fides-tcf.css | 166 ++++++++++ 6 files changed, 272 insertions(+), 219 deletions(-) create mode 100644 clients/fides-js/src/components/tcf/fides-tcf.css diff --git a/CHANGELOG.md b/CHANGELOG.md index dbbb4d94d3..1d3c6f9d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ The types of changes are: - Model changes to support consent signals (Fidesplus) [#5190](https://github.com/ethyca/fides/pull/5190) - Updated Datasets page with new UI for better usability and consistency with Detection and Discovery UI [#5191](https://github.com/ethyca/fides/pull/5191) - Updated the Yotpo Reviews integration to use email and phone number identities instead of external ID [#5169](https://github.com/ethyca/fides/pull/5169) +- Update TCF banner button layout and styles [#5204](https://github.com/ethyca/fides/pull/5204) ### Developer Experience diff --git a/clients/fides-js/src/components/ConsentBanner.tsx b/clients/fides-js/src/components/ConsentBanner.tsx index 65821f88d3..dfdb9a9d54 100644 --- a/clients/fides-js/src/components/ConsentBanner.tsx +++ b/clients/fides-js/src/components/ConsentBanner.tsx @@ -3,7 +3,6 @@ import { useEffect } from "preact/hooks"; import { getConsentContext } from "../lib/consent-context"; import { GpcStatus } from "../lib/consent-types"; -import { useMediaQuery } from "../lib/hooks/useMediaQuery"; import { I18n, messageExists } from "../lib/i18n"; import CloseButton from "./CloseButton"; import ExperienceDescription from "./ExperienceDescription"; @@ -38,7 +37,6 @@ const ConsentBanner: FunctionComponent = ({ className, isEmbedded, }) => { - const isMobile = useMediaQuery("(max-width: 768px)"); const showGpcBadge = getConsentContext().globalPrivacyControl; useEffect(() => { @@ -122,9 +120,8 @@ const ConsentBanner: FunctionComponent = ({ {children} - {!isMobile && renderButtonGroup()} - {isMobile && renderButtonGroup()} + {renderButtonGroup()} diff --git a/clients/fides-js/src/components/ConsentButtons.tsx b/clients/fides-js/src/components/ConsentButtons.tsx index 3908e5cb9e..9d0774ebd3 100644 --- a/clients/fides-js/src/components/ConsentButtons.tsx +++ b/clients/fides-js/src/components/ConsentButtons.tsx @@ -55,6 +55,14 @@ export const ConsentButtons = ({ {!!renderFirstButton && renderFirstButton()} {!hideOptInOut && ( + {isTCF && !!onManagePreferencesClick && ( + + {parts[0]} + {!onVendorPageClick && vendorCount && ( + {vendorCount} + )} + {onVendorPageClick && vendorCount && ( + + )} + {parts[1]} ); } diff --git a/clients/fides-js/src/components/tcf/TcfOverlay.tsx b/clients/fides-js/src/components/tcf/TcfOverlay.tsx index 8dab5e09b0..243d58e692 100644 --- a/clients/fides-js/src/components/tcf/TcfOverlay.tsx +++ b/clients/fides-js/src/components/tcf/TcfOverlay.tsx @@ -41,6 +41,7 @@ import type { TCFVendorLegitimateInterestsRecord, TCFVendorSave, } from "../../lib/tcf/types"; +import { useVendorButton } from "../../lib/tcf/vendor-button-context"; import { fetchGvlTranslations } from "../../services/api"; import Button from "../Button"; import ConsentBanner from "../ConsentBanner"; @@ -205,6 +206,8 @@ const TcfOverlay: FunctionComponent = ({ cookie, savedConsent, }) => { + const { setVendorCount } = useVendorButton(); + const initialEnabledIds: EnabledIds = useMemo(() => { const { tcf_purpose_consents: consentPurposes = [], @@ -252,6 +255,12 @@ const TcfOverlay: FunctionComponent = ({ setCurrentLocale(locale); }; + useEffect(() => { + if (experience.vendor_count && setVendorCount) { + setVendorCount(experience.vendor_count); + } + }, [experience, setVendorCount]); + useEffect(() => { if (!currentLocale && locale && defaultLocale) { if (locale !== defaultLocale) { diff --git a/clients/fides-js/src/components/tcf/VendorInfoBanner.tsx b/clients/fides-js/src/components/tcf/VendorInfoBanner.tsx index 965c547324..4175d6c5a9 100644 --- a/clients/fides-js/src/components/tcf/VendorInfoBanner.tsx +++ b/clients/fides-js/src/components/tcf/VendorInfoBanner.tsx @@ -1,8 +1,9 @@ import { h } from "preact"; -import { useMemo } from "preact/hooks"; +import { useEffect, useMemo } from "preact/hooks"; import { PrivacyExperience } from "../../lib/consent-types"; import type { I18n } from "../../lib/i18n"; +import { useVendorButton } from "../../lib/tcf/vendor-button-context"; const VendorInfo = ({ label, @@ -38,6 +39,7 @@ const VendorInfoBanner = ({ i18n: I18n; goToVendorTab: () => void; }) => { + const { setVendorCount } = useVendorButton(); const counts = useMemo(() => { const { tcf_vendor_consents: consentVendors = [], @@ -57,6 +59,12 @@ const VendorInfoBanner = ({ return { total, consent, legint }; }, [experience]); + useEffect(() => { + if (counts.total && setVendorCount) { + setVendorCount(counts.total); + } + }, [counts.total, setVendorCount]); + return (
>; } -const I18nContext = createContext({} as I18nContextProps); +const I18nContext = createContext>({}); export const I18nProvider: FunctionComponent = ({ children }) => { const [currentLocale, setCurrentLocale] = useState(); @@ -41,7 +41,7 @@ export const I18nProvider: FunctionComponent = ({ children }) => { export const useI18n = () => { const context = useContext(I18nContext); - if (!context) { + if (!context || Object.keys(context).length === 0) { throw new Error("useI18n must be used within a I18nProvider"); } return context; diff --git a/clients/fides-js/src/lib/tcf/renderOverlay.tsx b/clients/fides-js/src/lib/tcf/renderOverlay.tsx index 1a8098d5ac..99922e6ab5 100644 --- a/clients/fides-js/src/lib/tcf/renderOverlay.tsx +++ b/clients/fides-js/src/lib/tcf/renderOverlay.tsx @@ -4,6 +4,7 @@ import TcfOverlay from "../../components/tcf/TcfOverlay"; import { OverlayProps } from "../../components/types"; import { I18nProvider } from "../i18n/i18n-context"; import { loadTcfMessagesFromFiles } from "./i18n/tcf-i18n-utils"; +import { VendorButtonProvider } from "./vendor-button-context"; export const renderOverlay = (props: OverlayProps, parent: ContainerNode) => { /** @@ -18,7 +19,9 @@ export const renderOverlay = (props: OverlayProps, parent: ContainerNode) => { render( - + + + , parent, ); diff --git a/clients/fides-js/src/lib/tcf/vendor-button-context.tsx b/clients/fides-js/src/lib/tcf/vendor-button-context.tsx new file mode 100644 index 0000000000..d5a5460ab9 --- /dev/null +++ b/clients/fides-js/src/lib/tcf/vendor-button-context.tsx @@ -0,0 +1,46 @@ +import { createContext, h } from "preact"; +import { FC } from "preact/compat"; +import { + Dispatch, + StateUpdater, + useContext, + useMemo, + useState, +} from "preact/hooks"; + +interface VendorButtonContextProps { + vendorCount?: number; + setVendorCount: Dispatch>; +} + +export const VendorButtonContext = createContext< + VendorButtonContextProps | Record +>({}); + +export const VendorButtonProvider: FC = ({ children }) => { + const [vendorCount, setVendorCount] = useState(); + + const value: VendorButtonContextProps = useMemo( + () => ({ + vendorCount, + setVendorCount, + }), + [vendorCount, setVendorCount], + ); + + return ( + + {children} + + ); +}; + +export const useVendorButton = () => { + const context = useContext(VendorButtonContext); + if (!context || Object.keys(context).length === 0) { + throw new Error( + "useVendorButton must be used within a VendorButtonProvider", + ); + } + return context; +}; diff --git a/clients/privacy-center/cypress/e2e/consent-banner-tcf.cy.ts b/clients/privacy-center/cypress/e2e/consent-banner-tcf.cy.ts index a573f4a71b..2854096cd0 100644 --- a/clients/privacy-center/cypress/e2e/consent-banner-tcf.cy.ts +++ b/clients/privacy-center/cypress/e2e/consent-banner-tcf.cy.ts @@ -275,7 +275,14 @@ describe("Fides-js TCF", () => { }); }); - it("can open the modal", () => { + it("can open the modal from vendor count", () => { + cy.get("div#fides-banner").within(() => { + cy.get(".fides-vendor-count").first().should("have.text", "2").click(); + }); + cy.get("#fides-tab-vendors"); + }); + + it("can open the modal from preferences button", () => { cy.get("div#fides-banner").within(() => { cy.get("#fides-button-group").within(() => { cy.get("button").contains("Manage preferences").click(); diff --git a/clients/privacy-center/cypress/e2e/consent-i18n.cy.ts b/clients/privacy-center/cypress/e2e/consent-i18n.cy.ts index 46bbba4eb8..b22cf0d168 100644 --- a/clients/privacy-center/cypress/e2e/consent-i18n.cy.ts +++ b/clients/privacy-center/cypress/e2e/consent-i18n.cy.ts @@ -153,6 +153,8 @@ const ENGLISH_NOTICES: TestNoticeTranslations[] = [ const ENGLISH_TCF_BANNER: TestTcfBannerTranslations = { ...ENGLISH_BANNER, ...{ + banner_description: + "[banner] We, and our 2 vendors, use cookies and similar", vendors_count: "Vendors", vendors_consent_count: "Vendors using consent", vendors_legint_count: "Vendors using legitimate interest", diff --git a/clients/privacy-center/cypress/fixtures/consent/experience_tcf.json b/clients/privacy-center/cypress/fixtures/consent/experience_tcf.json index 7be4fb12ab..1b53ef4985 100644 --- a/clients/privacy-center/cypress/fixtures/consent/experience_tcf.json +++ b/clients/privacy-center/cypress/fixtures/consent/experience_tcf.json @@ -17,7 +17,7 @@ "language": "en", "accept_button_label": "Opt in to all", "acknowledge_button_label": "OK", - "banner_description": "[banner] We use cookies and similar methods to recognize visitors and remember their preferences. We may also use these technologies to gauge the effectiveness of advertising campaigns, target advertisements, and analyze website traffic. Some of these technologies are essential for ensuring the proper functioning of the service or website and cannot be disabled, while others are optional but serve to enhance the user experience in various ways.\n\nWe, in collaboration with our partners, store and/or access information on a user's device, including but not limited to IP addresses, unique identifiers, and browsing data stored in cookies, in order to process personal data. You have the option to manage your preferences by selecting the 'Manage Preferences' option located in the page's footer. To review or object to instances where our partners assert a legitimate interest in utilizing your data, please visit our vendors page.\n", + "banner_description": "[banner] We, and our ${VENDOR_COUNT_LINK} vendors, use cookies and similar methods to recognize visitors and remember their preferences. We may also use these technologies to gauge the effectiveness of advertising campaigns, target advertisements, and analyze website traffic. Some of these technologies are essential for ensuring the proper functioning of the service or website and cannot be disabled, while others are optional but serve to enhance the user experience in various ways.\n\nWe, in collaboration with our partners, store and/or access information on a user's device, including but not limited to IP addresses, unique identifiers, and browsing data stored in cookies, in order to process personal data. You have the option to manage your preferences by selecting the 'Manage Preferences' option located in the page's footer. To review or object to instances where our partners assert a legitimate interest in utilizing your data, please visit our vendors page.\n", "banner_title": "[banner] Manage your consent preferences", "description": "We use cookies and similar methods to recognize visitors and remember their preferences. We may also use these technologies to gauge the effectiveness of advertising campaigns, target advertisements, and analyze website traffic. Some of these technologies are essential for ensuring the proper functioning of the service or website and cannot be disabled, while others are optional but serve to enhance the user experience in various ways.\n\nWe, in collaboration with our partners, store and/or access information on a user's device, including but not limited to IP addresses, unique identifiers, and browsing data stored in cookies, in order to process personal data. You have the option to manage your preferences by selecting the 'Manage Preferences' option located in the page's footer. To review or object to instances where our partners assert a legitimate interest in utilizing your data, please visit our vendors page.\n", "modal_link_label": "Manage my consent preferences",