import * as React from 'react'; import { WebView } from 'react-native-webview'; import { CustomError } from '../types'; import { FirebaseOptions } from 'firebase/app'; export interface FirebaseAuthApplicationVerifier { readonly type: string; verify(): Promise; } interface Props extends React.ComponentProps { firebaseConfig?: FirebaseOptions; firebaseVersion?: string; appVerificationDisabledForTesting?: boolean; languageCode?: string; onLoad?: () => any; onError?: () => any; onVerify: (token: string) => any; onFullChallenge?: () => any; invisible?: boolean; verify?: boolean; } function getWebviewSource( firebaseConfig: FirebaseOptions, firebaseVersion?: string, appVerificationDisabledForTesting: boolean = false, languageCode?: string, invisible?: boolean ) { firebaseVersion = firebaseVersion || '8.0.0'; return { baseUrl: `https://${firebaseConfig.authDomain}`, html: ` ${ invisible ? `` : `
` } `, }; } function validateFirebaseConfig(firebaseConfig?: FirebaseOptions) { if (!firebaseConfig) { const err = new Error('Missing firebase web configuration.') as CustomError; err['code'] = 'ERR_FIREBASE_RECAPTCHA_CONFIG'; throw err; } const { authDomain } = firebaseConfig; if (!authDomain) { const err = new Error( 'Missing "authDomain" in firebase web configuration.' ) as CustomError; err['code'] = 'ERR_FIREBASE_RECAPTCHA_CONFIG'; } } export function FirebaseRecaptcha(props: Props) { const { firebaseConfig, firebaseVersion, appVerificationDisabledForTesting, languageCode, onVerify, onLoad, onError, onFullChallenge, invisible, verify, ...otherProps } = props; const webview = React.useRef(null); const [loaded, setLoaded] = React.useState(false); React.useEffect(() => { if (webview.current && loaded && verify) { // @ts-ignore: Object is possibly null webview.current.injectJavaScript(` (function(){ window.dispatchEvent(new MessageEvent('message', {data: { verify: true }})); })(); true; `); } return () => {}; }, [webview, verify, loaded]); validateFirebaseConfig(firebaseConfig); if (!firebaseConfig) { console.error( `FirebaseRecaptcha: Missing firebase web configuration. Please set the "expo.web.config.firebase" field in "app.json" or use the "firebaseConfig" prop.` ); return null; } return ( { const data = JSON.parse(event.nativeEvent.data); switch (data.type) { case 'load': if (onLoad) { setLoaded(true); onLoad(); } break; case 'error': if (onError) { onError(); } break; case 'verify': onVerify(data.token); break; case 'fullChallenge': if (onFullChallenge) { onFullChallenge(); } break; } }} {...otherProps} /> ); }