Check if biometry is enrolled

This commit is contained in:
Diego Mello 2020-04-20 14:36:11 -03:00
parent 0f896867d8
commit a79f8335d3
4 changed files with 65 additions and 20 deletions

View File

@ -23,4 +23,6 @@ export default class Server extends Model {
@field('auto_lock') autoLock;
@field('auto_lock_time') autoLockTime;
@field('biometry') biometry;
}

View File

@ -27,7 +27,8 @@ export default appSchema({
{ name: 'version', type: 'string', isOptional: true },
{ name: 'last_local_authenticated_session', type: 'number', isOptional: true },
{ name: 'auto_lock', type: 'boolean', isOptional: true },
{ name: 'auto_lock_time', type: 'number', isOptional: true }
{ name: 'auto_lock_time', type: 'number', isOptional: true },
{ name: 'biometry', type: 'boolean', isOptional: true }
]
})
]

View File

@ -76,12 +76,14 @@ export const localAuthenticate = async(server) => {
}
};
export const supportedAuthenticationLabel = async() => {
const supported = await LocalAuthentication.supportedAuthenticationTypesAsync();
console.log('supportedAuthenticationLabel -> supported', supported);
export const supportedBiometryLabel = async() => {
const enrolled = await LocalAuthentication.isEnrolledAsync();
console.log('supportedAuthenticationLabel -> enrolled', enrolled);
if (!enrolled) {
return null;
}
const supported = await LocalAuthentication.supportedAuthenticationTypesAsync();
if (supported.includes(LocalAuthentication.AuthenticationType.FACIAL_RECOGNITION)) {
return isIOS ? 'FaceID' : 'facial recognition';

View File

@ -5,6 +5,7 @@ import {
} from 'react-native';
import { SafeAreaView } from 'react-navigation';
import { connect } from 'react-redux';
import RNUserDefaults from 'rn-user-defaults';
import I18n from '../i18n';
import { themedHeader } from '../utils/navigation';
@ -16,10 +17,8 @@ import Separator from '../containers/Separator';
import ListItem from '../containers/ListItem';
import { CustomIcon } from '../lib/Icons';
import database from '../lib/database';
import { supportedAuthenticationLabel } from '../utils/localAuthentication';
import { supportedBiometryLabel } from '../utils/localAuthentication';
import { DisclosureImage } from '../containers/DisclosureIndicator';
import EventEmitter from '../utils/events';
import RNUserDefaults from 'rn-user-defaults';
import { PASSCODE_KEY } from '../constants/passcode';
// RNUserDefaults.set(PASSCODE_KEY, '')
@ -96,7 +95,9 @@ class ScreenLockConfigView extends React.Component {
})
static propTypes = {
theme: PropTypes.string
theme: PropTypes.string,
server: PropTypes.string,
navigation: PropTypes.object
}
constructor(props) {
@ -105,7 +106,8 @@ class ScreenLockConfigView extends React.Component {
autoLock: false,
autoLockTime: null,
supported: [],
autoLockLabel: ''
biometry: true,
biometryLabel: null
};
this.init();
}
@ -116,22 +118,27 @@ class ScreenLockConfigView extends React.Component {
const serversCollection = serversDB.collections.get('servers');
try {
this.serverRecord = await serversCollection.find(server);
this.setState({ autoLock: this.serverRecord?.autoLock, autoLockTime: this.serverRecord?.autoLockTime });
this.setState({
autoLock: this.serverRecord?.autoLock,
autoLockTime: this.serverRecord?.autoLockTime || 1800,
biometry: this.serverRecord?.biometry || true
});
} catch (error) {
// TODO: raise error in case server wasn't found and pop?
}
const autoLockLabel = await supportedAuthenticationLabel();
this.setState({ autoLockLabel });
const biometryLabel = await supportedBiometryLabel();
this.setState({ biometryLabel });
}
save = async() => {
const { autoLock, autoLockTime } = this.state;
const { autoLock, autoLockTime, biometry } = this.state;
const serversDB = database.servers;
await serversDB.action(async() => {
await this.serverRecord?.update((record) => {
record.autoLock = autoLock;
record.autoLockTime = autoLockTime;
record.biometry = biometry;
});
});
}
@ -154,6 +161,10 @@ class ScreenLockConfigView extends React.Component {
});
}
toggleBiometry = () => {
this.setState(({ biometry }) => ({ biometry: !biometry }), () => this.save());
}
isSelected = (value) => {
const { autoLockTime } = this.state;
return autoLockTime === value;
@ -194,8 +205,7 @@ class ScreenLockConfigView extends React.Component {
);
}
renderSwitch = () => {
// const { allowCrashReport } = this.props;
renderAutoLockSwitch = () => {
const { autoLock } = this.state;
return (
<Switch
@ -206,6 +216,17 @@ class ScreenLockConfigView extends React.Component {
);
}
renderBiometrySwitch = () => {
const { biometry } = this.state;
return (
<Switch
value={biometry}
trackColor={SWITCH_TRACK_COLOR}
onValueChange={this.toggleBiometry}
/>
);
}
renderAutoLockItems = () => {
const { autoLock, supported } = this.state;
const { theme } = this.props;
@ -226,14 +247,32 @@ class ScreenLockConfigView extends React.Component {
return <DisclosureImage theme={theme} />;
}
renderBiometry = () => {
const { autoLock, biometryLabel } = this.state;
const { theme } = this.props;
if (!autoLock || !biometryLabel) {
return null;
}
return (
<>
<Separator theme={theme} />
<ListItem
title={`Unlock with ${ biometryLabel }`}
right={() => this.renderBiometrySwitch()}
theme={theme}
/>
<Separator theme={theme} />
</>
);
}
render() {
const { autoLock, supported, autoLockLabel } = this.state;
const { autoLock } = this.state;
const { theme } = this.props;
return (
<SafeAreaView
style={[sharedStyles.container, { backgroundColor: themes[theme].auxiliaryBackground }]}
forceInset={{ vertical: 'never' }}
testID='default-browser-view'
>
<StatusBar theme={theme} />
<ScrollView
@ -243,7 +282,7 @@ class ScreenLockConfigView extends React.Component {
<Separator theme={theme} />
<ListItem
title='Unlock with Passcode'
right={() => this.renderSwitch()}
right={() => this.renderAutoLockSwitch()}
theme={theme}
/>
{autoLock
@ -265,6 +304,7 @@ class ScreenLockConfigView extends React.Component {
info={'Note: if you forget the passcode, you\'ll need to delete and reinstall the app.'}
theme={theme}
/>
{this.renderBiometry()}
{this.renderAutoLockItems()}
</ScrollView>
</SafeAreaView>