From 339e08c46212f5088030a6b02f05eb7090130554 Mon Sep 17 00:00:00 2001 From: adityankannan-tw <109274996+adityankannan-tw@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:59:02 +0530 Subject: [PATCH] [INJIMOB-1433,528] - Add passive liveness detection with blink detection (#1474) * [INJIMOB-528] add liveness support for face verification Signed-off-by: adityankannan-tw * [INJIMOB-528] add and comment blink detection Signed-off-by: adityankannan-tw * [INJIMOB-528] update locales and remove blink detection Signed-off-by: adityankannan-tw * [INJIMOB-1433] add blinking and increase threshold if blinking is detected Signed-off-by: adityankannan-tw * [INJIMOB-1433] sync package lock json Signed-off-by: adityankannan-tw * [INJIMOB-1433] update node version to 18 for android build Signed-off-by: adityankannan-tw * [INJIMOB-1433] refactor Signed-off-by: adityankannan-tw * [INJIMOB-1433] refactor components Signed-off-by: adityankannan-tw * [INJIMOB-1433] use the default version of package resolved file Signed-off-by: adityankannan-tw * [INJIMOB-1433] refactor and add new env for liveness in workflow Signed-off-by: adityankannan-tw * [INJIMOB-1433] remove new env and unused code Signed-off-by: adityankannan-tw * [INJIMOB-1433] add new env for liveness and combine build descriptiona and build name Signed-off-by: adityankannan-tw * [INJIMOB-528] update package lock & pbxproj files Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1433] add test id for elements Signed-off-by: adityankannan-tw --------- Signed-off-by: adityankannan-tw Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> Co-authored-by: adityankannan-tw Co-authored-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> --- .env | 3 + .github/workflows/internal-build.yml | 24 +- .github/workflows/push-triggers.yml | 2 +- .talismanrc | 4 +- components/FaceScanner.tsx | 140 -- components/FaceScanner/FaceCompare.tsx | 78 ++ components/FaceScanner/FaceScanner.tsx | 209 +++ components/FaceScanner/FaceScannerHelper.ts | 264 ++++ components/FaceScanner/LivenessDetection.tsx | 86 ++ components/ui/Modal.tsx | 7 +- components/ui/themes/DefaultTheme.ts | 27 + components/ui/themes/PurpleTheme.ts | 27 + ios/Inji.xcodeproj/project.pbxproj | 18 +- .../xcshareddata/swiftpm/Package.resolved | 2 +- ios/Podfile | 2 +- ios/Podfile.lock | 114 +- locales/ara.json | 5 + locales/en.json | 5 + locales/fil.json | 5 + locales/hin.json | 5 + locales/kan.json | 5 + locales/tam.json | 5 + machines/faceScanner.ts | 4 + machines/faceScanner.typegen.ts | 116 +- machines/settings.ts | 2 +- machines/settings.typegen.ts | 121 +- package-lock.json | 1124 ++++++++++++++++- package.json | 5 + screens/QrLogin/QrLogin.tsx | 3 +- screens/Scan/ScanLayout.tsx | 2 + screens/Scan/SendVcScreen.tsx | 2 + screens/VerifyIdentityOverlay.tsx | 28 +- shared/commonUtil.ts | 5 + shared/constants.ts | 5 +- types/react-native-dotenv/index.d.ts | 5 + 35 files changed, 2095 insertions(+), 364 deletions(-) delete mode 100644 components/FaceScanner.tsx create mode 100644 components/FaceScanner/FaceCompare.tsx create mode 100644 components/FaceScanner/FaceScanner.tsx create mode 100644 components/FaceScanner/FaceScannerHelper.ts create mode 100644 components/FaceScanner/LivenessDetection.tsx diff --git a/.env b/.env index 81d2e083..289ef854 100644 --- a/.env +++ b/.env @@ -16,6 +16,9 @@ CREDENTIAL_REGISTRY_EDIT=true DEBUG_MODE=false +#Toggle liveness detection +LIVENESS_DETECTION=true + #supported languages( en, fil, ar, hi, kn, ta) APPLICATION_LANGUAGE=en diff --git a/.github/workflows/internal-build.yml b/.github/workflows/internal-build.yml index c94be9cc..f33240dc 100644 --- a/.github/workflows/internal-build.yml +++ b/.github/workflows/internal-build.yml @@ -24,7 +24,7 @@ on: buildName: description: 'Build App For' required: true - default: 'Sprint-x/Collab/release-x.x.x' + default: 'Sprint-x/QA-Inji/Release-x.x.x' type: string mimotoBackendServiceUrl: description: 'Mimoto backend service URL' @@ -66,11 +66,6 @@ on: options: - orange - purple - buildDescription: - description: 'What to test' - required: true - default: 'QA-Triple environment' - type: string allow_env_edit: description: 'Edit ENV' required: true @@ -79,6 +74,14 @@ on: options: - false - true + liveness_detection: + description: 'Detect Liveness' + required: true + default: 'true' + type: choice + options: + - false + - true jobs: set-client-id: @@ -106,8 +109,9 @@ jobs: MIMOTO_HOST: ${{ inputs.mimotoBackendServiceUrl }} ESIGNET_HOST: ${{ inputs.esignetBackendServiceUrl }} APPLICATION_THEME: ${{ inputs.theme }} - BUILD_DESCRIPTION: ${{ inputs.buildDescription }} + BUILD_DESCRIPTION: ${{ inputs.buildName }} ALLOW_ENV_EDIT: ${{ inputs.allow_env_edit }} + LIVENESS_DETECTION: ${{ inputs.liveness_detection }} APP_FLAVOR: ${{ inputs.injiFlavor }} SERVICE_LOCATION: '.' ANDROID_SERVICE_LOCATION: 'android' @@ -132,8 +136,9 @@ jobs: MIMOTO_HOST: ${{ inputs.mimotoBackendServiceUrl }} ESIGNET_HOST: ${{ inputs.esignetBackendServiceUrl }} APPLICATION_THEME: ${{ inputs.theme }} - BUILD_DESCRIPTION: ${{ inputs.buildDescription }} + BUILD_DESCRIPTION: ${{ inputs.buildName }} ALLOW_ENV_EDIT: ${{ inputs.allow_env_edit }} + LIVENESS_DETECTION: ${{ inputs.liveness_detection }} APP_FLAVOR: ${{ inputs.injiFlavor }} SERVICE_LOCATION: '.' ANDROID_SERVICE_LOCATION: 'android' @@ -156,8 +161,9 @@ jobs: MIMOTO_HOST: ${{ inputs.mimotoBackendServiceUrl }} ESIGNET_HOST: ${{ inputs.esignetBackendServiceUrl }} APPLICATION_THEME: ${{ inputs.theme }} - TESTFLIGHT_BETA_APP_DESCRIPTION: ${{ inputs.buildDescription }} + TESTFLIGHT_BETA_APP_DESCRIPTION: ${{ inputs.buildName }} ALLOW_ENV_EDIT: ${{ inputs.allow_env_edit }} + LIVENESS_DETECTION: ${{ inputs.liveness_detection }} TESTFLIGHT_INTERNAL_TESTERS_GROUP: ${{ inputs.internal-testers }} APP_FLAVOR: ${{ inputs.injiFlavor }} SERVICE_LOCATION: '.' diff --git a/.github/workflows/push-triggers.yml b/.github/workflows/push-triggers.yml index 40a2c39e..e82c7086 100644 --- a/.github/workflows/push-triggers.yml +++ b/.github/workflows/push-triggers.yml @@ -21,7 +21,7 @@ jobs: build-android: uses: mosip/kattu/.github/workflows/android-build.yml@master with: - NODE_VERSION: "16.x" + NODE_VERSION: "18.x" KEYSTORE_ALIAS: androidbuildkey KEYSTORE_PASSWORD: 'password' SERVICE_LOCATION: '.' diff --git a/.talismanrc b/.talismanrc index cf5fda2c..18ac4bf0 100644 --- a/.talismanrc +++ b/.talismanrc @@ -2,7 +2,7 @@ fileignoreconfig: - filename: package.json checksum: 5b4fcb5ddc7cc96cc2d1733b544d56ea66e88cdab995a1052fbf9ac0e9c2dc21 - filename: package-lock.json - checksum: a67d97b91ebdc0dd132a6a38835e9ca36449e3acff8a0fdc05d1948061951240 + checksum: 50254c7e3e84d59dceb77cde95ce71cb5d0625cb5ec84971a28b6fc4f95db7f1 - filename: lib/jsonld-signatures/suites/ed255192018/ed25519.ts checksum: 493b6e31144116cb612c24d98b97d8adcad5609c0a52c865a6847ced0a0ddc3a - filename: components/PasscodeVerify.tsx @@ -346,5 +346,5 @@ fileignoreconfig: - filename: ios/Inji.xcworkspace/xcshareddata/swiftpm/Package.resolved checksum: b168940c6b487dc96fd22f564f2e187dae46f4fa5e4a64cf81c4d810b1c1ae78 - filename: ios/Inji.xcodeproj/project.pbxproj - checksum: e86064dc53172114fab4fbad7508889ea47c2ecd7d60ccc4d1f71cf32ea9169c + checksum: 4359976ed4d1ac3206d76b87d3458d070027199c8569ba123436c4b5343aba74 version: "" diff --git a/components/FaceScanner.tsx b/components/FaceScanner.tsx deleted file mode 100644 index 56fbc16d..00000000 --- a/components/FaceScanner.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import React, {useCallback, useContext, useEffect, useRef} from 'react'; -import {Camera} from 'expo-camera'; -import {TouchableOpacity, View} from 'react-native'; -import {Button, Centered, Column, Row, Text} from './ui'; -import {useInterpret, useSelector} from '@xstate/react'; -import {useTranslation} from 'react-i18next'; -import { - FaceScannerEvents, - selectIsCheckingPermission, - selectIsValid, - selectIsPermissionDenied, - selectIsScanning, - selectWhichCamera, - createFaceScannerMachine, - selectIsInvalid, - selectIsCapturing, - selectIsVerifying, -} from '../machines/faceScanner'; -import {GlobalContext} from '../shared/GlobalContext'; -import {selectIsActive} from '../machines/app'; -import {RotatingIcon} from './RotatingIcon'; -import {Theme} from './ui/styleUtils'; -import {SvgImage} from './ui/svg'; -import testIDProps from '../shared/commonUtil'; - -export const FaceScanner: React.FC = props => { - const {t} = useTranslation('FaceScanner'); - const {appService} = useContext(GlobalContext); - const isActive = useSelector(appService, selectIsActive); - - const machine = useRef(createFaceScannerMachine(props.vcImage)); - const service = useInterpret(machine.current); - - const whichCamera = useSelector(service, selectWhichCamera); - - const isPermissionDenied = useSelector(service, selectIsPermissionDenied); - const isValid = useSelector(service, selectIsValid); - const isInvalid = useSelector(service, selectIsInvalid); - const isCheckingPermission = useSelector(service, selectIsCheckingPermission); - const isScanning = useSelector(service, selectIsScanning); - const isCapturing = useSelector(service, selectIsCapturing); - const isVerifying = useSelector(service, selectIsVerifying); - - const setCameraRef = useCallback( - (node: Camera) => { - if (node != null && !isScanning) { - service.send(FaceScannerEvents.READY(node)); - } - }, - [isScanning], - ); - - useEffect(() => { - if (isValid) { - props.onValid(); - } else if (isInvalid) { - props.onInvalid(); - } - }, [isValid, isInvalid]); - - useEffect(() => { - if (isActive) { - service.send(FaceScannerEvents.APP_FOCUSED()); - } - }, [isActive]); - - if (isCheckingPermission) { - return ; - } else if (isPermissionDenied) { - return ( - - - {t('missingPermissionText')} - -