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(`Unrecognised authentication type returned: '${type}'`);
60        }
61      })
62      .join(', ');
63    alert(stringResult ? `Available types: ${stringResult}` : 'No available authentication types!');
64  };
65
66  render() {
67    const { hasHardware, isEnrolled } = this.state;
68
69    return (
70      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
71        <View style={{ paddingBottom: 30 }}>
72          <Text>
73            LocalAuthentication.hasHardwareAsync():
74            <Text style={{ fontWeight: 'bold' }}>{` ${hasHardware}`}</Text>
75          </Text>
76          <Text>
77            LocalAuthentication.isEnrolledAsync():
78            <Text style={{ fontWeight: 'bold' }}>{` ${isEnrolled}`}</Text>
79          </Text>
80        </View>
81        <Button
82          style={{ margin: 5 }}
83          onPress={this.authenticate}
84          title={this.state.waiting ? 'Waiting for authentication... ' : 'Authenticate'}
85        />
86        <Button
87          style={{ margin: 5 }}
88          onPress={this.checkAuthenticationsTypes}
89          title="Check available authentications types"
90        />
91      </View>
92    );
93  }
94}
95