package com.samplenativemodule import android.app.Application import android.util.Log import com.bureau.base.Environment import com.bureau.base.models.BureauConfig import com.bureau.behavioralbiometrics.BehavioralBiometricsModule import com.bureau.devicefingerprint.BureauAPI import com.bureau.devicefingerprint.models.ErrorResponse import com.bureau.devicefingerprint.models.SubmitResponse import com.bureau.devicefingerprint.tools.DataCallback import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.WritableMap import com.google.gson.Gson class FraudNativeModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { companion object { const val NAME = "FraudNativeModule" private const val LOG_TAG = "FraudNativeModule" } private val gson = Gson() private var enableBehavioralBiometrics: Boolean = false override fun getName(): String { return NAME } @ReactMethod fun initDeviceIntelligence(credentialId: String, env: String, enableBehavioralBiometrics: Boolean, enableSmartInsightFetch: Boolean) { try { if (credentialId.isBlank()) { Log.e(LOG_TAG, "Cannot initialize with empty or blank credentialId") return } val environment = when (env.lowercase()) { "production", "prod" -> { Log.d(LOG_TAG, "Initializing with PRODUCTION environment") Environment.ENV_PRODUCTION } "sandbox", "dev", "development" -> { Log.d(LOG_TAG, "Initializing with SANDBOX environment") Environment.ENV_SANDBOX } else -> { Log.w(LOG_TAG, "Unknown environment '$env', defaulting to SANDBOX") Environment.ENV_SANDBOX } } this.enableBehavioralBiometrics = enableBehavioralBiometrics val config = BureauConfig( credentialId, environment, reactContext.applicationContext as Application, enableSmartInsightFetch ) val api = BureauAPI.init(config) if (enableBehavioralBiometrics) { Log.d("BureauPlugin", "initialising with bb...") val activity = reactContext.currentActivity if (activity != null) { api.addModule(BehavioralBiometricsModule(activity)) } else { Log.d("BureauPlugin", "enableBehavioralBiometrics=true but activity is null, skipping BB module") } } else { Log.d("BureauPlugin", "initialising only Device") } } catch (e: Throwable) { Log.e(LOG_TAG, "Failed to initialize device intelligence: ${e.message}") } } @ReactMethod fun submitDeviceIntelligence(promise: Promise) { val callback = object : DataCallback { override fun onResult(message: SubmitResponse) { Log.d(LOG_TAG, "Fingerprint recorded successfully") val map: WritableMap = Arguments.createMap() map.putString("message", message.message) map.putString("eventId", message.eventId) map.putString("action", message.action) map.putString("iv", message.iv) message.insights?.let { insights -> try { val insightsJson = gson.toJson(insights) map.putString("insights", insightsJson) Log.d(LOG_TAG, "Insights serialized successfully") } catch (e: Throwable) { Log.w(LOG_TAG, "Failed to serialize insights: ${e.message}") map.putString("insights", null) } } ?: run { map.putString("insights", null) } promise.resolve(map) } override fun onError(errorMessage: ErrorResponse) { val errorMsg = "Fingerprint failed to be recorded - Message: ${errorMessage.message}, Code: ${errorMessage.errorCode}" Log.e(LOG_TAG, errorMsg) val map: WritableMap = Arguments.createMap() map.putString("message", errorMsg) map.putString("eventId", errorMessage.eventId) promise.resolve(map) } } BureauAPI.submit(callback) } @ReactMethod fun asyncSubmitDeviceIntelligence(promise: Promise) { try { val eventId = BureauAPI.asyncSubmit() Log.d(LOG_TAG, "Async submit initiated with eventId: $eventId") promise.resolve(eventId) } catch (e: Throwable) { val detailedMessage = "${e.javaClass.name}: ${e.message}" Log.e(LOG_TAG, "Failed to async submit: $detailedMessage", e) promise.reject("ASYNC_SUBMIT_FAILED", detailedMessage, e) } } @ReactMethod fun getUserId(promise: Promise) { CoroutineScope(Dispatchers.IO).launch { try { val userId = BureauAPI.getUserId() Log.d(LOG_TAG, "Retrieved userId successfully") promise.resolve(userId) } catch (e: Throwable) { Log.e(LOG_TAG, "Failed to get userId: ${e.message}") promise.reject("GET_USER_ID_FAILED", e.message, e) } } } @ReactMethod fun isInitialized(promise: Promise) { try { val isInitialized = BureauAPI.isInitialized() promise.resolve(isInitialized) } catch (e: Throwable) { Log.e(LOG_TAG, "Failed to check initialization status: ${e.message}") promise.resolve(false) } } @ReactMethod fun setMetaInfo(json: ReadableMap) { try { val data = mutableMapOf() val hashMap = json.toHashMap() for ((key, value) in hashMap.entries) { when (value) { is String -> data[key] = value null -> data[key] = "" else -> data[key] = value.toString() } } BureauAPI.setMetaInfo(data) Log.d(LOG_TAG, "MetaInfo set successfully with ${data.size} entries") } catch (e: Throwable) { Log.e(LOG_TAG, "Failed to set meta info: ${e.message}") } } @ReactMethod fun setUserId(userId: String) { try { if (userId.isBlank()) { Log.w(LOG_TAG, "Attempting to set empty or blank userId") return } BureauAPI.setUserId(userId) Log.d(LOG_TAG, "UserId set successfully") } catch (e: Throwable) { Log.e(LOG_TAG, "Failed to set userId: ${e.message}") } } @ReactMethod fun setFlow(flow: String) { try { if (flow.isBlank()) { Log.w(LOG_TAG, "Attempting to set empty or blank flow") return } BureauAPI.setFlow(flow) Log.d(LOG_TAG, "Flow set successfully: $flow") } catch (e: Throwable) { Log.e(LOG_TAG, "Failed to set flow: ${e.message}") } } }