Change passcode
This commit is contained in:
parent
28c58ed802
commit
0f896867d8
|
@ -0,0 +1,3 @@
|
||||||
|
export const PASSCODE_KEY = 'kPasscode';
|
||||||
|
|
||||||
|
export const PASSCODE_LENGTH = 6;
|
|
@ -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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
{autoLock
|
||||||
|
? (
|
||||||
|
<>
|
||||||
<Separator theme={theme} />
|
<Separator theme={theme} />
|
||||||
<ListItem
|
<ListItem
|
||||||
title='Change Passcode'
|
title='Change Passcode'
|
||||||
theme={theme}
|
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.'}
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue