1import React from 'react';
2import { Text, View } from 'react-native';
3import * as LocalAuthentication from 'expo-local-authentication';
4import Button from '../components/Button';
5
6interface State {
7  waiting: boolean;
8  hasHardware?: boolean;
9  isEnrolled?: boolean;
10}
11
12export default class LocalAuthenticationScreen extends React.Component<{}, State> {
13  static navigationOptions = {
14    title: 'LocalAuthentication',
15  };
16
17  readonly state: State = {
18    waiting: false,
19  };
20
21  componentDidMount() {
22    this.checkDevicePossibilities();
23  }
24
25  async checkDevicePossibilities() {
26    const hasHardware = await LocalAuthentication.hasHardwareAsync();
27    const isEnrolled = await LocalAuthentication.isEnrolledAsync();
28
29    this.setState({ hasHardware, isEnrolled });
30  }
31
32  authenticate = async () => {
33    this.setState({ waiting: true });
34    try {
35      const result = await LocalAuthentication.authenticateAsync({
36        promptMessage: 'This message only shows up on iOS',
37        fallbackLabel: '',
38      });
39      if (result.success) {
40        alert('Authenticated!');
41      } else {
42        alert('Failed to authenticate, reason: ' + result.error);
43      }
44    } finally {
45      this.setState({ waiting: false });
46    }
47  }
48
49  checkAuthenticationsTypes = async () => {
50    const result = await LocalAuthentication.supportedAuthenticationTypesAsync();
51    const stringResult = result
52      .map(type => {
53        switch (type) {
54          case LocalAuthentication.AuthenticationType.FINGERPRINT:
55            return 'FINGERPRINT';
56          case LocalAuthentication.AuthenticationType.FACIAL_RECOGNITION:
57            return 'FACIAL_RECOGNITION';
58          default:
59            throw new Error(
60              `Unrecognised authentication type returned: '${type}'`
61            );
62        }
63      })
64      .join(', ');
65    alert(
66      stringResult
67        ? `Available types: ${stringResult}`
68        : 'No available authentication types!'
69    );
70  }
71
72  render() {
73    const { hasHardware, isEnrolled } = this.state;
74
75    return (
76      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
77        <View style={{ paddingBottom: 30 }}>
78          <Text>
79            LocalAuthentication.hasHardwareAsync():
80            <Text style={{ fontWeight: 'bold' }}>{` ${hasHardware}`}</Text>
81          </Text>
82          <Text>
83            LocalAuthentication.isEnrolledAsync():
84            <Text style={{ fontWeight: 'bold' }}>{` ${isEnrolled}`}</Text>
85          </Text>
86        </View>
87        <Button
88          onPress={this.authenticate}
89          title={
90            this.state.waiting
91              ? 'Waiting for authentication... '
92              : 'Authenticate'
93          }
94        />
95        <Button
96          onPress={this.checkAuthenticationsTypes}
97          title="Check authentications types available on the device"
98        />
99      </View>
100    );
101  }
102}
103