securiti-consent-sdk 1.132.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NitroSecuritiConsentSdk.podspec +37 -0
- package/README.md +45 -0
- package/android/CMakeLists.txt +29 -0
- package/android/build.gradle +146 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/margelo/nitro/securiticonsentsdk/HybridConsentSDK.kt +669 -0
- package/android/src/main/java/com/margelo/nitro/securiticonsentsdk/NitroSecuritiConsentSdkPackage.java +33 -0
- package/ios/Bridge.h +10 -0
- package/ios/HybridConsentSDK.swift +640 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NitroSecuritiConsentSdk+autolinking.cmake +78 -0
- package/nitrogen/generated/android/NitroSecuritiConsentSdk+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroSecuritiConsentSdkOnLoad.cpp +48 -0
- package/nitrogen/generated/android/NitroSecuritiConsentSdkOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JAppPermission.hpp +86 -0
- package/nitrogen/generated/android/c++/JBannerConfig.hpp +194 -0
- package/nitrogen/generated/android/c++/JCmpSDKOptions.hpp +94 -0
- package/nitrogen/generated/android/c++/JCustomColors.hpp +82 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +74 -0
- package/nitrogen/generated/android/c++/JHybridConsentSDKSpec.cpp +277 -0
- package/nitrogen/generated/android/c++/JHybridConsentSDKSpec.hpp +78 -0
- package/nitrogen/generated/android/c++/JPermissionConsent.hpp +61 -0
- package/nitrogen/generated/android/c++/JPostConsentsRequest.hpp +137 -0
- package/nitrogen/generated/android/c++/JPurpose.hpp +118 -0
- package/nitrogen/generated/android/c++/JPurposeConsent.hpp +65 -0
- package/nitrogen/generated/android/c++/JSDK.hpp +104 -0
- package/nitrogen/generated/android/c++/JSettingsPrompt.hpp +88 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/AppPermission.kt +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/BannerConfig.kt +57 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/CmpSDKOptions.kt +36 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/CustomColors.kt +33 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/Func_void_bool.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/HybridConsentSDKSpec.kt +121 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/NitroSecuritiConsentSdkOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/PermissionConsent.kt +28 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/PostConsentsRequest.kt +37 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/Purpose.kt +37 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/PurposeConsent.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/SDK.kt +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/SettingsPrompt.kt +30 -0
- package/nitrogen/generated/ios/NitroSecuritiConsentSdk+autolinking.rb +60 -0
- package/nitrogen/generated/ios/NitroSecuritiConsentSdk-Swift-Cxx-Bridge.cpp +96 -0
- package/nitrogen/generated/ios/NitroSecuritiConsentSdk-Swift-Cxx-Bridge.hpp +604 -0
- package/nitrogen/generated/ios/NitroSecuritiConsentSdk-Swift-Cxx-Umbrella.hpp +78 -0
- package/nitrogen/generated/ios/NitroSecuritiConsentSdkAutolinking.mm +33 -0
- package/nitrogen/generated/ios/NitroSecuritiConsentSdkAutolinking.swift +25 -0
- package/nitrogen/generated/ios/c++/HybridConsentSDKSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridConsentSDKSpecSwift.hpp +223 -0
- package/nitrogen/generated/ios/swift/AppPermission.swift +267 -0
- package/nitrogen/generated/ios/swift/BannerConfig.swift +918 -0
- package/nitrogen/generated/ios/swift/CmpSDKOptions.swift +217 -0
- package/nitrogen/generated/ios/swift/CustomColors.swift +256 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_BannerConfig_.swift +52 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_SettingsPrompt_.swift +52 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_AppPermission_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_Purpose_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_SDK_.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridConsentSDKSpec.swift +64 -0
- package/nitrogen/generated/ios/swift/HybridConsentSDKSpec_cxx.swift +398 -0
- package/nitrogen/generated/ios/swift/PermissionConsent.swift +57 -0
- package/nitrogen/generated/ios/swift/PostConsentsRequest.swift +216 -0
- package/nitrogen/generated/ios/swift/Purpose.swift +354 -0
- package/nitrogen/generated/ios/swift/PurposeConsent.swift +68 -0
- package/nitrogen/generated/ios/swift/SDK.swift +285 -0
- package/nitrogen/generated/ios/swift/SettingsPrompt.swift +181 -0
- package/nitrogen/generated/shared/c++/AppPermission.hpp +102 -0
- package/nitrogen/generated/shared/c++/BannerConfig.hpp +197 -0
- package/nitrogen/generated/shared/c++/CmpSDKOptions.hpp +110 -0
- package/nitrogen/generated/shared/c++/CustomColors.hpp +98 -0
- package/nitrogen/generated/shared/c++/HybridConsentSDKSpec.cpp +37 -0
- package/nitrogen/generated/shared/c++/HybridConsentSDKSpec.hpp +102 -0
- package/nitrogen/generated/shared/c++/PermissionConsent.hpp +77 -0
- package/nitrogen/generated/shared/c++/PostConsentsRequest.hpp +120 -0
- package/nitrogen/generated/shared/c++/Purpose.hpp +117 -0
- package/nitrogen/generated/shared/c++/PurposeConsent.hpp +81 -0
- package/nitrogen/generated/shared/c++/SDK.hpp +103 -0
- package/nitrogen/generated/shared/c++/SettingsPrompt.hpp +87 -0
- package/package.json +107 -0
- package/react-native.config.js +16 -0
- package/src/ConsentSDK.nitro.ts +232 -0
- package/src/index.ts +133 -0
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
package com.margelo.nitro.securiticonsentsdk
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import android.app.Application
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.margelo.nitro.core.Promise
|
|
7
|
+
import kotlinx.coroutines.CoroutineScope
|
|
8
|
+
import kotlinx.coroutines.Dispatchers
|
|
9
|
+
import kotlinx.coroutines.SupervisorJob
|
|
10
|
+
import kotlinx.coroutines.runBlocking
|
|
11
|
+
import ai.securiti.cmpsdkcore.main.SecuritiMobileCmp
|
|
12
|
+
import ai.securiti.cmpsdkcore.main.CmpSDKLoggerLevel
|
|
13
|
+
import ai.securiti.cmpsdkcore.ui.SecuritiMobileCmpExtensions.Companion.presentConsentBanner
|
|
14
|
+
import ai.securiti.cmpsdkcore.ui.SecuritiMobileCmpExtensions.Companion.presentPreferenceCenter
|
|
15
|
+
import com.margelo.nitro.NitroModules
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Implementation of the HybridConsentSDK Android for React Native.
|
|
19
|
+
*/
|
|
20
|
+
class HybridConsentSDK : HybridConsentSDKSpec() {
|
|
21
|
+
private var sdkOptions: CmpSDKOptions? = null
|
|
22
|
+
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
|
23
|
+
|
|
24
|
+
companion object {
|
|
25
|
+
private const val TAG = "ConsentSDK"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Initialize the Securiti SDK with the provided options.
|
|
30
|
+
*/
|
|
31
|
+
override fun initialize(options: CmpSDKOptions) {
|
|
32
|
+
Log.d(TAG, "Initialize called with options: $options")
|
|
33
|
+
this.sdkOptions = options
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
// Get the application context from NitroModules
|
|
37
|
+
val appContext = NitroModules.applicationContext
|
|
38
|
+
if (appContext == null) {
|
|
39
|
+
Log.e(TAG, "Application context is null, cannot initialize SDK")
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Convert logger level string to SDK's enum
|
|
44
|
+
val loggerLevel = when (options.loggerLevel.uppercase()) {
|
|
45
|
+
"DEBUG" -> CmpSDKLoggerLevel.DEBUG
|
|
46
|
+
"INFO" -> CmpSDKLoggerLevel.INFO
|
|
47
|
+
"WARNING" -> CmpSDKLoggerLevel.WARNING
|
|
48
|
+
"ERROR" -> CmpSDKLoggerLevel.ERROR
|
|
49
|
+
else -> CmpSDKLoggerLevel.DEBUG
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Create the native SDK options
|
|
53
|
+
val securitiOptions = ai.securiti.cmpsdkcore.main.CmpSDKOptions(
|
|
54
|
+
options.appURL,
|
|
55
|
+
options.cdnURL,
|
|
56
|
+
options.tenantID,
|
|
57
|
+
options.appID,
|
|
58
|
+
options.testingMode,
|
|
59
|
+
loggerLevel,
|
|
60
|
+
options.consentsCheckInterval.toInt(),
|
|
61
|
+
options.subjectId,
|
|
62
|
+
options.languageCode,
|
|
63
|
+
options.locationCode
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
// Initialize the SDK
|
|
67
|
+
SecuritiMobileCmp.initialize(appContext.applicationContext as Application, securitiOptions)
|
|
68
|
+
Log.d(TAG, "SDK initialized successfully")
|
|
69
|
+
} catch (e: Exception) {
|
|
70
|
+
Log.e(TAG, "Error initializing SDK: ${e.message}", e)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Check if the SDK is ready.
|
|
76
|
+
*/
|
|
77
|
+
override fun isSdkReady(): Boolean {
|
|
78
|
+
Log.d(TAG, "isSdkReady called")
|
|
79
|
+
return try {
|
|
80
|
+
SecuritiMobileCmp.isReady()
|
|
81
|
+
} catch (e: Exception) {
|
|
82
|
+
Log.e(TAG, "Error checking if SDK is ready: ${e.message}")
|
|
83
|
+
false
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Present the preference center UI.
|
|
89
|
+
*/
|
|
90
|
+
override fun presentPreferenceCenter() {
|
|
91
|
+
Log.d(TAG, "presentPreferenceCenter called")
|
|
92
|
+
try {
|
|
93
|
+
val appContext = NitroModules.applicationContext
|
|
94
|
+
if (appContext == null) {
|
|
95
|
+
Log.e(TAG, "Application context is null, cannot present preference center")
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
val activity = appContext.currentActivity
|
|
100
|
+
if (activity != null) {
|
|
101
|
+
SecuritiMobileCmp.presentPreferenceCenter(activity)
|
|
102
|
+
} else {
|
|
103
|
+
Log.e(TAG, "Cannot present preference center: Current activity is null")
|
|
104
|
+
}
|
|
105
|
+
} catch (e: Exception) {
|
|
106
|
+
Log.e(TAG, "Error presenting preference center: ${e.message}")
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Present the consent banner UI.
|
|
112
|
+
*/
|
|
113
|
+
override fun presentConsentBanner() {
|
|
114
|
+
Log.d(TAG, "presentConsentBanner called")
|
|
115
|
+
try {
|
|
116
|
+
val appContext = NitroModules.applicationContext
|
|
117
|
+
if (appContext == null) {
|
|
118
|
+
Log.e(TAG, "Application context is null, cannot present consent banner")
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
val activity = appContext.currentActivity
|
|
123
|
+
if (activity != null) {
|
|
124
|
+
SecuritiMobileCmp.presentConsentBanner(activity)
|
|
125
|
+
} else {
|
|
126
|
+
Log.e(TAG, "Cannot present consent banner: Current activity is null")
|
|
127
|
+
}
|
|
128
|
+
} catch (e: Exception) {
|
|
129
|
+
Log.e(TAG, "Error presenting consent banner: ${e.message}")
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check if the SDK is ready with a callback.
|
|
135
|
+
*/
|
|
136
|
+
override fun isReady(callback: (Boolean) -> Unit) {
|
|
137
|
+
Log.d(TAG, "isReady called")
|
|
138
|
+
try {
|
|
139
|
+
SecuritiMobileCmp.isReady { isReady ->
|
|
140
|
+
callback(isReady)
|
|
141
|
+
}
|
|
142
|
+
} catch (e: Exception) {
|
|
143
|
+
Log.e(TAG, "Error in isReady callback: ${e.message}")
|
|
144
|
+
callback(false)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Reset all stored consents.
|
|
150
|
+
*/
|
|
151
|
+
override fun resetConsents() {
|
|
152
|
+
Log.d(TAG, "resetConsents called")
|
|
153
|
+
try {
|
|
154
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
155
|
+
Log.e(TAG, "SDK is not ready, cannot reset consents")
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
SecuritiMobileCmp.resetConsents()
|
|
160
|
+
} catch (e: Exception) {
|
|
161
|
+
Log.e(TAG, "Error resetting consents: ${e.message}")
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get consent status for a purpose by ID.
|
|
167
|
+
*/
|
|
168
|
+
override fun getConsentByPurposeId(purposeId: Double): Promise<String> {
|
|
169
|
+
Log.d(TAG, "getConsentByPurposeId called with id: $purposeId")
|
|
170
|
+
|
|
171
|
+
return Promise.async {
|
|
172
|
+
try {
|
|
173
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
174
|
+
Log.e(TAG, "SDK is not ready, cannot get consent by purpose ID")
|
|
175
|
+
return@async "not_determined"
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
val consentStatus = SecuritiMobileCmp.getConsent(purposeId.toInt())
|
|
179
|
+
convertConsentStatusToString(consentStatus)
|
|
180
|
+
} catch (e: Exception) {
|
|
181
|
+
Log.e(TAG, "Error getting consent by purpose ID: ${e.message}")
|
|
182
|
+
"not_determined"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get consent status for a permission by ID.
|
|
189
|
+
*/
|
|
190
|
+
override fun getConsentByPermissionId(permissionId: String): Promise<String> {
|
|
191
|
+
Log.d(TAG, "getConsentByPermissionId called with id: $permissionId")
|
|
192
|
+
|
|
193
|
+
return Promise.async {
|
|
194
|
+
try {
|
|
195
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
196
|
+
Log.e(TAG, "SDK is not ready, cannot get consent by permission ID")
|
|
197
|
+
return@async "not_determined"
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
val consentStatus = SecuritiMobileCmp.getConsent(permissionId)
|
|
201
|
+
convertConsentStatusToString(consentStatus)
|
|
202
|
+
} catch (e: Exception) {
|
|
203
|
+
Log.e(TAG, "Error getting consent by permission ID: ${e.message}")
|
|
204
|
+
"not_determined"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get all available permissions.
|
|
211
|
+
*/
|
|
212
|
+
override fun getPermissions(): Promise<Array<AppPermission>> {
|
|
213
|
+
Log.d(TAG, "getPermissions called")
|
|
214
|
+
|
|
215
|
+
return Promise.async {
|
|
216
|
+
try {
|
|
217
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
218
|
+
Log.e(TAG, "SDK is not ready, cannot get permissions")
|
|
219
|
+
return@async arrayOf()
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
val nativePermissions = SecuritiMobileCmp.getPermissions()
|
|
223
|
+
nativePermissions.map { nativePermission ->
|
|
224
|
+
AppPermission(
|
|
225
|
+
id = nativePermission.id?.toDouble(),
|
|
226
|
+
name = nativePermission.name,
|
|
227
|
+
permissionId = nativePermission.permissionId,
|
|
228
|
+
description = this.getString(nativePermission.description),
|
|
229
|
+
group = nativePermission.group,
|
|
230
|
+
groupId = nativePermission.groupId?.toDouble(),
|
|
231
|
+
consentStatus = convertConsentStatusToString(nativePermission.consentStatus),
|
|
232
|
+
nameMap = this.getString(nativePermission.nameMap),
|
|
233
|
+
isSettingsPromptEnabled = nativePermission.isSettingsPromptEnabled
|
|
234
|
+
)
|
|
235
|
+
}.toTypedArray()
|
|
236
|
+
} catch (e: Exception) {
|
|
237
|
+
Log.e(TAG, "Error getting permissions: ${e.message}")
|
|
238
|
+
arrayOf()
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Get all available purposes.
|
|
245
|
+
*/
|
|
246
|
+
override fun getPurposes(): Promise<Array<Purpose>> {
|
|
247
|
+
Log.d(TAG, "getPurposes called")
|
|
248
|
+
|
|
249
|
+
return Promise.async {
|
|
250
|
+
try {
|
|
251
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
252
|
+
Log.e(TAG, "SDK is not ready, cannot get purposes")
|
|
253
|
+
return@async arrayOf()
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
val nativePurposes = SecuritiMobileCmp.getPurposes()
|
|
257
|
+
nativePurposes.map { nativePurpose ->
|
|
258
|
+
Purpose(
|
|
259
|
+
purposeId = nativePurpose.purposeId?.toDouble(),
|
|
260
|
+
purposeName = this.getString(nativePurpose.purposeName),
|
|
261
|
+
purposeDescription = this.getString(nativePurpose.purposeDescription),
|
|
262
|
+
// Convert SDK list if available
|
|
263
|
+
sdks = nativePurpose.sdks?.map { nativeSdk ->
|
|
264
|
+
SDK(
|
|
265
|
+
sdkId = nativeSdk.sdkId?.toDouble(),
|
|
266
|
+
namespaceId = nativeSdk.namespaceId,
|
|
267
|
+
sdkName = this.getString(nativeSdk.sdkName),
|
|
268
|
+
sdkDescription = this.getString(nativeSdk.sdkDescription),
|
|
269
|
+
vendor = nativeSdk.vendor,
|
|
270
|
+
logoBase64 = nativeSdk.logoBase64,
|
|
271
|
+
website = nativeSdk.website,
|
|
272
|
+
matchedBy = nativeSdk.matchedBy?.toTypedArray(),
|
|
273
|
+
collectingData = nativeSdk.collectingData
|
|
274
|
+
)
|
|
275
|
+
}?.toTypedArray(),
|
|
276
|
+
consentStatus = convertConsentStatusToString(nativePurpose.consentStatus),
|
|
277
|
+
disableOptOut = nativePurpose.disableOptOut,
|
|
278
|
+
optOutText = this.getString(nativePurpose.optOutText),
|
|
279
|
+
hideDetails = nativePurpose.hideDetails,
|
|
280
|
+
isGADMapped = nativePurpose.isGADMapped,
|
|
281
|
+
gadDescription = this.getString(nativePurpose.gadDescription),
|
|
282
|
+
isATTMapped = false,
|
|
283
|
+
attDescription = ""
|
|
284
|
+
)
|
|
285
|
+
}.toTypedArray()
|
|
286
|
+
} catch (e: Exception) {
|
|
287
|
+
Log.e(TAG, "Error getting purposes: ${e.message}")
|
|
288
|
+
arrayOf()
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Get all SDKs associated with a purpose.
|
|
295
|
+
*/
|
|
296
|
+
override fun getSdksInPurpose(purposeId: Double): Promise<Array<SDK>> {
|
|
297
|
+
Log.d(TAG, "getSdksInPurpose called with purposeId: $purposeId")
|
|
298
|
+
|
|
299
|
+
return Promise.async {
|
|
300
|
+
try {
|
|
301
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
302
|
+
Log.e(TAG, "SDK is not ready, cannot get SDKs in purpose")
|
|
303
|
+
return@async arrayOf()
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
val nativeSdks = SecuritiMobileCmp.getSdksInPurpose(purposeId.toInt())
|
|
307
|
+
nativeSdks.map { nativeSdk ->
|
|
308
|
+
SDK(
|
|
309
|
+
sdkId = nativeSdk.sdkId?.toDouble(),
|
|
310
|
+
namespaceId = nativeSdk.namespaceId,
|
|
311
|
+
sdkName = this.getString(nativeSdk.sdkName),
|
|
312
|
+
sdkDescription = this.getString(nativeSdk.sdkDescription),
|
|
313
|
+
vendor = nativeSdk.vendor,
|
|
314
|
+
logoBase64 = nativeSdk.logoBase64,
|
|
315
|
+
website = nativeSdk.website,
|
|
316
|
+
matchedBy = nativeSdk.matchedBy?.toTypedArray(),
|
|
317
|
+
collectingData = nativeSdk.collectingData
|
|
318
|
+
)
|
|
319
|
+
}.toTypedArray()
|
|
320
|
+
} catch (e: Exception) {
|
|
321
|
+
Log.e(TAG, "Error getting SDKs in purpose: ${e.message}")
|
|
322
|
+
arrayOf()
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Set consent status for a purpose.
|
|
329
|
+
*/
|
|
330
|
+
override fun setPurposeConsent(purpose: Purpose, consent: String): Boolean {
|
|
331
|
+
Log.d(TAG, "setPurposeConsent called with purpose ID: ${purpose.purposeId}, consent: $consent")
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
335
|
+
Log.e(TAG, "SDK is not ready, cannot set purpose consent")
|
|
336
|
+
return false
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
val purposeId = purpose.purposeId?.toInt() ?: run {
|
|
340
|
+
Log.e(TAG, "Purpose ID is null")
|
|
341
|
+
return false
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
val consentStatus = convertStringToConsentStatus(consent)
|
|
345
|
+
|
|
346
|
+
// Create native purpose object directly with the required fields
|
|
347
|
+
// Only the purposeId and disableOptOut properties are used in the native implementation
|
|
348
|
+
val nativePurpose = ai.securiti.cmpsdkcore.network.models.common.Purpose(
|
|
349
|
+
purposeId = purposeId,
|
|
350
|
+
purposeName = null, // Using null since we don't need to map this for setConsent
|
|
351
|
+
purposeDescription = null, // Using null since we don't need to map this for setConsent
|
|
352
|
+
disableOptOut = purpose.disableOptOut,
|
|
353
|
+
sdks = null, // Not needed for setting consent
|
|
354
|
+
consentStatus = null, // Will be updated by the setConsent method
|
|
355
|
+
// Other fields are not needed for consent setting
|
|
356
|
+
optOutText = null,
|
|
357
|
+
hideDetails = null,
|
|
358
|
+
isGADMapped = null,
|
|
359
|
+
gadDescription = null
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
// Set consent directly without fetching all purposes first
|
|
363
|
+
return SecuritiMobileCmp.setConsent(nativePurpose, consentStatus)
|
|
364
|
+
} catch (e: Exception) {
|
|
365
|
+
Log.e(TAG, "Error in setPurposeConsent: ${e.message}")
|
|
366
|
+
return false
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Set consent status for a permission.
|
|
372
|
+
*/
|
|
373
|
+
override fun setPermissionConsent(permission: AppPermission, consent: String): Boolean {
|
|
374
|
+
Log.d(TAG, "setPermissionConsent called with permission ID: ${permission.permissionId}, consent: $consent")
|
|
375
|
+
|
|
376
|
+
try {
|
|
377
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
378
|
+
Log.e(TAG, "SDK is not ready, cannot set permission consent")
|
|
379
|
+
return false
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
val permissionId = permission.permissionId ?: run {
|
|
383
|
+
Log.e(TAG, "Permission ID is null")
|
|
384
|
+
return false
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
val consentStatus = convertStringToConsentStatus(consent)
|
|
388
|
+
|
|
389
|
+
// Create a native AppPermission with just the permissionId field
|
|
390
|
+
// This matches what the actual implementation requires
|
|
391
|
+
val nativePermission = ai.securiti.cmpsdkcore.network.models.common.AppPermission(
|
|
392
|
+
id = null,
|
|
393
|
+
name = null,
|
|
394
|
+
permissionId = permissionId,
|
|
395
|
+
description = null,
|
|
396
|
+
group = null,
|
|
397
|
+
groupId = null,
|
|
398
|
+
consentStatus = null,
|
|
399
|
+
nameMap = null,
|
|
400
|
+
isSettingsPromptEnabled = null
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
// Call setConsent directly with the native AppPermission
|
|
404
|
+
return SecuritiMobileCmp.setConsent(nativePermission, consentStatus)
|
|
405
|
+
} catch (e: Exception) {
|
|
406
|
+
Log.e(TAG, "Error in setPermissionConsent: ${e.message}")
|
|
407
|
+
return false
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Get the banner configuration.
|
|
413
|
+
*/
|
|
414
|
+
override fun getBannerConfig(): Promise<BannerConfig?> {
|
|
415
|
+
Log.d(TAG, "getBannerConfig called")
|
|
416
|
+
|
|
417
|
+
return Promise.async {
|
|
418
|
+
try {
|
|
419
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
420
|
+
Log.e(TAG, "SDK is not ready, cannot get banner config")
|
|
421
|
+
return@async null
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Pass null for now since converting MainConfiguration is complex
|
|
425
|
+
val nativeBannerConfig = SecuritiMobileCmp.getBannerConfig(null)
|
|
426
|
+
|
|
427
|
+
if (nativeBannerConfig != null) {
|
|
428
|
+
// Convert native banner config to our format
|
|
429
|
+
val customColors = nativeBannerConfig.customPaletteTheme?.let {
|
|
430
|
+
CustomColors(
|
|
431
|
+
buttonBackground = it.buttonBackground,
|
|
432
|
+
buttonText = it.buttonText,
|
|
433
|
+
buttonBorder = it.buttonBorder,
|
|
434
|
+
bannerBackground = it.bannerBackground,
|
|
435
|
+
bannerText = it.bannerText,
|
|
436
|
+
bannerLinks = it.bannerLinks,
|
|
437
|
+
preferenceCenterFooterBackground = it.preferenceCenterFooterBackground,
|
|
438
|
+
preferenceCenterFooterSelector = it.preferenceCenterFooterSelector
|
|
439
|
+
)
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Create our BannerConfig from the native one
|
|
443
|
+
BannerConfig(
|
|
444
|
+
hideCloseButton = nativeBannerConfig.hideCloseButton,
|
|
445
|
+
hideAcceptButton = nativeBannerConfig.hideAcceptButton,
|
|
446
|
+
embedDSRPortalLink = nativeBannerConfig.embedDSRPortalLink,
|
|
447
|
+
recordConsentUponAppStart = nativeBannerConfig.recordConsentUponAppStart,
|
|
448
|
+
hideToggleForEssentialCategories = nativeBannerConfig.hideToggleForEssentialCategories,
|
|
449
|
+
name = nativeBannerConfig.name,
|
|
450
|
+
dsrPortalLink = nativeBannerConfig.dsrPortalLink,
|
|
451
|
+
complianceType = nativeBannerConfig.complianceType?.toString(),
|
|
452
|
+
bannerReappearanceTime = nativeBannerConfig.bannerReappearanceTime?.toString(),
|
|
453
|
+
privacyNoticeLink = nativeBannerConfig.privacyNoticeLink,
|
|
454
|
+
accept = this.getString(nativeBannerConfig.accept),
|
|
455
|
+
reject = this.getString(nativeBannerConfig.reject),
|
|
456
|
+
bannerText = this.getString(nativeBannerConfig.bannerText),
|
|
457
|
+
bannerHeading = this.getString(nativeBannerConfig.bannerHeading),
|
|
458
|
+
sdkTabHeading = this.getString(nativeBannerConfig.sdkTabHeading),
|
|
459
|
+
privacyNoticeText = this.getString(nativeBannerConfig.privacyNoticeText),
|
|
460
|
+
preferenceCenterLink = this.getString(nativeBannerConfig.preferenceCenterLink),
|
|
461
|
+
permissionsTabHeading = this.getString(nativeBannerConfig.permissionsTabHeading),
|
|
462
|
+
permissionsTabGuidance = this.getString(nativeBannerConfig.permissionsTabGuidance),
|
|
463
|
+
preferenceCenterHeading = this.getString(nativeBannerConfig.preferenceCenterHeading),
|
|
464
|
+
preferenceCenterGuidance = this.getString(nativeBannerConfig.preferenceCenterGuidance),
|
|
465
|
+
permissionsTabDescription = this.getString(nativeBannerConfig.permissionsTabDescription),
|
|
466
|
+
preferenceCenterDescription = this.getString(nativeBannerConfig.preferenceCenterDescription),
|
|
467
|
+
showPoweredBySecuritiLogo = nativeBannerConfig.showPoweredBySecuritiLogo,
|
|
468
|
+
showDescriptionTextWithPrefCenterToggle = nativeBannerConfig.showDescriptionTextWithPrefCenterToggle,
|
|
469
|
+
paletteTheme = nativeBannerConfig.paletteTheme?.toDouble(),
|
|
470
|
+
bannerPosition = nativeBannerConfig.bannerPosition?.toString(),
|
|
471
|
+
buttonShape = nativeBannerConfig.buttonShape?.toString(),
|
|
472
|
+
companyLogo = nativeBannerConfig.companyLogo,
|
|
473
|
+
customPaletteTheme = customColors,
|
|
474
|
+
shouldShowSettingsPrompt = nativeBannerConfig.shouldShowSettingsPrompt,
|
|
475
|
+
// Convert nested HashMap structure to a flattened Map
|
|
476
|
+
translations = nativeBannerConfig.translations?.entries?.associate { entry ->
|
|
477
|
+
// For each parent key (e.g., "Go back")
|
|
478
|
+
val parentKey = entry.key
|
|
479
|
+
// Get the inner HashMap and access the "_" value directly
|
|
480
|
+
val value = entry.value?.get("_") ?: ""
|
|
481
|
+
// Create a direct mapping from parent key to value
|
|
482
|
+
parentKey to value
|
|
483
|
+
}
|
|
484
|
+
)
|
|
485
|
+
} else {
|
|
486
|
+
null
|
|
487
|
+
}
|
|
488
|
+
} catch (e: Exception) {
|
|
489
|
+
Log.e(TAG, "Error getting banner config: ${e.message}")
|
|
490
|
+
null
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Get the current SDK options.
|
|
497
|
+
*/
|
|
498
|
+
override fun options(): CmpSDKOptions? {
|
|
499
|
+
Log.d(TAG, "options called")
|
|
500
|
+
return sdkOptions
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Get the settings prompt configuration.
|
|
505
|
+
*/
|
|
506
|
+
override fun getSettingsPrompt(): Promise<SettingsPrompt?> {
|
|
507
|
+
Log.d(TAG, "getSettingsPrompt called")
|
|
508
|
+
|
|
509
|
+
return Promise.async {
|
|
510
|
+
try {
|
|
511
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
512
|
+
Log.e(TAG, "SDK is not ready, cannot get settings prompt")
|
|
513
|
+
return@async null
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
try {
|
|
517
|
+
// Get the native SettingsPrompt from the SDK
|
|
518
|
+
val nativeSettingsPrompt = SecuritiMobileCmp.getSettingsPrompt()
|
|
519
|
+
|
|
520
|
+
if (nativeSettingsPrompt != null) {
|
|
521
|
+
// Log the structure and content of the native SettingsPrompt
|
|
522
|
+
Log.d(TAG, "Native SettingsPrompt found")
|
|
523
|
+
|
|
524
|
+
// Convert boolean permissions map to string-based permissions map
|
|
525
|
+
val permissionsMap = mutableListOf<String>()
|
|
526
|
+
nativeSettingsPrompt.permissions?.forEach { (key, value) ->
|
|
527
|
+
// Convert Boolean to String "true" or "false"
|
|
528
|
+
if(value) {
|
|
529
|
+
permissionsMap.add(key)
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Return our Nitro SettingsPrompt with converted values
|
|
534
|
+
return@async SettingsPrompt(
|
|
535
|
+
promptHeading = this.getString(nativeSettingsPrompt.promptHeading),
|
|
536
|
+
promptMessage = this.getString(nativeSettingsPrompt.promptMessage),
|
|
537
|
+
settingsButtonText = this.getString(nativeSettingsPrompt.settingsButtonText),
|
|
538
|
+
notNowButtonText = this.getString(nativeSettingsPrompt.notNowButtonText),
|
|
539
|
+
permissions = permissionsMap.toTypedArray()
|
|
540
|
+
)
|
|
541
|
+
} else {
|
|
542
|
+
// If native SDK returns null, return an empty SettingsPrompt
|
|
543
|
+
Log.d(TAG, "Native SettingsPrompt is null, returning empty SettingsPrompt")
|
|
544
|
+
return@async SettingsPrompt(
|
|
545
|
+
promptHeading = "",
|
|
546
|
+
promptMessage = "",
|
|
547
|
+
settingsButtonText = "",
|
|
548
|
+
notNowButtonText = "",
|
|
549
|
+
permissions = emptyArray()
|
|
550
|
+
)
|
|
551
|
+
}
|
|
552
|
+
} catch (e: Exception) {
|
|
553
|
+
Log.e(TAG, "Error processing settings prompt: ${e.message}", e)
|
|
554
|
+
// Return an empty SettingsPrompt in case of error
|
|
555
|
+
Log.d(TAG, "Returning empty SettingsPrompt due to error")
|
|
556
|
+
return@async SettingsPrompt(
|
|
557
|
+
promptHeading = "",
|
|
558
|
+
promptMessage = "",
|
|
559
|
+
settingsButtonText = "",
|
|
560
|
+
notNowButtonText = "",
|
|
561
|
+
permissions = emptyArray()
|
|
562
|
+
)
|
|
563
|
+
}
|
|
564
|
+
} catch (e: Exception) {
|
|
565
|
+
Log.e(TAG, "Error getting settings prompt: ${e.message}")
|
|
566
|
+
// Return an empty SettingsPrompt in case of error
|
|
567
|
+
Log.d(TAG, "Returning empty SettingsPrompt due to error")
|
|
568
|
+
return@async SettingsPrompt(
|
|
569
|
+
promptHeading = "",
|
|
570
|
+
promptMessage = "",
|
|
571
|
+
settingsButtonText = "",
|
|
572
|
+
notNowButtonText = "",
|
|
573
|
+
permissions = emptyArray()
|
|
574
|
+
)
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Upload consents to the server.
|
|
581
|
+
*/
|
|
582
|
+
override fun uploadConsents(request: PostConsentsRequest): Promise<Boolean> {
|
|
583
|
+
Log.d(TAG, "uploadConsents called")
|
|
584
|
+
|
|
585
|
+
return Promise.async {
|
|
586
|
+
try {
|
|
587
|
+
if (!SecuritiMobileCmp.isReady()) {
|
|
588
|
+
Log.e(TAG, "SDK is not ready, cannot upload consents")
|
|
589
|
+
return@async false
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Convert our request to native request
|
|
593
|
+
val purposeConsents = request.purposeConsents.map { purposeConsent ->
|
|
594
|
+
ai.securiti.cmpsdkcore.network.models.request.PurposeConsent(
|
|
595
|
+
purposeID = purposeConsent.purposeID.toInt(),
|
|
596
|
+
consentStatus = convertStringToConsentStatus(purposeConsent.consentStatus),
|
|
597
|
+
timestamp = purposeConsent.timestamp.toLong(),
|
|
598
|
+
isEssential = purposeConsent.isEssential
|
|
599
|
+
)
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
val permissionConsents = request.permissions.map { permissionConsent ->
|
|
603
|
+
ai.securiti.cmpsdkcore.network.models.request.PermissionConsent(
|
|
604
|
+
permission = permissionConsent.permission,
|
|
605
|
+
consentStatus = convertStringToConsentStatus(permissionConsent.consentStatus),
|
|
606
|
+
timestamp = permissionConsent.timestamp.toLong()
|
|
607
|
+
)
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
val nativeRequest = ai.securiti.cmpsdkcore.network.models.request.PostConsentsRequest(
|
|
611
|
+
uuid = request.uuid,
|
|
612
|
+
appUUID = request.appUUID,
|
|
613
|
+
device = request.device,
|
|
614
|
+
implicitConsent = request.implicitConsent,
|
|
615
|
+
version = request.version.toInt(),
|
|
616
|
+
purposeConsents = purposeConsents,
|
|
617
|
+
permissions = permissionConsents,
|
|
618
|
+
isTestMode = request.isTestMode,
|
|
619
|
+
adId = request.adId,
|
|
620
|
+
bannerInfo = request.bannerInfo,
|
|
621
|
+
sdkVersion = request.sdkVersion,
|
|
622
|
+
platform = request.platform ?: "android"
|
|
623
|
+
)
|
|
624
|
+
|
|
625
|
+
// Upload consents
|
|
626
|
+
SecuritiMobileCmp.uploadConsents(nativeRequest)
|
|
627
|
+
} catch (e: Exception) {
|
|
628
|
+
Log.e(TAG, "Error uploading consents: ${e.message}")
|
|
629
|
+
false
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Convert Securiti SDK's ConsentStatus to string representation.
|
|
636
|
+
*/
|
|
637
|
+
private fun convertConsentStatusToString(status: ai.securiti.cmpsdkcore.network.models.common.ConsentStatus?): String {
|
|
638
|
+
return when (status) {
|
|
639
|
+
ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.GRANTED -> "granted"
|
|
640
|
+
ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.DECLINED -> "declined"
|
|
641
|
+
ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.NOT_DETERMINED -> "not_determined"
|
|
642
|
+
ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.WITHDRAWN -> "withdrawn"
|
|
643
|
+
else -> "not_determined"
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Convert string representation to Securiti SDK's ConsentStatus.
|
|
649
|
+
*/
|
|
650
|
+
private fun convertStringToConsentStatus(status: String): ai.securiti.cmpsdkcore.network.models.common.ConsentStatus {
|
|
651
|
+
return when (status.lowercase()) {
|
|
652
|
+
"granted" -> ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.GRANTED
|
|
653
|
+
"declined" -> ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.DECLINED
|
|
654
|
+
"not_determined" -> ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.NOT_DETERMINED
|
|
655
|
+
"withdrawn" -> ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.WITHDRAWN
|
|
656
|
+
else -> ai.securiti.cmpsdkcore.network.models.common.ConsentStatus.NOT_DETERMINED
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Convert HashMap<String, String>? to String
|
|
661
|
+
private fun getString(map: HashMap<String, String>?) : String {
|
|
662
|
+
return map?.get("_") ?: ""
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// Overload for handling String? input
|
|
666
|
+
private fun getString(value: String?) : String {
|
|
667
|
+
return value ?: ""
|
|
668
|
+
}
|
|
669
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.margelo.nitro.securiticonsentsdk;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
|
|
5
|
+
import androidx.annotation.Nullable;
|
|
6
|
+
|
|
7
|
+
import com.facebook.react.bridge.NativeModule;
|
|
8
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
9
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
|
10
|
+
import com.facebook.react.TurboReactPackage;
|
|
11
|
+
import com.margelo.nitro.core.HybridObject;
|
|
12
|
+
|
|
13
|
+
import java.util.HashMap;
|
|
14
|
+
import java.util.function.Supplier;
|
|
15
|
+
|
|
16
|
+
public class NitroSecuritiConsentSdkPackage extends TurboReactPackage {
|
|
17
|
+
@Nullable
|
|
18
|
+
@Override
|
|
19
|
+
public NativeModule getModule(String name, ReactApplicationContext reactContext) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Override
|
|
24
|
+
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
|
25
|
+
return () -> {
|
|
26
|
+
return new HashMap<>();
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static {
|
|
31
|
+
NitroSecuritiConsentSdkOnLoad.initializeNative();
|
|
32
|
+
}
|
|
33
|
+
}
|