2021-02-10 13:02:57 +05:00
|
|
|
import React, {createRef} from 'react';
|
|
|
|
|
import {Clipboard, View} from 'react-native';
|
2020-09-24 17:39:53 +05:00
|
|
|
import QRCode from 'react-native-qrcode-svg';
|
|
|
|
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
2021-02-10 21:57:08 +05:00
|
|
|
|
2021-02-10 13:02:57 +05:00
|
|
|
import {LOGO_BASE64} from '../../assets/images/assets';
|
2020-10-28 11:26:58 +05:00
|
|
|
import {
|
2020-10-28 15:15:35 +05:00
|
|
|
eSendEvent,
|
2020-10-28 11:26:58 +05:00
|
|
|
eSubscribeEvent,
|
|
|
|
|
eUnSubscribeEvent,
|
2021-02-10 13:02:57 +05:00
|
|
|
ToastEvent,
|
2020-10-28 11:26:58 +05:00
|
|
|
} from '../../services/EventManager';
|
2021-02-10 13:02:57 +05:00
|
|
|
import {dWidth} from '../../utils';
|
|
|
|
|
import {db} from '../../utils/DB';
|
|
|
|
|
import {eOpenRecoveryKeyDialog, eOpenResultDialog} from '../../utils/Events';
|
|
|
|
|
import {SIZE} from '../../utils/SizeUtils';
|
2020-11-23 12:32:33 +05:00
|
|
|
import Storage from '../../utils/storage';
|
2021-02-10 13:02:57 +05:00
|
|
|
import {sleep} from '../../utils/TimeUtils';
|
2020-12-28 12:50:02 +05:00
|
|
|
import ActionSheetWrapper from '../ActionSheetComponent/ActionSheetWrapper';
|
2021-02-10 13:02:57 +05:00
|
|
|
import {Button} from '../Button';
|
|
|
|
|
import DialogHeader from '../Dialog/dialog-header';
|
2020-09-24 17:39:53 +05:00
|
|
|
import Seperator from '../Seperator';
|
2021-02-10 13:02:57 +05:00
|
|
|
import {Toast} from '../Toast';
|
2020-11-20 01:23:05 +05:00
|
|
|
import Heading from '../Typography/Heading';
|
|
|
|
|
import Paragraph from '../Typography/Paragraph';
|
2021-02-10 21:57:08 +05:00
|
|
|
|
|
|
|
|
let RNFetchBlob;
|
|
|
|
|
|
2020-09-24 17:39:53 +05:00
|
|
|
class RecoveryKeyDialog extends React.Component {
|
|
|
|
|
constructor(props) {
|
|
|
|
|
super(props);
|
|
|
|
|
this.state = {
|
2020-09-24 23:08:03 +05:00
|
|
|
key: null,
|
2020-11-23 12:32:33 +05:00
|
|
|
visible: false,
|
2020-09-24 17:39:53 +05:00
|
|
|
};
|
|
|
|
|
this.actionSheetRef = createRef();
|
|
|
|
|
this.svg = createRef();
|
2020-10-28 11:26:58 +05:00
|
|
|
this.user;
|
2020-10-28 15:15:35 +05:00
|
|
|
this.signup = false;
|
2021-02-10 13:02:57 +05:00
|
|
|
this.tapCount = 0;
|
2020-09-24 17:39:53 +05:00
|
|
|
}
|
|
|
|
|
|
2020-10-28 15:15:35 +05:00
|
|
|
open = (signup) => {
|
|
|
|
|
if (signup) {
|
|
|
|
|
this.signup = true;
|
|
|
|
|
}
|
2020-11-23 12:32:33 +05:00
|
|
|
this.setState(
|
|
|
|
|
{
|
|
|
|
|
visible: true,
|
|
|
|
|
},
|
|
|
|
|
() => {
|
2020-12-29 11:25:12 +05:00
|
|
|
this.actionSheetRef.current?.setModalVisible(true);
|
2020-11-23 12:32:33 +05:00
|
|
|
},
|
|
|
|
|
);
|
2020-09-24 17:39:53 +05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
close = () => {
|
2021-02-10 13:02:57 +05:00
|
|
|
if (this.tapCount === 0) {
|
|
|
|
|
ToastEvent.show('Tap one more time to confirm.', 'error', 'local');
|
|
|
|
|
this.tapCount++;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.tapCount = 0;
|
2020-12-29 11:25:12 +05:00
|
|
|
this.actionSheetRef.current?.setModalVisible(false);
|
2020-11-23 12:32:33 +05:00
|
|
|
sleep(200).then(() => {
|
|
|
|
|
this.setState({
|
|
|
|
|
visible: false,
|
|
|
|
|
});
|
|
|
|
|
});
|
2020-10-28 15:52:15 +05:00
|
|
|
if (this.signup) {
|
2020-10-28 15:15:35 +05:00
|
|
|
setTimeout(() => {
|
|
|
|
|
eSendEvent(eOpenResultDialog, {
|
|
|
|
|
title: 'Welcome!',
|
2020-12-28 12:50:02 +05:00
|
|
|
paragraph: 'Please verify your email to activate syncing.',
|
|
|
|
|
icon: 'check',
|
2020-10-28 15:15:35 +05:00
|
|
|
button: 'Thank You!',
|
|
|
|
|
});
|
|
|
|
|
}, 500);
|
|
|
|
|
}
|
2020-09-24 17:39:53 +05:00
|
|
|
};
|
|
|
|
|
async componentDidMount() {
|
|
|
|
|
eSubscribeEvent(eOpenRecoveryKeyDialog, this.open);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async componentWillUnmount() {
|
|
|
|
|
eUnSubscribeEvent(eOpenRecoveryKeyDialog, this.open);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-28 11:26:58 +05:00
|
|
|
saveQRCODE = async () => {
|
2021-02-10 21:57:08 +05:00
|
|
|
|
2020-10-28 11:26:58 +05:00
|
|
|
if ((await Storage.requestPermission()) === false) {
|
|
|
|
|
ToastEvent.show('Storage access not granted!', 'error', 'local');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-09-24 17:39:53 +05:00
|
|
|
|
2020-10-28 11:26:58 +05:00
|
|
|
this.svg.current?.toDataURL(async (data) => {
|
|
|
|
|
let path = await Storage.checkAndCreateDir('/');
|
2021-02-10 21:57:08 +05:00
|
|
|
RNFetchBlob = require("rn-fetch-blob");
|
2020-12-16 12:52:00 +05:00
|
|
|
let fileName = 'nn_' + this.user.email + '_recovery_key_qrcode.png';
|
2020-10-28 11:26:58 +05:00
|
|
|
RNFetchBlob.fs.writeFile(path + fileName, data, 'base64').then((res) => {
|
|
|
|
|
RNFetchBlob.fs
|
|
|
|
|
.scanFile([
|
|
|
|
|
{
|
|
|
|
|
path: path + fileName,
|
|
|
|
|
mime: 'image/png',
|
|
|
|
|
},
|
|
|
|
|
])
|
|
|
|
|
.then((r) => {
|
|
|
|
|
ToastEvent.show(
|
|
|
|
|
'Recovery key saved to Gallery as ' + path + fileName,
|
|
|
|
|
'success',
|
|
|
|
|
'local',
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
});
|
2020-09-24 17:39:53 +05:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2020-10-28 11:26:58 +05:00
|
|
|
saveToTextFile = async () => {
|
2021-02-10 21:57:08 +05:00
|
|
|
|
2020-10-28 11:26:58 +05:00
|
|
|
if ((await Storage.requestPermission()) === false) {
|
|
|
|
|
ToastEvent.show('Storage access not granted!', 'error', 'local');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let path = await Storage.checkAndCreateDir('/');
|
2020-12-16 12:52:00 +05:00
|
|
|
let fileName = 'nn_' + this.user.email + '_recovery_key.txt';
|
2021-02-10 21:57:08 +05:00
|
|
|
RNFetchBlob = require("rn-fetch-blob");
|
2020-10-28 11:26:58 +05:00
|
|
|
RNFetchBlob.fs
|
|
|
|
|
.writeFile(path + fileName, this.state.key, 'utf8')
|
|
|
|
|
.then((r) => {
|
|
|
|
|
ToastEvent.show(
|
|
|
|
|
'Recovery key saved as ' + path + fileName,
|
|
|
|
|
'success',
|
|
|
|
|
'local',
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
.catch((e) => {});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onOpen = async () => {
|
2020-12-20 12:48:08 +05:00
|
|
|
let k = await db.user.getEncryptionKey();
|
2020-12-16 14:57:58 +05:00
|
|
|
this.user = await db.user.getUser();
|
2020-11-20 02:43:07 +05:00
|
|
|
|
2020-10-28 11:26:58 +05:00
|
|
|
if (k) {
|
|
|
|
|
this.setState({
|
|
|
|
|
key: k.key,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-09-24 17:39:53 +05:00
|
|
|
render() {
|
|
|
|
|
const {colors} = this.props;
|
2020-11-23 12:32:33 +05:00
|
|
|
if (!this.state.visible) return null;
|
2020-09-24 17:39:53 +05:00
|
|
|
return (
|
2020-12-28 12:50:02 +05:00
|
|
|
<ActionSheetWrapper
|
2020-10-28 15:15:35 +05:00
|
|
|
closeOnTouchBackdrop={false}
|
2020-12-28 12:50:02 +05:00
|
|
|
gestureEnabled={false}
|
2020-10-28 11:26:58 +05:00
|
|
|
onOpen={this.onOpen}
|
2020-12-28 12:50:02 +05:00
|
|
|
fwdRef={this.actionSheetRef}>
|
2020-09-24 17:39:53 +05:00
|
|
|
<View
|
|
|
|
|
style={{
|
2021-02-10 13:02:57 +05:00
|
|
|
width: '100%',
|
2020-09-24 17:39:53 +05:00
|
|
|
backgroundColor: colors.bg,
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
paddingHorizontal: 12,
|
|
|
|
|
borderRadius: 10,
|
|
|
|
|
paddingTop: 10,
|
|
|
|
|
}}>
|
2021-02-10 13:02:57 +05:00
|
|
|
<DialogHeader
|
|
|
|
|
title="Your Data Recovery Key"
|
|
|
|
|
paragraph="If you forget your password, you can recover your
|
|
|
|
|
data and reset your password using your data recovery key."
|
|
|
|
|
/>
|
2020-09-24 23:01:35 +05:00
|
|
|
|
2020-09-24 17:39:53 +05:00
|
|
|
<View
|
|
|
|
|
style={{
|
2020-09-24 23:01:35 +05:00
|
|
|
backgroundColor: colors.nav,
|
2020-09-24 17:39:53 +05:00
|
|
|
borderRadius: 5,
|
2020-09-24 23:01:35 +05:00
|
|
|
padding: 10,
|
|
|
|
|
marginTop: 10,
|
2020-09-24 17:39:53 +05:00
|
|
|
}}>
|
2020-11-20 01:23:05 +05:00
|
|
|
<Paragraph
|
|
|
|
|
color={colors.icon}
|
|
|
|
|
size={SIZE.md}
|
2020-09-24 17:39:53 +05:00
|
|
|
numberOfLines={2}
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
maxWidth: '100%',
|
|
|
|
|
paddingRight: 10,
|
|
|
|
|
}}>
|
|
|
|
|
{this.state.key}
|
2020-11-20 01:23:05 +05:00
|
|
|
</Paragraph>
|
2021-02-10 13:02:57 +05:00
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
onPress={() => {
|
|
|
|
|
Clipboard.setString(this.state.key);
|
|
|
|
|
ToastEvent.show('Copied!', 'success', 'local');
|
|
|
|
|
}}
|
|
|
|
|
icon="content-copy"
|
|
|
|
|
title="Copy to Clipboard"
|
|
|
|
|
width="100%"
|
|
|
|
|
type="gray"
|
|
|
|
|
fontSize={SIZE.md}
|
|
|
|
|
height={50}
|
|
|
|
|
/>
|
2020-09-24 23:01:35 +05:00
|
|
|
</View>
|
|
|
|
|
<Seperator />
|
|
|
|
|
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
alignSelf: 'center',
|
|
|
|
|
marginBottom: 15,
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
width: '100%',
|
2021-02-10 13:02:57 +05:00
|
|
|
justifyContent: 'center',
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
opacity: 0,
|
2020-09-24 23:01:35 +05:00
|
|
|
}}>
|
2020-09-24 23:08:03 +05:00
|
|
|
{this.state.key ? (
|
|
|
|
|
<QRCode
|
|
|
|
|
getRef={this.svg}
|
2021-02-10 13:02:57 +05:00
|
|
|
size={500}
|
2020-09-24 23:08:03 +05:00
|
|
|
value={this.state.key}
|
|
|
|
|
logo={{uri: LOGO_BASE64}}
|
|
|
|
|
logoBorderRadius={10}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
2020-09-24 17:39:53 +05:00
|
|
|
</View>
|
|
|
|
|
|
2021-02-10 13:02:57 +05:00
|
|
|
<Button
|
|
|
|
|
title="Save QR-Code to Gallery"
|
|
|
|
|
onPress={this.saveQRCODE}
|
|
|
|
|
width="100%"
|
|
|
|
|
type="accent"
|
|
|
|
|
fontSize={SIZE.md}
|
|
|
|
|
height={50}
|
|
|
|
|
/>
|
2020-09-24 17:39:53 +05:00
|
|
|
<Seperator />
|
2021-02-10 13:02:57 +05:00
|
|
|
<Button
|
|
|
|
|
onPress={this.saveToTextFile}
|
|
|
|
|
title="Save to Text File"
|
|
|
|
|
width="100%"
|
|
|
|
|
type="accent"
|
|
|
|
|
fontSize={SIZE.md}
|
|
|
|
|
height={50}
|
|
|
|
|
/>
|
2020-10-28 15:15:35 +05:00
|
|
|
<Seperator />
|
|
|
|
|
<Button
|
2021-02-10 13:02:57 +05:00
|
|
|
title="I Have Saved the Key."
|
2020-10-28 15:15:35 +05:00
|
|
|
width="100%"
|
|
|
|
|
height={50}
|
2021-02-10 13:02:57 +05:00
|
|
|
type="error"
|
|
|
|
|
fontSize={SIZE.md}
|
2020-10-28 15:15:35 +05:00
|
|
|
onPress={this.close}
|
|
|
|
|
/>
|
2020-09-24 17:39:53 +05:00
|
|
|
<Toast context="local" />
|
|
|
|
|
</View>
|
2020-12-28 12:50:02 +05:00
|
|
|
</ActionSheetWrapper>
|
2020-09-24 17:39:53 +05:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default RecoveryKeyDialog;
|