mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 05:27:57 -05:00
feat: add consent check to face-matching
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useContext, useEffect, useRef } from 'react';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import { Camera } from 'expo-camera';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Platform, StyleSheet } from 'react-native';
|
||||
import { Button, Centered, Column, Row, Text } from './ui';
|
||||
import { useInterpret, useSelector } from '@xstate/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -110,6 +110,12 @@ export const FaceScanner: React.FC<FaceScannerProps> = (props) => {
|
||||
/>
|
||||
</Row>
|
||||
)}
|
||||
{/* TODO: remove warning when iOS SDK is ready */}
|
||||
{Platform.OS === 'ios' && (
|
||||
<Text size="smaller" color={Theme.Colors.textLabel} align="center">
|
||||
(face-matching in iOS is mocked)
|
||||
</Text>
|
||||
)}
|
||||
</Centered>
|
||||
</Column>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
createVcItemMachine,
|
||||
selectVerifiableCredential,
|
||||
selectGeneratedOn,
|
||||
selectTag,
|
||||
selectId,
|
||||
vcItemMachine,
|
||||
selectContext,
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
createVcItemMachine,
|
||||
selectVerifiableCredential,
|
||||
selectGeneratedOn,
|
||||
selectTag,
|
||||
vcItemMachine,
|
||||
selectContext,
|
||||
} from '../machines/vcItem';
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
createVcItemMachine,
|
||||
selectVerifiableCredential,
|
||||
selectGeneratedOn,
|
||||
selectTag,
|
||||
selectId,
|
||||
vcItemMachine,
|
||||
} from '../machines/vcItem';
|
||||
@@ -27,7 +26,6 @@ export const VidItem: React.FC<VcItemProps> = (props) => {
|
||||
);
|
||||
const service = useInterpret(machine.current);
|
||||
const uin = useSelector(service, selectId);
|
||||
const tag = useSelector(service, selectTag);
|
||||
const verifiableCredential = useSelector(service, selectVerifiableCredential);
|
||||
const generatedOn = useSelector(service, selectGeneratedOn);
|
||||
|
||||
|
||||
@@ -87,8 +87,6 @@ PODS:
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCTRequired (0.64.4)
|
||||
- RCTSystemSetting (1.7.6):
|
||||
- React
|
||||
- RCTTypeSafety (0.64.4):
|
||||
- FBLazyVector (= 0.64.4)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
@@ -406,7 +404,6 @@ DEPENDENCIES:
|
||||
- Permission-LocationWhenInUse (from `../node_modules/react-native-permissions/ios/LocationWhenInUse`)
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTSystemSetting (from `../node_modules/react-native-system-setting`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
@@ -518,8 +515,6 @@ EXTERNAL SOURCES:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/RCTRequired"
|
||||
RCTSystemSetting:
|
||||
:path: "../node_modules/react-native-system-setting"
|
||||
RCTTypeSafety:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
@@ -618,7 +613,7 @@ SPEC CHECKSUMS:
|
||||
EXUpdates: a83e036243b0f6ece53a8c1cb883b6751c88a5f8
|
||||
EXUpdatesInterface: a9814f422d3cd6e7cfd260d13c27786148ece20e
|
||||
FBLazyVector: fa8275d5086566e22a26ddc385ab5772e7f9b1bd
|
||||
FBReactNativeSpec: 7ead992e0bbaf608b93d456361caa6ccf6745df5
|
||||
FBReactNativeSpec: c3dafd68550f3c95f009beee5c20ab07949ec4e4
|
||||
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
|
||||
GoogleInterchangeUtilities: d5bc4d88d5b661ab72f9d70c58d02ca8c27ad1f7
|
||||
GoogleNetworkingUtilities: 3edd3a8161347494f2da60ea0deddc8a472d94cb
|
||||
@@ -632,7 +627,6 @@ SPEC CHECKSUMS:
|
||||
Permission-LocationWhenInUse: 3ba99e45c852763f730eabecec2870c2382b7bd4
|
||||
RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
|
||||
RCTRequired: f85fa00af016059cf88b90b8f8ff9a6af9e4b6c3
|
||||
RCTSystemSetting: 5107b7350d63b3f7b42a1277d07e4e5d9df879be
|
||||
RCTTypeSafety: 5279aaf0fb1ad715cbbbbee32d5c98c72598bc9c
|
||||
React: ff4e89fbcb05461c9533fd4da3c0f44cda6ab618
|
||||
React-callinvoker: 4670ac7842699e4a39b19a08b4ede02573c1e5dd
|
||||
|
||||
@@ -239,7 +239,8 @@
|
||||
"title": "Notice",
|
||||
"message": "Your {{vcLabel}} was rejected by {{receiver}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"consentToPhotoVerification": "I give consent to have my photo taken for authentication"
|
||||
},
|
||||
"VerifyIdentityOverlay": {
|
||||
"status": {
|
||||
|
||||
@@ -240,7 +240,9 @@ export const requestMachine = model.createMachine(
|
||||
verifyingIdentity: {
|
||||
on: {
|
||||
FACE_VALID: {
|
||||
target: 'verifyingVp',
|
||||
target: 'accepting',
|
||||
actions: 'clearShouldVerifyPresence',
|
||||
// target: 'verifyingVp',
|
||||
},
|
||||
FACE_INVALID: {
|
||||
target: 'invalidIdentity',
|
||||
@@ -419,14 +421,14 @@ export const requestMachine = model.createMachine(
|
||||
console.log(
|
||||
getDeviceNameSync(),
|
||||
'<Receiver.Event>',
|
||||
JSON.stringify(event)
|
||||
JSON.stringify(event).slice(0, 100)
|
||||
);
|
||||
}),
|
||||
IdpassSmartshare.handleLogEvents((event) => {
|
||||
console.log(
|
||||
getDeviceNameSync(),
|
||||
'<Receiver.Log>',
|
||||
JSON.stringify(event)
|
||||
JSON.stringify(event).slice(0, 100)
|
||||
);
|
||||
}),
|
||||
];
|
||||
@@ -497,6 +499,13 @@ export const requestMachine = model.createMachine(
|
||||
},
|
||||
{ to: (context) => context.serviceRefs.vc }
|
||||
),
|
||||
|
||||
clearShouldVerifyPresence: assign({
|
||||
incomingVc: (context) => ({
|
||||
...context.incomingVc,
|
||||
shouldVerifyPresence: false,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
|
||||
services: {
|
||||
|
||||
@@ -38,6 +38,7 @@ export interface Typegen0 {
|
||||
delays: never;
|
||||
};
|
||||
'eventsCausingActions': {
|
||||
clearShouldVerifyPresence: 'FACE_VALID';
|
||||
disconnect:
|
||||
| ''
|
||||
| 'CANCEL'
|
||||
@@ -65,6 +66,7 @@ export interface Typegen0 {
|
||||
requestExistingVc: 'VC_RESPONSE';
|
||||
requestReceivedVcs:
|
||||
| 'ACCEPT'
|
||||
| 'FACE_VALID'
|
||||
| 'done.invoke.request.reviewing.verifyingVp:invocation[0]';
|
||||
requestReceiverInfo: 'CONNECTED';
|
||||
sendVcReceived: 'STORE_RESPONSE';
|
||||
@@ -86,7 +88,7 @@ export interface Typegen0 {
|
||||
receiveVc: 'EXCHANGE_DONE';
|
||||
requestBluetooth: 'BLUETOOTH_DISABLED';
|
||||
sendVcResponse: 'CANCEL' | 'REJECT' | 'STORE_RESPONSE';
|
||||
verifyVp: 'FACE_VALID';
|
||||
verifyVp: never;
|
||||
};
|
||||
'eventsCausingGuards': {
|
||||
hasExistingVc: 'VC_RESPONSE';
|
||||
|
||||
@@ -50,6 +50,7 @@ const model = createModel(
|
||||
verificationImage: {} as CameraCapturedPicture,
|
||||
sharingProtocol: 'OFFLINE' as SharingProtocol,
|
||||
scannedQrParams: {} as ConnectionParams,
|
||||
shouldVerifySender: false,
|
||||
},
|
||||
{
|
||||
events: {
|
||||
@@ -57,7 +58,10 @@ const model = createModel(
|
||||
RECEIVE_DEVICE_INFO: (info: DeviceInfo) => ({ info }),
|
||||
SELECT_VC: (vc: VC) => ({ vc }),
|
||||
SCAN: (params: string) => ({ params }),
|
||||
ACCEPT_REQUEST: () => ({}),
|
||||
ACCEPT_REQUEST: (shouldVerifySender: boolean) => ({ shouldVerifySender }),
|
||||
VERIFY_AND_ACCEPT_REQUEST: (shouldVerifySender: boolean) => ({
|
||||
shouldVerifySender,
|
||||
}),
|
||||
VC_ACCEPTED: () => ({}),
|
||||
VC_REJECTED: () => ({}),
|
||||
CANCEL: () => ({}),
|
||||
@@ -73,7 +77,6 @@ const model = createModel(
|
||||
UPDATE_VC_NAME: (vcName: string) => ({ vcName }),
|
||||
STORE_RESPONSE: (response: unknown) => ({ response }),
|
||||
APP_ACTIVE: () => ({}),
|
||||
VERIFY_AND_SELECT_VC: (vc: VC) => ({ vc }),
|
||||
FACE_VALID: () => ({}),
|
||||
FACE_INVALID: () => ({}),
|
||||
RETRY_VERIFICATION: () => ({}),
|
||||
@@ -243,35 +246,34 @@ export const scanMachine = model.createMachine(
|
||||
},
|
||||
},
|
||||
reviewing: {
|
||||
on: {
|
||||
CANCEL: 'findingConnection',
|
||||
DISMISS: 'findingConnection',
|
||||
ACCEPT_REQUEST: '.selectingVc',
|
||||
UPDATE_REASON: {
|
||||
actions: ['setReason'],
|
||||
},
|
||||
},
|
||||
initial: 'idle',
|
||||
initial: 'selectingVc',
|
||||
states: {
|
||||
idle: {
|
||||
on: {
|
||||
ACCEPT_REQUEST: 'selectingVc',
|
||||
DISCONNECT: findingConnectionId,
|
||||
CANCEL: 'cancelling',
|
||||
},
|
||||
},
|
||||
selectingVc: {
|
||||
on: {
|
||||
UPDATE_REASON: {
|
||||
actions: ['setReason'],
|
||||
},
|
||||
DISCONNECT: findingConnectionId,
|
||||
SELECT_VC: {
|
||||
target: 'sendingVc',
|
||||
actions: ['setSelectedVc'],
|
||||
},
|
||||
VERIFY_AND_SELECT_VC: {
|
||||
target: 'verifyingIdentity',
|
||||
actions: ['setSelectedVc'],
|
||||
},
|
||||
CANCEL: 'idle',
|
||||
VERIFY_AND_ACCEPT_REQUEST: [
|
||||
{
|
||||
cond: 'shouldVerifySender',
|
||||
target: 'verifyingIdentity',
|
||||
},
|
||||
{
|
||||
target: 'verifyingIdentity',
|
||||
},
|
||||
],
|
||||
ACCEPT_REQUEST: [
|
||||
{
|
||||
cond: 'shouldVerifySender',
|
||||
actions: 'setShouldVerifyPresence',
|
||||
target: 'sendingVc',
|
||||
},
|
||||
],
|
||||
CANCEL: 'cancelling',
|
||||
},
|
||||
},
|
||||
cancelling: {
|
||||
@@ -315,12 +317,17 @@ export const scanMachine = model.createMachine(
|
||||
DISMISS: 'navigatingToHome',
|
||||
},
|
||||
},
|
||||
rejected: {},
|
||||
rejected: {
|
||||
on: {
|
||||
DISMISS: findingConnectionId,
|
||||
},
|
||||
},
|
||||
navigatingToHome: {},
|
||||
verifyingIdentity: {
|
||||
on: {
|
||||
FACE_VALID: {
|
||||
target: 'creatingVp',
|
||||
target: 'sendingVc',
|
||||
// target: 'creatingVp',
|
||||
},
|
||||
FACE_INVALID: {
|
||||
target: 'invalidIdentity',
|
||||
@@ -435,14 +442,14 @@ export const scanMachine = model.createMachine(
|
||||
console.log(
|
||||
getDeviceNameSync(),
|
||||
'<Sender.Event>',
|
||||
JSON.stringify(event)
|
||||
JSON.stringify(event).slice(0, 100)
|
||||
);
|
||||
}),
|
||||
IdpassSmartshare.handleLogEvents((event) => {
|
||||
console.log(
|
||||
getDeviceNameSync(),
|
||||
'<Sender.Log>',
|
||||
JSON.stringify(event)
|
||||
JSON.stringify(event).slice(0, 100)
|
||||
);
|
||||
}),
|
||||
];
|
||||
@@ -473,6 +480,13 @@ export const scanMachine = model.createMachine(
|
||||
),
|
||||
|
||||
openSettings: () => Linking.openSettings(),
|
||||
|
||||
setShouldVerifyPresence: assign({
|
||||
selectedVc: (context) => ({
|
||||
...context.selectedVc,
|
||||
shouldVerifyPresence: true,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
|
||||
services: {
|
||||
@@ -665,6 +679,8 @@ export const scanMachine = model.createMachine(
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
shouldVerifySender: (_context, event) => event.shouldVerifySender,
|
||||
},
|
||||
|
||||
delays: {
|
||||
|
||||
@@ -55,7 +55,6 @@ export interface Typegen0 {
|
||||
| 'xstate.after(3000)#scan.reviewing.cancelling'
|
||||
| 'xstate.stop';
|
||||
clearScannedQrParams:
|
||||
| 'CANCEL'
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'xstate.after(3000)#scan.reviewing.cancelling'
|
||||
@@ -72,13 +71,11 @@ export interface Typegen0 {
|
||||
logShared: 'VC_ACCEPTED';
|
||||
openSettings: 'LOCATION_REQUEST';
|
||||
registerLoggers:
|
||||
| 'CANCEL'
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'xstate.after(3000)#scan.reviewing.cancelling'
|
||||
| 'xstate.after(CLEAR_DELAY)#clearingConnection';
|
||||
removeLoggers:
|
||||
| 'CANCEL'
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'SCREEN_BLUR'
|
||||
@@ -93,29 +90,35 @@ export interface Typegen0 {
|
||||
setReason: 'UPDATE_REASON';
|
||||
setReceiverInfo: 'EXCHANGE_DONE';
|
||||
setScannedQrParams: 'SCAN';
|
||||
setSelectedVc: 'SELECT_VC' | 'VERIFY_AND_SELECT_VC';
|
||||
setSelectedVc: 'SELECT_VC';
|
||||
setSenderInfo: 'RECEIVE_DEVICE_INFO';
|
||||
setShouldVerifyPresence: 'ACCEPT_REQUEST';
|
||||
};
|
||||
'eventsCausingServices': {
|
||||
checkLocationPermission: 'APP_ACTIVE' | 'LOCATION_ENABLED';
|
||||
checkLocationStatus: 'CANCEL' | 'SCREEN_FOCUS';
|
||||
createVp: 'FACE_VALID';
|
||||
createVp: never;
|
||||
discoverDevice: 'RECEIVE_DEVICE_INFO';
|
||||
exchangeDeviceInfo: 'CONNECTED';
|
||||
monitorConnection: 'SCREEN_BLUR' | 'SCREEN_FOCUS' | 'xstate.init';
|
||||
sendDisconnect: 'CANCEL';
|
||||
sendVc: 'SELECT_VC' | 'done.invoke.scan.reviewing.creatingVp:invocation[0]';
|
||||
sendVc:
|
||||
| 'ACCEPT_REQUEST'
|
||||
| 'FACE_VALID'
|
||||
| 'done.invoke.scan.reviewing.creatingVp:invocation[0]';
|
||||
};
|
||||
'eventsCausingGuards': {
|
||||
isQrOffline: 'SCAN';
|
||||
isQrOnline: 'SCAN';
|
||||
shouldVerifySender: 'ACCEPT_REQUEST' | 'VERIFY_AND_ACCEPT_REQUEST';
|
||||
};
|
||||
'eventsCausingDelays': {
|
||||
CLEAR_DELAY: 'LOCATION_ENABLED';
|
||||
CONNECTION_TIMEOUT:
|
||||
| 'ACCEPT_REQUEST'
|
||||
| 'CONNECTED'
|
||||
| 'FACE_VALID'
|
||||
| 'RECEIVE_DEVICE_INFO'
|
||||
| 'SELECT_VC'
|
||||
| 'done.invoke.scan.reviewing.creatingVp:invocation[0]';
|
||||
};
|
||||
'matchesStates':
|
||||
@@ -141,7 +144,6 @@ export interface Typegen0 {
|
||||
| 'reviewing.accepted'
|
||||
| 'reviewing.cancelling'
|
||||
| 'reviewing.creatingVp'
|
||||
| 'reviewing.idle'
|
||||
| 'reviewing.invalidIdentity'
|
||||
| 'reviewing.navigatingToHome'
|
||||
| 'reviewing.rejected'
|
||||
@@ -163,7 +165,6 @@ export interface Typegen0 {
|
||||
| 'accepted'
|
||||
| 'cancelling'
|
||||
| 'creatingVp'
|
||||
| 'idle'
|
||||
| 'invalidIdentity'
|
||||
| 'navigatingToHome'
|
||||
| 'rejected'
|
||||
|
||||
@@ -195,7 +195,7 @@ export const vcItemMachine =
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
actions: 'logError',
|
||||
actions: log((_, event) => (event.data as Error).message),
|
||||
target: 'idle',
|
||||
},
|
||||
],
|
||||
|
||||
@@ -69,7 +69,7 @@ export interface Typegen0 {
|
||||
verifyCredential: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
|
||||
};
|
||||
'missingImplementations': {
|
||||
actions: 'logError';
|
||||
actions: never;
|
||||
services: never;
|
||||
guards: never;
|
||||
delays: never;
|
||||
@@ -92,7 +92,6 @@ export interface Typegen0 {
|
||||
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
|
||||
logDownloaded: 'CREDENTIAL_DOWNLOADED';
|
||||
logError: 'error.platform.vc-item.verifyingCredential:invocation[0]';
|
||||
logRevoked: 'STORE_RESPONSE';
|
||||
markVcValid: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
|
||||
requestStoredContext: 'GET_VC_RESPONSE' | 'REFRESH';
|
||||
|
||||
@@ -20,7 +20,7 @@ export function useBiometricScreen(props: RootRouteProps) {
|
||||
const [error, setError] = useState('');
|
||||
const [isReEnabling, setReEnabling] = useState(false);
|
||||
const [initAuthBio, updateInitAuthBio] = useState(true);
|
||||
const [bioState, bioSend, bioService] = useMachine(biometricsMachine);
|
||||
const [bioSend, bioService] = useMachine(biometricsMachine);
|
||||
|
||||
const isAuthorized = useSelector(authService, selectAuthorized);
|
||||
const isAvailable = useSelector(bioService, selectIsAvailable);
|
||||
@@ -29,7 +29,6 @@ export function useBiometricScreen(props: RootRouteProps) {
|
||||
const isUnenrolled = useSelector(bioService, selectIsUnenrolled);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('bioState', bioState);
|
||||
if (isAuthorized) {
|
||||
props.navigation.reset({
|
||||
index: 0,
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ReceiveVcScreen: React.FC = () => {
|
||||
<VcDetails vc={controller.incomingVc} />
|
||||
</Column>
|
||||
<Column padding="0 24" margin="32 0 0 0">
|
||||
{controller.isIncomingVp ? (
|
||||
{controller.incomingVc.shouldVerifyPresence ? (
|
||||
<Button
|
||||
type="outline"
|
||||
title={t('acceptRequestAndVerify')}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Dimensions, Platform } from 'react-native';
|
||||
import { Dimensions } from 'react-native';
|
||||
import { Overlay } from 'react-native-elements/dist/overlay/Overlay';
|
||||
import { Button, Column, Text } from '../../components/ui';
|
||||
import { Theme } from '../../components/ui/styleUtils';
|
||||
@@ -47,16 +47,13 @@ export const SelectVcOverlay: React.FC<SelectVcOverlayProps> = (props) => {
|
||||
onPress={controller.onSelect}
|
||||
margin="8 0 0 0"
|
||||
/>
|
||||
{/* TODO: presence verification is not yet available for iOS */}
|
||||
{Platform.OS === 'android' && (
|
||||
<Button
|
||||
type="outline"
|
||||
title={t('verifyAndShare')}
|
||||
disabled={controller.selectedIndex == null}
|
||||
onPress={controller.onVerifyAndSelect}
|
||||
margin="8 0 0 0"
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
type="outline"
|
||||
title={t('verifyAndShare')}
|
||||
disabled={controller.selectedIndex == null}
|
||||
onPress={controller.onVerifyAndSelect}
|
||||
margin="8 0 0 0"
|
||||
/>
|
||||
<Button
|
||||
type="clear"
|
||||
title={t('common:cancel')}
|
||||
|
||||
@@ -16,5 +16,6 @@
|
||||
"title": "Notice",
|
||||
"message": "Your {{vcLabel}} was rejected by {{receiver}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"consentToPhotoVerification": "I give consent to have my photo taken for authentication"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Input } from 'react-native-elements';
|
||||
import { CheckBox, Input } from 'react-native-elements';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { DeviceInfoList } from '../../components/DeviceInfoList';
|
||||
@@ -9,30 +9,12 @@ import { MessageOverlay } from '../../components/MessageOverlay';
|
||||
import { useSendVcScreen } from './SendVcScreenController';
|
||||
import { VerifyIdentityOverlay } from '../VerifyIdentityOverlay';
|
||||
import { VcItem } from '../../components/VcItem';
|
||||
import { useSelectVcOverlay } from './SelectVcOverlayController';
|
||||
import { SingleVcItem } from '../../components/SingleVcItem';
|
||||
import { SelectVcOverlay } from './SelectVcOverlay';
|
||||
|
||||
export const SendVcScreen: React.FC = () => {
|
||||
const { t } = useTranslation('SendVcScreen');
|
||||
const controller = useSendVcScreen();
|
||||
|
||||
const onShare = () => {
|
||||
controller.ACCEPT_REQUEST();
|
||||
controller2.onSelect();
|
||||
};
|
||||
|
||||
const details = {
|
||||
isVisible: controller.isSelectingVc,
|
||||
receiverName: controller.receiverInfo.deviceName,
|
||||
onSelect: controller.SELECT_VC,
|
||||
onCancel: controller.CANCEL,
|
||||
vcKeys: controller.vcKeys,
|
||||
onVerifyAndSelect: controller.VERIFY_AND_SELECT_VC,
|
||||
};
|
||||
|
||||
const controller2 = useSelectVcOverlay(details);
|
||||
|
||||
const reasonLabel = t('reasonForSharing');
|
||||
|
||||
return (
|
||||
@@ -40,6 +22,11 @@ export const SendVcScreen: React.FC = () => {
|
||||
<Column fill backgroundColor={Theme.Colors.lightGreyBackgroundColor}>
|
||||
<Column padding="16 0" scroll>
|
||||
<DeviceInfoList of="receiver" deviceInfo={controller.receiverInfo} />
|
||||
<CheckBox
|
||||
title={t('consentToPhotoVerification')}
|
||||
checked={controller.shouldVerifySender}
|
||||
onPress={controller.TOGGLE_USER_CONSENT}
|
||||
/>
|
||||
<Column padding="24">
|
||||
<Input
|
||||
value={controller.reason ? controller.reason : ''}
|
||||
@@ -55,9 +42,9 @@ export const SendVcScreen: React.FC = () => {
|
||||
key={controller.vcKeys[0]}
|
||||
vcKey={controller.vcKeys[0]}
|
||||
margin="0 2 8 2"
|
||||
onShow={controller2.selectVcItem(0)}
|
||||
onPress={controller.SELECT_VC_ITEM(0)}
|
||||
selectable
|
||||
selected={0 === controller2.selectedIndex}
|
||||
selected={0 === controller.selectedIndex}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -67,9 +54,9 @@ export const SendVcScreen: React.FC = () => {
|
||||
key={vcKey}
|
||||
vcKey={vcKey}
|
||||
margin="0 2 8 2"
|
||||
onPress={controller2.selectVcItem(index)}
|
||||
onPress={controller.SELECT_VC_ITEM(index)}
|
||||
selectable
|
||||
selected={index === controller2.selectedIndex}
|
||||
selected={index === controller.selectedIndex}
|
||||
/>
|
||||
))}
|
||||
</Column>
|
||||
@@ -82,8 +69,15 @@ export const SendVcScreen: React.FC = () => {
|
||||
<Button
|
||||
title={t('acceptRequest', { vcLabel: controller.vcLabel.singular })}
|
||||
margin="12 0 12 0"
|
||||
disabled={controller2.selectedIndex == null}
|
||||
onPress={onShare}
|
||||
disabled={controller.selectedIndex == null}
|
||||
onPress={controller.ACCEPT_REQUEST}
|
||||
/>
|
||||
<Button
|
||||
type="outline"
|
||||
title={t('acceptRequestAndVerify')}
|
||||
margin="12 0 12 0"
|
||||
disabled={controller.selectedIndex == null}
|
||||
onPress={controller.VERIFY_AND_ACCEPT_REQUEST}
|
||||
/>
|
||||
<Button
|
||||
type="clear"
|
||||
@@ -94,15 +88,6 @@ export const SendVcScreen: React.FC = () => {
|
||||
</Column>
|
||||
</Column>
|
||||
|
||||
<SelectVcOverlay
|
||||
isVisible={controller.isSelectingVc}
|
||||
receiverName={controller.receiverInfo.deviceName}
|
||||
onSelect={controller.SELECT_VC}
|
||||
onVerifyAndSelect={controller.VERIFY_AND_SELECT_VC}
|
||||
onCancel={controller.CANCEL}
|
||||
vcKeys={controller.vcKeys}
|
||||
/>
|
||||
|
||||
<VerifyIdentityOverlay
|
||||
isVisible={controller.isVerifyingIdentity}
|
||||
vc={controller.selectedVc}
|
||||
@@ -157,7 +142,7 @@ export const SendVcScreen: React.FC = () => {
|
||||
vcLabel: controller.vcLabel.singular,
|
||||
receiver: controller.receiverInfo.deviceName,
|
||||
})}
|
||||
onShow={controller.DISMISS}
|
||||
onBackdropPress={controller.DISMISS}
|
||||
/>
|
||||
|
||||
<MessageOverlay
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useSelector } from '@xstate/react';
|
||||
import { useContext } from 'react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ActorRefFrom } from 'xstate';
|
||||
import { MessageOverlayProps } from '../../components/MessageOverlay';
|
||||
import {
|
||||
ScanEvents,
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
} from '../../machines/scan';
|
||||
import { selectVcLabel } from '../../machines/settings';
|
||||
import { selectShareableVcs } from '../../machines/vc';
|
||||
import { vcItemMachine } from '../../machines/vcItem';
|
||||
import { GlobalContext } from '../../shared/GlobalContext';
|
||||
import { VC } from '../../types/vc';
|
||||
|
||||
@@ -46,7 +48,21 @@ export function useSendVcScreen() {
|
||||
};
|
||||
}
|
||||
|
||||
const [shouldVerifySender, setShouldVerifySender] = useState(false);
|
||||
const [selectedIndex, setSelectedIndex] = useState<number>(null);
|
||||
const SELECT_VC = (vc: VC) => scanService.send(ScanEvents.SELECT_VC(vc));
|
||||
|
||||
return {
|
||||
selectedIndex,
|
||||
shouldVerifySender,
|
||||
TOGGLE_USER_CONSENT: () => setShouldVerifySender(!shouldVerifySender),
|
||||
SELECT_VC_ITEM:
|
||||
(index: number) => (vcRef: ActorRefFrom<typeof vcItemMachine>) => {
|
||||
setSelectedIndex(index);
|
||||
const vcData = vcRef.getSnapshot().context;
|
||||
SELECT_VC(vcData);
|
||||
},
|
||||
|
||||
status,
|
||||
receiverInfo: useSelector(scanService, selectReceiverInfo),
|
||||
reason: useSelector(scanService, selectReason),
|
||||
@@ -64,11 +80,14 @@ export function useSendVcScreen() {
|
||||
isInvalidIdentity: useSelector(scanService, selectIsInvalidIdentity),
|
||||
isCancelling: useSelector(scanService, selectIsCancelling),
|
||||
|
||||
ACCEPT_REQUEST: () => scanService.send(ScanEvents.ACCEPT_REQUEST()),
|
||||
CANCEL,
|
||||
SELECT_VC: (vc: VC) => scanService.send(ScanEvents.SELECT_VC(vc)),
|
||||
VERIFY_AND_SELECT_VC: (vc: VC) =>
|
||||
scanService.send(ScanEvents.VERIFY_AND_SELECT_VC(vc)),
|
||||
SELECT_VC,
|
||||
ACCEPT_REQUEST: () =>
|
||||
scanService.send(ScanEvents.ACCEPT_REQUEST(shouldVerifySender)),
|
||||
VERIFY_AND_ACCEPT_REQUEST: () =>
|
||||
scanService.send(
|
||||
ScanEvents.VERIFY_AND_ACCEPT_REQUEST(shouldVerifySender)
|
||||
),
|
||||
DISMISS: () => scanService.send(ScanEvents.DISMISS()),
|
||||
UPDATE_REASON: (reason: string) =>
|
||||
scanService.send(ScanEvents.UPDATE_REASON(reason)),
|
||||
|
||||
@@ -19,7 +19,7 @@ export function onlineSubscribe<T extends SmartshareEventType>(
|
||||
return GoogleNearbyMessages.subscribe(
|
||||
(foundMessage) => {
|
||||
if (__DEV__) {
|
||||
console.log('\n[request] MESSAGE_FOUND', foundMessage);
|
||||
console.log('\n[request] MESSAGE_FOUND', foundMessage.slice(0, 100));
|
||||
}
|
||||
const response = SmartshareEvent.fromString<T>(foundMessage);
|
||||
if (response.type === 'disconnect') {
|
||||
@@ -31,7 +31,7 @@ export function onlineSubscribe<T extends SmartshareEventType>(
|
||||
},
|
||||
(lostMessage) => {
|
||||
if (__DEV__) {
|
||||
console.log('\n[request] MESSAGE_LOST', lostMessage);
|
||||
console.log('\n[request] MESSAGE_LOST', lostMessage.slice(0, 100));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface VC {
|
||||
lastVerifiedOn: number;
|
||||
locked: boolean;
|
||||
reason?: VCSharingReason[];
|
||||
shouldVerifyPresence?: boolean;
|
||||
}
|
||||
|
||||
export interface VCSharingReason {
|
||||
|
||||
Reference in New Issue
Block a user