import React, { Fragment, useRef, useState } from 'react'; import { ActivityIndicator, Platform, StyleSheet, Text, View, } from 'react-native'; import { WebView, type WebViewMessageEvent } from 'react-native-webview'; import { faceVerificationSdkBaseUrl } from '../../lib/config'; type OmnipayProps = { color: string; env: 'dev' | 'prod'; preAuthKey: string; onVerificationSuccessful: (faceAuthToken: string) => void; }; type Status = 'error' | 'loading' | 'success'; export const FaceVerification = ({ color, env, preAuthKey, onVerificationSuccessful, }: OmnipayProps): JSX.Element => { const webviewRef = useRef(null); const [webviewStatus, setWebviewStatus] = useState('loading'); const webHost = getWebHost(); const webUrl = getWebUrl(); const onWebviewMount = ` window.nativeOs = ${Platform.OS}; true; `; function getWebHost() { return faceVerificationSdkBaseUrl[env]; } function getWebUrl() { const themeColor = color.includes('#') ? color.split('#')[1] : color; return `${webHost}auth?theme=${themeColor}&preAuthKey=${preAuthKey}`; } function handleMessage(e: WebViewMessageEvent) { try { if (e.nativeEvent && e.nativeEvent.data) { const data = JSON.parse(e.nativeEvent.data); if (data.type === 'FACE_AUTH_COMPLETE' && data.faceAuthToken) { onVerificationSuccessful(data.faceAuthToken); } } } catch (error) { // Handle parsing errors silently } } if (!preAuthKey) { return Preauth key is required; } if (preAuthKey.length !== 64) { return Invalid preauth key; } if (color.length < 3) { return Invalid color; } if (!['dev', 'prod'].includes(env)) { return Invalid environment; } return ( setWebviewStatus('success')} mediaPlaybackRequiresUserAction={false} allowsInlineMediaPlayback={true} javaScriptEnabled={true} domStorageEnabled={true} allowsFullscreenVideo={true} mediaCapturePermissionGrantType="grant" originWhitelist={['*']} /> {webviewStatus === 'loading' && ( )} ); }; const styles = StyleSheet.create({ hide: { display: 'none', }, full: { flex: 1, width: '100%', height: '100%', }, webview: { flex: 1, width: '100%', height: '100%', }, webviewLoader: { zIndex: 3, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center', flex: 1, width: '100%', height: '100%', position: 'absolute', top: 0, left: 0, }, errorText: { textAlign: 'center', padding: 20, color: '#666', }, });