diff --git a/app/lib/database/model/Server.js b/app/lib/database/model/Server.js index 568fd2ad4..5ff103fac 100644 --- a/app/lib/database/model/Server.js +++ b/app/lib/database/model/Server.js @@ -23,4 +23,6 @@ export default class Server extends Model { @field('auto_lock') autoLock; @field('auto_lock_time') autoLockTime; + + @field('biometry') biometry; } diff --git a/app/lib/database/schema/servers.js b/app/lib/database/schema/servers.js index e5506fe04..7557f8b1c 100644 --- a/app/lib/database/schema/servers.js +++ b/app/lib/database/schema/servers.js @@ -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 } ] }) ] diff --git a/app/utils/localAuthentication.js b/app/utils/localAuthentication.js index be6f0cda7..f92c4cbc6 100644 --- a/app/utils/localAuthentication.js +++ b/app/utils/localAuthentication.js @@ -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'; diff --git a/app/views/ScreenLockConfigView.js b/app/views/ScreenLockConfigView.js index 7bb3bac76..11bddfae7 100644 --- a/app/views/ScreenLockConfigView.js +++ b/app/views/ScreenLockConfigView.js @@ -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 ( { + const { biometry } = this.state; + return ( + + ); + } + renderAutoLockItems = () => { const { autoLock, supported } = this.state; const { theme } = this.props; @@ -226,14 +247,32 @@ class ScreenLockConfigView extends React.Component { return ; } + renderBiometry = () => { + const { autoLock, biometryLabel } = this.state; + const { theme } = this.props; + if (!autoLock || !biometryLabel) { + return null; + } + return ( + <> + + this.renderBiometrySwitch()} + theme={theme} + /> + + + ); + } + render() { - const { autoLock, supported, autoLockLabel } = this.state; + const { autoLock } = this.state; const { theme } = this.props; return ( 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()}