feat: add consent check to face-matching

This commit is contained in:
Paolo Miguel de Leon
2022-11-15 14:33:10 +08:00
parent d428bfb354
commit 5bcd9e20a7
20 changed files with 140 additions and 114 deletions

View File

@@ -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>
);

View File

@@ -7,7 +7,6 @@ import {
createVcItemMachine,
selectVerifiableCredential,
selectGeneratedOn,
selectTag,
selectId,
vcItemMachine,
selectContext,

View File

@@ -7,7 +7,6 @@ import {
createVcItemMachine,
selectVerifiableCredential,
selectGeneratedOn,
selectTag,
vcItemMachine,
selectContext,
} from '../machines/vcItem';

View File

@@ -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);

View File

@@ -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

View File

@@ -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": {

View File

@@ -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: {

View File

@@ -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';

View File

@@ -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: {

View File

@@ -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'

View File

@@ -195,7 +195,7 @@ export const vcItemMachine =
],
onError: [
{
actions: 'logError',
actions: log((_, event) => (event.data as Error).message),
target: 'idle',
},
],

View File

@@ -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';

View File

@@ -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,

View File

@@ -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')}

View File

@@ -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')}

View File

@@ -16,5 +16,6 @@
"title": "Notice",
"message": "Your {{vcLabel}} was rejected by {{receiver}}"
}
}
},
"consentToPhotoVerification": "I give consent to have my photo taken for authentication"
}

View File

@@ -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

View File

@@ -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)),

View File

@@ -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));
}
}
);

View File

@@ -11,6 +11,7 @@ export interface VC {
lastVerifiedOn: number;
locked: boolean;
reason?: VCSharingReason[];
shouldVerifyPresence?: boolean;
}
export interface VCSharingReason {