diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 50a047e6..6db20f7e 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -2,6 +2,9 @@ xmlns:tools="http://schemas.android.com/tools"> - + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 775353ea..0bfdfacb 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -5,6 +5,10 @@ + + + @@ -45,4 +49,4 @@ - \ No newline at end of file + diff --git a/android/app/src/main/java/io/mosip/residentapp/MainActivity.java b/android/app/src/main/java/io/mosip/residentapp/MainActivity.java index ef1e17f8..671862c9 100644 --- a/android/app/src/main/java/io/mosip/residentapp/MainActivity.java +++ b/android/app/src/main/java/io/mosip/residentapp/MainActivity.java @@ -32,6 +32,10 @@ public class MainActivity extends ReactActivity { Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + // required for Android 12 and above + Manifest.permission.BLUETOOTH_SCAN, + Manifest.permission.BLUETOOTH_CONNECT, + Manifest.permission.BLUETOOTH_ADVERTISE }; private static final int REQUEST_CODE_REQUIRED_PERMISSIONS = 1; diff --git a/android/build.gradle b/android/build.gradle index dd920685..00c882f1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -4,7 +4,7 @@ buildscript { ext { buildToolsVersion = "29.0.3" minSdkVersion = 23 - compileSdkVersion = 30 + compileSdkVersion = 31 targetSdkVersion = 30 } repositories { diff --git a/ios/Podfile.lock b/ios/Podfile.lock index bbfc45de..e701b300 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -280,7 +280,7 @@ PODS: - React-Core - react-native-netinfo (7.1.3): - React-Core - - react-native-openid4vp-ble (0.3.11): + - react-native-openid4vp-ble (0.3.12): - CrcSwift (~> 0.0.3) - GzipSwift - React-Core @@ -674,7 +674,7 @@ SPEC CHECKSUMS: React-jsinspector: d4f6973dd474357dbaaf6f52f31ffc713bf3e766 react-native-mmkv-storage: 8ba3c0216a6df283ece11205b442a3e435aec4e5 react-native-netinfo: 42c0965fca99069b92e3f7360ab2d425985e5104 - react-native-openid4vp-ble: 98e3371b181b695a44f446f55d7c25c63fe0aa5f + react-native-openid4vp-ble: 57aa174ee33cadb1846f542722d950cb8f4fdc81 react-native-restart: 45c8dca02491980f2958595333cbccd6877cb57e react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a react-native-safe-area-context: 584dc04881deb49474363f3be89e4ca0e854c057 diff --git a/machines/QrLoginMachine.ts b/machines/QrLoginMachine.ts index 3182c10b..fd2fffee 100644 --- a/machines/QrLoginMachine.ts +++ b/machines/QrLoginMachine.ts @@ -1,11 +1,10 @@ import { ActorRefFrom, assign, - ErrorPlatformEvent, EventFrom, send, - StateFrom, sendParent, + StateFrom, } from 'xstate'; import { createModel } from 'xstate/lib/model'; import { AppServices } from '../shared/GlobalContext'; @@ -14,7 +13,10 @@ import { StoreEvents } from './store'; import { linkTransactionResponse, VC } from '../types/vc'; import { request } from '../shared/request'; import { getJwt } from '../shared/cryptoutil/cryptoUtil'; -import { getPrivateKey } from '../shared/keystore/SecureKeystore'; +import { + getBindingCertificateConstant, + getPrivateKey, +} from '../shared/keystore/SecureKeystore'; import i18n from '../i18n'; const model = createModel( @@ -23,6 +25,7 @@ const model = createModel( selectedVc: {} as VC, linkCode: '', myVcs: [] as string[], + thumbprint: '', linkTransactionResponse: {} as linkTransactionResponse, authFactors: [], authorizeScopes: null, @@ -183,7 +186,7 @@ export const qrLoginMachine = requestConsent: { on: { CONFIRM: { - target: 'sendingConsent', + target: 'loadingThumbprint', }, TOGGLE_CONSENT_CLAIM: { actions: 'setConsentClaims', @@ -195,6 +198,15 @@ export const qrLoginMachine = }, }, }, + loadingThumbprint: { + entry: 'loadThumbprint', + on: { + STORE_RESPONSE: { + actions: 'setThumbprint', + target: 'sendingConsent', + }, + }, + }, sendingConsent: { invoke: { src: 'sendConsent', @@ -238,6 +250,20 @@ export const qrLoginMachine = myVcs: (_context, event) => (event.response || []) as string[], }), + loadThumbprint: send( + (context) => + StoreEvents.GET( + getBindingCertificateConstant( + context.selectedVc.walletBindingResponse?.walletBindingId + ) + ), + { to: (context) => context.serviceRefs.store } + ), + setThumbprint: assign({ + thumbprint: (_context, event) => { + return (event.response || '') as string; + }, + }), resetLinkTransactionId: model.assign({ linkTransactionId: () => '', }), @@ -333,8 +359,7 @@ export const qrLoginMachine = var jwt = await getJwt( privateKey, context.selectedVc.id, - walletBindingResponse?.keyId, - walletBindingResponse?.thumbprint + context.thumbprint ); const response = await request( @@ -366,8 +391,7 @@ export const qrLoginMachine = var jwt = await getJwt( privateKey, context.selectedVc.id, - walletBindingResponse?.keyId, - walletBindingResponse?.thumbprint + context.thumbprint ); const response = await request( diff --git a/machines/QrLoginMachine.typegen.ts b/machines/QrLoginMachine.typegen.ts index 7b0bf787..6bb013c7 100644 --- a/machines/QrLoginMachine.typegen.ts +++ b/machines/QrLoginMachine.typegen.ts @@ -46,6 +46,7 @@ export interface Typegen0 { expandLinkTransResp: 'done.invoke.QrLogin.linkTransaction:invocation[0]'; forwardToParent: 'DISMISS'; loadMyVcs: 'done.invoke.QrLogin.linkTransaction:invocation[0]'; + loadThumbprint: 'CONFIRM'; resetLinkTransactionId: 'GET'; resetSelectedVoluntaryClaims: 'GET'; setClaims: 'done.invoke.QrLogin.linkTransaction:invocation[0]'; @@ -54,14 +55,15 @@ export interface Typegen0 { setMyVcs: 'STORE_RESPONSE'; setScanData: 'GET'; setSelectedVc: 'SELECT_VC'; + setThumbprint: 'STORE_RESPONSE'; setlinkTransactionResponse: 'done.invoke.QrLogin.linkTransaction:invocation[0]'; }; 'eventsCausingDelays': {}; 'eventsCausingGuards': {}; 'eventsCausingServices': { linkTransaction: 'GET'; - sendAuthenticate: 'FACE_VALID'; - sendConsent: 'CONFIRM'; + sendAuthenticate: never; + sendConsent: 'STORE_RESPONSE'; }; 'matchesStates': | 'ShowError' @@ -70,6 +72,7 @@ export interface Typegen0 { | 'invalidIdentity' | 'linkTransaction' | 'loadMyVcs' + | 'loadingThumbprint' | 'requestConsent' | 'sendingAuthenticate' | 'sendingConsent' diff --git a/machines/vc.ts b/machines/vc.ts index 43a07439..7fa059e7 100644 --- a/machines/vc.ts +++ b/machines/vc.ts @@ -241,18 +241,15 @@ export function selectIsRefreshingReceivedVcs(state: State) { } /* - This Methods gets the Wallet's Distinct Binded VCs, which got recently added. + this methods returns all the binded vc's in the wallet. */ export function selectBindedVcs(state: State) { - const distinctBindedVcs = new Set(); return (state.context.myVcs as Array).filter((key) => { - let walletBindingResponse = state.context.vcs[key].walletBindingResponse; - let validVC = + const walletBindingResponse = state.context.vcs[key]?.walletBindingResponse; + return ( !isEmpty(walletBindingResponse) && - !isEmpty(walletBindingResponse?.walletBindingId) && - !distinctBindedVcs.has(walletBindingResponse.walletBindingId); - distinctBindedVcs.add(walletBindingResponse?.walletBindingId); - return validVC; + !isEmpty(walletBindingResponse?.walletBindingId) + ); }); } function isEmpty(object) { diff --git a/machines/vcItem.ts b/machines/vcItem.ts index bc51d034..b8faec18 100644 --- a/machines/vcItem.ts +++ b/machines/vcItem.ts @@ -464,7 +464,10 @@ export const vcItemMachine = onDone: [ { target: 'updatingPrivateKey', - actions: ['setWalletBindingId'], + actions: [ + 'setWalletBindingId', + 'setThumbprintForWalletBindingId', + ], }, ], onError: [ @@ -535,6 +538,21 @@ export const vcItemMachine = to: (context) => context.serviceRefs.vc, } ), + setThumbprintForWalletBindingId: send( + (context) => { + const { walletBindingResponse } = context; + const walletBindingIdKey = getBindingCertificateConstant( + walletBindingResponse.walletBindingId + ); + return StoreEvents.SET( + walletBindingIdKey, + walletBindingResponse.thumbprint + ); + }, + { + to: (context) => context.serviceRefs.store, + } + ), requestVcContext: send( (context) => ({ diff --git a/package-lock.json b/package-lock.json index 24038d2f..d72ea33a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,13 +52,13 @@ "react-native-bluetooth-state-manager": "^1.3.2", "react-native-device-info": "^8.4.8", "react-native-dotenv": "^3.3.1", - "react-native-elements": "^3.4.2", + "react-native-elements": "3.4.2", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "~2.1.0", "react-native-keychain": "^8.0.0", "react-native-location-enabler": "^4.1.0", "react-native-mmkv-storage": "0.8.0", - "react-native-openid4vp-ble": "github:mosip/tuvali#v0.3.11", + "react-native-openid4vp-ble": "github:mosip/tuvali#v0.3.12", "react-native-permissions": "^3.6.0", "react-native-popable": "^0.4.3", "react-native-qrcode-svg": "^6.1.1", @@ -21397,8 +21397,8 @@ } }, "node_modules/react-native-openid4vp-ble": { - "version": "0.3.11", - "resolved": "git+ssh://git@github.com/mosip/tuvali.git#cf22b7869cefda9cbd3908b73b980ae459503338", + "version": "0.3.12", + "resolved": "git+ssh://git@github.com/mosip/tuvali.git#3bb01b85f6955367dc35310735a7e6e22e7360a2", "license": "MIT", "peerDependencies": { "react": "*", @@ -44497,8 +44497,8 @@ "requires": {} }, "react-native-openid4vp-ble": { - "version": "git+ssh://git@github.com/mosip/tuvali.git#cf22b7869cefda9cbd3908b73b980ae459503338", - "from": "react-native-openid4vp-ble@github:mosip/tuvali#v0.3.11", + "version": "git+ssh://git@github.com/mosip/tuvali.git#3bb01b85f6955367dc35310735a7e6e22e7360a2", + "from": "react-native-openid4vp-ble@github:mosip/tuvali#v0.3.12", "requires": {} }, "react-native-permissions": { diff --git a/package.json b/package.json index 1debbd52..bed15984 100644 --- a/package.json +++ b/package.json @@ -57,13 +57,13 @@ "react-native-bluetooth-state-manager": "^1.3.2", "react-native-device-info": "^8.4.8", "react-native-dotenv": "^3.3.1", - "react-native-elements": "^3.4.2", + "react-native-elements": "3.4.2", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "~2.1.0", "react-native-keychain": "^8.0.0", "react-native-location-enabler": "^4.1.0", "react-native-mmkv-storage": "0.8.0", - "react-native-openid4vp-ble": "github:mosip/tuvali#v0.3.11", + "react-native-openid4vp-ble": "github:mosip/tuvali#v0.3.12", "react-native-permissions": "^3.6.0", "react-native-popable": "^0.4.3", "react-native-qrcode-svg": "^6.1.1", diff --git a/patches/react-native-elements+3.4.2.patch b/patches/react-native-elements+3.4.2.patch new file mode 100644 index 00000000..f684a7cb --- /dev/null +++ b/patches/react-native-elements+3.4.2.patch @@ -0,0 +1,26 @@ +diff --git a/node_modules/react-native-elements/dist/tab/Tab.js b/node_modules/react-native-elements/dist/tab/Tab.js +index 1204a46..bcce099 100644 +--- a/node_modules/react-native-elements/dist/tab/Tab.js ++++ b/node_modules/react-native-elements/dist/tab/Tab.js +@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) { + return t; + }; + import React from 'react'; +-import { View, Animated, StyleSheet, } from 'react-native'; ++import { View, Animated, StyleSheet, I18nManager } from 'react-native'; + import Button from '../buttons/Button'; + import { withTheme } from '../config'; + import Color from 'color'; +@@ -69,7 +69,11 @@ const TabContainer = (_a) => { + { + translateX: animation.interpolate({ + inputRange: [0, 1], +- outputRange: [0, WIDTH], ++ /** ++ * The Fix has been raised as PR in the upstream, This patch has to removed once the fix is made in the upstream. ++ * PR : https://github.com/react-native-elements/react-native-elements/pull/3779 ++ */ ++ outputRange: [0, I18nManager.isRTL ? -WIDTH : WIDTH], + }), + }, + ], diff --git a/shared/cryptoutil/cryptoUtil.ts b/shared/cryptoutil/cryptoUtil.ts index 54d750f0..0d5acc5f 100644 --- a/shared/cryptoutil/cryptoUtil.ts +++ b/shared/cryptoutil/cryptoUtil.ts @@ -9,7 +9,6 @@ export function generateKeys(): Promise { export async function getJwt( privateKey: string, individualId: string, - keyId: string, thumbprint: string ) { var token: string = null;