diff --git a/android/build.gradle b/android/build.gradle index 1537ef8..3a238c1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -99,6 +99,6 @@ dependencies { //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation("com.ts.sdk:identityverification:1.1.1") + implementation("com.ts.sdk:identityverification:1.2.+") } diff --git a/android/src/main/java/com/tsidv/TsIdvModule.kt b/android/src/main/java/com/tsidv/TsIdvModule.kt index 9a0255a..59204be 100644 --- a/android/src/main/java/com/tsidv/TsIdvModule.kt +++ b/android/src/main/java/com/tsidv/TsIdvModule.kt @@ -10,6 +10,7 @@ import com.facebook.react.bridge.ReactContext import com.facebook.react.bridge.WritableMap import com.facebook.react.modules.core.DeviceEventManagerModule import com.transmit.identityverification.ITSFaceAuthenticationStatus +import com.transmit.identityverification.ITSIdentityVerificationMosaicUIStatus import com.transmit.identityverification.ITSIdentityVerificationStatus import com.transmit.identityverification.TSIdentityVerification import com.transmit.identityverification.TSIdentityVerification.registerForStatus @@ -19,7 +20,7 @@ import com.transmit.identityverification.TSRecaptureReason import com.ts.coresdk.TSLog class TsIdvModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), - ITSIdentityVerificationStatus, ITSFaceAuthenticationStatus { + ITSIdentityVerificationStatus, ITSFaceAuthenticationStatus, ITSIdentityVerificationMosaicUIStatus { private val idvStatusChangeEventName: String = "idv_status_change_event" private val TAG = "IDV" @@ -49,6 +50,12 @@ class TsIdvModule(private val reactContext: ReactApplicationContext) : ReactCont FaceAuthenticationFail("faceAuthenticationDidFail") } + enum class MosaicUIAuthStatusType(val status: String) { + mosaicUIVerificationDidComplete("mosaicUIVerificationDidComplete"), + mosaicUIVerificationDidCancel("mosaicUIVerificationDidCancel"), + mosaicUIVerificationDidFail("mosaicUIVerificationDidFail") + } + // region IDV SDK API @ReactMethod @@ -82,7 +89,19 @@ class TsIdvModule(private val reactContext: ReactApplicationContext) : ReactCont return } val activity = currentActivity!! - start(activity, startToken) + TSIdentityVerification.start(activity, startToken) + promise.resolve(true) + } + + @ReactMethod + fun startMosaicUI(startToken: String, promise: Promise) { + Log.d(TAG, "startMosaicUI") + if (currentActivity == null) { + promise.reject("Error during startMosaicUI", "currentActivity is NULL") + return + } + val activity = currentActivity!! + TSIdentityVerification.startWithSmartUI(activity, startToken); promise.resolve(true) } @@ -197,24 +216,31 @@ class TsIdvModule(private val reactContext: ReactApplicationContext) : ReactCont // endregion - // region Helpers + // region Identity Verification Mosaic UI Status -// private fun parseLogLevel(jsLogLevel: String): TSLogLevel? { -// return when (jsLogLevel) { -// "verbose" -> TSLogLevel.VERBOSE -// "debug" -> TSLogLevel.DEBUG -// "info" -> TSLogLevel.INFO -// "warning" -> TSLogLevel.WARNING -// "error" -> TSLogLevel.ERROR -// "crytical" -> TSLogLevel.CRITICAL -// "off" -> TSLogLevel.OFF -// else -> null -// } -// } + override fun mosaicUIVerificationCompleted() { + reportIDVStatusChange(MosaicUIAuthStatusType.mosaicUIVerificationDidComplete.status, null) + } + + override fun mosaicUIVerificationCanceled() { + reportIDVStatusChange(MosaicUIAuthStatusType.mosaicUIVerificationDidCancel.status, null) + } + + override fun mosaicUIVerificationFailed(error: TSIdentityVerificationError) { + Log.d("MosaicUI verificationDidFail", error.name) + val errorMap: WritableMap = Arguments.createMap() + errorMap.putString("error", error.name) + reportIDVStatusChange(MosaicUIAuthStatusType.mosaicUIVerificationDidFail.status, errorMap) + } + + // endregion + + // region Helpers private fun registerSDKStatus() { registerForStatus(this) TSIdentityVerification.registerForFaceAuthStatus(this) + TSIdentityVerification.registerForStatusMosaicUI(this) } diff --git a/example/ios/.xcode.env b/example/ios/.xcode.env index d85cff7..70b1cfd 100644 --- a/example/ios/.xcode.env +++ b/example/ios/.xcode.env @@ -1 +1 @@ -export NODE_BINARY=/usr/local/bin/node +export NODE_BINARY='/usr/local/bin/node' diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index d804a50..6c354b4 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,14 +1,14 @@ PODS: - - AccountProtection (2.1.4): - - TSCoreSDK (~> 1.0.24) + - AccountProtection (2.1.10): + - TSCoreSDK (~> 1.0.27) - boost (1.84.0) - DoubleConversion (1.1.6) - FBLazyVector (0.75.2) - fmt (9.1.0) - glog (0.3.5) - - IdentityVerification (1.1.2): - - AccountProtection (~> 2.1.3) - - TSCoreSDK (~> 1.0.23) + - IdentityVerification (1.2.2): + - AccountProtection (~> 2.1.9) + - TSCoreSDK (~> 1.0.27) - RCT-Folly (2024.01.01.00): - boost - DoubleConversion @@ -1214,10 +1214,10 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-ts-idv (1.0.4): + - react-native-ts-idv (1.0.5): - DoubleConversion - glog - - IdentityVerification (~> 1.1.2) + - IdentityVerification (~> 1.2.2) - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety @@ -1479,7 +1479,7 @@ PODS: - React-logger (= 0.75.2) - React-perflogger (= 0.75.2) - React-utils (= 0.75.2) - - ReactNativeHost (0.4.12): + - ReactNativeHost (0.5.3): - DoubleConversion - glog - RCT-Folly (= 2024.01.01.00) @@ -1501,12 +1501,12 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - ReactTestApp-DevSupport (3.10.1): + - ReactTestApp-DevSupport (3.10.22): - React-Core - React-jsi - ReactTestApp-Resources (1.0.0-dev) - SocketRocket (0.7.0) - - TSCoreSDK (1.0.24) + - TSCoreSDK (1.0.27) - Yoga (0.0.0) DEPENDENCIES: @@ -1715,13 +1715,13 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - AccountProtection: d34c382ae6eed651f2d72baf4856a2f95a45d749 + AccountProtection: 9154d08c86586d632ef1821962953e22a4f313f3 boost: 4cb898d0bf20404aab1850c656dcea009429d6c1 DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5 FBLazyVector: 38bb611218305c3bc61803e287b8a81c6f63b619 fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: 69ef571f3de08433d766d614c73a9838a06bf7eb - IdentityVerification: 2ca41a6c740105bf5165266ffa4b2ac55288bfb8 + IdentityVerification: e48bf94fd0f858f7fb70a2ace1d07160140ec1d3 RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740 RCTDeprecation: 34cbf122b623037ea9facad2e92e53434c5c7422 RCTRequired: 24c446d7bcd0f517d516b6265d8df04dc3eb1219 @@ -1751,7 +1751,7 @@ SPEC CHECKSUMS: React-logger: 8db32983d75dc2ad54f278f344ccb9b256e694fc React-Mapbuffer: 1c08607305558666fd16678b85ef135e455d5c96 React-microtasksnativemodule: e8efd9e5df1ab51a58e45326b98787cf21d47e6e - react-native-ts-idv: 15f4f7012cea8db1fcc535c82192f8fab2741247 + react-native-ts-idv: cc1712cd435ec9a1b66b1f7801a34a2aad7f41aa React-nativeconfig: 57781b79e11d5af7573e6f77cbf1143b71802a6d React-NativeModulesApple: e35ceb132b4005f4bb8924a3a87b9fd3c21b15ee React-perflogger: 8a360ccf603de6ddbe9ff8f54383146d26e6c936 @@ -1777,11 +1777,11 @@ SPEC CHECKSUMS: React-utils: 87f64cff8c1fe244bf688a7a48395a70eb61a509 ReactCodegen: f8ed6f835a2fffe2a3666dfbce5ff1b120f24982 ReactCommon: a33f215e2ca23410f8f44b0a94ab93120882e5e5 - ReactNativeHost: 6452a9f39ec92ef8ce5f752ec2e1fa0cd2180b8e - ReactTestApp-DevSupport: 6a2de08b780d695cb5d2fbe3e2222ea471de5866 + ReactNativeHost: 478750aa4ff0e22768467a4193c64ddb959f26de + ReactTestApp-DevSupport: 42abce6b0c88dfb47c86e80aa22831b2abcc3144 ReactTestApp-Resources: 7db90c026cccdf40cfa495705ad436ccc4d64154 SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d - TSCoreSDK: b480415b11b5b202cbf43275b1ea40f68b546b6e + TSCoreSDK: 750f7723e2c8c8e7501f050021674bc30e48de37 Yoga: a1d7895431387402a674fd0d1c04ec85e87909b8 PODFILE CHECKSUM: 73892cfbb7baf5a735ea7d27759f1ed18058b6d7 diff --git a/example/src/App.tsx b/example/src/App.tsx index dd9ff64..7b92011 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -48,7 +48,11 @@ const enum VerificationStatus { faceAuthenticationDidComplete = "faceAuthenticationDidComplete", faceAuthenticationDidFail = "faceAuthenticationDidFail", faceAuthenticationDidStartCapturing = "faceAuthenticationDidStartCapturing", - faceAuthenticationDidStartProcessing = "faceAuthenticationDidStartProcessing" + faceAuthenticationDidStartProcessing = "faceAuthenticationDidStartProcessing", + + mosaicUIVerificationDidComplete = "mosaicUIVerificationDidComplete", + mosaicUIVerificationDidCancel = "mosaicUIVerificationDidCancel", + mosaicUIVerificationDidFail = "mosaicUIVerificationDidFail", } export default class App extends React.Component { @@ -82,6 +86,7 @@ export default class App extends React.Component { @@ -163,6 +168,20 @@ export default class App extends React.Component { } } + onStartMosaicUI = async (): Promise => { + try { + const accessToken = this.accessTokenResponse?.token || ""; + + this.verificationSession = await this.mockServer.createVerificationSession(accessToken); + await IdentityVerification.startMosaicUI(this.verificationSession.startToken); + + this.logAppEvent("Started identity verification with MosaicUI process"); + } catch (error) { + this.logAppEvent(`Error verifying user identity: ${error}`); + this.setState({ errorMessage: `${error}` }); + } + } + private identityVerificationCompleted = async (sessionId: string, accessToken: string): Promise => { try { @@ -197,13 +216,8 @@ export default class App extends React.Component { } IdentityVerification.setLogLevel(TSIDV.IDVLogLevel.verbose); - - if (Platform.OS === "android") { - await IdentityVerification.initializeSDK(); - } else { - await IdentityVerification.initialize(config.clientId); - } - + await IdentityVerification.initialize(config.clientId); + this.registerForEvents(); this.requestCameraPermissions(); diff --git a/example/src/home.tsx b/example/src/home.tsx index ff93b92..36f35b4 100644 --- a/example/src/home.tsx +++ b/example/src/home.tsx @@ -1,18 +1,20 @@ -import React, { ReactElement } from 'react'; +import React, { type ReactElement } from 'react'; import { Button, StyleSheet, Text, View } from 'react-native'; export type Props = { onStartIDV: () => void; onStartFaceAuth: () => void; + onStartMosaicUI: () => void; isInSession: boolean; errorMessage: string; }; -const HomeScreen: React.FC = ({ onStartIDV, onStartFaceAuth, isInSession, errorMessage }) => { +const HomeScreen: React.FC = ({ onStartIDV, onStartFaceAuth, onStartMosaicUI, isInSession, errorMessage }) => { return ( {"Identinty Verification"} + { renderStartIDVWithMosaicUIButton() } { renderStartIDVButton() } { renderStartFaceAuthVButton() } { renderStatusLabel() } @@ -39,6 +41,18 @@ const HomeScreen: React.FC = ({ onStartIDV, onStartFaceAuth, isInSession, ) } + function renderStartIDVWithMosaicUIButton(): ReactElement { + if (isInSession) { return <> } + return ( + +