From a0a2832480e7a1c51bfcd7bb8f59cecc94de2f5d Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 17 Dec 2024 15:58:48 +0300 Subject: [PATCH] setting up enhanced biometric screens --- android/gradle.properties | 8 +-- .../com/smileidentity/react/SmileIdPackage.kt | 4 ++ ...SelfieAuthenticationEnhancedViewManager.kt | 64 +++++++++++++++++++ ...martSelfieEnrollmentEnhancedViewManager.kt | 64 +++++++++++++++++++ ...IDSmartSelfieAuthenticationEnhancedView.kt | 64 +++++++++++++++++++ ...mileIDSmartSelfieEnrollmentEnhancedView.kt | 63 ++++++++++++++++++ example/src/HomeScreen.tsx | 34 ++++++++++ example/src/types/Product.ts | 4 ++ ...DSmartSelfieAuthenticationEnhancedView.tsx | 47 ++++++++++++++ ...ileIDSmartSelfieEnrollmentEnhancedView.tsx | 47 ++++++++++++++ 10 files changed, 395 insertions(+), 4 deletions(-) create mode 100644 android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieAuthenticationEnhancedViewManager.kt create mode 100644 android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieEnrollmentEnhancedViewManager.kt create mode 100644 android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationEnhancedView.kt create mode 100644 android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentEnhancedView.kt create mode 100644 src/SmileIDSmartSelfieAuthenticationEnhancedView.tsx create mode 100644 src/SmileIDSmartSelfieEnrollmentEnhancedView.tsx diff --git a/android/gradle.properties b/android/gradle.properties index 60bccda..291e4b7 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,7 +1,7 @@ SmileId_kotlinVersion=2.0.0 SmileId_minSdkVersion=21 -SmileId_targetSdkVersion=34 -SmileId_compileSdkVersion=34 +SmileId_targetSdkVersion=35 +SmileId_compileSdkVersion=35 SmileId_ndkversion=21.4.7075529 -SmileId_androidVersion=10.3.7 -SmileId_kotlinCompilerExtensionVersion=1.5.11 +SmileId_androidVersion=10.4.0 +#SmileId_kotlinCompilerExtensionVersion=1.5.11 diff --git a/android/src/main/java/com/smileidentity/react/SmileIdPackage.kt b/android/src/main/java/com/smileidentity/react/SmileIdPackage.kt index 3f06481..4001176 100644 --- a/android/src/main/java/com/smileidentity/react/SmileIdPackage.kt +++ b/android/src/main/java/com/smileidentity/react/SmileIdPackage.kt @@ -12,8 +12,10 @@ import com.smileidentity.react.viewmanagers.SmileIDDocumentCaptureViewManager import com.smileidentity.react.viewmanagers.SmileIDDocumentVerificationViewManager import com.smileidentity.react.viewmanagers.SmileIDEnhancedDocumentVerificationViewManager import com.smileidentity.react.viewmanagers.SmileIDSmartSelfieAuthenticationViewManager +import com.smileidentity.react.viewmanagers.SmileIDSmartSelfieAuthenticationEnhancedViewManager import com.smileidentity.react.viewmanagers.SmileIDSmartSelfieCaptureViewManager import com.smileidentity.react.viewmanagers.SmileIDSmartSelfieEnrollmentViewManager +import com.smileidentity.react.viewmanagers.SmileIDSmartSelfieEnrollmentEnhancedViewManager import com.smileidentity.react.views.SmileIDDocumentCaptureView class SmileIdPackage : TurboReactPackage() { @@ -24,6 +26,8 @@ class SmileIdPackage : TurboReactPackage() { SmileIDDocumentCaptureViewManager(reactContext), SmileIDSmartSelfieEnrollmentViewManager(reactContext), SmileIDSmartSelfieAuthenticationViewManager(reactContext), + SmileIDSmartSelfieEnrollmentEnhancedViewManager(reactContext), + SmileIDSmartSelfieAuthenticationEnhancedViewManager(reactContext), SmileIDDocumentVerificationViewManager(reactContext), SmileIDEnhancedDocumentVerificationViewManager(reactContext), SmileIDConsentViewManager(reactContext), diff --git a/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieAuthenticationEnhancedViewManager.kt b/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieAuthenticationEnhancedViewManager.kt new file mode 100644 index 0000000..5a39ca2 --- /dev/null +++ b/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieAuthenticationEnhancedViewManager.kt @@ -0,0 +1,64 @@ +package com.smileidentity.react.viewmanagers + +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.uimanager.SimpleViewManager +import com.facebook.react.uimanager.ThemedReactContext +import com.smileidentity.react.utils.getBoolOrDefault +import com.smileidentity.react.utils.getImmutableMapOrDefault +import com.smileidentity.react.utils.getStringOrDefault +import com.smileidentity.react.views.SmileIDSmartSelfieAuthenticationEnhancedView + +@ReactModule(name = SmileIDSmartSelfieAuthenticationEnhancedViewManager.NAME) +class SmileIDSmartSelfieAuthenticationEnhancedViewManager( + private val reactApplicationContext: ReactApplicationContext +) : SimpleViewManager() { + + override fun getName(): String = NAME + + override fun getExportedCustomBubblingEventTypeConstants(): Map { + return mapOf( + "onSmileResult" to mapOf( + "phasedRegistrationNames" to mapOf( + "bubbled" to "onResult" + ) + ) + ) + } + + override fun getCommandsMap(): Map { + return mapOf("setParams" to COMMAND_SET_PARAMS) + } + + override fun receiveCommand( + view: SmileIDSmartSelfieAuthenticationEnhancedView, + commandId: String?, + args: ReadableArray? + ) { + super.receiveCommand(view, commandId, args) + when (commandId?.toInt()) { + COMMAND_SET_PARAMS -> { + // Extract params from args and apply to view + val params = args?.getMap(0) + params?.let { + view.extraPartnerParams = params.getImmutableMapOrDefault("extraPartnerParams") + view.userId = params.getStringOrDefault("userId") + view.showAttribution = params.getBoolOrDefault("showAttribution", true) + view.showInstructions = params.getBoolOrDefault("showInstructions", true) + view.allowNewEnroll = params.getBoolOrDefault("allowNewEnroll", false) + view.renderContent() + } + } + } + } + + override fun createViewInstance(p0: ThemedReactContext): SmileIDSmartSelfieAuthenticationEnhancedView { + return SmileIDSmartSelfieAuthenticationEnhancedView(reactApplicationContext) + } + + companion object { + const val NAME = "SmileIDSmartSelfieAuthenticationEnhancedView" + const val COMMAND_SET_PARAMS = 2 + } +} diff --git a/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieEnrollmentEnhancedViewManager.kt b/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieEnrollmentEnhancedViewManager.kt new file mode 100644 index 0000000..834aea6 --- /dev/null +++ b/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDSmartSelfieEnrollmentEnhancedViewManager.kt @@ -0,0 +1,64 @@ +package com.smileidentity.react.viewmanagers + +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.uimanager.SimpleViewManager +import com.facebook.react.uimanager.ThemedReactContext +import com.smileidentity.react.utils.getBoolOrDefault +import com.smileidentity.react.utils.getImmutableMapOrDefault +import com.smileidentity.react.utils.getStringOrDefault +import com.smileidentity.react.views.SmileIDSmartSelfieEnrollmentEnhancedView + +@ReactModule(name = SmileIDSmartSelfieEnrollmentEnhancedViewManager.NAME) +class SmileIDSmartSelfieEnrollmentEnhancedViewManager( + private val reactApplicationContext: ReactApplicationContext +) : SimpleViewManager() { + + override fun getName(): String = NAME + + override fun getExportedCustomBubblingEventTypeConstants(): Map { + return mapOf( + "onSmileResult" to mapOf( + "phasedRegistrationNames" to mapOf( + "bubbled" to "onResult" + ) + ) + ) + } + + override fun getCommandsMap(): Map { + return mapOf("setParams" to COMMAND_SET_PARAMS) + } + + override fun receiveCommand( + view: SmileIDSmartSelfieEnrollmentEnhancedView, + commandId: String?, + args: ReadableArray? + ) { + super.receiveCommand(view, commandId, args) + when (commandId?.toInt()) { + COMMAND_SET_PARAMS -> { + // Extract params from args and apply to view + val params = args?.getMap(0) + params?.let { + view.extraPartnerParams = params.getImmutableMapOrDefault("extraPartnerParams") + view.userId = params.getStringOrDefault("userId") + view.showAttribution = params.getBoolOrDefault("showAttribution", true) + view.showInstructions = params.getBoolOrDefault("showInstructions", true) + view.allowNewEnroll = params.getBoolOrDefault("allowNewEnroll", false) + view.renderContent() + } + } + } + } + + override fun createViewInstance(p0: ThemedReactContext): SmileIDSmartSelfieEnrollmentEnhancedView { + return SmileIDSmartSelfieEnrollmentEnhancedView(reactApplicationContext) + } + + companion object { + const val NAME = "SmileIDSmartSelfieEnrollmentEnhancedView" + const val COMMAND_SET_PARAMS = 1 + } +} diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationEnhancedView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationEnhancedView.kt new file mode 100644 index 0000000..fc9e96a --- /dev/null +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationEnhancedView.kt @@ -0,0 +1,64 @@ +package com.smileidentity.react.views + +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner +import com.facebook.react.bridge.ReactApplicationContext +import com.smileidentity.SmileID +import com.smileidentity.compose.SmartSelfieAuthenticationEnhanced +import com.smileidentity.react.results.SmartSelfieCaptureResult +import com.smileidentity.react.utils.SelfieCaptureResultAdapter +import com.smileidentity.results.SmileIDResult +import com.smileidentity.util.randomUserId +import kotlinx.collections.immutable.toImmutableMap + +class SmileIDSmartSelfieAuthenticationEnhancedView(context: ReactApplicationContext) : + SmileIDView(context) { + + override fun renderContent() { + composeView.apply { + val customViewModelStoreOwner = CustomViewModelStoreOwner() + setContent { + CompositionLocalProvider(LocalViewModelStoreOwner provides customViewModelStoreOwner) { + SmileID.SmartSelfieAuthenticationEnhanced( + userId = userId ?: rememberSaveable { randomUserId() }, + allowNewEnroll = allowNewEnroll ?: false, + showAttribution = showAttribution, + showInstructions = showInstructions, + extraPartnerParams = extraPartnerParams, + ) { res -> + when (res) { + is SmileIDResult.Success -> { +// val result = +// SmartSelfieCaptureResult( +// selfieFile = res.data.selfieFile, +// livenessFiles = res.data.livenessFiles, +// apiResponse = res.data.apiResponse, +// ) +// val newMoshi = +// SmileID.moshi +// .newBuilder() +// .add(SelfieCaptureResultAdapter.FACTORY) +// .build() +// val json = +// try { +// newMoshi +// .adapter(SmartSelfieCaptureResult::class.java) +// .toJson(result) +// } catch (e: Exception) { +// emitFailure(e) +// return@SmartSelfieAuthentication +// } +// json?.let { js -> +// emitSuccess(js) +// } + } + + is SmileIDResult.Error -> emitFailure(res.throwable) + } + } + } + } + } + } +} diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentEnhancedView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentEnhancedView.kt new file mode 100644 index 0000000..17fc1b0 --- /dev/null +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentEnhancedView.kt @@ -0,0 +1,63 @@ +package com.smileidentity.react.views + +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner +import com.facebook.react.bridge.ReactApplicationContext +import com.smileidentity.SmileID +import com.smileidentity.compose.SmartSelfieEnrollmentEnhanced +import com.smileidentity.react.results.SmartSelfieCaptureResult +import com.smileidentity.react.utils.SelfieCaptureResultAdapter +import com.smileidentity.results.SmileIDResult +import com.smileidentity.util.randomUserId +import kotlinx.collections.immutable.toImmutableMap + +class SmileIDSmartSelfieEnrollmentEnhancedView(context: ReactApplicationContext) : SmileIDView(context) { + + override fun renderContent() { + composeView.apply { + setContent { + val customViewModelStoreOwner = CustomViewModelStoreOwner() + CompositionLocalProvider(LocalViewModelStoreOwner provides customViewModelStoreOwner) { + SmileID.SmartSelfieEnrollmentEnhanced( + userId = userId ?: rememberSaveable { randomUserId() }, + allowNewEnroll = allowNewEnroll ?: false, + showAttribution = showAttribution, + showInstructions = showInstructions, + extraPartnerParams = extraPartnerParams, + ) { res -> + when (res) { + is SmileIDResult.Success -> { +// val result = +// SmartSelfieCaptureResult( +// selfieFile = res.data.selfieFile, +// livenessFiles = res.data.livenessFiles, +// apiResponse = res.data.apiResponse, +// ) +// val newMoshi = +// SmileID.moshi +// .newBuilder() +// .add(SelfieCaptureResultAdapter.FACTORY) +// .build() +// val json = +// try { +// newMoshi +// .adapter(SmartSelfieCaptureResult::class.java) +// .toJson(result) +// } catch (e: Exception) { +// emitFailure(e) +// return@SmartSelfieEnrollment +// } +// json?.let { js -> +// emitSuccess(js) +// } + } + + is SmileIDResult.Error -> emitFailure(res.throwable) + } + } + } + } + } + } +} diff --git a/example/src/HomeScreen.tsx b/example/src/HomeScreen.tsx index 816870a..4867973 100644 --- a/example/src/HomeScreen.tsx +++ b/example/src/HomeScreen.tsx @@ -7,6 +7,8 @@ import type { DocumentVerificationRequest, SmartSelfieAuthenticationRequest, SmartSelfieEnrollmentRequest, + SmartSelfieAuthenticationRequestEnhanced, + SmartSelfieEnrollmentRequestEnhanced } from '@smile_identity/react-native'; import { SmileID } from '@smile_identity/react-native'; @@ -58,6 +60,14 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { ...defaultProductRef.current, userId: 'user_0ffc7e8b-9b31-41bc-8131-03103a45d944', }); + const [smartSelfieEnrollmentEnhanced, setSmartSelfieEnrollmentEnhanced] = + useState({ + userId: 'user_0ffc7e8b-9b31-41bc-8131-03103a45d944', + }) + const [smartSelfieAuthenticationEnhanced, setSmartSelfieAuthenticationEnhanced] = + useState({ + userId: 'user_0ffc7e8b-9b31-41bc-8131-03103a45d944', + }) const [documentVerification, setDocumentVerification] = useState({ ...defaultProductRef.current, @@ -135,6 +145,20 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { }, }); + setSmartSelfieEnrollmentEnhanced({ + userId: generateUuid('user_'), + allowNewEnroll: false, + showInstructions: true, + showAttribution: true, + }) + + setSmartSelfieAuthenticationEnhanced({ + userId: 'user_0ffc7e8b-9b31-41bc-8131-03103a45d944', + allowNewEnroll: false, + showInstructions: true, + showAttribution: true, + }) + setDocumentVerification({ ...defaultProductRef.current, countryCode: 'ZW', @@ -186,6 +210,14 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { title: 'SmartSelfie Authentication', product: smartSelfieAuthentication, }, + { + title: 'SmartSelfie Enrollment (Enhanced)', + product: smartSelfieEnrollmentEnhanced, + }, + { + title: 'SmartSelfie Authentication (Enhanced)', + product: smartSelfieAuthenticationEnhanced, + }, { title: 'Document Verification', product: documentVerification, @@ -208,6 +240,8 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { documentCapture, smartSelfieEnrollment, smartSelfieAuthentication, + smartSelfieEnrollmentEnhanced, + smartSelfieAuthenticationEnhanced, documentVerification, biometricKYC, consentScreen, diff --git a/example/src/types/Product.ts b/example/src/types/Product.ts index a578943..e9f633b 100644 --- a/example/src/types/Product.ts +++ b/example/src/types/Product.ts @@ -4,6 +4,8 @@ import type { SmileIDViewProps, SmartSelfieEnrollmentRequest, SmartSelfieAuthenticationRequest, + SmartSelfieEnrollmentRequestEnhanced, + SmartSelfieAuthenticationRequestEnhanced, BiometricKYCRequest, ConsentRequest, } from '@smile_identity/react-native'; @@ -15,6 +17,8 @@ export type Product = { | DocumentVerificationRequest | SmartSelfieEnrollmentRequest | SmartSelfieAuthenticationRequest + | SmartSelfieEnrollmentRequestEnhanced + | SmartSelfieAuthenticationRequestEnhanced | BiometricKYCRequest | SmileIDViewProps | ConsentRequest; diff --git a/src/SmileIDSmartSelfieAuthenticationEnhancedView.tsx b/src/SmileIDSmartSelfieAuthenticationEnhancedView.tsx new file mode 100644 index 0000000..877f526 --- /dev/null +++ b/src/SmileIDSmartSelfieAuthenticationEnhancedView.tsx @@ -0,0 +1,47 @@ +import React, { Component } from 'react'; +import type { HostComponent } from 'react-native'; +import { UIManager, findNodeHandle, Platform } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; +import type { SmartSelfieAuthenticationRequest } from './index'; + +const SmileIDSmartSelfieAuthenticationEnhancedComponent = + codegenNativeComponent( + 'SmileIDSmartSelfieAuthenticationEnhancedView' + ) as HostComponent; + +export default class SmileIDSmartSelfieAuthenticationEnhancedView extends Component { + private viewRef = React.createRef(); // + + componentDidMount() { + const parameters = { + ...this.props, + }; + + // Obtain the command identifier + const commandId = UIManager.getViewManagerConfig( + 'SmileIDSmartSelfieAuthenticationEnhancedView' + ).Commands.setParams; + + // Ensure the commandId is defined and is a number + if (typeof commandId !== 'undefined') { + UIManager.dispatchViewManagerCommand( + findNodeHandle(this.viewRef.current), + Platform.OS === 'android' ? commandId.toString() : commandId, + [parameters] + ); + } else { + throw new Error( + 'Command "setParams" is not defined for MyNativeComponent' + ); + } + } + + render() { + return ( + + ); + } +} diff --git a/src/SmileIDSmartSelfieEnrollmentEnhancedView.tsx b/src/SmileIDSmartSelfieEnrollmentEnhancedView.tsx new file mode 100644 index 0000000..a08555b --- /dev/null +++ b/src/SmileIDSmartSelfieEnrollmentEnhancedView.tsx @@ -0,0 +1,47 @@ +import React, { Component } from 'react'; +import type { HostComponent } from 'react-native'; +import { UIManager, findNodeHandle, Platform } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; +import type { SmartSelfieEnrollmentRequest } from './index'; + +const SmileIDSmartSelfieEnrollmentEnhancedComponent = + codegenNativeComponent( + 'SmileIDSmartSelfieEnrollmentEnhancedView' + ) as HostComponent; + +export default class SmileIDSmartSelfieEnrollmentEnhancedView extends Component { + private viewRef = React.createRef(); // + + componentDidMount() { + const parameters = { + ...this.props, + }; + + // Obtain the command identifier + const commandId = UIManager.getViewManagerConfig( + 'SmileIDSmartSelfieEnrollmentEnhancedView' + ).Commands.setParams; + + // Ensure the commandId is defined and is a number + if (typeof commandId !== 'undefined') { + UIManager.dispatchViewManagerCommand( + findNodeHandle(this.viewRef.current), + Platform.OS === 'android' ? commandId.toString() : commandId, + [parameters] + ); + } else { + throw new Error( + 'Command "setParams" is not defined for MyNativeComponent' + ); + } + } + + render() { + return ( + + ); + } +}