From e8e162991fa6352ab1be9cc0e96e530223f4e718 Mon Sep 17 00:00:00 2001 From: Mustafa Buyukcelebi Date: Wed, 19 Dec 2018 22:51:51 +0300 Subject: [PATCH] Added reset pin code feature on settings. Fixed #244 --- .../settingsItem/view/settingsItemView.js | 9 +++ src/providers/steem/auth.js | 45 +++++++++++++ .../pinCode/container/pinCodeContainer.js | 64 +++++++++++++++++-- .../settings/container/settingsContainer.js | 24 +++++-- src/screens/settings/screen/settingsScreen.js | 4 +- 5 files changed, 134 insertions(+), 12 deletions(-) diff --git a/src/components/settingsItem/view/settingsItemView.js b/src/components/settingsItem/view/settingsItemView.js index fabbb874f..4119c35ae 100644 --- a/src/components/settingsItem/view/settingsItemView.js +++ b/src/components/settingsItem/view/settingsItemView.js @@ -61,6 +61,15 @@ class SettingsItemView extends Component { onToggle={e => handleOnChange(e, type, actionType)} /> ); + case 'button': + return ( + handleOnChange(null, type, actionType)} + textStyle={styles.textStyle} + style={styles.textButton} + text={text} + /> + ); default: return ( diff --git a/src/providers/steem/auth.js b/src/providers/steem/auth.js index b3f352162..7cdd0ba39 100644 --- a/src/providers/steem/auth.js +++ b/src/providers/steem/auth.js @@ -8,6 +8,7 @@ import { setPinCode, getPinCode, updateCurrentUsername, + getUserData, } from '../../realm/realm'; import { encryptKey, decryptKey } from '../../utils/crypto'; import steemConnect from './steemConnectAPI'; @@ -201,6 +202,50 @@ export const setUserDataWithPinCode = data => new Promise((resolve, reject) => { }); }); +export const updatePinCode = async (data) => { + let updatedUserData; + + const users = await getUserData(); + if (users.length > 0) { + users.forEach(async (userData) => { + const password = decryptKey(userData.masterKey, data.oldPinCode); + const privateKeys = getPrivateKeys(userData.username, password); + if (userData.authType === 'masterKey') { + updatedUserData = { + username: userData.username, + authType: 'masterKey', + masterKey: encryptKey(password, data.pinCode), + postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode), + activeKey: encryptKey(privateKeys.active.toString(), data.pinCode), + memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode), + }; + } else if (userData.authType === 'steemConnect') { + updatedUserData = { + username: userData.username, + authType: 'steemConnect', + accessToken: encryptKey(data.accessToken, data.pinCode), + masterKey: '', + postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode), + activeKey: encryptKey(privateKeys.active.toString(), data.pinCode), + memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode), + }; + } + + const response = await updateUserData(updatedUserData); + const authData = { + isLoggedIn: true, + currentUsername: userData.username, + }; + + await setAuthStatus(authData); + const encriptedPinCode = encryptKey(data.pinCode, 'pin-code'); + await setPinCode(encriptedPinCode); + + return response; + }); + } +}; + export const getDigitPinCode = async () => decryptKey(await getPinCode(), 'pin-code'); export const verifyPinCode = async (data) => { diff --git a/src/screens/pinCode/container/pinCodeContainer.js b/src/screens/pinCode/container/pinCodeContainer.js index 2c48a1941..83fc115d9 100644 --- a/src/screens/pinCode/container/pinCodeContainer.js +++ b/src/screens/pinCode/container/pinCodeContainer.js @@ -3,7 +3,11 @@ import { Alert } from 'react-native'; import { connect } from 'react-redux'; import { injectIntl } from 'react-intl'; -import { setUserDataWithPinCode, verifyPinCode } from '../../../providers/steem/auth'; +import { + setUserDataWithPinCode, + verifyPinCode, + updatePinCode, +} from '../../../providers/steem/auth'; // Actions & Services import { closePinCodeModal } from '../../../redux/actions/applicationActions'; @@ -18,6 +22,8 @@ class PinCodeContainer extends Component { isExistUser: null, informationText: '', pinCode: null, + isOldPinVerified: false, + oldPinCode: null, }; } @@ -25,9 +31,9 @@ class PinCodeContainer extends Component { // TODO: these text should move to view! componentDidMount() { this._getDataFromStorage().then(() => { - const { intl } = this.props; + const { intl, isReset } = this.props; const { isExistUser } = this.state; - if (isExistUser) { + if (isExistUser || !isReset) { this.setState({ informationText: intl.formatMessage({ id: 'pincode.enter_text', @@ -63,9 +69,53 @@ class PinCodeContainer extends Component { navigateTo, navigation, intl, + isReset, } = this.props; - const { isExistUser, pinCode } = this.state; - if (isExistUser) { + const { + isExistUser, pinCode, isOldPinVerified, oldPinCode, + } = this.state; + + if (isReset) { + const pinData = { + pinCode: pin, + password: currentAccount ? currentAccount.password : '', + username: currentAccount ? currentAccount.name : '', + accessToken, + oldPinCode, + }; + + if (isOldPinVerified) { + updatePinCode(pinData).then((response) => { + const _currentAccount = currentAccount; + _currentAccount.local = response; + + dispatch(updateCurrentAccount({ ..._currentAccount })); + + dispatch(closePinCodeModal()); + if (navigateTo) { + navigation.navigate(navigateTo); + } + resolve(); + }); + } else { + verifyPinCode(pinData) + .then(() => { + this.setState({ isOldPinVerified: true }); + this.setState({ + informationText: intl.formatMessage({ + id: 'pincode.set_new', + }), + pinCode: null, + oldPinCode: pin, + }); + resolve(); + }) + .catch((err) => { + Alert.alert('Warning', err.message); + reject(err); + }); + } + } else if (isExistUser) { // If the user is exist, we are just checking to pin and navigating to home screen const pinData = { pinCode: pin, @@ -104,8 +154,8 @@ class PinCodeContainer extends Component { } else if (pinCode === pin) { const pinData = { pinCode: pin, - password: currentAccount.password, - username: currentAccount.name, + password: currentAccount ? currentAccount.password : '', + username: currentAccount ? currentAccount.name : '', accessToken, }; setUserDataWithPinCode(pinData).then((response) => { diff --git a/src/screens/settings/container/settingsContainer.js b/src/screens/settings/container/settingsContainer.js index baa5309f7..e94476ff6 100644 --- a/src/screens/settings/container/settingsContainer.js +++ b/src/screens/settings/container/settingsContainer.js @@ -20,16 +20,15 @@ import { setCurrency, setApi, isDarkTheme, + openPinCodeModal, } from '../../../redux/actions/applicationActions'; -import { setPushToken } from '../../../providers/esteem/esteem'; -import { getNodes } from '../../../providers/esteem/esteem'; +import { setPushToken, getNodes } from '../../../providers/esteem/esteem'; // Middleware // Constants import { VALUE as CURRENCY_VALUE } from '../../../constants/options/currency'; import { VALUE as LANGUAGE_VALUE } from '../../../constants/options/language'; -import API_VALUE from '../../../constants/options/api'; // Utilities @@ -86,7 +85,7 @@ class SettingsContainer extends Component { }; _handleToggleChanged = (action, actionType) => { - const { dispatch } = this.props; + const { dispatch, setPinCodeState } = this.props; switch (actionType) { case 'notification': @@ -98,7 +97,23 @@ class SettingsContainer extends Component { dispatch(isDarkTheme(action)); setTheme(action); break; + case 'pincode': + // test + dispatch(openPinCodeModal()); + setPinCodeState({ isReset: true }); + break; + default: + break; + } + }; + _handleButtonPress = (action, actionType) => { + const { dispatch, setPinCodeState } = this.props; + switch (actionType) { + case 'pincode': + dispatch(openPinCodeModal()); + setPinCodeState({ isReset: true }); + break; default: break; } @@ -115,6 +130,7 @@ class SettingsContainer extends Component { break; case 'button': + this._handleButtonPress(action, actionType); break; default: diff --git a/src/screens/settings/screen/settingsScreen.js b/src/screens/settings/screen/settingsScreen.js index 7354a940d..30614c536 100644 --- a/src/screens/settings/screen/settingsScreen.js +++ b/src/screens/settings/screen/settingsScreen.js @@ -5,7 +5,6 @@ import { injectIntl } from 'react-intl'; // Constants import LANGUAGE, { VALUE as LANGUAGE_VALUE } from '../../../constants/options/language'; import CURRENCY, { VALUE as CURRENCY_VALUE } from '../../../constants/options/currency'; -import API, { VALUE as API_VALUE } from '../../../constants/options/api'; // Components import { BasicHeader } from '../../../components/basicHeader'; @@ -105,6 +104,9 @@ class SettingsScreen extends Component { text={intl.formatMessage({ id: 'settings.reset', })} + type="button" + actionType="pincode" + handleOnChange={handleOnChange} />