diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f01ba840e0..0307c165c7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ Changes can also be flagged with a GitHub label for tracking purposes. The URL o - Migrate var(--fidesui-*) consumers to --ant-* and delete Sass var generation [#8065](https://github.com/ethyca/fides/pull/8065) - Rename Ant cssVar prefix to fidesui and migrate all var(--ant-*) consumers [#8066](https://github.com/ethyca/fides/pull/8066) - Upgrade ESLint and fix no-unused-vars errors for mapped types in admin-ui [#8050](https://github.com/ethyca/fides/pull/8050) +- Bundle policy-engine Go source in the ethyca-fides wheel and build libpbac in the Docker image for in-process PBAC evaluation [#8093](https://github.com/ethyca/fides/pull/8093) ### Docs - Updated FidesJS JSDoc links to match the new fidesdocs domain-based structure [#8038](https://github.com/ethyca/fides/pull/8038) diff --git a/Dockerfile b/Dockerfile index af8ba84a662..0cb916863eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,13 @@ # If you update this, also update `DEFAULT_PYTHON_VERSION` in the GitHub workflow files ARG PYTHON_VERSION="3.13.11" +############################ +## Build libpbac (Go→C) ## +############################ +FROM golang:1.24-bookworm AS libpbac_builder +WORKDIR /build +COPY policy-engine/ . +RUN go build -buildmode=c-shared -o libpbac.so ./cmd/libpbac/ + ######################### ## Compile Python Deps ## ######################### @@ -70,6 +78,7 @@ USER fidesuser ENV USER=fidesuser COPY --chown=fidesuser:fidesgroup . /fides +COPY --from=libpbac_builder --chown=fidesuser:fidesgroup /build/libpbac.so /fides/src/fides/bin/libpbac.so WORKDIR /fides # Immediately flush to stdout, globally diff --git a/clients/fides-js/__tests__/lib/i18n/i18n-utils.test.ts b/clients/fides-js/__tests__/lib/i18n/i18n-utils.test.ts index f0d17deb70f..c327584cb12 100644 --- a/clients/fides-js/__tests__/lib/i18n/i18n-utils.test.ts +++ b/clients/fides-js/__tests__/lib/i18n/i18n-utils.test.ts @@ -1,6 +1,5 @@ import { ExperienceConfig, - FidesExperienceTranslationOverrides, FidesInitOptions, PrivacyExperience, PrivacyNoticeWithPreference, @@ -339,75 +338,14 @@ describe("i18n-utils", () => { expect(mockI18n.load).toHaveBeenCalledWith("en", mockI18nCatalogLoad[0]); }); - it("sets overrides experience_config translations when locale matches", () => { - const experienceTranslationOverrides: Partial = - { - title: "My override title", - description: "My override description", - override_language: "en", - }; - loadMessagesFromExperience( - mockI18n, - mockExperience, - experienceTranslationOverrides, - ); - const EXPECTED_NUM_TRANSLATIONS = 2; - expect(mockI18n.load).toHaveBeenCalledTimes(EXPECTED_NUM_TRANSLATIONS); - expect(mockI18n.load).toHaveBeenCalledWith("en", { - ...mockI18nCatalogLoad[0], - ...{ - "exp.description": experienceTranslationOverrides.description, - "exp.title": experienceTranslationOverrides.title, - }, - }); - expect(mockI18n.load).toHaveBeenCalledWith("es", mockI18nCatalogLoad[1]); - }); - it("does not set overrides experience_config translations when no locale match", () => { - const experienceTranslationOverrides: Partial = - { - title: "My override title", - description: "My override description", - override_language: "ja", - }; - loadMessagesFromExperience( - mockI18n, - mockExperience, - experienceTranslationOverrides, - ); + loadMessagesFromExperience(mockI18n, mockExperience); const EXPECTED_NUM_TRANSLATIONS = 2; expect(mockI18n.load).toHaveBeenCalledTimes(EXPECTED_NUM_TRANSLATIONS); expect(mockI18n.load).toHaveBeenCalledWith("en", mockI18nCatalogLoad[0]); expect(mockI18n.load).toHaveBeenCalledWith("es", mockI18nCatalogLoad[1]); }); - it("always override privacy_policy_url, even if locale doesn't match", () => { - const experienceTranslationOverrides: Partial = - { - title: "My override title", - description: "My override description", - privacy_policy_url: "https://example.com/privacy", - override_language: "ja", - }; - loadMessagesFromExperience( - mockI18n, - mockExperience, - experienceTranslationOverrides, - ); - const EXPECTED_NUM_TRANSLATIONS = 2; - expect(mockI18n.load).toHaveBeenCalledTimes(EXPECTED_NUM_TRANSLATIONS); - expect(mockI18n.load).toHaveBeenCalledWith("en", { - ...mockI18nCatalogLoad[0], - "exp.privacy_policy_url": - experienceTranslationOverrides.privacy_policy_url, - }); - expect(mockI18n.load).toHaveBeenCalledWith("es", { - ...mockI18nCatalogLoad[1], - "exp.privacy_policy_url": - experienceTranslationOverrides.privacy_policy_url, - }); - }); - describe("when loading from a tcf_overlay experience", () => { it("reads all messages from gvl translations API response and loads into the i18n catalog", () => { // Mock out a partial response for a tcf_overlay including translations diff --git a/clients/fides-js/src/components/tcf/TcfOverlay.tsx b/clients/fides-js/src/components/tcf/TcfOverlay.tsx index 9e04578abbc..bfb8423f97f 100644 --- a/clients/fides-js/src/components/tcf/TcfOverlay.tsx +++ b/clients/fides-js/src/components/tcf/TcfOverlay.tsx @@ -10,10 +10,8 @@ import { ConsentMethod, EmptyExperience, FidesAttStatus, - FidesExperienceTranslationOverrides, FidesModalDefaultView, NoticeConsent, - OverrideType, PrivacyExperience, PrivacyExperienceMinimal, PrivacyNoticeWithPreference, @@ -111,16 +109,10 @@ export const TcfOverlay = () => { const { fidesRegionString, cookie, - config, options, saved_consent: savedConsent, } = fidesGlobal; const experienceMinimal = fidesGlobal.experience as PrivacyExperienceMinimal; - const translationOverrides: Partial = - getOverridesByType>( - OverrideType.EXPERIENCE_TRANSLATION, - config, - ); const { i18n, currentLocale, @@ -276,7 +268,7 @@ export const TcfOverlay = () => { if (isFullExperience) { // Load messages from experience // This includes any custom notices, but not the GVL translations. - loadMessagesFromExperience(i18n, experienceFull, translationOverrides); + loadMessagesFromExperience(i18n, experienceFull); // Set the locale to the best locale window.Fides.locale = bestLocale; diff --git a/clients/fides-js/src/fides-headless.ts b/clients/fides-js/src/fides-headless.ts index 992d621411a..6b2e19bd908 100644 --- a/clients/fides-js/src/fides-headless.ts +++ b/clients/fides-js/src/fides-headless.ts @@ -10,7 +10,6 @@ import { getConsentContext } from "./lib/consent-context"; import { FidesConfig, FidesCookie, - FidesExperienceTranslationOverrides, FidesGlobal, FidesInitOptionsOverrides, FidesOverrides, @@ -77,11 +76,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { OverrideType.OPTIONS, config, ); - const experienceTranslationOverrides: Partial = - getOverridesByType>( - OverrideType.EXPERIENCE_TRANSLATION, - config, - ); // DEFER: not implemented - ability to override Fides consent with OneTrust overrides const consentPrefsOverrides: GetPreferencesFnResp | null = await customGetConsentPreferences(config); @@ -92,7 +86,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { const overrides: Partial = { optionsOverrides, consentPrefsOverrides, - experienceTranslationOverrides, }; config = { ...config, @@ -178,7 +171,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { const updatedFides = await initialize({ fides: this, updateExperience, - overrides, automatedConsentContext, }); Object.assign(this, updatedFides); diff --git a/clients/fides-js/src/fides-tcf.ts b/clients/fides-js/src/fides-tcf.ts index bba5f48fa1b..678e63343ea 100644 --- a/clients/fides-js/src/fides-tcf.ts +++ b/clients/fides-js/src/fides-tcf.ts @@ -14,7 +14,6 @@ import { FidesCookie, isNewFidesCookie } from "./fides"; import { getConsentContext } from "./lib/consent-context"; import { FidesConfig, - FidesExperienceTranslationOverrides, FidesGlobal, FidesInitOptionsOverrides, FidesOverrides, @@ -119,11 +118,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { true, }); - const experienceTranslationOverrides: Partial = - getOverridesByType>( - OverrideType.EXPERIENCE_TRANSLATION, - config, - ); const consentPrefsOverrides: GetPreferencesFnResp | null = await customGetConsentPreferences(config); // if we don't already have a fidesString override, use fidesString from consent prefs if they exist @@ -133,7 +127,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { const overrides: Partial = { optionsOverrides, consentPrefsOverrides, - experienceTranslationOverrides, }; // eslint-disable-next-line no-param-reassign config = { @@ -236,7 +229,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { initOverlay, renderOverlay, updateExperience: updateTCFExperience, - overrides, automatedConsentContext, }); Object.assign(this, updatedFides); diff --git a/clients/fides-js/src/fides.ts b/clients/fides-js/src/fides.ts index 3045e45888b..e9e32d28db3 100644 --- a/clients/fides-js/src/fides.ts +++ b/clients/fides-js/src/fides.ts @@ -10,7 +10,6 @@ import { getConsentContext } from "./lib/consent-context"; import { FidesConfig, FidesCookie, - FidesExperienceTranslationOverrides, FidesGlobal, FidesInitOptionsOverrides, FidesOverrides, @@ -79,11 +78,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { OverrideType.OPTIONS, config, ); - const experienceTranslationOverrides: Partial = - getOverridesByType>( - OverrideType.EXPERIENCE_TRANSLATION, - config, - ); const consentPrefsOverrides: GetPreferencesFnResp | null = await customGetConsentPreferences(config); // if we don't already have a fidesString override, use fidesString from consent prefs if they exist @@ -93,7 +87,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { const overrides: Partial = { optionsOverrides, consentPrefsOverrides, - experienceTranslationOverrides, }; config = { @@ -184,7 +177,6 @@ async function init(this: FidesGlobal, providedConfig?: FidesConfig) { initOverlay, renderOverlay, updateExperience, - overrides, automatedConsentContext, }); Object.assign(this, updatedFides); diff --git a/clients/fides-js/src/lib/consent-constants.ts b/clients/fides-js/src/lib/consent-constants.ts index 766b1d42150..75f75a1a38a 100644 --- a/clients/fides-js/src/lib/consent-constants.ts +++ b/clients/fides-js/src/lib/consent-constants.ts @@ -1,7 +1,4 @@ -import { - FidesExperienceLanguageValidatorMap, - FidesOverrideValidatorMap, -} from "./consent-types"; +import { FidesOverrideValidatorMap } from "./consent-types"; import { LOCALE_REGEX } from "./i18n/i18n-constants"; import { parseCommaSeparatedString } from "./shared-consent-utils"; @@ -174,38 +171,6 @@ export const FIDES_OVERRIDE_OPTIONS_VALIDATOR_MAP: FidesOverrideValidatorMap[] = }, ]; -/** - * Allows various user-provided experience lang overrides to be validated and mapped to the appropriate Fides variable. - * overrideName is Fides internal, but overrideKey is the key the user uses to override the option. - */ -export const FIDES_OVERRIDE_EXPERIENCE_LANGUAGE_VALIDATOR_MAP: FidesExperienceLanguageValidatorMap[] = - [ - { - overrideName: "title", - overrideType: "string", - overrideKey: "fides_title", - validationRegex: /(.*)/, - }, - { - overrideName: "description", - overrideType: "string", - overrideKey: "fides_description", - validationRegex: /(.*)/, - }, - { - overrideName: "privacy_policy_url", - overrideType: "string", - overrideKey: "fides_privacy_policy_url", - validationRegex: /(.*)/, - }, - { - overrideName: "override_language", - overrideType: "string", - overrideKey: "fides_override_language", - validationRegex: LOCALE_REGEX, - }, - ]; - export const FIDES_OVERLAY_WRAPPER = "fides-overlay-wrapper"; export const FIDES_I18N_ICON = "fides-i18n-icon"; diff --git a/clients/fides-js/src/lib/consent-types.ts b/clients/fides-js/src/lib/consent-types.ts index 73ae9a075fa..92d57612aeb 100644 --- a/clients/fides-js/src/lib/consent-types.ts +++ b/clients/fides-js/src/lib/consent-types.ts @@ -899,13 +899,6 @@ export enum FidesModalDefaultView { */ export { FidesOptions }; -export type OverrideExperienceTranslations = { - fides_title: string; - fides_description: string; - fides_privacy_policy_url: string; - fides_override_language: string; -}; - /** * Select the subset of FidesInitOptions that can be overridden at runtime using * one of the customer-provided FidesOptions properties above. There's a 1:1 @@ -941,22 +934,13 @@ export type FidesInitOptionsOverrides = Pick< | "fidesExternalId" >; -export type FidesExperienceTranslationOverrides = { - title: string; - description: string; - privacy_policy_url: string; - override_language: string; -}; - export type FidesOverrides = { optionsOverrides: Partial; consentPrefsOverrides: GetPreferencesFnResp | null; - experienceTranslationOverrides: Partial; }; export enum OverrideType { OPTIONS = "options", - EXPERIENCE_TRANSLATION = "language", } export enum ButtonType { @@ -1156,13 +1140,6 @@ export type FidesOverrideValidatorMap = FidesValidatorMap< keyof FidesOptions >; -export type FidesExperienceLanguageValidatorMap = FidesValidatorMap< - FidesExperienceTranslationOverrides, - string ->; - -export type FidesWindowOverrides = Partial< - FidesOptions & OverrideExperienceTranslations -> & { +export type FidesWindowOverrides = Partial & { [key: string]: string | boolean | undefined; }; diff --git a/clients/fides-js/src/lib/consent-utils.ts b/clients/fides-js/src/lib/consent-utils.ts index f4b5da4fce4..3f1187db6a8 100644 --- a/clients/fides-js/src/lib/consent-utils.ts +++ b/clients/fides-js/src/lib/consent-utils.ts @@ -1,5 +1,4 @@ import { - FIDES_OVERRIDE_EXPERIENCE_LANGUAGE_VALIDATOR_MAP, FIDES_OVERRIDE_OPTIONS_VALIDATOR_MAP, VALID_ISO_3166_LOCATION_REGEX, } from "./consent-constants"; @@ -12,7 +11,6 @@ import { ConsentNonApplicableFlagMode, EmptyExperience, FidesCookie, - FidesExperienceLanguageValidatorMap, FidesInitOptions, FidesOverrideValidatorMap, FidesWindowOverrides, @@ -150,16 +148,11 @@ export const validateOptions = (options: FidesInitOptions): boolean => { export const getOverrideValidatorMapByType = ( overrideType: OverrideType, -): - | FidesOverrideValidatorMap[] - | FidesExperienceLanguageValidatorMap[] - | null => { +): FidesOverrideValidatorMap[] | null => { // eslint-disable-next-line default-case switch (overrideType) { case OverrideType.OPTIONS: return FIDES_OVERRIDE_OPTIONS_VALIDATOR_MAP; - case OverrideType.EXPERIENCE_TRANSLATION: - return FIDES_OVERRIDE_EXPERIENCE_LANGUAGE_VALIDATOR_MAP; default: return null; } diff --git a/clients/fides-js/src/lib/i18n/i18n-utils.ts b/clients/fides-js/src/lib/i18n/i18n-utils.ts index 83b7119eeba..8b07cd8394a 100644 --- a/clients/fides-js/src/lib/i18n/i18n-utils.ts +++ b/clients/fides-js/src/lib/i18n/i18n-utils.ts @@ -3,7 +3,6 @@ import { ExperienceConfig, ExperienceConfigMinimal, ExperienceConfigTranslation, - FidesExperienceTranslationOverrides, FidesInitOptions, PrivacyExperience, PrivacyExperienceMinimal, @@ -71,7 +70,6 @@ export function areLocalesEqual(a: Locale, b: Locale): boolean { */ function extractMessagesFromExperienceConfig( experienceConfig: ExperienceConfig | ExperienceConfigMinimal, - experienceTranslationOverrides?: Partial, ): Record { const extracted: Record = {}; const EXPERIENCE_TRANSLATION_FIELDS = [ @@ -100,33 +98,10 @@ function extractMessagesFromExperienceConfig( // For each translation, extract each of the translated fields (translation: ExperienceConfigTranslation) => { const locale = translation.language; - // We only override experience translations if the override_language matches current locale - let localeHasOverride = false; - if (experienceTranslationOverrides?.override_language) { - // If translation overrides exist for this language, we will need to apply them below - localeHasOverride = areLocalesEqual( - experienceTranslationOverrides.override_language, - locale, - ); - } const messages: Messages = {}; EXPERIENCE_TRANSLATION_FIELDS.forEach((key) => { - let overrideValue: string | null | undefined = null; - - const isPrivacyPolicyUrl = key === "privacy_policy_url"; - // Override value when matching translation override exists for the language. - // Override privacy_policy_url, even if the translation doesn't match the language - const shouldOverrideValue = - experienceTranslationOverrides && - (localeHasOverride || isPrivacyPolicyUrl); - if (shouldOverrideValue) { - overrideValue = - key in experienceTranslationOverrides - ? experienceTranslationOverrides[ - key as keyof FidesExperienceTranslationOverrides - ] - : null; - } + const overrideValue: string | null | undefined = null; + const message = translation[key]; if (typeof message === "string") { messages[`exp.${key}`] = overrideValue || message; @@ -266,7 +241,6 @@ export function loadMessagesFromFiles(i18n: I18n): Locale[] { export function loadMessagesFromExperience( i18n: I18n, experience: Partial, - experienceTranslationOverrides?: Partial, ) { const allMessages: Record = {}; const availableLocales: Locale[] = experience.available_locales?.length @@ -277,10 +251,7 @@ export function loadMessagesFromExperience( if (experience?.experience_config) { const config = experience.experience_config; const extracted: Record = - extractMessagesFromExperienceConfig( - config, - experienceTranslationOverrides, - ); + extractMessagesFromExperienceConfig(config); Object.keys(extracted).forEach((locale) => { allMessages[locale] = { ...extracted[locale], @@ -523,14 +494,13 @@ export function initializeI18n( navigator: Partial, experience: Partial, options?: Partial, - experienceTranslationOverrides?: Partial, ): void { // Extract & update all the translated messages from both our static files and the experience API loadMessagesFromFiles(i18n); const availableLocales: Locale[] = experience.available_locales?.length ? experience.available_locales : [DEFAULT_LOCALE]; - loadMessagesFromExperience(i18n, experience, experienceTranslationOverrides); + loadMessagesFromExperience(i18n, experience); fidesDebugger( `Loaded Fides i18n with available locales (${availableLocales.length}) = ${availableLocales}`, ); diff --git a/clients/fides-js/src/lib/initialize.ts b/clients/fides-js/src/lib/initialize.ts index 6859e0210bd..0b93bcc6956 100644 --- a/clients/fides-js/src/lib/initialize.ts +++ b/clients/fides-js/src/lib/initialize.ts @@ -215,7 +215,6 @@ export const initialize = async ({ initOverlay, renderOverlay, updateExperience, - overrides, automatedConsentContext, }: InitializeProps): Promise> => { const { config } = fides; @@ -395,13 +394,7 @@ export const initialize = async ({ // Initialize the i18n singleton before we render the overlay const i18n = setupI18n(); - initializeI18n( - i18n, - window?.navigator, - fides.experience, - options, - overrides?.experienceTranslationOverrides, - ); + initializeI18n(i18n, window?.navigator, fides.experience, options); // eslint-disable-next-line no-param-reassign fides.locale = i18n.locale || DEFAULT_LOCALE; diff --git a/clients/privacy-center/components/ConsentPage.tsx b/clients/privacy-center/components/ConsentPage.tsx index 8c8229db4f8..b5d3a61eae7 100644 --- a/clients/privacy-center/components/ConsentPage.tsx +++ b/clients/privacy-center/components/ConsentPage.tsx @@ -261,15 +261,9 @@ const ConsentPage: NextPage = () => { return; } - initializeI18n( - i18n, - window?.navigator, - experience as PrivacyExperience, - { - debug: process.env.NODE_ENV === "development", - }, - {}, - ); + initializeI18n(i18n, window?.navigator, experience as PrivacyExperience, { + debug: process.env.NODE_ENV === "development", + }); setI18nInstance(i18n); setIsI18nInitialized(true); diff --git a/clients/privacy-center/cypress/e2e/fides-js/consent-banner.cy.ts b/clients/privacy-center/cypress/e2e/fides-js/consent-banner.cy.ts index e2f9b7709c6..c1ac91fd20c 100644 --- a/clients/privacy-center/cypress/e2e/fides-js/consent-banner.cy.ts +++ b/clients/privacy-center/cypress/e2e/fides-js/consent-banner.cy.ts @@ -20,7 +20,7 @@ import { mockPrivacyNotice, mockPrivacyNoticeTranslation, } from "../../support/mocks"; -import { OVERRIDE, overrideTranslation, stubConfig } from "../../support/stubs"; +import { OVERRIDE, stubConfig } from "../../support/stubs"; const PRIVACY_NOTICE_KEY_1 = "advertising"; const PRIVACY_NOTICE_KEY_2 = "essential"; @@ -736,162 +736,6 @@ describe("Consent overlay", () => { }); }); - describe("experience descriptions", () => { - describe("when experience uses rich HTML descriptions", () => { - // Shared helper that overrides the experience config description with - // an HTML example and allows toggling the allowHTMLDescription option - const setupHTMLDescriptionTest = ( - options: Partial = {}, - ) => { - const HTMLDescription = ` - This test is overriding the
experience_config.description
with a HTML description, which is used to allow users to configure banners with clickable links and... - - ...multiple paragraphs with ease. However, it's not enabled by default unless the
options.allowHTMLDescription
flag is
true
to reduce the likelihood of XSS attacks. - `; - cy.fixture("consent/fidesjs_options_banner_modal.json").then( - (config) => { - const newExperienceTranslationsConfig = [ - overrideTranslation( - config.experience.experience_config.translations[0], - { banner_description: HTMLDescription }, - ), - ]; - stubConfig({ - experience: { - experience_config: { - ...config.experience.experience_config, - ...{ translations: newExperienceTranslationsConfig }, - }, - }, - options, - }); - }, - ); - }; - - it("does not render HTML by default", () => { - setupHTMLDescriptionTest({ allowHTMLDescription: false }); - cy.get("div#fides-banner").within(() => { - cy.get( - "div#fides-banner-description.fides-banner-description", - ).contains("This test is overriding"); - cy.get("div#fides-banner-description.fides-banner-description") - .contains("a", "clickable links") - .should("not.exist"); - }); - }); - - it("renders HTML when options.allowHTMLDescription = true", () => { - setupHTMLDescriptionTest({ allowHTMLDescription: true }); - cy.get("div#fides-banner").within(() => { - cy.get( - "div#fides-banner-description.fides-banner-description", - ).contains("This test is overriding"); - cy.get("div#fides-banner-description.fides-banner-description") - .contains("a", "clickable links") - .should("exist"); - }); - }); - }); - - describe("when experience uses different descriptions for modal & banner", () => { - beforeEach(() => { - const bannerDescription = - "This test is overriding the banner description separately from modal!"; - const modalDescription = - "This test is overriding the modal description separately from banner!"; - cy.fixture("consent/fidesjs_options_banner_modal.json").then( - (config) => { - const newExperienceTranslationsConfig = [ - overrideTranslation( - config.experience.experience_config.translations[0], - { - description: modalDescription, - banner_description: bannerDescription, - }, - ), - ]; - stubConfig({ - experience: { - experience_config: { - ...config.experience.experience_config, - ...{ translations: newExperienceTranslationsConfig }, - }, - }, - }); - }, - ); - }); - - it("renders the expected modal & banner descriptions", () => { - cy.get("div#fides-banner").within(() => { - cy.get( - "div#fides-banner-description.fides-banner-description", - ).contains( - "This test is overriding the banner description separately from modal!", - ); - }); - - cy.contains("button", "Manage preferences").click(); - cy.getByTestId("consent-modal").should("be.visible"); - - cy.get("div#fides-modal").within(() => { - cy.get(".fides-modal-description").contains( - "This test is overriding the modal description separately from banner!", - ); - }); - }); - }); - }); - - describe("titles", () => { - describe("when experience uses different titles for modal & banner", () => { - beforeEach(() => { - const bannerTitle = - "This test is overriding the banner title separately from modal!"; - const modalTitle = - "This test is overriding the modal title separately from banner!"; - cy.fixture("consent/fidesjs_options_banner_modal.json").then( - (config) => { - const newExperienceTranslationsConfig = [ - overrideTranslation( - config.experience.experience_config.translations[0], - { title: modalTitle, banner_title: bannerTitle }, - ), - ]; - stubConfig({ - experience: { - experience_config: { - ...config.experience.experience_config, - ...{ translations: newExperienceTranslationsConfig }, - }, - }, - }); - }, - ); - }); - - it("renders the expected modal & banner title", () => { - cy.get("div#fides-banner").within(() => { - cy.get(".fides-banner-title") - .first() - .contains( - "This test is overriding the banner title separately from modal!", - ); - }); - - cy.contains("button", "Manage preferences").click(); - cy.getByTestId("consent-modal").should("be.visible"); - - cy.get("div#fides-modal").within(() => { - cy.get(".fides-modal-title").contains( - "This test is overriding the modal title separately from banner!", - ); - }); - }); - }); - }); - it("can persist state between modal and banner", () => { cy.get("div#fides-banner").within(() => { cy.get("button").contains("Opt in to all").click(); diff --git a/clients/privacy-center/cypress/e2e/fides-js/consent-i18n.cy.ts b/clients/privacy-center/cypress/e2e/fides-js/consent-i18n.cy.ts index 7fa1a52d764..3990a5eda90 100644 --- a/clients/privacy-center/cypress/e2e/fides-js/consent-i18n.cy.ts +++ b/clients/privacy-center/cypress/e2e/fides-js/consent-i18n.cy.ts @@ -944,58 +944,6 @@ describe("Consent i18n", () => { fixture: "experience_banner_modal.json", }); }); - it("applies experience language overrides", () => { - const experienceTranslationOverrides = { - fides_title: "My override title", - fides_description: "My override description", - fides_privacy_policy_url: "https://example.com/privacy", - fides_override_language: "en", - }; - cy.fixture("consent/experience_banner_modal.json").then( - (experience) => { - const experienceItem = experience.items[0]; - const translation: ExperienceConfigTranslation = - experienceItem.experience_config.translations.filter( - (i: ExperienceConfigTranslation) => i.language === "en", - )[0]; - stubConfig( - { - options: { - customOptionsPath: TEST_OVERRIDE_WINDOW_PATH, - }, - experience: experienceItem, - }, - null, - null, - undefined, - { ...experienceTranslationOverrides }, - ); - cy.get("div#fides-banner").within(() => { - cy.get(".fides-banner-title") - .first() - .contains(translation.banner_title as string); - cy.get( - "div#fides-banner-description.fides-banner-description", - ).contains(translation.banner_description as string); - cy.get("#fides-privacy-policy-link a").should( - "have.attr", - "href", - experienceTranslationOverrides.fides_privacy_policy_url, - ); - }); - // Open the modal - cy.contains("button", "Manage preferences").click(); - cy.get("div#fides-modal").within(() => { - cy.get(".fides-modal-title").contains( - experienceTranslationOverrides.fides_title, - ); - cy.get(".fides-modal-description").contains( - experienceTranslationOverrides.fides_description, - ); - }); - }, - ); - }); }); describe("when fides_override_language is only part of an experience locale string", () => { @@ -1006,59 +954,6 @@ describe("Consent i18n", () => { fixture: "experience_banner_modal.json", }); }); - // TODO (PROD-1885): matchLocale needs to support partial language match - it.skip("applies experience language overrides", () => { - const experienceTranslationOverrides = { - fides_title: "My French override title", - fides_description: "My French override description", - fides_privacy_policy_url: "https://example.com/privacy-french", - fides_override_language: "fr", - }; - cy.fixture("consent/experience_banner_modal.json").then( - (experience) => { - const experienceItem = experience.items[0]; - const translation: ExperienceConfigTranslation = - experienceItem.experience_config.translations.filter( - (i: ExperienceConfigTranslation) => i.language === "fr-CA", - )[0]; - stubConfig( - { - options: { - customOptionsPath: TEST_OVERRIDE_WINDOW_PATH, - }, - experience: experienceItem, - }, - null, - null, - undefined, - { ...experienceTranslationOverrides }, - ); - cy.get("div#fides-banner").within(() => { - cy.get(".fides-banner-title") - .first() - .contains(translation.banner_title as string); - cy.get( - "div#fides-banner-description.fides-banner-description", - ).contains(translation.banner_description as string); - cy.get("#fides-privacy-policy-link a").should( - "have.attr", - "href", - experienceTranslationOverrides.fides_privacy_policy_url, - ); - }); - // Open the modal - cy.contains("button", "Manage preferences").click(); - cy.get("div#fides-modal").within(() => { - cy.get(".fides-modal-title").contains( - experienceTranslationOverrides.fides_title, - ); - cy.get(".fides-modal-description").contains( - experienceTranslationOverrides.fides_description, - ); - }); - }, - ); - }); }); describe("when fides_override_language is in a locale that does not exist in experience translations", () => { @@ -1069,83 +964,6 @@ describe("Consent i18n", () => { fixture: "experience_banner_modal.json", }); }); - it("does not apply experience translation overrides", () => { - const experienceTranslationOverrides = { - fides_title: "My override title", - fides_description: "My override description", - fides_override_language: "ja", - }; - cy.fixture("consent/experience_banner_modal.json").then( - (experience) => { - const experienceItem = experience.items[0]; - // we expect to default to english translation - const translation: ExperienceConfigTranslation = - experienceItem.experience_config.translations.filter( - (i: ExperienceConfigTranslation) => i.language === "en", - )[0]; - stubConfig( - { - options: { - customOptionsPath: TEST_OVERRIDE_WINDOW_PATH, - }, - experience: experienceItem, - }, - null, - null, - undefined, - { ...experienceTranslationOverrides }, - ); - cy.get("div#fides-banner").within(() => { - cy.get(".fides-banner-title") - .first() - .contains(translation.banner_title as string); - cy.get( - "div#fides-banner-description.fides-banner-description", - ).contains(translation.banner_description as string); - }); - // Open the modal - cy.contains("button", "Manage preferences").click(); - cy.get("div#fides-modal").within(() => { - cy.get(".fides-modal-title").contains( - translation.title as string, - ); - cy.get(".fides-modal-description").contains( - translation.description as string, - ); - }); - }, - ); - }); - it("does apply fides_privacy_policy_url override", () => { - const experienceTranslationOverrides = { - fides_privacy_policy_url: "https://example.com/privacy", - fides_override_language: "ja", - }; - cy.fixture("consent/experience_banner_modal.json").then( - (experience) => { - const experienceItem = experience.items[0]; - stubConfig( - { - options: { - customOptionsPath: TEST_OVERRIDE_WINDOW_PATH, - }, - experience: experienceItem, - }, - null, - null, - undefined, - { ...experienceTranslationOverrides }, - ); - cy.get("div#fides-banner").within(() => { - cy.get("#fides-privacy-policy-link a").should( - "have.attr", - "href", - experienceTranslationOverrides.fides_privacy_policy_url as string, - ); - }); - }, - ); - }); }); describe("when fides_override_language is not provided", () => { @@ -1202,35 +1020,6 @@ describe("Consent i18n", () => { }, ); }); - it("does apply fides_privacy_policy_url override", () => { - const experienceTranslationOverrides = { - fides_privacy_policy_url: "https://example.com/privacy", - }; - cy.fixture("consent/experience_banner_modal.json").then( - (experience) => { - const experienceItem = experience.items[0]; - stubConfig( - { - options: { - customOptionsPath: TEST_OVERRIDE_WINDOW_PATH, - }, - experience: experienceItem, - }, - null, - null, - undefined, - { ...experienceTranslationOverrides }, - ); - cy.get("div#fides-banner").within(() => { - cy.get("#fides-privacy-policy-link a").should( - "have.attr", - "href", - experienceTranslationOverrides.fides_privacy_policy_url as string, - ); - }); - }, - ); - }); }); }); }); diff --git a/clients/privacy-center/cypress/support/stubs.ts b/clients/privacy-center/cypress/support/stubs.ts index 9288ce5188d..694e85fdba3 100644 --- a/clients/privacy-center/cypress/support/stubs.ts +++ b/clients/privacy-center/cypress/support/stubs.ts @@ -52,18 +52,6 @@ interface FidesConfigTesting { options: Partial | OVERRIDE; } -/** - * Helper function to override translations for Experience Configs / Notices - * @example overrideTranslation({language: "en", privacy_experience_config_history_id: "1342314"}, { description: "hello" }) - */ -export const overrideTranslation = ( - translation: ExperienceConfigTranslation | PrivacyNoticeTranslation, - override: Partial, -): ExperienceConfigTranslation | PrivacyNoticeTranslation => ({ - ...translation, - ...override, -}); - /** * Helper function to swap out config * @example stubExperience({experience: {component: ComponentType.PRIVACY_CENTER}}) diff --git a/pyproject.toml b/pyproject.toml index 5719f776646..d9f6c296d85 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -191,6 +191,10 @@ packages = ["src/fides"] # populated by our clients/admin-ui build process to allow the Admin UI app to # be distributed as part of the ethyca-fides Python package. artifacts = ["src/fides/ui-build"] +# Bundle policy-engine Go source so downstream consumers can build libpbac +# from the same fides commit they installed. +[tool.hatch.build.targets.wheel.force-include] +"policy-engine" = "fides/policy-engine" [tool.hatch.build.targets.sdist] # Ensure that the "ui-build" folder is included in wheel and sdist (see above) diff --git a/src/fides/service/pbac/consumers/entities.py b/src/fides/service/pbac/consumers/entities.py index 2c30a0a1db5..d58f7d92266 100644 --- a/src/fides/service/pbac/consumers/entities.py +++ b/src/fides/service/pbac/consumers/entities.py @@ -8,7 +8,7 @@ from fides.service.pbac.purposes.entities import DataPurposeEntity if TYPE_CHECKING: - from fides.api.models.data_consumer import ( # type: ignore[import-not-found] + from fides.api.models.data_consumer import ( # type: ignore[import-untyped] DataConsumer, ) from fides.api.models.sql_models import System # type: ignore[attr-defined] diff --git a/src/fides/service/pbac/purposes/entities.py b/src/fides/service/pbac/purposes/entities.py index ce28c669f34..54e8061c52e 100644 --- a/src/fides/service/pbac/purposes/entities.py +++ b/src/fides/service/pbac/purposes/entities.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: - from fides.api.models.data_purpose import ( # type: ignore[import-not-found] + from fides.api.models.data_purpose import ( # type: ignore[import-untyped] DataPurpose, )