Skip to content

Commit 7508a17

Browse files
Release: 2.24.2 (#141)
1 parent 4ae6b87 commit 7508a17

17 files changed

Lines changed: 112 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
[Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/)
22

3+
### 2.24.2 – Dec 5, 2025
4+
## Improvement
5+
* Patch with security fixes
6+
37
### 2.24.1 – Oct 31, 2025
48
## Improvement
59
* TCF 2.3 Support: fixes about tcString

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
def usercentrics_version = "2.24.1"
1+
def usercentrics_version = "2.24.2"
22

33
group 'com.usercentrics.sdk.flutter'
44
version usercentrics_version

android/src/main/kotlin/com/usercentrics/sdk/flutter/bridge/DenyAllForTCFBridge.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ internal class DenyAllForTCFBridge(
1515
override val name: String
1616
get() = "denyAllForTCF"
1717

18+
@Suppress("UNCHECKED_CAST")
1819
override fun invoke(call: FlutterMethodCall, result: FlutterResult) {
1920
assert(name == call.method)
2021
val argsMap = call.arguments as Map<*, *>
22+
val unsavedPurposeLIDecisions = (argsMap["unsavedPurposeLIDecisions"] as? Map<Int, Boolean>)
2123
val consents = usercentrics.instance.denyAllForTCF(
2224
fromLayer = TCFDecisionUILayer.valueOf(argsMap["fromLayer"] as String),
23-
consentType = UsercentricsConsentType.valueOf(argsMap["consentType"] as String)
25+
consentType = UsercentricsConsentType.valueOf(argsMap["consentType"] as String),
26+
unsavedPurposeLIDecisions = unsavedPurposeLIDecisions
2427
)
2528
result.success(consents.map { it.serialize() })
2629
}

android/src/test/java/com/usercentrics/sdk/flutter/bridge/DenyAllForTCFBridgeTest.kt

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class DenyAllForTCFBridgeTest {
3232
@Test
3333
fun testInvoke() {
3434
val usercentricsSDK = mockk<UsercentricsSDK>()
35-
every { usercentricsSDK.denyAllForTCF(any(), any()) }.returns(DenyAllForTCFMock.fake)
35+
every { usercentricsSDK.denyAllForTCF(any(), any(), any()) }.returns(DenyAllForTCFMock.fake)
3636
val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
3737
val instance = DenyAllForTCFBridge(usercentricsProxy)
3838
val result = FakeFlutterResult()
@@ -42,7 +42,30 @@ class DenyAllForTCFBridgeTest {
4242
verify(exactly = 1) {
4343
usercentricsSDK.denyAllForTCF(
4444
fromLayer = DenyAllForTCFMock.callFromLayer,
45-
consentType = DenyAllForTCFMock.callConsentType
45+
consentType = DenyAllForTCFMock.callConsentType,
46+
unsavedPurposeLIDecisions = null
47+
)
48+
}
49+
50+
Assert.assertEquals(1, result.successCount)
51+
Assert.assertEquals(DenyAllForTCFMock.expected, result.successResultArgument)
52+
}
53+
54+
@Test
55+
fun testInvokeWithUnsavedPurposeLIDecisions() {
56+
val usercentricsSDK = mockk<UsercentricsSDK>()
57+
every { usercentricsSDK.denyAllForTCF(any(), any(), any()) }.returns(DenyAllForTCFMock.fake)
58+
val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
59+
val instance = DenyAllForTCFBridge(usercentricsProxy)
60+
val result = FakeFlutterResult()
61+
62+
instance.invoke(DenyAllForTCFMock.callWithUnsavedPurposeLIDecisions, result)
63+
64+
verify(exactly = 1) {
65+
usercentricsSDK.denyAllForTCF(
66+
fromLayer = DenyAllForTCFMock.callFromLayer,
67+
consentType = DenyAllForTCFMock.callConsentType,
68+
unsavedPurposeLIDecisions = DenyAllForTCFMock.callUnsavedPurposeLIDecisions
4669
)
4770
}
4871

android/src/test/java/com/usercentrics/sdk/flutter/mock/DenyAllForTCFMock.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,18 @@ internal object DenyAllForTCFMock {
3434
"consentType" to "EXPLICIT"
3535
)
3636
)
37+
38+
val callWithUnsavedPurposeLIDecisions = FakeFlutterMethodCall(
39+
method = "denyAllForTCF", arguments = mapOf(
40+
"fromLayer" to "FIRST_LAYER",
41+
"consentType" to "EXPLICIT",
42+
"unsavedPurposeLIDecisions" to mapOf(1 to true, 2 to false)
43+
)
44+
)
45+
3746
val callFromLayer = TCFDecisionUILayer.FIRST_LAYER
3847
val callConsentType = UsercentricsConsentType.EXPLICIT
48+
val callUnsavedPurposeLIDecisions = mapOf(1 to true, 2 to false)
3949
val expected = listOf(
4050
mapOf(
4151
"templateId" to "ocv9HNX_g",

example/ios/Podfile.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
PODS:
22
- Flutter (1.0.0)
3-
- Usercentrics (2.24.1)
4-
- usercentrics_sdk (2.24.1):
3+
- Usercentrics (2.24.2)
4+
- usercentrics_sdk (2.24.2):
55
- Flutter
6-
- UsercentricsUI (= 2.24.1)
7-
- UsercentricsUI (2.24.1):
8-
- Usercentrics (= 2.24.1)
6+
- UsercentricsUI (= 2.24.2)
7+
- UsercentricsUI (2.24.2):
8+
- Usercentrics (= 2.24.2)
99
- webview_flutter_wkwebview (0.0.1):
1010
- Flutter
1111

example/test/fake_usercentrics.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class FakeUsercentrics extends UsercentricsPlatform {
8080
Future<List<UsercentricsServiceConsent>> denyAllForTCF({
8181
required UsercentricsConsentType consentType,
8282
required TCFDecisionUILayer fromLayer,
83+
Map<int, bool>? unsavedPurposeLIDecisions,
8384
}) {
8485
throw UnimplementedError();
8586
}

ios/Classes/API/Bool+KotlinBoolean.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@ extension Bool {
88
self.init(value.boolValue)
99
}
1010
}
11+
12+
extension Dictionary where Key == Int, Value == Bool {
13+
func asKotlinIntBooleanDict() -> [KotlinInt: KotlinBoolean] {
14+
var result: [KotlinInt: KotlinBoolean] = [:]
15+
for (key, value) in self {
16+
result[KotlinInt(int: Int32(key))] = KotlinBoolean(bool: value)
17+
}
18+
return result
19+
}
20+
}

ios/Classes/Bridge/DenyAllForTCFBridge.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ struct DenyAllForTCFBridge : MethodBridge {
1010
let argsDict = call.arguments as! Dictionary<String, Any>
1111
let fromLayer = TCFDecisionUILayer.initialize(from: argsDict["fromLayer"])!
1212
let consentType = UsercentricsConsentType.initialize(from: argsDict["consentType"])!
13-
let consents = usercentrics.shared.denyAllForTCF(fromLayer: fromLayer, consentType: consentType)
13+
let unsavedPurposeLIDecisions = (argsDict["unsavedPurposeLIDecisions"] as? [Int: Bool])?.asKotlinIntBooleanDict()
14+
let consents = usercentrics.shared.denyAllForTCF(fromLayer: fromLayer, consentType: consentType, unsavedPurposeLIDecisions: unsavedPurposeLIDecisions)
1415
result(consents.map { $0.serialize() })
1516
}
1617
}

ios/usercentrics_sdk.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'usercentrics_sdk'
3-
s.version = '2.24.1'
3+
s.version = '2.24.2'
44
s.summary = 'Usercentrics Flutter SDK.'
55
s.description = <<-DESC
66
Usercentrics Flutter SDK.

0 commit comments

Comments
 (0)