1import * as LocalAuthentication from 'expo-local-authentication'; 2import React from 'react'; 3import { Text, View } from 'react-native'; 4 5import Button from '../components/Button'; 6import MonoText from '../components/MonoText'; 7 8interface State { 9 waiting: boolean; 10 supportedAuthenticationTypes?: string[]; 11 hasHardware?: boolean; 12 isEnrolled?: boolean; 13} 14 15export default class LocalAuthenticationScreen extends React.Component<object, State> { 16 static navigationOptions = { 17 title: 'LocalAuthentication', 18 }; 19 20 readonly state: State = { 21 waiting: false, 22 }; 23 24 componentDidMount() { 25 this.checkDevicePossibilities(); 26 } 27 28 async checkDevicePossibilities() { 29 const [hasHardware, isEnrolled, supportedAuthenticationTypes] = await Promise.all([ 30 LocalAuthentication.hasHardwareAsync(), 31 LocalAuthentication.isEnrolledAsync(), 32 this.getAuthenticationTypes(), 33 ]); 34 this.setState({ hasHardware, isEnrolled, supportedAuthenticationTypes }); 35 } 36 37 async getAuthenticationTypes() { 38 return (await LocalAuthentication.supportedAuthenticationTypesAsync()).map( 39 type => LocalAuthentication.AuthenticationType[type] 40 ); 41 } 42 43 authenticateWithFallback = () => { 44 this.authenticate(true); 45 }; 46 47 authenticateWithoutFallback = () => { 48 this.authenticate(false); 49 }; 50 51 async authenticate(withFallback: boolean = true) { 52 this.setState({ waiting: true }); 53 try { 54 const result = await LocalAuthentication.authenticateAsync({ 55 promptMessage: 'Authenticate', 56 cancelLabel: 'Cancel label', 57 disableDeviceFallback: !withFallback, 58 }); 59 if (result.success) { 60 alert('Authenticated!'); 61 } else { 62 alert('Failed to authenticate, reason: ' + result.error); 63 } 64 } finally { 65 this.setState({ waiting: false }); 66 } 67 } 68 69 render() { 70 const { waiting, ...capabilities } = this.state; 71 72 return ( 73 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> 74 <View style={{ paddingBottom: 30 }}> 75 <Text>Device capabilities:</Text> 76 <MonoText textStyle={{ fontSize: 14 }}>{JSON.stringify(capabilities, null, 2)}</MonoText> 77 </View> 78 <View style={{ height: 200 }}> 79 {waiting ? ( 80 <Text>Waiting for authentication...</Text> 81 ) : ( 82 <View> 83 <Button 84 style={{ margin: 5 }} 85 onPress={this.authenticateWithFallback} 86 title="Authenticate with device fallback" 87 /> 88 <Button 89 style={{ margin: 5 }} 90 onPress={this.authenticateWithoutFallback} 91 title="Authenticate without device fallback" 92 /> 93 </View> 94 )} 95 </View> 96 </View> 97 ); 98 } 99} 100