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.
Files changed (86) hide show
  1. package/NitroSecuritiConsentSdk.podspec +37 -0
  2. package/README.md +45 -0
  3. package/android/CMakeLists.txt +29 -0
  4. package/android/build.gradle +146 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  8. package/android/src/main/java/com/margelo/nitro/securiticonsentsdk/HybridConsentSDK.kt +669 -0
  9. package/android/src/main/java/com/margelo/nitro/securiticonsentsdk/NitroSecuritiConsentSdkPackage.java +33 -0
  10. package/ios/Bridge.h +10 -0
  11. package/ios/HybridConsentSDK.swift +640 -0
  12. package/nitrogen/generated/.gitattributes +1 -0
  13. package/nitrogen/generated/android/NitroSecuritiConsentSdk+autolinking.cmake +78 -0
  14. package/nitrogen/generated/android/NitroSecuritiConsentSdk+autolinking.gradle +27 -0
  15. package/nitrogen/generated/android/NitroSecuritiConsentSdkOnLoad.cpp +48 -0
  16. package/nitrogen/generated/android/NitroSecuritiConsentSdkOnLoad.hpp +25 -0
  17. package/nitrogen/generated/android/c++/JAppPermission.hpp +86 -0
  18. package/nitrogen/generated/android/c++/JBannerConfig.hpp +194 -0
  19. package/nitrogen/generated/android/c++/JCmpSDKOptions.hpp +94 -0
  20. package/nitrogen/generated/android/c++/JCustomColors.hpp +82 -0
  21. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +74 -0
  22. package/nitrogen/generated/android/c++/JHybridConsentSDKSpec.cpp +277 -0
  23. package/nitrogen/generated/android/c++/JHybridConsentSDKSpec.hpp +78 -0
  24. package/nitrogen/generated/android/c++/JPermissionConsent.hpp +61 -0
  25. package/nitrogen/generated/android/c++/JPostConsentsRequest.hpp +137 -0
  26. package/nitrogen/generated/android/c++/JPurpose.hpp +118 -0
  27. package/nitrogen/generated/android/c++/JPurposeConsent.hpp +65 -0
  28. package/nitrogen/generated/android/c++/JSDK.hpp +104 -0
  29. package/nitrogen/generated/android/c++/JSettingsPrompt.hpp +88 -0
  30. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/AppPermission.kt +34 -0
  31. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/BannerConfig.kt +57 -0
  32. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/CmpSDKOptions.kt +36 -0
  33. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/CustomColors.kt +33 -0
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/Func_void_bool.kt +80 -0
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/HybridConsentSDKSpec.kt +121 -0
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/NitroSecuritiConsentSdkOnLoad.kt +35 -0
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/PermissionConsent.kt +28 -0
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/PostConsentsRequest.kt +37 -0
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/Purpose.kt +37 -0
  40. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/PurposeConsent.kt +29 -0
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/SDK.kt +34 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/securiticonsentsdk/SettingsPrompt.kt +30 -0
  43. package/nitrogen/generated/ios/NitroSecuritiConsentSdk+autolinking.rb +60 -0
  44. package/nitrogen/generated/ios/NitroSecuritiConsentSdk-Swift-Cxx-Bridge.cpp +96 -0
  45. package/nitrogen/generated/ios/NitroSecuritiConsentSdk-Swift-Cxx-Bridge.hpp +604 -0
  46. package/nitrogen/generated/ios/NitroSecuritiConsentSdk-Swift-Cxx-Umbrella.hpp +78 -0
  47. package/nitrogen/generated/ios/NitroSecuritiConsentSdkAutolinking.mm +33 -0
  48. package/nitrogen/generated/ios/NitroSecuritiConsentSdkAutolinking.swift +25 -0
  49. package/nitrogen/generated/ios/c++/HybridConsentSDKSpecSwift.cpp +11 -0
  50. package/nitrogen/generated/ios/c++/HybridConsentSDKSpecSwift.hpp +223 -0
  51. package/nitrogen/generated/ios/swift/AppPermission.swift +267 -0
  52. package/nitrogen/generated/ios/swift/BannerConfig.swift +918 -0
  53. package/nitrogen/generated/ios/swift/CmpSDKOptions.swift +217 -0
  54. package/nitrogen/generated/ios/swift/CustomColors.swift +256 -0
  55. package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  56. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
  57. package/nitrogen/generated/ios/swift/Func_void_std__optional_BannerConfig_.swift +52 -0
  58. package/nitrogen/generated/ios/swift/Func_void_std__optional_SettingsPrompt_.swift +52 -0
  59. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
  60. package/nitrogen/generated/ios/swift/Func_void_std__vector_AppPermission_.swift +46 -0
  61. package/nitrogen/generated/ios/swift/Func_void_std__vector_Purpose_.swift +46 -0
  62. package/nitrogen/generated/ios/swift/Func_void_std__vector_SDK_.swift +46 -0
  63. package/nitrogen/generated/ios/swift/HybridConsentSDKSpec.swift +64 -0
  64. package/nitrogen/generated/ios/swift/HybridConsentSDKSpec_cxx.swift +398 -0
  65. package/nitrogen/generated/ios/swift/PermissionConsent.swift +57 -0
  66. package/nitrogen/generated/ios/swift/PostConsentsRequest.swift +216 -0
  67. package/nitrogen/generated/ios/swift/Purpose.swift +354 -0
  68. package/nitrogen/generated/ios/swift/PurposeConsent.swift +68 -0
  69. package/nitrogen/generated/ios/swift/SDK.swift +285 -0
  70. package/nitrogen/generated/ios/swift/SettingsPrompt.swift +181 -0
  71. package/nitrogen/generated/shared/c++/AppPermission.hpp +102 -0
  72. package/nitrogen/generated/shared/c++/BannerConfig.hpp +197 -0
  73. package/nitrogen/generated/shared/c++/CmpSDKOptions.hpp +110 -0
  74. package/nitrogen/generated/shared/c++/CustomColors.hpp +98 -0
  75. package/nitrogen/generated/shared/c++/HybridConsentSDKSpec.cpp +37 -0
  76. package/nitrogen/generated/shared/c++/HybridConsentSDKSpec.hpp +102 -0
  77. package/nitrogen/generated/shared/c++/PermissionConsent.hpp +77 -0
  78. package/nitrogen/generated/shared/c++/PostConsentsRequest.hpp +120 -0
  79. package/nitrogen/generated/shared/c++/Purpose.hpp +117 -0
  80. package/nitrogen/generated/shared/c++/PurposeConsent.hpp +81 -0
  81. package/nitrogen/generated/shared/c++/SDK.hpp +103 -0
  82. package/nitrogen/generated/shared/c++/SettingsPrompt.hpp +87 -0
  83. package/package.json +107 -0
  84. package/react-native.config.js +16 -0
  85. package/src/ConsentSDK.nitro.ts +232 -0
  86. 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
+ }