Skip to content

Commit

Permalink
release 2.9.0 (#69)
Browse files Browse the repository at this point in the history
Co-authored-by: leonardo briotto <[email protected]>
  • Loading branch information
uc-franciscocunha and uc-leo authored Oct 11, 2023
1 parent faeb553 commit 32820fb
Show file tree
Hide file tree
Showing 41 changed files with 929 additions and 230 deletions.
32 changes: 16 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@ jobs:
format:
name: Format
runs-on: ubuntu-latest
container: cirrusci/flutter:stable
container: ghcr.io/cirruslabs/flutter:3.13.5

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Check format
run: scripts/check_format.sh

lint:
name: Lint
runs-on: ubuntu-latest
container: cirrusci/flutter:stable
container: ghcr.io/cirruslabs/flutter:3.13.5

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Get dependencies
run: flutter pub get
- name: Lint using flutter analyze
Expand All @@ -38,23 +38,23 @@ jobs:
pub-dry-run:
name: Publish Dry Run
runs-on: ubuntu-latest
container: cirrusci/flutter:stable
container: ghcr.io/cirruslabs/flutter:3.13.5

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Run publish dry run
run: dart pub publish --dry-run

test-flutter:
name: Test Flutter
needs: [ lint, format, pub-dry-run ]
runs-on: ubuntu-latest
container: cirrusci/flutter:stable
container: ghcr.io/cirruslabs/flutter:3.13.5

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Get dependencies
run: flutter pub get
- name: Run all tests
Expand All @@ -66,13 +66,13 @@ jobs:
name: Test Android
needs: [ lint, format, pub-dry-run ]
runs-on: ubuntu-latest
container: cirrusci/flutter:stable
container: ghcr.io/cirruslabs/flutter:3.13.5
env:
GRADLE_VERSION: 7.2

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Cache Gradle
id: cache-gradle
uses: actions/cache@v2
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
with:
xcode-version: '14.2'
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
Expand All @@ -124,11 +124,11 @@ jobs:
name: Build Android Example
needs: [ lint, format, pub-dry-run ]
runs-on: ubuntu-latest
container: cirrusci/flutter:stable
container: ghcr.io/cirruslabs/flutter:3.13.5

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Get dependencies
run: flutter pub get
- name: Build
Expand All @@ -146,7 +146,7 @@ jobs:
with:
xcode-version: '14.2'
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
Expand All @@ -162,13 +162,13 @@ jobs:
if: github.event_name == 'release'
needs: [ test-flutter, test-android, test-ios, build-android, build-ios ]
runs-on: ubuntu-latest
container: cirrusci/flutter:stable
container: ghcr.io/cirruslabs/flutter:3.13.5
env:
PUB_DEV_CREDENTIAL: ${{ secrets.PUB_DEV_CREDENTIAL }}

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Validate version
run: dart scripts/check_release_version.dart ${{ github.ref }}
- name: Setup credentials
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
[Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/)

### 2.9.0 - October 6, 2023

## Features

* :rocket: **Full TCF 2.2 Support**: As the industry shifts to TCF 2.2 (deadline: November 20, 2024), we are pleased to announce that SDK Version 2.9.0 now offers comprehensive support for this new industry standard.
* :warning: **Important Note**: Please be aware that this version is incompatible with TCF 2.0. Before upgrading to V 2.9.0, ensure a smooth transition to TCF 2.2 following the guidelines:

[How to migrate from TCF v2.0 to TCF v2.2](https://usercentrics.atlassian.net/wiki/spaces/SKB/pages/2668789801/How+to+migrate+from+TCF+v2.0+to+TCF+v2.2#\uD83D\uDCD8-Migration-instructions-for-TCF-v2.2)

## Key Changes and Enhancements:

* Updated Global Vendor List: We've transitioned to Global Vendor List v3 to align with industry standards.
* Legitimate Interest: To enhance transparency and privacy, purposes 3 to 6 have been removed, and purpose 11 has been introduced.
* Improved User Interface: We've made enhancements to the banner's second layer for a better user experience.
* Vendor Count Display: Users can now easily see the total count of IAB and non-IAB vendors.
* New Resurface Requirements: We've implemented new resurfacing requirements to keep your CMP compliant with the latest standards.

### 2.8.4 - September 27, 2023

## Improvements
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def usercentrics_version = "2.8.4"
def usercentrics_version = "2.9.0"

group 'com.usercentrics.sdk.flutter'
version usercentrics_version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ private fun TCF2Settings.serialize(): Any {
"linksVendorListLinkLabel" to linksVendorListLinkLabel,
"cmpId" to cmpId,
"cmpVersion" to cmpVersion,
"categoriesOfDataLabel" to categoriesOfDataLabel,
"dataRetentionPeriodLabel" to dataRetentionPeriodLabel,
"legitimateInterestLabel" to legitimateInterestLabel,
"version" to version,
"examplesLabel" to examplesLabel,
// Optional
"firstLayerHideToggles" to firstLayerHideToggles,
"secondLayerHideToggles" to secondLayerHideToggles,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.usercentrics.sdk.flutter.serializer

import com.usercentrics.sdk.services.tcf.interfaces.*
import com.usercentrics.tcf.core.model.gvl.DataRetention
import com.usercentrics.tcf.core.model.gvl.RetentionPeriod
import com.usercentrics.tcf.core.model.gvl.VendorUrl

internal fun TCFData.serialize(): Any {
return mapOf(
Expand All @@ -10,14 +13,15 @@ internal fun TCFData.serialize(): Any {
"specialPurposes" to specialPurposes.map { it.serialize() },
"stacks" to stacks.map { it.serialize() },
"vendors" to vendors.map { it.serialize() },
"tcString" to tcString
"tcString" to tcString,
"thirdPartyCount" to thirdPartyCount
)
}

private fun TCFFeature.serialize(): Any {
return mapOf(
"purposeDescription" to purposeDescription,
"descriptionLegal" to descriptionLegal,
"illustrations" to illustrations,
"id" to id,
"name" to name,
)
Expand All @@ -26,7 +30,7 @@ private fun TCFFeature.serialize(): Any {
private fun TCFPurpose.serialize(): Any {
return mapOf(
"purposeDescription" to purposeDescription,
"descriptionLegal" to descriptionLegal,
"illustrations" to illustrations,
"id" to id,
"name" to name,
"consent" to consent,
Expand All @@ -42,7 +46,7 @@ private fun TCFPurpose.serialize(): Any {
private fun TCFSpecialPurpose.serialize(): Any {
return mapOf(
"purposeDescription" to purposeDescription,
"descriptionLegal" to descriptionLegal,
"illustrations" to illustrations,
"id" to id,
"name" to name,
)
Expand All @@ -51,7 +55,7 @@ private fun TCFSpecialPurpose.serialize(): Any {
private fun TCFSpecialFeature.serialize(): Any {
return mapOf(
"purposeDescription" to purposeDescription,
"descriptionLegal" to descriptionLegal,
"illustrations" to illustrations,
"id" to id,
"name" to name,
"consent" to consent,
Expand Down Expand Up @@ -93,5 +97,24 @@ private fun TCFVendor.serialize(): Any {
// "deviceStorage" to deviceStorage.serialize(),
"usesCookies" to usesCookies,
"cookieRefresh" to cookieRefresh,
"dataSharedOutsideEU" to dataSharedOutsideEU,
"dataRetention" to dataRetention?.serializer(),
"dataCategories" to dataCategories.map { it.id },
"vendorUrls" to vendorUrls.map { it.serializer() }
)
}

private fun DataRetention.serializer(): Any {
return mapOf(
"stdRetention" to this.stdRetention,
"purposes" to this.purposes.idAndPeriod,
"specialPurposes" to this.specialPurposes.idAndPeriod
)
}
private fun VendorUrl.serializer(): Any {
return mapOf(
"langId" to this.langId,
"privacy" to this.privacy,
"legIntClaim" to this.legIntClaim
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,12 @@ internal object GetCMPDataMock {
firstLayerHideToggles = false,
gdprApplies = true,
linksVendorListLinkLabel = "Vendorlist",
tabsPurposeLabel = "Purposes"
tabsPurposeLabel = "Purposes",
categoriesOfDataLabel = "Categories of data",
dataRetentionPeriodLabel = "Data Retention Period",
legitimateInterestLabel = "Legitimate Interest at stake",
version = "2.2",
examplesLabel = "Examples",
)
private val fakeCCPASettings = CCPASettings(
secondLayerHideLanguageSwitch = false,
Expand Down Expand Up @@ -404,6 +409,11 @@ internal object GetCMPDataMock {
"togglesSpecialFeaturesToggleOff" to "Off",
"appLayerNoteResurface" to "You can change your privacy settings or withdraw your consent at any time by opening the menu point Privacy Settings.",
"firstLayerNoteResurface" to "You can change your privacy settings or withdraw your consent at any time by clicking on our Privacy Button.",
"examplesLabel" to "Examples",
"version" to "2.2",
"categoriesOfDataLabel" to "Categories of data",
"dataRetentionPeriodLabel" to "Data Retention Period",
"legitimateInterestLabel" to "Legitimate Interest at stake",
)
private val expectedCCPASettings = mapOf(
"optOutNoticeLabel" to "Do not sell my personal information",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@ package com.usercentrics.sdk.flutter.mock

import com.usercentrics.sdk.flutter.api.FakeFlutterMethodCall
import com.usercentrics.sdk.services.tcf.interfaces.*
import com.usercentrics.tcf.core.model.gvl.DataRetention
import com.usercentrics.tcf.core.model.gvl.VendorUrl

internal object GetTCFDataMock {

val fake = TCFData(
thirdPartyCount = 2,
tcString = "abc",
features = listOf(
TCFFeature(
purposeDescription = "Data from offline data sources can be combined with your online activity in support of one or more purposes",
descriptionLegal = "Vendors can:\n* Combine data obtained offline with data collected online in support of one or more Purposes or Special Purposes.",
illustrations = listOf(),
id = 2,
name = "Link different devices",
)
),
purposes = listOf(
TCFPurpose(
purposeDescription = "Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.",
descriptionLegal = "Vendors can:\n* Store and access information on the device such as cookies and device identifiers presented to a user.",
illustrations = listOf("Most purposes explained in this notice rely on the storage or accessing of information from your device when you use an app or visit a website. For example, a vendor or publisher might need to store a cookie on your device during your first visit on a website, to be able to recognise your device during your next visits (by accessing this cookie each time)."),
id = 1,
name = "Store and/or access information on a device",
consent = null,
Expand All @@ -32,7 +35,7 @@ internal object GetTCFDataMock {
specialFeatures = listOf(
TCFSpecialFeature(
purposeDescription = "Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters.",
descriptionLegal = "Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user’s location; this can be accurate to within several meters.",
illustrations = listOf(),
id = 1,
name = "Use precise geolocation data",
consent = null,
Expand All @@ -44,7 +47,7 @@ internal object GetTCFDataMock {
specialPurposes = listOf(
TCFSpecialPurpose(
purposeDescription = "Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely.",
descriptionLegal = "To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose.\nNote: Data collected and used to ensure security, prevent fraud, and debug may include automatically-sent device characteristics for identification, precise geolocation data, and data obtained by actively scanning device characteristics for identification without separate disclosure and/or opt-in.",
illustrations = listOf("An advertising intermediary delivers ads from various advertisers to its network of partnering websites. It notices a large increase in clicks on ads relating to one advertiser, and uses data regarding the source of the clicks to determine that 80% of the clicks come from bots rather than humans."),
id = 1,
name = "Ensure security, prevent fraud, and debug",
)
Expand Down Expand Up @@ -94,26 +97,31 @@ internal object GetTCFDataMock {
deviceStorage = null,
usesCookies = false,
cookieRefresh = null,
dataSharedOutsideEU = true,
dataRetention = null,
dataCategories = listOf(IdAndName(1, "")),
vendorUrls = listOf(),
)
),
)

// From the debugger
val call = FakeFlutterMethodCall(method = "getTCFData", arguments = null)
val expected = mapOf(
"thirdPartyCount" to 2,
"tcString" to "abc",
"features" to listOf(
mapOf(
"purposeDescription" to "Data from offline data sources can be combined with your online activity in support of one or more purposes",
"descriptionLegal" to "Vendors can:\n* Combine data obtained offline with data collected online in support of one or more Purposes or Special Purposes.",
"illustrations" to listOf<String>(),
"id" to 2,
"name" to "Link different devices",
)
),
"purposes" to listOf(
mapOf(
"purposeDescription" to "Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.",
"descriptionLegal" to "Vendors can:\n* Store and access information on the device such as cookies and device identifiers presented to a user.",
"illustrations" to listOf("Most purposes explained in this notice rely on the storage or accessing of information from your device when you use an app or visit a website. For example, a vendor or publisher might need to store a cookie on your device during your first visit on a website, to be able to recognise your device during your next visits (by accessing this cookie each time)."),
"id" to 1,
"name" to "Store and/or access information on a device",
"consent" to null,
Expand All @@ -127,7 +135,7 @@ internal object GetTCFDataMock {
"specialFeatures" to listOf(
mapOf(
"purposeDescription" to "Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters.",
"descriptionLegal" to "Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user’s location; this can be accurate to within several meters.",
"illustrations" to listOf<String>(),
"id" to 1,
"name" to "Use precise geolocation data",
"consent" to null,
Expand All @@ -139,7 +147,7 @@ internal object GetTCFDataMock {
"specialPurposes" to listOf(
mapOf(
"purposeDescription" to "Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely.",
"descriptionLegal" to "To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose.\nNote: Data collected and used to ensure security, prevent fraud, and debug may include automatically-sent device characteristics for identification, precise geolocation data, and data obtained by actively scanning device characteristics for identification without separate disclosure and/or opt-in.",
"illustrations" to listOf("An advertising intermediary delivers ads from various advertisers to its network of partnering websites. It notices a large increase in clicks on ads relating to one advertiser, and uses data regarding the source of the clicks to determine that 80% of the clicks come from bots rather than humans."),
"id" to 1,
"name" to "Ensure security, prevent fraud, and debug",
)
Expand Down Expand Up @@ -186,8 +194,12 @@ internal object GetTCFDataMock {
"deviceStorageDisclosureUrl" to null,
"usesCookies" to false,
"cookieRefresh" to null,
"dataSharedOutsideEU" to true,
"dataRetention" to null,
"dataCategories" to listOf(1),
"vendorUrls" to listOf<Any>()
),
),
)

}
}
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
Loading

0 comments on commit 32820fb

Please sign in to comment.