Change passcode

This commit is contained in:
Diego Mello 2020-04-20 10:09:19 -03:00
parent 28c58ed802
commit 0f896867d8
6 changed files with 131 additions and 22 deletions

View File

@ -0,0 +1,3 @@
export const PASSCODE_KEY = 'kPasscode';
export const PASSCODE_LENGTH = 6;

View File

@ -228,6 +228,9 @@ const SettingsStack = createStackNavigator({
}, },
ScreenLockConfigView: { ScreenLockConfigView: {
getScreen: () => require('./views/ScreenLockConfigView').default getScreen: () => require('./views/ScreenLockConfigView').default
},
ChangePasscodeView: {
getScreen: () => require('./views/ChangePasscodeView').default
} }
}, { }, {
defaultNavigationOptions: defaultHeader, defaultNavigationOptions: defaultHeader,
@ -324,6 +327,9 @@ const InsideStackModal = createStackNavigator({
CreateDiscussionStack, CreateDiscussionStack,
JitsiMeetView: { JitsiMeetView: {
getScreen: () => require('./views/JitsiMeetView').default getScreen: () => require('./views/JitsiMeetView').default
},
ChangePasscodeViewModal: {
getScreen: () => require('./views/ChangePasscodeView').default
} }
}, },
{ {

View File

@ -5,6 +5,7 @@ import database from '../lib/database';
import { isIOS } from './deviceInfo'; import { isIOS } from './deviceInfo';
import EventEmitter from './events'; import EventEmitter from './events';
import { LOCAL_AUTHENTICATE } from '../views/ScreenLockedView'; import { LOCAL_AUTHENTICATE } from '../views/ScreenLockedView';
import RNBootSplash from 'react-native-bootsplash';
export const saveLastLocalAuthenticationSession = async(server, serverRecord) => { export const saveLastLocalAuthenticationSession = async(server, serverRecord) => {
const serversDB = database.servers; const serversDB = database.servers;
@ -46,12 +47,16 @@ export const localAuthenticate = async(server) => {
// if screen lock is enabled // if screen lock is enabled
if (serverRecord?.autoLock) { if (serverRecord?.autoLock) {
// diff to last authenticated session // diff to last authenticated session
const diffToLastSession = moment().diff(serverRecord?.lastLocalAuthenticatedSession, 'seconds'); const diffToLastSession = moment().diff(serverRecord?.lastLocalAuthenticatedSession, 'seconds');
console.log('localAuthenticate -> diffToLastSession', diffToLastSession); console.log('localAuthenticate -> diffToLastSession', diffToLastSession);
// if last authenticated session is older than configured auto lock time, authentication is required // if last authenticated session is older than configured auto lock time, authentication is required
if (diffToLastSession >= serverRecord?.autoLockTime) { if (diffToLastSession >= serverRecord?.autoLockTime) {
// Make sure splash screen has been hidden
RNBootSplash.hide();
const isEnrolled = await LocalAuthentication.isEnrolledAsync(); const isEnrolled = await LocalAuthentication.isEnrolledAsync();
const isSupported = await LocalAuthentication.supportedAuthenticationTypesAsync(); const isSupported = await LocalAuthentication.supportedAuthenticationTypesAsync();

View File

@ -0,0 +1,52 @@
import React from 'react';
import PropTypes from 'prop-types';
import { SafeAreaView } from 'react-navigation';
import PINCode from '@haskkor/react-native-pincode';
import RNUserDefaults from 'rn-user-defaults';
import I18n from '../i18n';
import { themedHeader } from '../utils/navigation';
import { withTheme } from '../theme';
import { themes } from '../constants/colors';
import sharedStyles from './Styles';
import { PASSCODE_KEY, PASSCODE_LENGTH } from '../constants/passcode';
const ScreenLockConfigView = React.memo(({ navigation, theme }) => {
const savePasscode = async(passcode) => {
await RNUserDefaults.set(PASSCODE_KEY, passcode);
navigation.pop();
};
return (
<SafeAreaView
style={[sharedStyles.container, { backgroundColor: themes[theme].auxiliaryBackground }]}
>
<PINCode
status='choose'
passwordLength={PASSCODE_LENGTH}
customBackSpaceIcon={() => null}
storePin={savePasscode}
/>
</SafeAreaView>
);
});
ScreenLockConfigView.navigationOptions = ({ screenProps, navigation }) => {
const forceSetPasscode = navigation.getParam('forceSetPasscode', false);
if (forceSetPasscode) {
return {
header: null
};
}
return {
title: 'Change Passcode',
...themedHeader(screenProps.theme)
};
};
ScreenLockConfigView.propTypes = {
navigation: PropTypes.object,
theme: PropTypes.string
};
export default withTheme(ScreenLockConfigView);

View File

@ -17,11 +17,17 @@ import ListItem from '../containers/ListItem';
import { CustomIcon } from '../lib/Icons'; import { CustomIcon } from '../lib/Icons';
import database from '../lib/database'; import database from '../lib/database';
import { supportedAuthenticationLabel } from '../utils/localAuthentication'; import { supportedAuthenticationLabel } 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, '')
const DEFAULT_AUTO_LOCK = [ const DEFAULT_AUTO_LOCK = [
{ {
title: 'After 1 minute', title: 'After 1 minute',
value: 15 value: 5
}, },
{ {
title: 'After 5 minutes', title: 'After 5 minutes',
@ -130,8 +136,22 @@ class ScreenLockConfigView extends React.Component {
}); });
} }
setPasscode = async() => {
const { autoLock } = this.state;
const { navigation } = this.props;
if (autoLock) {
const storedPasscode = await RNUserDefaults.get(PASSCODE_KEY);
if (!storedPasscode) {
navigation.navigate('ChangePasscodeView', { forceSetPasscode: true });
}
}
}
autoLock = () => { autoLock = () => {
this.setState(({ autoLock }) => ({ autoLock: !autoLock }), () => this.save()); this.setState(({ autoLock }) => ({ autoLock: !autoLock }), () => {
this.save();
this.setPasscode();
});
} }
isSelected = (value) => { isSelected = (value) => {
@ -143,6 +163,11 @@ class ScreenLockConfigView extends React.Component {
this.setState({ autoLockTime }, () => this.save()); this.setState({ autoLockTime }, () => this.save());
} }
changePasscode = () => {
const { navigation } = this.props;
navigation.navigate('ChangePasscodeView');
}
renderSeparator = () => { renderSeparator = () => {
const { theme } = this.props; const { theme } = this.props;
return <Separator theme={theme} />; return <Separator theme={theme} />;
@ -196,6 +221,11 @@ class ScreenLockConfigView extends React.Component {
); );
} }
renderDisclosure = () => {
const { theme } = this.props;
return <DisclosureImage theme={theme} />;
}
render() { render() {
const { autoLock, supported, autoLockLabel } = this.state; const { autoLock, supported, autoLockLabel } = this.state;
const { theme } = this.props; const { theme } = this.props;
@ -216,11 +246,20 @@ class ScreenLockConfigView extends React.Component {
right={() => this.renderSwitch()} right={() => this.renderSwitch()}
theme={theme} theme={theme}
/> />
<Separator theme={theme} /> {autoLock
<ListItem ? (
title='Change Passcode' <>
theme={theme} <Separator theme={theme} />
/> <ListItem
title='Change Passcode'
theme={theme}
right={this.renderDisclosure}
onPress={this.changePasscode}
/>
</>
)
: null
}
<Separator theme={theme} /> <Separator theme={theme} />
<ItemInfo <ItemInfo
info={'Note: if you forget the passcode, you\'ll need to delete and reinstall the app.'} info={'Note: if you forget the passcode, you\'ll need to delete and reinstall the app.'}

View File

@ -1,22 +1,21 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { import {
View, Text, StyleSheet, TextInput View, StyleSheet
} from 'react-native'; } from 'react-native';
import { connect } from 'react-redux';
import PINCode from '@haskkor/react-native-pincode'; import PINCode from '@haskkor/react-native-pincode';
import Modal from 'react-native-modal'; import Modal from 'react-native-modal';
import useDeepCompareEffect from 'use-deep-compare-effect'; import useDeepCompareEffect from 'use-deep-compare-effect';
import _ from 'lodash'; import _ from 'lodash';
import RNUserDefaults from 'rn-user-defaults';
import { appInit as appInitAction } from '../actions';
import I18n from '../i18n'; import I18n from '../i18n';
import StatusBar from '../containers/StatusBar';
import { withTheme } from '../theme'; import { withTheme } from '../theme';
import { themes } from '../constants/colors'; import { themes } from '../constants/colors';
import EventEmitter from '../utils/events'; import EventEmitter from '../utils/events';
import sharedStyles from './Styles'; import sharedStyles from './Styles';
import { withSplit } from '../split'; import { withSplit } from '../split';
import { PASSCODE_KEY, PASSCODE_LENGTH } from '../constants/passcode';
export const LOCAL_AUTHENTICATE = 'LOCAL_AUTHENTICATE'; export const LOCAL_AUTHENTICATE = 'LOCAL_AUTHENTICATE';
@ -35,7 +34,7 @@ const styles = StyleSheet.create({
}); });
const ScreenLockedView = React.memo(withTheme(({ theme, split }) => { const ScreenLockedView = React.memo(withTheme(({ theme, split }) => {
const [passcode, setPasscode] = useState('');
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [data, setData] = useState({}); const [data, setData] = useState({});
@ -47,18 +46,26 @@ const ScreenLockedView = React.memo(withTheme(({ theme, split }) => {
} }
}, [data]); }, [data]);
const showScreenLock = args => setData(args); const fetchPasscode = async() => {
const storedPin = await RNUserDefaults.get(PASSCODE_KEY);
setPasscode(storedPin);
};
const showScreenLock = (args) => {
setData(args);
fetchPasscode();
};
useEffect(() => { useEffect(() => {
EventEmitter.addEventListener(LOCAL_AUTHENTICATE, showScreenLock); EventEmitter.addEventListener(LOCAL_AUTHENTICATE, showScreenLock);
fetchPasscode();
return () => EventEmitter.removeListener(LOCAL_AUTHENTICATE); return () => EventEmitter.removeListener(LOCAL_AUTHENTICATE);
}, []); }, []);
const onSubmit = () => { const onSubmit = () => {
const { submit } = data; const { submit } = data;
if (submit) { if (submit) {
submit() submit();
} }
setData({}); setData({});
}; };
@ -72,16 +79,13 @@ const ScreenLockedView = React.memo(withTheme(({ theme, split }) => {
> >
<View style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}> <View style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}>
<PINCode <PINCode
status={'enter'} status='enter'
passwordLength={6} passwordLength={PASSCODE_LENGTH}
customBackSpaceIcon={() => null} customBackSpaceIcon={() => null}
// endProcessFunction={console.log}
finishProcess={onSubmit} finishProcess={onSubmit}
// onFail={() => alert('fail')} storedPin={passcode}
storedPin='111111' // maxAttempts={3}
maxAttempts={3}
/> />
{/* <Text onPress={onSubmit}>VAI</Text> */}
</View> </View>
</Modal> </Modal>
); );