diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e7365dc29..61e097825f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ The types of changes are: - Added our CMP ID [#4233](https://github.com/ethyca/fides/pull/4233) - Allow Admin UI users to turn on Configure Consent flag [#4246](https://github.com/ethyca/fides/pull/4246) - Styling improvements for the fides.js consent banners and modals [#4222](https://github.com/ethyca/fides/pull/4222) +- Update frontend to handle updated Compass schema [#4254](https://github.com/ethyca/fides/pull/4254) - Assume Universal Vendor ID usage in TC String translation [#4256](https://github.com/ethyca/fides/pull/4256) ### Fixed diff --git a/clients/admin-ui/cypress/e2e/consent-configuration.cy.ts b/clients/admin-ui/cypress/e2e/consent-configuration.cy.ts index 91f54e002b..42b746cc63 100644 --- a/clients/admin-ui/cypress/e2e/consent-configuration.cy.ts +++ b/clients/admin-ui/cypress/e2e/consent-configuration.cy.ts @@ -215,9 +215,9 @@ describe("Consent configuration", () => { // Also check one that shouldn't have any cookies cy.getSelectValueContainer( - "input-privacy_declarations.3.data_use" + "input-privacy_declarations.1.data_use" ).contains("analytics.reporting.campaign_insights"); - cy.getByTestId("input-privacy_declarations.3.cookieNames").contains( + cy.getByTestId("input-privacy_declarations.1.cookieNames").contains( "Select..." ); // There should be 13 declarations (but start from 0, so 12) @@ -249,25 +249,47 @@ describe("Consent configuration", () => { ], cookies: [ { - name: "av_*", - domain: "**", - path: "/", + name: "2_C_*", + domain: "*.aniview.com", + path: null, }, { name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", + domain: "*.aniview.com", + path: null, }, { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", + name: "av_*", + domain: "*", + path: null, }, ], }, { name: "", - data_use: "functional.storage", + data_use: "analytics.reporting.campaign_insights", + data_categories: [ + "user.device.ip_address", + "user.device", + "user.sensor", + "user.user_sensor", + "user.telemetry", + "user.device.cookie_id", + "user.device.device_id", + "user.device.cookie", + "user.behavior.purchase_history", + "user.behavior", + "user.behavior.browsing_history", + "user.behavior.media_consumption", + "user.behavior.search_history", + "user.social", + "user.location.imprecise", + ], + cookies: [], + }, + { + name: "", + data_use: "analytics.reporting.ad_performance", data_categories: [ "user.device.ip_address", "user.device", @@ -287,25 +309,25 @@ describe("Consent configuration", () => { ], cookies: [ { - name: "av_*", - domain: "**", - path: "/", + name: "2_C_*", + domain: "*.aniview.com", + path: null, }, { name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", + domain: "*.aniview.com", + path: null, }, { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", + name: "av_*", + domain: "*", + path: null, }, ], }, { name: "", - data_use: "analytics.reporting.ad_performance", + data_use: "marketing.advertising.first_party.targeted", data_categories: [ "user.device.ip_address", "user.device", @@ -325,25 +347,25 @@ describe("Consent configuration", () => { ], cookies: [ { - name: "av_*", - domain: "**", - path: "/", + name: "2_C_*", + domain: "*.aniview.com", + path: null, }, { name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", + domain: "*.aniview.com", + path: null, }, { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", + name: "av_*", + domain: "*", + path: null, }, ], }, { name: "", - data_use: "analytics.reporting.campaign_insights", + data_use: "marketing.advertising.third_party.targeted", data_categories: [ "user.device.ip_address", "user.device", @@ -361,11 +383,27 @@ describe("Consent configuration", () => { "user.social", "user.location.imprecise", ], - cookies: [], + cookies: [ + { + name: "2_C_*", + domain: "*.aniview.com", + path: null, + }, + { + name: "aniC", + domain: "*.aniview.com", + path: null, + }, + { + name: "av_*", + domain: "*", + path: null, + }, + ], }, { name: "", - data_use: "marketing.advertising.first_party.targeted", + data_use: "functional.storage", data_categories: [ "user.device.ip_address", "user.device", @@ -385,25 +423,25 @@ describe("Consent configuration", () => { ], cookies: [ { - name: "av_*", - domain: "**", - path: "/", + name: "2_C_*", + domain: "*.aniview.com", + path: null, }, { name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", + domain: "*.aniview.com", + path: null, }, { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", + name: "av_*", + domain: "*", + path: null, }, ], }, { name: "", - data_use: "functional.service.improve", + data_use: "essential.fraud_detection", data_categories: [ "user.device.ip_address", "user.device", @@ -425,7 +463,7 @@ describe("Consent configuration", () => { }, { name: "", - data_use: "analytics.reporting.content_performance", + data_use: "marketing.advertising.negative_targeting", data_categories: [ "user.device.ip_address", "user.device", @@ -443,11 +481,27 @@ describe("Consent configuration", () => { "user.social", "user.location.imprecise", ], - cookies: [], + cookies: [ + { + name: "2_C_*", + domain: "*.aniview.com", + path: null, + }, + { + name: "aniC", + domain: "*.aniview.com", + path: null, + }, + { + name: "av_*", + domain: "*", + path: null, + }, + ], }, { name: "", - data_use: "essential.fraud_detection", + data_use: "marketing.advertising.frequency_capping", data_categories: [ "user.device.ip_address", "user.device", @@ -465,11 +519,27 @@ describe("Consent configuration", () => { "user.social", "user.location.imprecise", ], - cookies: [], + cookies: [ + { + name: "2_C_*", + domain: "*.aniview.com", + path: null, + }, + { + name: "aniC", + domain: "*.aniview.com", + path: null, + }, + { + name: "av_*", + domain: "*", + path: null, + }, + ], }, { name: "", - data_use: "essential.service.security", + data_use: "analytics.reporting.content_performance", data_categories: [ "user.device.ip_address", "user.device", @@ -491,7 +561,7 @@ describe("Consent configuration", () => { }, { name: "", - data_use: "marketing.advertising.negative_targeting", + data_use: "marketing.advertising.first_party.contextual", data_categories: [ "user.device.ip_address", "user.device", @@ -511,25 +581,25 @@ describe("Consent configuration", () => { ], cookies: [ { - name: "av_*", - domain: "**", - path: "/", + name: "2_C_*", + domain: "*.aniview.com", + path: null, }, { name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", + domain: "*.aniview.com", + path: null, }, { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", + name: "av_*", + domain: "*", + path: null, }, ], }, { name: "", - data_use: "marketing.advertising.first_party.contextual", + data_use: "functional.service.improve", data_categories: [ "user.device.ip_address", "user.device", @@ -547,27 +617,11 @@ describe("Consent configuration", () => { "user.social", "user.location.imprecise", ], - cookies: [ - { - name: "av_*", - domain: "**", - path: "/", - }, - { - name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", - }, - { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", - }, - ], + cookies: [], }, { name: "", - data_use: "marketing.advertising.frequency_capping", + data_use: "personalize.content.limited", data_categories: [ "user.device.ip_address", "user.device", @@ -585,27 +639,11 @@ describe("Consent configuration", () => { "user.social", "user.location.imprecise", ], - cookies: [ - { - name: "av_*", - domain: "**", - path: "/", - }, - { - name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", - }, - { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", - }, - ], + cookies: [], }, { name: "", - data_use: "marketing.advertising.third_party.targeted", + data_use: "essential.service.security", data_categories: [ "user.device.ip_address", "user.device", @@ -623,23 +661,7 @@ describe("Consent configuration", () => { "user.social", "user.location.imprecise", ], - cookies: [ - { - name: "av_*", - domain: "**", - path: "/", - }, - { - name: "aniC", - domain: "*.aniview.com*.aniview.com", - path: "/", - }, - { - name: "2_C_*", - domain: "*.aniview.com*.aniview.com", - path: "/", - }, - ], + cookies: [], }, ]); }); diff --git a/clients/admin-ui/cypress/e2e/systems-plus.cy.ts b/clients/admin-ui/cypress/e2e/systems-plus.cy.ts index 2827560357..4928f10c7b 100644 --- a/clients/admin-ui/cypress/e2e/systems-plus.cy.ts +++ b/clients/admin-ui/cypress/e2e/systems-plus.cy.ts @@ -36,8 +36,10 @@ describe("System management with Plus features", () => { cy.selectOption("input-vendor_id", "Aniview LTD"); cy.getSelectValueContainer("input-vendor_id").contains("Aniview LTD"); - cy.selectOption("input-vendor_id", "Jaduda GmbH"); - cy.getSelectValueContainer("input-vendor_id").contains("Jaduda GmbH"); + cy.selectOption("input-vendor_id", "Anzu Virtual Reality LTD"); + cy.getSelectValueContainer("input-vendor_id").contains( + "Anzu Virtual Reality LTD" + ); }); // some DictSuggestionTextInputs don't get populated right, causing diff --git a/clients/admin-ui/cypress/fixtures/dictionary-declarations.json b/clients/admin-ui/cypress/fixtures/dictionary-declarations.json index b6429b8714..61c9e7e12b 100644 --- a/clients/admin-ui/cypress/fixtures/dictionary-declarations.json +++ b/clients/admin-ui/cypress/fixtures/dictionary-declarations.json @@ -1,9 +1,7 @@ { "items": [ { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "marketing.advertising.profiling", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -21,44 +19,82 @@ "user.social", "user.location.imprecise" ], + "data_use": "marketing.advertising.profiling", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 3, - "special_purpose": null, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], "cookies": [ { - "identifier": "av_*", - "type": "web", + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "**" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "aniC", + "name": "aniC", + "path": null, + "domain": "*.aniview.com", "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "2_C_*", - "type": "cookie", + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null } - ] + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 3, + "special_purpose": null, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "functional.storage", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -76,44 +112,126 @@ "user.social", "user.location.imprecise" ], + "data_use": "analytics.reporting.campaign_insights", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 1, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 9, "special_purpose": null, + "gvl_version": "3" + }, + { + "name": null, + "data_categories": [ + "user.device.ip_address", + "user.device", + "user.sensor", + "user.user_sensor", + "user.telemetry", + "user.device.cookie_id", + "user.device.device_id", + "user.device.cookie", + "user.behavior.purchase_history", + "user.behavior", + "user.behavior.browsing_history", + "user.behavior.media_consumption", + "user.behavior.search_history", + "user.social", + "user.location.imprecise" + ], + "data_use": "analytics.reporting.ad_performance", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, + "features": [ + "Identify devices based on information transmitted automatically" + ], + "flexible_legal_basis_for_processing": false, + "legal_basis_for_processing": "Consent", + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], "cookies": [ { - "identifier": "av_*", - "type": "web", + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "**" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "aniC", + "name": "aniC", + "path": null, + "domain": "*.aniview.com", "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "2_C_*", - "type": "cookie", + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null } - ] + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 7, + "special_purpose": null, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "analytics.reporting.ad_performance", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -131,44 +249,82 @@ "user.social", "user.location.imprecise" ], + "data_use": "marketing.advertising.first_party.targeted", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 7, - "special_purpose": null, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], "cookies": [ { - "identifier": "av_*", - "type": "web", + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "**" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "aniC", + "name": "aniC", + "path": null, + "domain": "*.aniview.com", "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "2_C_*", - "type": "cookie", + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null } - ] + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 4, + "special_purpose": null, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "analytics.reporting.campaign_insights", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -186,19 +342,82 @@ "user.social", "user.location.imprecise" ], + "data_use": "marketing.advertising.third_party.targeted", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 9, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [ + { + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + }, + { + "name": "aniC", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + }, + { + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + } + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 4, "special_purpose": null, - "cookies": [] + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "marketing.advertising.first_party.targeted", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -216,44 +435,82 @@ "user.social", "user.location.imprecise" ], + "data_use": "functional.storage", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 4, - "special_purpose": null, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], "cookies": [ { - "identifier": "av_*", - "type": "web", + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "**" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "aniC", + "name": "aniC", + "path": null, + "domain": "*.aniview.com", "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "2_C_*", - "type": "cookie", + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null } - ] + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 1, + "special_purpose": null, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "functional.service.improve", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -271,19 +528,33 @@ "user.social", "user.location.imprecise" ], + "data_use": "essential.fraud_detection", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], - "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 10, - "special_purpose": null, - "cookies": [] + "flexible_legal_basis_for_processing": false, + "legal_basis_for_processing": "Legitimate interests", + "impact_assessment_location": null, + "retention_period": "100", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": null, + "special_purpose": 1, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "analytics.reporting.content_performance", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -301,19 +572,82 @@ "user.social", "user.location.imprecise" ], + "data_use": "marketing.advertising.negative_targeting", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 8, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [ + { + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + }, + { + "name": "aniC", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + }, + { + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + } + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 2, "special_purpose": null, - "cookies": [] + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "essential.fraud_detection", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -331,19 +665,82 @@ "user.social", "user.location.imprecise" ], + "data_use": "marketing.advertising.frequency_capping", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], - "legal_basis_for_processing": "Legitimate Interests", - "retention_period": 4320, - "purpose": null, - "special_purpose": 1, - "cookies": [] + "flexible_legal_basis_for_processing": false, + "legal_basis_for_processing": "Consent", + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [ + { + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + }, + { + "name": "aniC", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + }, + { + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, + "purposes": [1, 2, 3, 4, 7], + "special_purposes": [], + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null + } + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 2, + "special_purpose": null, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "essential.service.security", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -361,19 +758,33 @@ "user.social", "user.location.imprecise" ], + "data_use": "analytics.reporting.content_performance", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], - "legal_basis_for_processing": "Legitimate Interests", - "retention_period": 4320, - "purpose": null, - "special_purpose": 1, - "cookies": [] + "flexible_legal_basis_for_processing": false, + "legal_basis_for_processing": "Consent", + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 8, + "special_purpose": null, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "marketing.advertising.negative_targeting", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -391,44 +802,82 @@ "user.social", "user.location.imprecise" ], + "data_use": "marketing.advertising.first_party.contextual", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 2, - "special_purpose": null, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], "cookies": [ { - "identifier": "av_*", - "type": "web", + "name": "2_C_*", + "path": null, + "domain": "*.aniview.com", + "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 86400, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "**" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "aniC", + "name": "aniC", + "path": null, + "domain": "*.aniview.com", "type": "cookie", + "cookie_refresh": false, + "max_age_seconds": 1728000, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null }, { - "identifier": "2_C_*", - "type": "cookie", + "name": "av_*", + "path": null, + "domain": "*", + "type": "web", + "cookie_refresh": false, + "max_age_seconds": null, + "uses_non_cookie_access": false, "purposes": [1, 2, 3, 4, 7], "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" + "features": [], + "special_features": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "gvl_version": null } - ] + ], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 2, + "special_purpose": null, + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "marketing.advertising.first_party.contextual", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -446,44 +895,33 @@ "user.social", "user.location.imprecise" ], + "data_use": "functional.service.improve", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 2, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 10, "special_purpose": null, - "cookies": [ - { - "identifier": "av_*", - "type": "web", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "**" - }, - { - "identifier": "aniC", - "type": "cookie", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" - }, - { - "identifier": "2_C_*", - "type": "cookie", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" - } - ] + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "marketing.advertising.frequency_capping", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -501,44 +939,33 @@ "user.social", "user.location.imprecise" ], + "data_use": "personalize.content.limited", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], + "flexible_legal_basis_for_processing": false, "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 2, + "impact_assessment_location": null, + "retention_period": "4320", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": 11, "special_purpose": null, - "cookies": [ - { - "identifier": "av_*", - "type": "web", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "**" - }, - { - "identifier": "aniC", - "type": "cookie", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" - }, - { - "identifier": "2_C_*", - "type": "cookie", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" - } - ] + "gvl_version": "3" }, { - "vendor_id": "780", - "vendor_name": "Aniview LTD", - "data_use": "marketing.advertising.third_party.targeted", + "name": null, "data_categories": [ "user.device.ip_address", "user.device", @@ -556,42 +983,33 @@ "user.social", "user.location.imprecise" ], + "data_use": "essential.service.security", + "data_qualifier": null, + "data_subjects": [], + "dataset_references": null, + "egress": null, + "ingress": null, "features": [ - "Receive and use automatically-sent device characteristics for identification" + "Identify devices based on information transmitted automatically" ], - "legal_basis_for_processing": "Consent", - "retention_period": 4320, - "purpose": 4, - "special_purpose": null, - "cookies": [ - { - "identifier": "av_*", - "type": "web", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "**" - }, - { - "identifier": "aniC", - "type": "cookie", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" - }, - { - "identifier": "2_C_*", - "type": "cookie", - "purposes": [1, 2, 3, 4, 7], - "special_purposes": [], - "vendor_id": "780", - "domains": "*.aniview.com*.aniview.com" - } - ] + "flexible_legal_basis_for_processing": false, + "legal_basis_for_processing": "Legitimate interests", + "impact_assessment_location": null, + "retention_period": "100", + "processes_special_category_data": false, + "special_category_legal_basis": null, + "data_shared_with_third_parties": false, + "third_parties": null, + "shared_categories": [], + "cookies": [], + "vendor_id": "gvl.780", + "vendor_name": "Aniview LTD", + "purpose": null, + "special_purpose": 1, + "gvl_version": "3" } ], - "total": 13, + "total": 14, "page": 1, "size": 1000, "pages": 1 diff --git a/clients/admin-ui/cypress/fixtures/dictionary-entries.json b/clients/admin-ui/cypress/fixtures/dictionary-entries.json index fd117913d5..1f98b74313 100644 --- a/clients/admin-ui/cypress/fixtures/dictionary-entries.json +++ b/clients/admin-ui/cypress/fixtures/dictionary-entries.json @@ -1,48 +1,193 @@ { "items": [ { - "id": "780", - "legal_name": "Aniview LTD", + "fides_key": null, + "organization_fides_key": "default_organization", + "tags": [], + "name": null, + "description": null, + "registry_id": null, + "meta": null, + "fidesctl_meta": null, + "system_type": null, + "data_responsibility_title": null, + "egress": null, + "ingress": null, + "privacy_declarations": [], + "joint_controller": null, + "third_country_transfers": null, + "administrating_department": "Not defined", + "data_protection_impact_assessment": null, + "vendor_id": "gvl.780", + "dataset_references": [], + "processes_personal_data": true, + "exempt_from_privacy_regulations": false, + "reason_for_exemption": null, + "uses_profiling": false, + "legal_basis_for_profiling": [], + "does_international_transfers": true, + "legal_basis_for_transfers": ["Adequacy Decision", "SCCs"], + "requires_data_protection_assessments": false, + "dpa_location": null, + "dpa_progress": null, "privacy_policy": "https://www.aniview.com/privacy-policy/", - "dpo": "support@aniview.com", + "legal_name": "Aniview LTD", "legal_address": "Maetzler Rechtsanwalts GmbH &;Schellinggasse 3/10;Co KG;Schellinggasse 3/10;Vienna", - "international_transfers": true, - "legal_basis_for_transfers": "'Adequacy Decision', 'SCCs'", - "uses_profiling": false, - "legal_basis_for_profiling": null, - "data_security_practices": null, - "tags": null, - "logo": null, - "cookies": [] - }, - { - "id": "733", - "legal_name": "Anzu Virtual Reality LTD", - "privacy_policy": "https://www.anzu.io/privacy-policy", - "dpo": "info@anzu.io", - "legal_address": "Anzu Virtual Reality LTD;Keizerkarelweg 390;Amstelveen;1181 RK Amstelveen;Netherlands", - "international_transfers": true, - "legal_basis_for_transfers": "'Adequacy Decision', 'SCCs'", - "uses_profiling": false, - "legal_basis_for_profiling": null, + "responsibility": [], + "dpo": "support@aniview.com", + "joint_controller_info": null, "data_security_practices": null, - "tags": null, + "cookie_max_age_seconds": 7776000, + "uses_cookies": true, + "cookie_refresh": false, + "uses_non_cookie_access": true, + "legitimate_interest_disclosure_url": "https://www.aniview.com/privacy-policy/", + "purposes": [1, 2, 3, 4, 7, 8, 9, 10, 11], + "special_purposes": [1], + "leg_int_purposes": [], + "flexible_purposes": [], + "features": [3], + "special_features": [], + "data_declaration": [1, 2, 3, 6, 8], + "device_storage_disclosure_url": "https://player.aniview.com/gdpr/gdpr.json", + "overflow": null, + "territorial_scope": [ + "AT", + "BE", + "BG", + "HR", + "CY", + "CZ", + "DK", + "EE", + "FI", + "FR", + "DE", + "GR", + "HU", + "IS", + "IE", + "IT", + "LV", + "LI", + "LT", + "LU", + "MT", + "NL", + "NO", + "PL", + "PT", + "RO", + "SK", + "SI", + "ES", + "SE", + "CH", + "GB" + ], + "environments": [ + "Web", + "Native App (Mobile)", + "Native App (CTV)", + "Other" + ], + "service_types": ["SSP", "Ad Serving", "Header Bidding Service"], + "domains": null, "logo": null, + "gvl_version": "3", "cookies": [] }, { - "id": "252", - "legal_name": "Jaduda GmbH", - "privacy_policy": "https://www.splicky.com/en/web/privacy-delivery", - "dpo": "info@jaduda.com", - "legal_address": "Jaduda GmbH;Körtestraße 10;Berlin;10967;Germany", - "international_transfers": true, - "legal_basis_for_transfers": "'Adequacy Decision', 'SCCs', 'Supplementary measures'", + "fides_key": null, + "organization_fides_key": "default_organization", + "tags": [], + "name": null, + "description": null, + "registry_id": null, + "meta": null, + "fidesctl_meta": null, + "system_type": null, + "data_responsibility_title": null, + "egress": null, + "ingress": null, + "privacy_declarations": [], + "joint_controller": null, + "third_country_transfers": null, + "administrating_department": "Not defined", + "data_protection_impact_assessment": null, + "vendor_id": "gvl.733", + "dataset_references": [], + "processes_personal_data": true, + "exempt_from_privacy_regulations": false, + "reason_for_exemption": null, "uses_profiling": false, - "legal_basis_for_profiling": null, + "legal_basis_for_profiling": [], + "does_international_transfers": true, + "legal_basis_for_transfers": ["Adequacy Decision", "SCCs"], + "requires_data_protection_assessments": false, + "dpa_location": null, + "dpa_progress": null, + "privacy_policy": "https://www.anzu.io/privacy-policy", + "legal_name": "Anzu Virtual Reality LTD", + "legal_address": "Marshalllaan 2, unit 2.02;GZ Delft;2625;Netherlands;Netherlands", + "responsibility": [], + "dpo": "DPO@anzu.io", + "joint_controller_info": null, "data_security_practices": null, - "tags": null, + "cookie_max_age_seconds": null, + "uses_cookies": false, + "cookie_refresh": false, + "uses_non_cookie_access": true, + "legitimate_interest_disclosure_url": "https://www.anzu.io/privacy-policy", + "purposes": [1, 2, 3, 4, 9], + "special_purposes": [1, 2], + "leg_int_purposes": [7], + "flexible_purposes": [2, 7, 9], + "features": [1, 3], + "special_features": [1], + "data_declaration": [1, 2, 3, 6, 8, 10, 11], + "device_storage_disclosure_url": "https://admins-api.anzu.io/tcf2_disc.json", + "overflow": null, + "territorial_scope": [ + "AT", + "BE", + "BG", + "HR", + "CY", + "CZ", + "DK", + "EE", + "FI", + "FR", + "DE", + "GR", + "HU", + "IS", + "IE", + "IT", + "LV", + "LI", + "LT", + "LU", + "MT", + "NL", + "NO", + "PL", + "PT", + "RO", + "SK", + "SI", + "ES", + "SE", + "CH", + "GB", + "OTHER" + ], + "environments": ["Native App (Mobile)", "Native App (CTV)", "Other"], + "service_types": ["SSP", "Ad Serving"], + "domains": null, "logo": null, + "gvl_version": "3", "cookies": [] } ] diff --git a/clients/admin-ui/src/features/plus/plus.slice.ts b/clients/admin-ui/src/features/plus/plus.slice.ts index ee1fe491ba..dc76d59111 100644 --- a/clients/admin-ui/src/features/plus/plus.slice.ts +++ b/clients/admin-ui/src/features/plus/plus.slice.ts @@ -33,8 +33,11 @@ import { SystemScanResponse, SystemsDiff, } from "~/types/api"; - -import { DictDataUse, DictEntry, Page } from "./types"; +import { + DataUseDeclaration, + Page_DataUseDeclaration_, + Page_Vendor_, +} from "~/types/dictionary-api"; interface ScanParams { classify?: boolean; @@ -246,9 +249,9 @@ const plusApi = baseApi.injectEndpoints({ transformResponse: (list: CustomFieldDefinitionWithId[]) => list.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? "")), }), - getAllDictionaryEntries: build.query, void>({ + getAllDictionaryEntries: build.query({ query: () => ({ - params: { size: 1000 }, + params: { size: 2000 }, url: `plus/dictionary/system`, }), providesTags: ["Dictionary"], @@ -261,7 +264,7 @@ const plusApi = baseApi.injectEndpoints({ providesTags: ["Fides Cloud Config"], }), getDictionaryDataUses: build.query< - Page, + Page_DataUseDeclaration_, { vendor_id: string } >({ query: ({ vendor_id }) => ({ @@ -448,8 +451,8 @@ export const selectAllDictEntries = createSelector( data ? data.items .map((d) => ({ - label: d.display_name ? d.display_name : d.legal_name, - value: d.id, + label: (d.name ?? d.legal_name) || "", + value: d.vendor_id || "", description: d.description ? d.description : undefined, })) .sort((a, b) => (a.label > b.label ? 1 : -1)) @@ -461,13 +464,13 @@ export const selectDictEntry = (vendorId: string) => createSelector( [(state) => state, plusApi.endpoints.getAllDictionaryEntries.select()], (state, { data }) => { - const dictEntry = data?.items.find((d) => d.id.toString() === vendorId); + const dictEntry = data?.items.find((d) => d.vendor_id === vendorId); return dictEntry || EMPTY_DICT_ENTRY; } ); -const EMPTY_DATA_USES: DictDataUse[] = []; +const EMPTY_DATA_USES: DataUseDeclaration[] = []; export const selectDictDataUses = (vendorId: string) => createSelector( diff --git a/clients/admin-ui/src/features/plus/types.ts b/clients/admin-ui/src/features/plus/types.ts deleted file mode 100644 index 6a73ff8e44..0000000000 --- a/clients/admin-ui/src/features/plus/types.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - TODO: These are handmade types that will be replaced - with autogenerated types from the API once the schema - is stable. - */ -export type Page = { - items: T[]; - page: number; - pages: number; - size: number; - total: number; -}; - -export type DictEntry = { - id: string; - display_name: string; - legal_name: string; - privacy_policy: string; - dpo: string; - legal_address: string; - international_transfers: boolean; - legal_basis_for_transfers?: string[]; - uses_profiling: boolean; - legal_basis_for_profiling?: string[]; - data_security_practices?: string; - tags?: string; - logo?: string; - cookies: DictCookie[]; - description: string; -}; - -export type CookieType = "web" | "cookie"; - -export type DictCookie = { - identifier: string; - type: CookieType; - purposes: string; - vendor_id: string; - domains: string; -}; - -export type DictDataUse = { - vendor_id: string; - vendor_name: string; - data_use: string; - data_categories: string[]; - features: string[]; - legal_basis_for_processing: string; - retention_period: number; - purpose: number; - special_purpose: number; - cookies: any[]; -}; diff --git a/clients/admin-ui/src/features/system/SystemInformationForm.tsx b/clients/admin-ui/src/features/system/SystemInformationForm.tsx index 8c7abeab70..1b3675e70e 100644 --- a/clients/admin-ui/src/features/system/SystemInformationForm.tsx +++ b/clients/admin-ui/src/features/system/SystemInformationForm.tsx @@ -234,7 +234,7 @@ const SystemInformationForm = ({ vendor.name ?? (vendor.legal_name || "")} isRequired label="System name" tooltip="Give the system a unique, and relevant name for reporting purposes. e.g. “Email Data Warehouse”" @@ -253,7 +253,6 @@ const SystemInformationForm = ({ id="description" name="description" label="Description" - dictField="description" tooltip="What services does this system perform?" /> @@ -346,7 +344,6 @@ const SystemInformationForm = ({ @@ -373,7 +369,6 @@ const SystemInformationForm = ({ diff --git a/clients/admin-ui/src/features/system/dictionary-data-uses/DataUseCheckboxTable.tsx b/clients/admin-ui/src/features/system/dictionary-data-uses/DataUseCheckboxTable.tsx index 2e5aa4b0de..18be1c237b 100644 --- a/clients/admin-ui/src/features/system/dictionary-data-uses/DataUseCheckboxTable.tsx +++ b/clients/admin-ui/src/features/system/dictionary-data-uses/DataUseCheckboxTable.tsx @@ -10,14 +10,14 @@ import { Tr, } from "@fidesui/react"; -import { DataUse } from "../../../types/api"; -import { DictDataUse } from "../../plus/types"; +import { DataUse } from "~/types/api"; +import { DataUseDeclaration } from "~/types/dictionary-api"; interface Props { - onChange: (dataUses: DictDataUse[]) => void; + onChange: (dataUses: DataUseDeclaration[]) => void; allDataUses: DataUse[]; - dictDataUses: DictDataUse[]; - checked: DictDataUse[]; + dictDataUses: DataUseDeclaration[]; + checked: DataUseDeclaration[]; } const DataUseCheckboxTable = ({ @@ -34,7 +34,7 @@ const DataUseCheckboxTable = ({ } }; - const onCheck = (dataUse: DictDataUse) => { + const onCheck = (dataUse: DataUseDeclaration) => { const exists = checked.filter((du) => du.data_use === dataUse.data_use).length > 0; if (!exists) { @@ -48,7 +48,7 @@ const DataUseCheckboxTable = ({ } }; - const declarationTitle = (declaration: DictDataUse) => { + const declarationTitle = (declaration: DataUseDeclaration) => { const dataUse = allDataUses.filter( (du) => du.fides_key === declaration.data_use )[0]; diff --git a/clients/admin-ui/src/features/system/dictionary-data-uses/PrivacyDeclarationDictModalComponents.tsx b/clients/admin-ui/src/features/system/dictionary-data-uses/PrivacyDeclarationDictModalComponents.tsx index d90f9e4dd0..fec2db0ccd 100644 --- a/clients/admin-ui/src/features/system/dictionary-data-uses/PrivacyDeclarationDictModalComponents.tsx +++ b/clients/admin-ui/src/features/system/dictionary-data-uses/PrivacyDeclarationDictModalComponents.tsx @@ -12,18 +12,18 @@ import { selectDictDataUses, useGetDictionaryDataUsesQuery, } from "~/features/plus/plus.slice"; +import { DataUseDeclaration } from "~/types/dictionary-api"; import { useAppSelector } from "../../../app/hooks"; import { DataUse } from "../../../types/api"; import { SparkleIcon } from "../../common/Icon/SparkleIcon"; -import { DictDataUse } from "../../plus/types"; import DataUseCheckboxTable from "./DataUseCheckboxTable"; interface Props { alreadyHasDataUses: boolean; allDataUses: DataUse[]; onCancel: () => void; - onAccept: (suggestions: DictDataUse[]) => void; + onAccept: (suggestions: DataUseDeclaration[]) => void; vendorId: string; } @@ -34,7 +34,9 @@ const PrivacyDeclarationDictModalComponents = ({ onAccept, vendorId, }: Props) => { - const [selectedDataUses, setSelectedDataUses] = useState([]); + const [selectedDataUses, setSelectedDataUses] = useState< + DataUseDeclaration[] + >([]); useGetDictionaryDataUsesQuery({ vendor_id: vendorId }); const dictDataUses = useAppSelector(selectDictDataUses(vendorId)); @@ -43,7 +45,7 @@ const PrivacyDeclarationDictModalComponents = ({ setSelectedDataUses(dictDataUses); }, [dictDataUses]); - const handleChangeChecked = (newChecked: DictDataUse[]) => { + const handleChangeChecked = (newChecked: DataUseDeclaration[]) => { setSelectedDataUses(newChecked); }; diff --git a/clients/admin-ui/src/features/system/dictionary-form/DictSuggestionInputs.tsx b/clients/admin-ui/src/features/system/dictionary-form/DictSuggestionInputs.tsx index af2d4e6ba2..7e8153fe88 100644 --- a/clients/admin-ui/src/features/system/dictionary-form/DictSuggestionInputs.tsx +++ b/clients/admin-ui/src/features/system/dictionary-form/DictSuggestionInputs.tsx @@ -21,13 +21,13 @@ import { } from "~/features/common/form/inputs"; import QuestionTooltip from "~/features/common/QuestionTooltip"; import { selectDictEntry } from "~/features/plus/plus.slice"; -import { DictEntry } from "~/features/plus/types"; import { selectSuggestions } from "~/features/system/dictionary-form/dict-suggestion.slice"; import type { FormValues } from "~/features/system/form"; +import { Vendor } from "~/types/dictionary-api"; const useDictSuggestion = ( fieldName: string, - dictField: string, + dictField?: (vendor: Vendor) => string | boolean, fieldType?: string ) => { const [initialField, meta, { setValue, setTouched }] = useField({ @@ -59,13 +59,13 @@ const useDictSuggestion = ( }, [isShowingSuggestions, setPreSuggestionValue]); useEffect(() => { - if ( - isShowingSuggestions === "showing" && - dictEntry && - dictField in dictEntry - ) { - if (field.value !== dictEntry[dictField as keyof DictEntry]) { - setValue(dictEntry[dictField as keyof DictEntry]); + if (isShowingSuggestions === "showing" && dictEntry) { + // Either use the passed in getter for a dictfield, or default to the field name + const dictFieldValue = dictField + ? dictField(dictEntry) + : dictEntry[fieldName as keyof Vendor]; + if (field.value !== dictFieldValue) { + setValue(dictFieldValue); // This blur is a workaround some forik issues. // the setTimeout is required to get around a @@ -78,7 +78,7 @@ const useDictSuggestion = ( } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isShowingSuggestions, setValue, dictEntry, dictField, inputRef.current]); + }, [isShowingSuggestions, setValue, dictEntry, inputRef.current]); useEffect(() => { if (isShowingSuggestions === "hiding") { @@ -96,7 +96,7 @@ const useDictSuggestion = ( }; type Props = { - dictField: string; + dictField?: (vendor: Vendor) => string | boolean; } & Omit & StringField; diff --git a/clients/admin-ui/src/features/system/dictionary-form/helpers.ts b/clients/admin-ui/src/features/system/dictionary-form/helpers.ts index dc4bd01be8..2d6c2df352 100644 --- a/clients/admin-ui/src/features/system/dictionary-form/helpers.ts +++ b/clients/admin-ui/src/features/system/dictionary-form/helpers.ts @@ -1,15 +1,9 @@ -import { DictDataUse } from "~/features/plus/types"; import { PrivacyDeclarationResponse } from "~/types/api"; +import { DataUseDeclaration } from "~/types/dictionary-api"; export const transformDictDataUseToDeclaration = ( - dataUse: DictDataUse -): PrivacyDeclarationResponse => { - // fix "Legitimate Interests" capitalization for API - const legalBasisForProcessing = - dataUse.legal_basis_for_processing === "Legitimate Interests" - ? "Legitimate interests" - : dataUse.legal_basis_for_processing; - + dataUse: DataUseDeclaration +): Omit => { // some data categories are nested on the backend, flatten them // https://github.com/ethyca/fides-services/issues/100 const dataCategories = dataUse.data_categories.flatMap((dc) => dc.split(",")); @@ -18,13 +12,12 @@ export const transformDictDataUseToDeclaration = ( data_use: dataUse.data_use, data_categories: dataCategories, features: dataUse.features, - // @ts-ignore - legal_basis_for_processing: legalBasisForProcessing, + legal_basis_for_processing: dataUse.legal_basis_for_processing, retention_period: `${dataUse.retention_period}`, - cookies: dataUse.cookies.map((c) => ({ - name: c.identifier, - domain: c.domains, - path: "/", + cookies: dataUse.cookies?.map((c) => ({ + name: c.name, + domain: c.domain, + path: c.path, })), }; }; diff --git a/clients/admin-ui/src/features/system/system-form-declaration-tab/PrivacyDeclarationFormTab.tsx b/clients/admin-ui/src/features/system/system-form-declaration-tab/PrivacyDeclarationFormTab.tsx index 87a7dae119..48a6b2ee81 100644 --- a/clients/admin-ui/src/features/system/system-form-declaration-tab/PrivacyDeclarationFormTab.tsx +++ b/clients/admin-ui/src/features/system/system-form-declaration-tab/PrivacyDeclarationFormTab.tsx @@ -30,10 +30,10 @@ import { System, SystemResponse, } from "~/types/api"; +import { DataUseDeclaration } from "~/types/dictionary-api"; import { isErrorResult } from "~/types/errors"; import { useFeatures } from "../../common/features"; -import { DictDataUse } from "../../plus/types"; import PrivacyDeclarationDictModalComponents from "../dictionary-data-uses/PrivacyDeclarationDictModalComponents"; interface Props { @@ -100,7 +100,7 @@ const PrivacyDeclarationFormTab = ({ }; const handleSave = async ( - updatedDeclarations: PrivacyDeclarationResponse[], + updatedDeclarations: Omit[], isDelete?: boolean ) => { // The API can return a null name, but cannot receive a null name, @@ -195,7 +195,7 @@ const PrivacyDeclarationFormTab = ({ setCurrentDeclaration(declarationToEdit); }; - const handleAcceptDictSuggestions = (suggestions: DictDataUse[]) => { + const handleAcceptDictSuggestions = (suggestions: DataUseDeclaration[]) => { const newDeclarations = suggestions.map((du) => transformDictDataUseToDeclaration(du) ); diff --git a/clients/admin-ui/src/types/dictionary-api/README.md b/clients/admin-ui/src/types/dictionary-api/README.md new file mode 100644 index 0000000000..82bcb4568e --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/README.md @@ -0,0 +1,15 @@ +# Fides Compass API Types + +**Do not manually edit these files.** + +The TypeScript files in this directory are auto-generated by OpenAPI. We do the same thing for our Fides backend types, but this is the equivalent for the dictionary service. Refer to [the Fides API types README](../api/README.md) for more information. + +## Updating + +These files can by regenerated by running: + +``` +turbo run openapi:generate-dictionary +``` + +**A local compass instance must be running on `localhost:8081`**. This will read the schema hosted at and generate all TS files under `clients/admin-ui/src/types/dictionary-api/`. diff --git a/clients/admin-ui/src/types/dictionary-api/index.ts b/clients/admin-ui/src/types/dictionary-api/index.ts new file mode 100644 index 0000000000..d85f25e242 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/index.ts @@ -0,0 +1,22 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type { ContactDetails } from "./models/ContactDetails"; +export type { Cookie } from "./models/Cookie"; +export type { Cookies } from "./models/Cookies"; +export { CookieType } from "./models/CookieType"; +export type { DataFlow } from "./models/DataFlow"; +export type { DataProtectionImpactAssessment } from "./models/DataProtectionImpactAssessment"; +export { DataResponsibilityTitle } from "./models/DataResponsibilityTitle"; +export type { DataUseDeclaration } from "./models/DataUseDeclaration"; +export type { HTTPValidationError } from "./models/HTTPValidationError"; +export { LegalBasisForProcessingEnum } from "./models/LegalBasisForProcessingEnum"; +export { LegalBasisForProfilingEnum } from "./models/LegalBasisForProfilingEnum"; +export type { Page_DataUseDeclaration_ } from "./models/Page_DataUseDeclaration_"; +export type { Page_Vendor_ } from "./models/Page_Vendor_"; +export type { PrivacyDeclaration } from "./models/PrivacyDeclaration"; +export { SpecialCategoryLegalBasisEnum } from "./models/SpecialCategoryLegalBasisEnum"; +export type { SystemMetadata } from "./models/SystemMetadata"; +export type { ValidationError } from "./models/ValidationError"; +export type { Vendor } from "./models/Vendor"; diff --git a/clients/admin-ui/src/types/dictionary-api/models/ContactDetails.ts b/clients/admin-ui/src/types/dictionary-api/models/ContactDetails.ts new file mode 100644 index 0000000000..b603a81889 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/ContactDetails.ts @@ -0,0 +1,31 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The contact details information model. + * + * Used to capture contact information for controllers, used + * as part of exporting a data map / ROPA. + * + * This model is nested under an Organization and + * potentially under a system/dataset. + */ +export type ContactDetails = { + /** + * An individual name used as part of publishing contact information. Encrypted at rest on the server. + */ + name?: string; + /** + * An individual address used as part of publishing contact information. Encrypted at rest on the server. + */ + address?: string; + /** + * An individual email used as part of publishing contact information. Encrypted at rest on the server. + */ + email?: string; + /** + * An individual phone number used as part of publishing contact information. Encrypted at rest on the server. + */ + phone?: string; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/Cookie.ts b/clients/admin-ui/src/types/dictionary-api/models/Cookie.ts new file mode 100644 index 0000000000..2278040c58 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/Cookie.ts @@ -0,0 +1,55 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { CookieType } from "./CookieType"; + +/** + * The Cookies resource model + */ +export type Cookie = { + name: string; + path?: string; + domain?: string; + type: CookieType; + /** + * Whether the cookie is refreshed after being initially set. + */ + cookie_refresh?: boolean; + /** + * The maximum storage duration, in seconds, for this cookie. + */ + max_age_seconds?: number; + /** + * Whether the associated Vendor record uses non-cookie methods of storage or accessing information stored on a user's device. + */ + uses_non_cookie_access?: boolean; + /** + * The record's GVL purposes + */ + purposes?: Array; + /** + * The record's GVL special purposes + */ + special_purposes?: Array; + /** + * The record's GVL features + */ + features?: Array; + /** + * The record's GVL special features + */ + special_features?: Array; + /** + * The ID of the vendor that the record belongs to + */ + vendor_id: string; + /** + * The name of the vendor that the record belongs to + */ + vendor_name: string; + /** + * The version of GVL from which the record is derived + */ + gvl_version?: string; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/CookieType.ts b/clients/admin-ui/src/types/dictionary-api/models/CookieType.ts new file mode 100644 index 0000000000..63e33fd270 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/CookieType.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * An enumeration. + */ +export enum CookieType { + COOKIE = "cookie", + WEB = "web", + APP = "app", +} diff --git a/clients/admin-ui/src/types/dictionary-api/models/Cookies.ts b/clients/admin-ui/src/types/dictionary-api/models/Cookies.ts new file mode 100644 index 0000000000..923ab591c3 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/Cookies.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The Cookies resource model + */ +export type Cookies = { + name: string; + path?: string; + domain?: string; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/DataFlow.ts b/clients/admin-ui/src/types/dictionary-api/models/DataFlow.ts new file mode 100644 index 0000000000..2352b76cdb --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/DataFlow.ts @@ -0,0 +1,23 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The DataFlow resource model. + * + * Describes a resource model with which a given System resource communicates. + */ +export type DataFlow = { + /** + * Identifies the System or Dataset resource with which the communication occurs. May also be 'user', to represent communication with the user(s) of a System. + */ + fides_key: string; + /** + * Specifies the resource model class for which the `fides_key` applies. May be any of dataset, system, user. + */ + type: string; + /** + * An array of data categories describing the data in transit. + */ + data_categories?: Array; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/DataProtectionImpactAssessment.ts b/clients/admin-ui/src/types/dictionary-api/models/DataProtectionImpactAssessment.ts new file mode 100644 index 0000000000..ee8fd39ef3 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/DataProtectionImpactAssessment.ts @@ -0,0 +1,28 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The DataProtectionImpactAssessment (DPIA) resource model. + * + * Contains information in regard to the data protection + * impact assessment exported on a data map or Record of + * Processing Activities (RoPA). + * + * A legal requirement under GDPR for any project that + * introduces a high risk to personal information. + */ +export type DataProtectionImpactAssessment = { + /** + * A boolean value determining if a data protection impact assessment is required. Defaults to False. + */ + is_required?: boolean; + /** + * The optional status of a Data Protection Impact Assessment. Returned on an exported data map or RoPA. + */ + progress?: string; + /** + * The optional link to the Data Protection Impact Assessment. Returned on an exported data map or RoPA. + */ + link?: string; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/DataResponsibilityTitle.ts b/clients/admin-ui/src/types/dictionary-api/models/DataResponsibilityTitle.ts new file mode 100644 index 0000000000..0de7664f15 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/DataResponsibilityTitle.ts @@ -0,0 +1,16 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The model defining the responsibility or role over + * the system that processes personal data. + * + * Used to identify whether the organization is a + * Controller, Processor, or Sub-Processor of the data + */ +export enum DataResponsibilityTitle { + CONTROLLER = "Controller", + PROCESSOR = "Processor", + SUB_PROCESSOR = "Sub-Processor", +} diff --git a/clients/admin-ui/src/types/dictionary-api/models/DataUseDeclaration.ts b/clients/admin-ui/src/types/dictionary-api/models/DataUseDeclaration.ts new file mode 100644 index 0000000000..8a8a24d5e5 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/DataUseDeclaration.ts @@ -0,0 +1,112 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { Cookie } from "./Cookie"; +import type { LegalBasisForProcessingEnum } from "./LegalBasisForProcessingEnum"; +import type { SpecialCategoryLegalBasisEnum } from "./SpecialCategoryLegalBasisEnum"; + +/** + * The PrivacyDeclaration resource model. + * + * States a function of a system, and describes how it relates + * to the privacy data types. + */ +export type DataUseDeclaration = { + /** + * The name of the privacy declaration on the system. + */ + name?: string; + /** + * An array of data categories describing a system in a privacy declaration. + */ + data_categories: Array; + /** + * The Data Use describing a system in a privacy declaration. + */ + data_use: string; + /** + * Deprecated. The fides key of the data qualifier describing a system in a privacy declaration. + */ + data_qualifier?: string; + /** + * An array of data subjects describing a system in a privacy declaration. + */ + data_subjects?: Array; + /** + * Referenced Dataset fides keys used by the system. + */ + dataset_references?: Array; + /** + * The resources to which data is sent. Any `fides_key`s included in this list reference `DataFlow` entries in the `egress` array of any `System` resources to which this `PrivacyDeclaration` is applied. + */ + egress?: Array; + /** + * The resources from which data is received. Any `fides_key`s included in this list reference `DataFlow` entries in the `ingress` array of any `System` resources to which this `PrivacyDeclaration` is applied. + */ + ingress?: Array; + /** + * The features of processing personal data. + */ + features?: Array; + /** + * Whether the legal basis for processing is 'flexible' (i.e. can be overridden in a privacy notice) for this declaration. + */ + flexible_legal_basis_for_processing?: boolean; + /** + * The legal basis under which personal data is processed for this purpose. + */ + legal_basis_for_processing?: LegalBasisForProcessingEnum; + /** + * Where the legitimate interest impact assessment is stored + */ + impact_assessment_location?: string; + /** + * An optional string to describe the time period for which data is retained for this purpose. + */ + retention_period?: string; + /** + * This system processes special category data + */ + processes_special_category_data?: boolean; + /** + * The legal basis under which the special category data is processed. + */ + special_category_legal_basis?: SpecialCategoryLegalBasisEnum; + /** + * This system shares data with third parties for this purpose. + */ + data_shared_with_third_parties?: boolean; + /** + * The types of third parties the data is shared with. + */ + third_parties?: string; + /** + * The categories of personal data that this system shares with third parties. + */ + shared_categories?: Array; + /** + * The Cookies associated with the record + */ + cookies?: Array; + /** + * The ID of the vendor that the record belongs to + */ + vendor_id: string; + /** + * The name of the vendor that the record belongs to + */ + vendor_name: string; + /** + * The GVL purpose associated with this data use declaration + */ + purpose?: number; + /** + * The GVL special purpose associated with this data use declaration + */ + special_purpose?: number; + /** + * The version of GVL from which the record is derived + */ + gvl_version?: string; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/HTTPValidationError.ts b/clients/admin-ui/src/types/dictionary-api/models/HTTPValidationError.ts new file mode 100644 index 0000000000..842405324c --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/HTTPValidationError.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ValidationError } from "./ValidationError"; + +export type HTTPValidationError = { + detail?: Array; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/LegalBasisForProcessingEnum.ts b/clients/admin-ui/src/types/dictionary-api/models/LegalBasisForProcessingEnum.ts new file mode 100644 index 0000000000..6cd70b6558 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/LegalBasisForProcessingEnum.ts @@ -0,0 +1,17 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The model for allowable legal basis categories on privacy declarations. + * + * Based upon article 6 of the GDPR + */ +export enum LegalBasisForProcessingEnum { + CONSENT = "Consent", + CONTRACT = "Contract", + LEGAL_OBLIGATIONS = "Legal obligations", + VITAL_INTERESTS = "Vital interests", + PUBLIC_INTEREST = "Public interest", + LEGITIMATE_INTERESTS = "Legitimate interests", +} diff --git a/clients/admin-ui/src/types/dictionary-api/models/LegalBasisForProfilingEnum.ts b/clients/admin-ui/src/types/dictionary-api/models/LegalBasisForProfilingEnum.ts new file mode 100644 index 0000000000..6b32dfd7f9 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/LegalBasisForProfilingEnum.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The model for describing the legal basis under which profiling is performed + */ +export enum LegalBasisForProfilingEnum { + EXPLICIT_CONSENT = "Explicit consent", + CONTRACT = "Contract", + AUTHORISED_BY_LAW = "Authorised by law", +} diff --git a/clients/admin-ui/src/types/dictionary-api/models/Page_DataUseDeclaration_.ts b/clients/admin-ui/src/types/dictionary-api/models/Page_DataUseDeclaration_.ts new file mode 100644 index 0000000000..85effa7afc --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/Page_DataUseDeclaration_.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DataUseDeclaration } from "./DataUseDeclaration"; + +export type Page_DataUseDeclaration_ = { + items: Array; + total: number; + page?: number; + size?: number; + pages?: number; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/Page_Vendor_.ts b/clients/admin-ui/src/types/dictionary-api/models/Page_Vendor_.ts new file mode 100644 index 0000000000..2897b0f39f --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/Page_Vendor_.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { Vendor } from "./Vendor"; + +export type Page_Vendor_ = { + items: Array; + total: number; + page?: number; + size?: number; + pages?: number; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/PrivacyDeclaration.ts b/clients/admin-ui/src/types/dictionary-api/models/PrivacyDeclaration.ts new file mode 100644 index 0000000000..ce76d10dc4 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/PrivacyDeclaration.ts @@ -0,0 +1,92 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { Cookies } from "./Cookies"; +import type { LegalBasisForProcessingEnum } from "./LegalBasisForProcessingEnum"; +import type { SpecialCategoryLegalBasisEnum } from "./SpecialCategoryLegalBasisEnum"; + +/** + * The PrivacyDeclaration resource model. + * + * States a function of a system, and describes how it relates + * to the privacy data types. + */ +export type PrivacyDeclaration = { + /** + * The name of the privacy declaration on the system. + */ + name?: string; + /** + * An array of data categories describing a system in a privacy declaration. + */ + data_categories: Array; + /** + * The Data Use describing a system in a privacy declaration. + */ + data_use: string; + /** + * Deprecated. The fides key of the data qualifier describing a system in a privacy declaration. + */ + data_qualifier?: string; + /** + * An array of data subjects describing a system in a privacy declaration. + */ + data_subjects?: Array; + /** + * Referenced Dataset fides keys used by the system. + */ + dataset_references?: Array; + /** + * The resources to which data is sent. Any `fides_key`s included in this list reference `DataFlow` entries in the `egress` array of any `System` resources to which this `PrivacyDeclaration` is applied. + */ + egress?: Array; + /** + * The resources from which data is received. Any `fides_key`s included in this list reference `DataFlow` entries in the `ingress` array of any `System` resources to which this `PrivacyDeclaration` is applied. + */ + ingress?: Array; + /** + * The features of processing personal data. + */ + features?: Array; + /** + * Whether the legal basis for processing is 'flexible' (i.e. can be overridden in a privacy notice) for this declaration. + */ + flexible_legal_basis_for_processing?: boolean; + /** + * The legal basis under which personal data is processed for this purpose. + */ + legal_basis_for_processing?: LegalBasisForProcessingEnum; + /** + * Where the legitimate interest impact assessment is stored + */ + impact_assessment_location?: string; + /** + * An optional string to describe the time period for which data is retained for this purpose. + */ + retention_period?: string; + /** + * This system processes special category data + */ + processes_special_category_data?: boolean; + /** + * The legal basis under which the special category data is processed. + */ + special_category_legal_basis?: SpecialCategoryLegalBasisEnum; + /** + * This system shares data with third parties for this purpose. + */ + data_shared_with_third_parties?: boolean; + /** + * The types of third parties the data is shared with. + */ + third_parties?: string; + /** + * The categories of personal data that this system shares with third parties. + */ + shared_categories?: Array; + /** + * Cookies associated with this data use to deliver services and functionality + */ + cookies?: Array; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/SpecialCategoryLegalBasisEnum.ts b/clients/admin-ui/src/types/dictionary-api/models/SpecialCategoryLegalBasisEnum.ts new file mode 100644 index 0000000000..8c16a65b64 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/SpecialCategoryLegalBasisEnum.ts @@ -0,0 +1,22 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The model for the legal basis for processing special categories of personal data + * on privacy declarations + * + * Based upon article 9 of the GDPR + */ +export enum SpecialCategoryLegalBasisEnum { + EXPLICIT_CONSENT = "Explicit consent", + EMPLOYMENT_SOCIAL_SECURITY_AND_SOCIAL_PROTECTION = "Employment, social security and social protection", + VITAL_INTERESTS = "Vital interests", + NOT_FOR_PROFIT_BODIES = "Not-for-profit bodies", + MADE_PUBLIC_BY_THE_DATA_SUBJECT = "Made public by the data subject", + LEGAL_CLAIMS_OR_JUDICIAL_ACTS = "Legal claims or judicial acts", + REASONS_OF_SUBSTANTIAL_PUBLIC_INTEREST_WITH_A_BASIS_IN_LAW_ = "Reasons of substantial public interest (with a basis in law)", + HEALTH_OR_SOCIAL_CARE_WITH_A_BASIS_IN_LAW_ = "Health or social care (with a basis in law)", + PUBLIC_HEALTH_WITH_A_BASIS_IN_LAW_ = "Public health (with a basis in law)", + ARCHIVING_RESEARCH_AND_STATISTICS_WITH_A_BASIS_IN_LAW_ = "Archiving, research and statistics (with a basis in law)", +} diff --git a/clients/admin-ui/src/types/dictionary-api/models/SystemMetadata.ts b/clients/admin-ui/src/types/dictionary-api/models/SystemMetadata.ts new file mode 100644 index 0000000000..08451a936b --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/SystemMetadata.ts @@ -0,0 +1,23 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * The SystemMetadata resource model. + * + * Object used to hold application specific metadata for a system + */ +export type SystemMetadata = { + /** + * The external resource id for the system being modeled. + */ + resource_id?: string; + /** + * The host of the external resource for the system being modeled. + */ + endpoint_address?: string; + /** + * The port of the external resource for the system being modeled. + */ + endpoint_port?: string; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/ValidationError.ts b/clients/admin-ui/src/types/dictionary-api/models/ValidationError.ts new file mode 100644 index 0000000000..b50d0aa414 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/ValidationError.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type ValidationError = { + loc: Array; + msg: string; + type: string; +}; diff --git a/clients/admin-ui/src/types/dictionary-api/models/Vendor.ts b/clients/admin-ui/src/types/dictionary-api/models/Vendor.ts new file mode 100644 index 0000000000..a6cfb02c19 --- /dev/null +++ b/clients/admin-ui/src/types/dictionary-api/models/Vendor.ts @@ -0,0 +1,260 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContactDetails } from "./ContactDetails"; +import type { Cookie } from "./Cookie"; +import type { DataFlow } from "./DataFlow"; +import type { DataProtectionImpactAssessment } from "./DataProtectionImpactAssessment"; +import type { DataResponsibilityTitle } from "./DataResponsibilityTitle"; +import type { LegalBasisForProfilingEnum } from "./LegalBasisForProfilingEnum"; +import type { PrivacyDeclaration } from "./PrivacyDeclaration"; +import type { SystemMetadata } from "./SystemMetadata"; + +/** + * The System resource model. + * + * Describes an application and includes a list of PrivacyDeclaration resources. + */ +export type Vendor = { + fides_key?: string; + /** + * Defines the Organization that this resource belongs to. + */ + organization_fides_key?: string; + tags?: Array; + name?: string; + /** + * A detailed description of what this resource is. + */ + description?: string; + /** + * The id of the system registry, if used. + */ + registry_id?: number; + /** + * An optional property to store any extra information for a resource. Data can be structured in any way: simple set of `key: value` pairs or deeply nested objects. + */ + meta?: any; + /** + * + * The SystemMetadata resource model. + * + * Object used to hold application specific metadata for a system + * + */ + fidesctl_meta?: SystemMetadata; + system_type?: string; + /** + * Deprecated. The responsibility or role over the system that processes personal data + */ + data_responsibility_title?: DataResponsibilityTitle; + /** + * The resources to which the system sends data. + */ + egress?: Array; + /** + * The resources from which the system receives data. + */ + ingress?: Array; + privacy_declarations?: Array; + /** + * Deprecated. + * The contact details information model. + * + * Used to capture contact information for controllers, used + * as part of exporting a data map / ROPA. + * + * This model is nested under an Organization and + * potentially under a system/dataset. + * + */ + joint_controller?: ContactDetails; + /** + * Deprecated. An optional array to identify any third countries where data is transited to. For consistency purposes, these fields are required to follow the Alpha-3 code set in ISO 3166-1. + */ + third_country_transfers?: Array; + /** + * An optional value to identify the owning department or group of the system within your organization + */ + administrating_department?: string; + /** + * Deprecated. + * The DataProtectionImpactAssessment (DPIA) resource model. + * + * Contains information in regard to the data protection + * impact assessment exported on a data map or Record of + * Processing Activities (RoPA). + * + * A legal requirement under GDPR for any project that + * introduces a high risk to personal information. + * + */ + data_protection_impact_assessment?: DataProtectionImpactAssessment; + /** + * The unique identifier for the vendor that's associated with this system. + */ + vendor_id?: string; + /** + * Referenced Dataset fides keys used by the system. + */ + dataset_references?: Array; + /** + * This toggle indicates whether the system stores or processes personal data. + */ + processes_personal_data?: boolean; + /** + * This toggle indicates whether the system is exempt from privacy regulation if they do process personal data. + */ + exempt_from_privacy_regulations?: boolean; + /** + * The reason that the system is exempt from privacy regulation. + */ + reason_for_exemption?: string; + /** + * Whether the vendor uses data to profile a consumer in a way that has a legal effect. + */ + uses_profiling?: boolean; + /** + * The legal basis (or bases) for performing profiling that has a legal effect. + */ + legal_basis_for_profiling?: Array; + /** + * Whether this system transfers data to other countries or international organizations. + */ + does_international_transfers?: boolean; + /** + * The legal basis (or bases) under which the data is transferred. + */ + legal_basis_for_transfers?: Array; + /** + * Whether this system requires data protection impact assessments. + */ + requires_data_protection_assessments?: boolean; + /** + * Location where the DPAs or DIPAs can be found. + */ + dpa_location?: string; + /** + * The optional status of a Data Protection Impact Assessment + */ + dpa_progress?: string; + /** + * A URL that points to the system's publicly accessible privacy policy. + */ + privacy_policy?: string; + /** + * The legal name for the business represented by the system. + */ + legal_name?: string; + /** + * The legal address for the business represented by the system. + */ + legal_address?: string; + /** + * + * The model defining the responsibility or role over + * the system that processes personal data. + * + * Used to identify whether the organization is a + * Controller, Processor, or Sub-Processor of the data + * + */ + responsibility?: Array; + /** + * The official privacy contact address or DPO. + */ + dpo?: string; + /** + * The party or parties that share the responsibility for processing personal data. + */ + joint_controller_info?: string; + /** + * The data security practices employed by this system. + */ + data_security_practices?: string; + /** + * The maximum storage duration, in seconds, for cookies used by this system. + */ + cookie_max_age_seconds?: number; + /** + * Whether this system uses cookie storage. + */ + uses_cookies?: boolean; + /** + * Whether the system's cookies are refreshed after being initially set. + */ + cookie_refresh?: boolean; + /** + * Whether the system uses non-cookie methods of storage or accessing information stored on a user's device. + */ + uses_non_cookie_access?: boolean; + /** + * A URL that points to the system's publicly accessible legitimate interest disclosure. + */ + legitimate_interest_disclosure_url?: string; + /** + * The record's GVL purposes + */ + purposes?: Array; + /** + * The record's GVL special purposes + */ + special_purposes?: Array; + /** + * The record's GVL legitimate interest purposes + */ + leg_int_purposes?: Array; + /** + * The record's GVL flexible purposes + */ + flexible_purposes?: Array; + /** + * The record's GVL features + */ + features?: Array; + /** + * The record's GVL special features + */ + special_features?: Array; + /** + * The vendor's GVL-provided data declaration list, which forms the basis for its associated data categories + */ + data_declaration?: Array; + /** + * The vendor's GVL-provided device storage disclosure URL + */ + device_storage_disclosure_url?: string; + /** + * The vendor's GVL-provided `overflow` property + */ + overflow?: string; + /** + * The vendor's territorial scope list, provided by the GVL additional information list + */ + territorial_scope?: Array; + /** + * The vendor's environments, provided by the GVL additional information list + */ + environments?: Array; + /** + * The vendor's service types, provided by the GVL additional information list + */ + service_types?: Array; + /** + * The vendor's domains, as provided by the Google additional consent providers list. + */ + domains?: string; + /** + * The URL pointing to the vendor's logo + */ + logo?: string; + /** + * The version of GVL from which the record is derived + */ + gvl_version?: string; + /** + * The Cookies associated with the record + */ + cookies?: Array; +}; diff --git a/tests/ops/util/test_tcf_experience_contents.py b/tests/ops/util/test_tcf_experience_contents.py index 4f4ac961d9..a782e5a90f 100644 --- a/tests/ops/util/test_tcf_experience_contents.py +++ b/tests/ops/util/test_tcf_experience_contents.py @@ -284,6 +284,7 @@ def test_system_exists_with_tcf_purpose_and_vendor(self, db): tcf_contents.tcf_vendor_relationships[0].description == "My TCF System Description" ) + # assert some additional TCF attributes are set to their defaults here - this is where they belong! assert tcf_contents.tcf_vendor_relationships[0].cookie_max_age_seconds is None assert tcf_contents.tcf_vendor_relationships[0].uses_cookies is False