Commit 130951cc by Nguyễn Thị Thúy

login by biometry

parent 4aafcc3c
import React, { Component } from 'react';
import {
Alert,
KeyboardAvoidingView,
Platform,
StyleSheet,
Text,
TextInput,
TouchableHighlight,
View,
} from 'react-native';
import SegmentedControlTab from 'react-native-segmented-control-tab';
import * as Keychain from 'react-native-keychain';
const ACCESS_CONTROL_OPTIONS = ['None', 'Passcode', 'Password'];
const ACCESS_CONTROL_OPTIONS_ANDROID = ['None'];
const ACCESS_CONTROL_MAP = [
null,
Keychain.ACCESS_CONTROL.DEVICE_PASSCODE,
Keychain.ACCESS_CONTROL.APPLICATION_PASSWORD,
Keychain.ACCESS_CONTROL.BIOMETRY_CURRENT_SET,
];
const ACCESS_CONTROL_MAP_ANDROID = [
null,
Keychain.ACCESS_CONTROL.BIOMETRY_CURRENT_SET,
];
const SECURITY_LEVEL_OPTIONS = ['Any', 'Software', 'Hardware'];
const SECURITY_LEVEL_MAP = [
Keychain.SECURITY_LEVEL.ANY,
Keychain.SECURITY_LEVEL.SECURE_SOFTWARE,
Keychain.SECURITY_LEVEL.SECURE_HARDWARE,
];
const SECURITY_STORAGE_OPTIONS = ['Best', 'FB', 'AES', 'RSA'];
const SECURITY_STORAGE_MAP = [
null,
Keychain.STORAGE_TYPE.FB,
Keychain.STORAGE_TYPE.AES,
Keychain.STORAGE_TYPE.RSA,
];
export default class KeychainExample extends Component {
state = {
username: '',
password: '',
status: '',
biometryType: null,
accessControl: null,
securityLevel: null,
storage: null,
};
componentDidMount() {
Keychain.getSupportedBiometryType({}).then((biometryType) => {
this.setState({ biometryType });
});
}
async save() {
try {
let start = new Date();
await Keychain.setGenericPassword(
this.state.username,
this.state.password,
{
accessControl: this.state.accessControl,
securityLevel: this.state.securityLevel,
storage: this.state.storageSelection,
}
);
console.log(this.state.accessControl,
this.state.securityLevel,
this.state.storageSelection)
let end = new Date();
this.setState({
username: '',
password: '',
status: `Credentials saved! takes: ${
end.getTime() - start.getTime()
} millis`,
});
} catch (err) {
this.setState({ status: 'Could not save credentials, ' + err });
}
}
async load() {
try {
const options = {
authenticationPrompt: {
title: 'Authentication needed',
subtitle: 'Subtitle',
description: 'Some descriptive text',
cancel: 'Cancel',
},
};
console.log(options)
const credentials = await Keychain.getGenericPassword(options);
if (credentials) {
this.setState({ ...credentials, status: 'Credentials loaded!' });
} else {
this.setState({ status: 'No credentials stored.' });
}
} catch (err) {
this.setState({ status: 'Could not load credentials. ' + err });
}
}
async reset() {
try {
await Keychain.resetGenericPassword();
this.setState({
status: 'Credentials Reset!',
username: '',
password: '',
});
} catch (err) {
this.setState({ status: 'Could not reset credentials, ' + err });
}
}
async getAll() {
try {
const result = await Keychain.getAllGenericPasswordServices();
this.setState({
status: `All keys successfully fetched! Found: ${result.length} keys.`,
});
} catch (err) {
this.setState({ status: 'Could not get all keys. ' + err });
}
}
async ios_specifics() {
try {
const reply = await Keychain.setSharedWebCredentials(
'server',
'username',
'password'
);
console.log(`setSharedWebCredentials: ${JSON.stringify(reply)}`);
} catch (err) {
Alert.alert('setSharedWebCredentials error', err.message);
}
try {
const reply = await Keychain.requestSharedWebCredentials();
console.log(`requestSharedWebCredentials: ${JSON.stringify(reply)}`);
} catch (err) {
Alert.alert('requestSharedWebCredentials error', err.message);
}
}
render() {
const VALUES =
Platform.OS === 'ios'
? ACCESS_CONTROL_OPTIONS
: ACCESS_CONTROL_OPTIONS_ANDROID;
const AC_MAP =
Platform.OS === 'ios' ? ACCESS_CONTROL_MAP : ACCESS_CONTROL_MAP_ANDROID;
const SL_MAP = Platform.OS === 'ios' ? [] : SECURITY_LEVEL_MAP;
const ST_MAP = Platform.OS === 'ios' ? [] : SECURITY_STORAGE_MAP;
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
style={styles.container}
>
<View style={styles.content}>
<Text style={styles.title}>Keychain Example</Text>
<View style={styles.field}>
<Text style={styles.label}>Username</Text>
<TextInput
style={styles.input}
autoCapitalize="none"
value={this.state.username}
onSubmitEditing={() => {
this.passwordTextInput.focus();
}}
onChange={(event) =>
this.setState({ username: event.nativeEvent.text })
}
underlineColorAndroid="transparent"
blurOnSubmit={false}
returnKeyType="next"
/>
</View>
<View style={styles.field}>
<Text style={styles.label}>Password</Text>
<TextInput
style={styles.input}
password={true}
autoCapitalize="none"
value={this.state.password}
ref={(input) => {
this.passwordTextInput = input;
}}
onChange={(event) =>
this.setState({ password: event.nativeEvent.text })
}
underlineColorAndroid="transparent"
/>
</View>
<View style={styles.field}>
<Text style={styles.label}>Access Control</Text>
<SegmentedControlTab
selectedIndex={this.state.selectedIndex}
values={
this.state.biometryType
? [...VALUES, this.state.biometryType]
: VALUES
}
onTabPress={(index) =>
this.setState({
...this.state,
accessControl: AC_MAP[index],
selectedIndex: index,
})
}
/>
</View>
{Platform.OS === 'android' && (
<View style={styles.field}>
<Text style={styles.label}>Security Level</Text>
<SegmentedControlTab
selectedIndex={this.state.selectedSecurityIndex}
values={SECURITY_LEVEL_OPTIONS}
onTabPress={(index) =>
this.setState({
...this.state,
securityLevel: SL_MAP[index],
selectedSecurityIndex: index,
})
}
/>
<Text style={styles.label}>Storage</Text>
<SegmentedControlTab
selectedIndex={this.state.selectedStorageIndex}
values={SECURITY_STORAGE_OPTIONS}
onTabPress={(index) =>
this.setState({
...this.state,
storageSelection: ST_MAP[index],
selectedStorageIndex: index,
})
}
/>
</View>
)}
{!!this.state.status && (
<Text style={styles.status}>{this.state.status}</Text>
)}
<View style={styles.buttons}>
<TouchableHighlight
onPress={() => this.save()}
style={styles.button}
>
<View style={styles.save}>
<Text style={styles.buttonText}>Save</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
onPress={() => this.load()}
style={styles.button}
>
<View style={styles.load}>
<Text style={styles.buttonText}>Load</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
onPress={() => this.reset()}
style={styles.button}
>
<View style={styles.reset}>
<Text style={styles.buttonText}>Reset</Text>
</View>
</TouchableHighlight>
</View>
<View style={[styles.buttons, styles.centerButtons]}>
<TouchableHighlight
onPress={() => this.getAll()}
style={styles.button}
>
<View style={styles.load}>
<Text style={styles.buttonText}>Get Used Keys</Text>
</View>
</TouchableHighlight>
{Platform.OS === 'android' && (
<TouchableHighlight
onPress={async () => {
const level = await Keychain.getSecurityLevel();
Alert.alert('Security Level', level);
}}
style={styles.button}
>
<View style={styles.load}>
<Text style={styles.buttonText}>Get security level</Text>
</View>
</TouchableHighlight>
)}
{Platform.OS === 'ios' && (
<TouchableHighlight
onPress={() => this.ios_specifics()}
style={styles.button}
>
<View style={styles.load}>
<Text style={styles.buttonText}>Test Other APIs</Text>
</View>
</TouchableHighlight>
)}
</View>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#F5FCFF',
},
content: {
marginHorizontal: 20,
},
title: {
fontSize: 28,
fontWeight: '200',
textAlign: 'center',
marginBottom: 20,
},
field: {
marginVertical: 5,
},
label: {
fontWeight: '500',
fontSize: 15,
marginBottom: 5,
},
input: {
color: '#000',
borderWidth: StyleSheet.hairlineWidth,
borderColor: '#ccc',
backgroundColor: 'white',
height: 32,
fontSize: 14,
padding: 8,
},
status: {
color: '#333',
fontSize: 12,
marginTop: 15,
},
biometryType: {
color: '#333',
fontSize: 12,
marginTop: 15,
},
buttons: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 20,
},
button: {
borderRadius: 3,
padding: 2,
overflow: 'hidden',
},
save: {
backgroundColor: '#0c0',
},
load: {
backgroundColor: '#333',
},
reset: {
backgroundColor: '#c00',
},
buttonText: {
color: 'white',
fontSize: 14,
paddingHorizontal: 16,
paddingVertical: 8,
},
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment