From 598038d8f6c64ebd9829c4f00e3090c78d30f470 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 13:36:03 +0500 Subject: [PATCH 01/18] added encUnlockPin entry in application store --- src/redux/actions/applicationActions.ts | 8 +++++++- src/redux/constants/constants.js | 1 + src/redux/reducers/applicationReducer.ts | 11 ++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/redux/actions/applicationActions.ts b/src/redux/actions/applicationActions.ts index 65effa481..f13fb24ac 100644 --- a/src/redux/actions/applicationActions.ts +++ b/src/redux/actions/applicationActions.ts @@ -31,7 +31,8 @@ import { SET_COLOR_THEME, SET_SETTINGS_MIGRATED, HIDE_POSTS_THUMBNAILS, - SET_TERMS_ACCEPTED + SET_TERMS_ACCEPTED, + SET_ENC_UNLOCK_PIN } from '../constants/constants'; export const login = (payload) => ({ @@ -209,4 +210,9 @@ export const setIsTermsAccepted = (isTermsAccepted:boolean) => ({ type: SET_TERMS_ACCEPTED }) +export const setEncryptedUnlockPin = (encryptedUnlockPin:string) => ({ + payload:encryptedUnlockPin, + type: SET_ENC_UNLOCK_PIN +}) + diff --git a/src/redux/constants/constants.js b/src/redux/constants/constants.js index 74d54ee44..5424ebee0 100644 --- a/src/redux/constants/constants.js +++ b/src/redux/constants/constants.js @@ -36,6 +36,7 @@ export const SET_LAST_APP_VERSION = 'SET_LAST_APP_VERSION'; export const SET_COLOR_THEME = 'SET_COLOR_THEME'; export const SET_SETTINGS_MIGRATED = 'SET_SETTINGS_MIGRATED'; export const SET_TERMS_ACCEPTED = 'SET_TERMS_ACCEPTED'; +export const SET_ENC_UNLOCK_PIN = 'SET_ENC_UNLOCK_PIN'; // Accounts export const ADD_OTHER_ACCOUNT = 'ADD_OTHER_ACCOUNT'; diff --git a/src/redux/reducers/applicationReducer.ts b/src/redux/reducers/applicationReducer.ts index 3b7984dd0..3efe2aacc 100644 --- a/src/redux/reducers/applicationReducer.ts +++ b/src/redux/reducers/applicationReducer.ts @@ -30,6 +30,7 @@ import { SET_SETTINGS_MIGRATED, HIDE_POSTS_THUMBNAILS, SET_TERMS_ACCEPTED, + SET_ENC_UNLOCK_PIN } from '../constants/constants'; interface State { @@ -65,6 +66,7 @@ interface State { pin: string|null; isPinCodeOpen: boolean; isRenderRequired: boolean; + encUnlockPin: string; lastAppVersion:string; settingsMigratedV2: boolean; hidePostsThumbnails: boolean; @@ -104,13 +106,14 @@ const initialState:State = { pin: null, isPinCodeOpen: false, isRenderRequired: false, + encUnlockPin: '', lastAppVersion:'', settingsMigratedV2: false, hidePostsThumbnails: false, isTermsAccepted: false, }; -export default function (state = initialState, action) { +export default function (state = initialState, action):State { switch (action.type) { case LOGIN: return { @@ -283,6 +286,12 @@ export default function (state = initialState, action) { isTermsAccepted:action.payload } + case SET_ENC_UNLOCK_PIN: + return { + ...state, + encUnlockPin:action.payload + } + default: return state; } From b3aff20f5cc8e25247fd0d7dc4f9d2a414f33234 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 14:27:44 +0500 Subject: [PATCH 02/18] moved migration helpers to utils --- .../application/children/migrationHelpers.ts | 83 -------- .../container/applicationContainer.tsx | 2 +- src/utils/migrationHelpers.ts | 179 ++++++++++++++++++ 3 files changed, 180 insertions(+), 84 deletions(-) delete mode 100644 src/screens/application/children/migrationHelpers.ts create mode 100644 src/utils/migrationHelpers.ts diff --git a/src/screens/application/children/migrationHelpers.ts b/src/screens/application/children/migrationHelpers.ts deleted file mode 100644 index 1f3c5774f..000000000 --- a/src/screens/application/children/migrationHelpers.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Appearance } from 'react-native'; - -// Constants -import THEME_OPTIONS from '../../../constants/options/theme'; - -// Services -import { - getSettings, -} from '../../../realm/realm'; - -import { - isDarkTheme, - changeNotificationSettings, - changeAllNotificationSettings, - setApi, - setCurrency, - setLanguage, - setUpvotePercent, - setNsfw, - isDefaultFooter, - isPinCodeOpen, - setColorTheme, - setSettingsMigrated, -} from '../../../redux/actions/applicationActions'; -import { - hideActionModal, - hideProfileModal, - setRcOffer, - toastNotification, -} from '../../../redux/actions/uiAction'; - - -//migrates settings from realm to redux once and do no user realm for settings again; -export const migrateSettings = async (dispatch: any, settingsMigratedV2: boolean) => { - - if (settingsMigratedV2) { - return; - } - - //reset certain properties - dispatch(hideActionModal()); - dispatch(hideProfileModal()); - dispatch(toastNotification('')); - dispatch(setRcOffer(false)); - - - const settings = await getSettings(); - - if (settings) { - const isDarkMode = Appearance.getColorScheme() === 'dark'; - dispatch(isDarkTheme(settings.isDarkTheme !== null ? settings.isDarkTheme : isDarkMode)); - dispatch(setColorTheme(THEME_OPTIONS.findIndex(item => item.value === settings.isDarkTheme))); - await dispatch(isPinCodeOpen(!!settings.isPinCodeOpen)); - if (settings.language !== '') dispatch(setLanguage(settings.language)); - if (settings.server !== '') dispatch(setApi(settings.server)); - if (settings.upvotePercent !== '') { - dispatch(setUpvotePercent(Number(settings.upvotePercent))); - } - if (settings.isDefaultFooter !== '') dispatch(isDefaultFooter(settings.isDefaultFooter)); //TODO: remove as not being used - - - if (settings.nsfw !== '') dispatch(setNsfw(settings.nsfw)); - - dispatch(setCurrency(settings.currency !== '' ? settings.currency : 'usd')); - - if (settings.notification !== '') { - dispatch( - changeNotificationSettings({ - type: 'notification', - action: settings.notification, - }), - ); - - dispatch(changeAllNotificationSettings(settings)); - } - - await dispatch(setSettingsMigrated(true)) - } -} - -export default { - migrateSettings -} \ No newline at end of file diff --git a/src/screens/application/container/applicationContainer.tsx b/src/screens/application/container/applicationContainer.tsx index 8e191b00e..b31cf0a09 100644 --- a/src/screens/application/container/applicationContainer.tsx +++ b/src/screens/application/container/applicationContainer.tsx @@ -89,7 +89,7 @@ import { setMomentLocale } from '../../../utils/time'; import parseAuthUrl from '../../../utils/parseAuthUrl'; import { purgeExpiredCache } from '../../../redux/actions/cacheActions'; import { fetchSubscribedCommunities } from '../../../redux/actions/communitiesAction'; -import MigrationHelpers from '../children/migrationHelpers'; +import MigrationHelpers from '../../../utils/migrationHelpers'; // Workaround let previousAppState = 'background'; diff --git a/src/utils/migrationHelpers.ts b/src/utils/migrationHelpers.ts new file mode 100644 index 000000000..391472653 --- /dev/null +++ b/src/utils/migrationHelpers.ts @@ -0,0 +1,179 @@ +import { Appearance } from 'react-native'; +import Config from 'react-native-config'; + +// Constants +import THEME_OPTIONS from '../constants/options/theme'; +import { getUnreadNotificationCount } from '../providers/ecency/ecency'; +import { getPointsSummary } from '../providers/ecency/ePoint'; +import { migrateToMasterKeyWithAccessToken, refreshSCToken, updatePinCode } from '../providers/hive/auth'; +import { getMutes } from '../providers/hive/dhive'; +import AUTH_TYPE from '../constants/authType'; + +// Services +import { + getSettings, getUserDataWithUsername, +} from '../realm/realm'; +import { updateCurrentAccount } from '../redux/actions/accountAction'; + +import { + isDarkTheme, + changeNotificationSettings, + changeAllNotificationSettings, + setApi, + setCurrency, + setLanguage, + setUpvotePercent, + setNsfw, + isDefaultFooter, + isPinCodeOpen, + setColorTheme, + setSettingsMigrated, + setPinCode, + setEncryptedUnlockPin, +} from '../redux/actions/applicationActions'; +import { fetchSubscribedCommunities } from '../redux/actions/communitiesAction'; +import { + hideActionModal, + hideProfileModal, + setRcOffer, + toastNotification, +} from '../redux/actions/uiAction'; +import { decryptKey, encryptKey } from './crypto'; + + +//migrates settings from realm to redux once and do no user realm for settings again; +export const migrateSettings = async (dispatch: any, settingsMigratedV2: boolean) => { + + if (settingsMigratedV2) { + return; + } + + //reset certain properties + dispatch(hideActionModal()); + dispatch(hideProfileModal()); + dispatch(toastNotification('')); + dispatch(setRcOffer(false)); + + + const settings = await getSettings(); + + if (settings) { + const isDarkMode = Appearance.getColorScheme() === 'dark'; + dispatch(isDarkTheme(settings.isDarkTheme !== null ? settings.isDarkTheme : isDarkMode)); + dispatch(setColorTheme(THEME_OPTIONS.findIndex(item => item.value === settings.isDarkTheme))); + await dispatch(isPinCodeOpen(!!settings.isPinCodeOpen)); + if (settings.language !== '') dispatch(setLanguage(settings.language)); + if (settings.server !== '') dispatch(setApi(settings.server)); + if (settings.upvotePercent !== '') { + dispatch(setUpvotePercent(Number(settings.upvotePercent))); + } + if (settings.isDefaultFooter !== '') dispatch(isDefaultFooter(settings.isDefaultFooter)); //TODO: remove as not being used + + + if (settings.nsfw !== '') dispatch(setNsfw(settings.nsfw)); + + dispatch(setCurrency(settings.currency !== '' ? settings.currency : 'usd')); + + if (settings.notification !== '') { + dispatch( + changeNotificationSettings({ + type: 'notification', + action: settings.notification, + }), + ); + + dispatch(changeAllNotificationSettings(settings)); + } + + await dispatch(setSettingsMigrated(true)) + } +} + + + +//migrates local user data to use default pin encruption instead of user pin encryption +export const migrateUserEncryption = async (dispatch, currentAccount, encUserPin, onFailure) => { + + const oldPinCode = decryptKey(encUserPin, Config.PIN_KEY); + + if (oldPinCode === undefined || oldPinCode === Config.DEFAULT_PIN) { + return; + } + + + try{ + const pinData = { + pinCode: Config.DEFAULT_PIN, + username: currentAccount.username, + oldPinCode, + }; + + const response = updatePinCode(pinData) + + const _currentAccount = currentAccount; + _currentAccount.local = response; + + dispatch( + updateCurrentAccount({ + ..._currentAccount, + }), + ); + + const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY); + dispatch(setPinCode(encryptedPin)); + + } catch(err){ + console.warn('pin update failure: ', err); + } + + + dispatch(setEncryptedUnlockPin(encUserPin)) + + const realmData = getUserDataWithUsername(currentAccount.name) + + let _currentAccount = currentAccount; + _currentAccount.username = _currentAccount.name; + _currentAccount.local = realmData[0]; + + try { + const pinHash = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY); + //migration script for previously mast key based logged in user not having access token + if ( + realmData[0].authType !== AUTH_TYPE.STEEM_CONNECT && + realmData[0].accessToken === '' + ) { + _currentAccount = await migrateToMasterKeyWithAccessToken( + _currentAccount, + realmData[0], + pinHash, + ); + } + + //refresh access token + const encryptedAccessToken = await refreshSCToken(_currentAccount.local, Config.DEFAULT_PIN); + _currentAccount.local.accessToken = encryptedAccessToken; + } catch (error) { + onFailure(error) + } + + //get unread notifications + try { + _currentAccount.unread_activity_count = await getUnreadNotificationCount(); + _currentAccount.pointsSummary = await getPointsSummary(_currentAccount.username); + _currentAccount.mutes = await getMutes(_currentAccount.username); + } catch (err) { + console.warn( + 'Optional user data fetch failed, account can still function without them', + err, + ); + } + + dispatch(updateCurrentAccount({ ..._currentAccount })); + dispatch(fetchSubscribedCommunities(_currentAccount.username)); + +} + +export default { + migrateSettings, + migrateUserEncryption +} From 9e73697842803aa71bcab345d70c5e1d62c7e530 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 14:28:12 +0500 Subject: [PATCH 03/18] added new pin verification method --- ...nCodeContainer.js => pinCodeContainer.tsx} | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) rename src/screens/pinCode/container/{pinCodeContainer.js => pinCodeContainer.tsx} (91%) diff --git a/src/screens/pinCode/container/pinCodeContainer.js b/src/screens/pinCode/container/pinCodeContainer.tsx similarity index 91% rename from src/screens/pinCode/container/pinCodeContainer.js rename to src/screens/pinCode/container/pinCodeContainer.tsx index 794493694..d90aafe05 100644 --- a/src/screens/pinCode/container/pinCodeContainer.js +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -38,8 +38,10 @@ import { updateCurrentAccount, removeOtherAccount } from '../../../redux/actions import { getDigitPinCode, getMutes, getUser } from '../../../providers/hive/dhive'; import { getPointsSummary } from '../../../providers/ecency/ePoint'; + // Utils import { encryptKey, decryptKey } from '../../../utils/crypto'; +import MigrationHelpers from '../../../utils/migrationHelpers'; // Component import PinCodeScreen from '../screen/pinCodeScreen'; @@ -268,6 +270,57 @@ class PinCodeContainer extends Component { }, 300); }; + + + //verifies is the pin entered is right or wrong + _verifyPinCodeNew = async (pin, { shouldUpdateRealm } = {}) => { + try{ + const { + currentAccount, + dispatch, + encUnlockPin, + applicationPinCode, + pinCodeParams: { navigateTo, navigateParams, callback }, + } = this.props; + const { oldPinCode } = this.state; + + let unlockPin = encUnlockPin ? + decryptKey(encUnlockPin, Config.PIN_KEY) : decryptKey(applicationPinCode, Config.PIN_KEY); + + + //check if pins match + if (unlockPin !== pin) { + throw new Error("Invalid pin added"); + } + + //migrate data to default pin if encUnlockPin is not set. + if (encUnlockPin) { + await MigrationHelpers.migrateUserEncryption(dispatch, currentAccount, applicationPinCode, this._onRefreshTokenFailed); + } + + + //on successful code verification run requested operation passed as props + if (callback) { + callback(pin, oldPinCode); + } + + if (navigateTo) { + navigate({ + routeName: navigateTo, + params: navigateParams, + }); + } + + dispatch(closePinCodeModal()); + + return true; + } catch(err){ + throw err + } + } + + + _verifyPinCode = (pin, { shouldUpdateRealm } = {}) => new Promise((resolve, reject) => { const { @@ -471,13 +524,13 @@ class PinCodeContainer extends Component { ); } } else { - await this._verifyPinCode(pin); + await this._verifyPinCodeNew(pin); } return true; } //means this is not reset routine and user do not exist - //only possible option left is user logging int, + //only possible option left is user logging in, //verifyPinCode then and update realm as well. else { await this._verifyPinCode(pin, { shouldUpdateRealm: true }); From 39830593420b939df648db67d9bcaba0e4c9efe7 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 14:30:58 +0500 Subject: [PATCH 04/18] updated new pin check logic --- src/screens/pinCode/container/pinCodeContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index d90aafe05..d633b8bd9 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -294,7 +294,7 @@ class PinCodeContainer extends Component { } //migrate data to default pin if encUnlockPin is not set. - if (encUnlockPin) { + if (!encUnlockPin) { await MigrationHelpers.migrateUserEncryption(dispatch, currentAccount, applicationPinCode, this._onRefreshTokenFailed); } From bfedd01144c18b462b4a2c973d1d4b682f685c0f Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 14:32:53 +0500 Subject: [PATCH 05/18] added missing await --- src/utils/migrationHelpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/migrationHelpers.ts b/src/utils/migrationHelpers.ts index 391472653..aaacab29e 100644 --- a/src/utils/migrationHelpers.ts +++ b/src/utils/migrationHelpers.ts @@ -129,7 +129,7 @@ export const migrateUserEncryption = async (dispatch, currentAccount, encUserPin dispatch(setEncryptedUnlockPin(encUserPin)) - const realmData = getUserDataWithUsername(currentAccount.name) + const realmData = await getUserDataWithUsername(currentAccount.name) let _currentAccount = currentAccount; _currentAccount.username = _currentAccount.name; From 07b050c819bddbdf1891ca91c0b0d19986709b9e Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 14:48:32 +0500 Subject: [PATCH 06/18] refreshing access token without unlocking if encUnlockPin is set --- src/screens/application/container/applicationContainer.tsx | 5 +++-- src/screens/pinCode/container/pinCodeContainer.tsx | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/screens/application/container/applicationContainer.tsx b/src/screens/application/container/applicationContainer.tsx index b31cf0a09..c771b8f00 100644 --- a/src/screens/application/container/applicationContainer.tsx +++ b/src/screens/application/container/applicationContainer.tsx @@ -666,9 +666,9 @@ class ApplicationContainer extends Component { }; _refreshAccessToken = async (currentAccount) => { - const { pinCode, isPinCodeOpen, dispatch, intl } = this.props; + const { pinCode, isPinCodeOpen, encUnlockPin, dispatch, intl } = this.props; - if (isPinCodeOpen) { + if (isPinCodeOpen && !encUnlockPin) { return currentAccount; } @@ -984,6 +984,7 @@ export default connect( isDarkTheme: state.application.isDarkTheme, selectedLanguage: state.application.language, isPinCodeOpen: state.application.isPinCodeOpen, + encUnlockPin: state.application.encUnlockPin, isLogingOut: state.application.isLogingOut, isLoggedIn: state.application.isLoggedIn, //TODO: remove as is not being used in this class isConnected: state.application.isConnected, diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index d633b8bd9..cb9d6dc21 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -23,6 +23,7 @@ import { login, logout, logoutDone, + setEncryptedUnlockPin, setPinCode as savePinCode, } from '../../../redux/actions/applicationActions'; import { @@ -64,6 +65,9 @@ class PinCodeContainer extends Component { // TODO: if check for decide to set to pin or verify to pin page // TODO: these text should move to view! componentDidMount() { + + // this.props.dispatch(setEncryptedUnlockPin(undefined)) + this._getDataFromStorage().then(() => { const { intl } = this.props; const { isOldPinVerified } = this.state; @@ -583,6 +587,7 @@ class PinCodeContainer extends Component { const mapStateToProps = (state) => ({ currentAccount: state.account.currentAccount, applicationPinCode: state.application.pin, + encUnlockPin: state.application.encUnlockPin, otherAccounts: state.account.otherAccounts, pinCodeParams: state.application.pinCodeNavigation, }); From bb2a68d0aaac57e781781180e2ac152a769fe1da Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 16:02:00 +0500 Subject: [PATCH 07/18] updated pin code enabled disable setting response. --- ...ingsContainer.js => settingsContainer.tsx} | 50 +++++-------------- 1 file changed, 13 insertions(+), 37 deletions(-) rename src/screens/settings/container/{settingsContainer.js => settingsContainer.tsx} (91%) diff --git a/src/screens/settings/container/settingsContainer.js b/src/screens/settings/container/settingsContainer.tsx similarity index 91% rename from src/screens/settings/container/settingsContainer.js rename to src/screens/settings/container/settingsContainer.tsx index f958cf8b0..0a47ce948 100644 --- a/src/screens/settings/container/settingsContainer.js +++ b/src/screens/settings/container/settingsContainer.tsx @@ -43,6 +43,7 @@ import { logoutDone, closePinCodeModal, setColorTheme, + setEncryptedUnlockPin, } from '../../../redux/actions/applicationActions'; import { toastNotification } from '../../../redux/actions/uiAction'; import { setPushToken, getNodes } from '../../../providers/ecency/ecency'; @@ -225,7 +226,7 @@ class SettingsContainer extends Component { if (action) { dispatch( openPinCodeModal({ - callback: () => this._setDefaultPinCode(action), + callback: () => this._enableDefaultUnlockPin(action), isReset: true, isOldPinVerified: true, oldPinCode: Config.DEFAULT_PIN, @@ -234,7 +235,7 @@ class SettingsContainer extends Component { } else { dispatch( openPinCodeModal({ - callback: () => this._setDefaultPinCode(action), + callback: () => this._enableDefaultUnlockPin(action), }), ); } @@ -394,7 +395,6 @@ class SettingsContainer extends Component { } dispatch(logoutDone()); dispatch(isPinCodeOpen(false)); - setPinCodeOpen(false); }) .catch((err) => { console.warn('Failed to remove user data', err); @@ -419,45 +419,21 @@ class SettingsContainer extends Component { }, 500); }; - _setDefaultPinCode = (action) => { - const { dispatch, username, currentAccount, pinCode } = this.props; - if (!action) { - const oldPinCode = decryptKey(pinCode, Config.PIN_KEY, this._onDecryptFail); + _enableDefaultUnlockPin = (isEnabled) => { + const { dispatch, encUnlockPin } = this.props; + + dispatch(isPinCodeOpen(isEnabled)); + + if (!isEnabled) { + const oldPinCode = decryptKey(encUnlockPin, Config.PIN_KEY, this._onDecryptFail); if (oldPinCode === undefined) { return; } - const pinData = { - pinCode: Config.DEFAULT_PIN, - username, - oldPinCode, - }; - updatePinCode(pinData) - .then((response) => { - const _currentAccount = currentAccount; - _currentAccount.local = response; - - dispatch( - updateCurrentAccount({ - ..._currentAccount, - }), - ); - - const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY); - dispatch(savePinCode(encryptedPin)); - - setPinCodeOpen(action); - dispatch(isPinCodeOpen(action)); - }) - .catch((err) => { - console.warn('pin update failure: ', err); - this._onDecryptFail(); - }); - } else { - setPinCodeOpen(action); - dispatch(isPinCodeOpen(action)); + const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY); + dispatch(setEncryptedUnlockPin(encryptedPin)); } }; @@ -483,7 +459,7 @@ const mapStateToProps = (state) => ({ isDarkTheme: state.application.isDarkTheme, colorTheme: state.application.colorTheme, isPinCodeOpen: state.application.isPinCodeOpen, - pinCode: state.application.pin, + encUnlockPin: state.application.encUnlockPin, isDefaultFooter: state.application.isDefaultFooter, isLoggedIn: state.application.isLoggedIn, isNotificationSettingsOpen: state.application.isNotificationOpen, From 166016cbdf02d6ff8ca54b6cc3079d9bd9721c0b Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 16:23:20 +0500 Subject: [PATCH 08/18] added support for resetting unlock pin --- .../pinCode/container/pinCodeContainer.tsx | 110 +++++++++--------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index cb9d6dc21..400ee2ae4 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -120,12 +120,15 @@ class PinCodeContainer extends Component { } }; + + _resetPinCode = (pin) => new Promise((resolve, reject) => { const { currentAccount, dispatch, pinCodeParams: { navigateTo, navigateParams, accessToken, callback }, + encUnlockPin, intl, } = this.props; const { isOldPinVerified, oldPinCode, newPinCode } = this.state; @@ -142,24 +145,20 @@ class PinCodeContainer extends Component { if (isOldPinVerified) { //if newPin already exist and pin is a valid pin, compare and set new pin if (pin !== undefined && pin === newPinCode) { - this._updatePinCodeRealm(pinData).then((status) => { - if (!status) { - resolve(); - return; - } - this._savePinCode(pin); - if (callback) { - callback(pin, oldPinCode); - } - dispatch(closePinCodeModal()); - if (navigateTo) { - navigate({ - routeName: navigateTo, - params: navigateParams, - }); - } - resolve(); - }); + + this._savePinCode(pin); + if (callback) { + callback(pin, oldPinCode); + } + dispatch(closePinCodeModal()); + + if (navigateTo) { + navigate({ + routeName: navigateTo, + params: navigateParams, + }); + } + resolve(); } // if newPin code exists and above case failed, that means pins did not match @@ -190,33 +189,40 @@ class PinCodeContainer extends Component { // if old pin code is not yet verified attempt to verify code else { - verifyPinCode(pinData) - .then(() => { - this.setState({ isOldPinVerified: true }); - this.setState({ - informationText: intl.formatMessage({ - id: 'pincode.set_new', - }), - newPinCode: null, - oldPinCode: pin, - }); - resolve(); - }) - .catch((err) => { - console.warn('Failed to verify pin code', err); - Alert.alert( - intl.formatMessage({ - id: 'alert.warning', - }), - intl.formatMessage({ - id: err.message, - }), - ); - reject(err); - }); + + let unlockPin = decryptKey(encUnlockPin, Config.PIN_KEY) + + //check if pins match + if (unlockPin !== pin) { + const err = new Error("Invalid pin added"); + console.warn('Failed to verify pin code', err); + Alert.alert( + intl.formatMessage({ + id: 'alert.warning', + }), + intl.formatMessage({ + id: err.message, + }), + ); + reject(err); + } + + + this.setState({ isOldPinVerified: true }); + this.setState({ + informationText: intl.formatMessage({ + id: 'pincode.set_new', + }), + newPinCode: null, + oldPinCode: pin, + }); + resolve(); + } }); + + _setFirstPinCode = (pin) => new Promise((resolve) => { const { @@ -278,7 +284,7 @@ class PinCodeContainer extends Component { //verifies is the pin entered is right or wrong _verifyPinCodeNew = async (pin, { shouldUpdateRealm } = {}) => { - try{ + try { const { currentAccount, dispatch, @@ -287,27 +293,27 @@ class PinCodeContainer extends Component { pinCodeParams: { navigateTo, navigateParams, callback }, } = this.props; const { oldPinCode } = this.state; - + let unlockPin = encUnlockPin ? decryptKey(encUnlockPin, Config.PIN_KEY) : decryptKey(applicationPinCode, Config.PIN_KEY); - - + + //check if pins match if (unlockPin !== pin) { throw new Error("Invalid pin added"); } - + //migrate data to default pin if encUnlockPin is not set. if (!encUnlockPin) { await MigrationHelpers.migrateUserEncryption(dispatch, currentAccount, applicationPinCode, this._onRefreshTokenFailed); } - - + + //on successful code verification run requested operation passed as props if (callback) { callback(pin, oldPinCode); } - + if (navigateTo) { navigate({ routeName: navigateTo, @@ -318,7 +324,7 @@ class PinCodeContainer extends Component { dispatch(closePinCodeModal()); return true; - } catch(err){ + } catch (err) { throw err } } @@ -414,7 +420,7 @@ class PinCodeContainer extends Component { _savePinCode = (pin) => { const { dispatch } = this.props; const encryptedPin = encryptKey(pin, Config.PIN_KEY); - dispatch(savePinCode(encryptedPin)); + dispatch(setEncryptedUnlockPin(encryptedPin)); }; _forgotPinCode = async () => { From d08bb0c5fe591c59ad5c13d5e0208d9f7fd0b330 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 17:28:06 +0500 Subject: [PATCH 09/18] updated auth/login routines to encrypt keys using default pin code --- src/providers/hive/auth.js | 51 ++++++++----------- src/screens/login/container/loginContainer.js | 7 +-- src/screens/steem-connect/hiveSigner.js | 2 +- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/providers/hive/auth.js b/src/providers/hive/auth.js index e78b3cd20..812792827 100644 --- a/src/providers/hive/auth.js +++ b/src/providers/hive/auth.js @@ -25,7 +25,7 @@ import { getSCAccessToken, getUnreadNotificationCount } from '../ecency/ecency'; import AUTH_TYPE from '../../constants/authType'; import { makeHsCode } from '../../utils/hive-signer-helper'; -export const login = async (username, password, isPinCodeOpen) => { +export const login = async (username, password) => { let loginFlag = false; let avatar = ''; let authType = ''; @@ -98,19 +98,15 @@ export const login = async (username, password, isPinCodeOpen) => { accessToken: '', }; - if (isPinCodeOpen) { - account.local = userData; - } else { - const resData = { - pinCode: Config.DEFAULT_PIN, - password, - accessToken: get(scTokens, 'access_token', ''), - }; - const updatedUserData = await getUpdatedUserData(userData, resData); + const resData = { + pinCode: Config.DEFAULT_PIN, + password, + accessToken: get(scTokens, 'access_token', ''), + }; + const updatedUserData = await getUpdatedUserData(userData, resData); - account.local = updatedUserData; - account.local.avatar = avatar; - } + account.local = updatedUserData; + account.local.avatar = avatar; const authData = { isLoggedIn: true, @@ -130,7 +126,7 @@ export const login = async (username, password, isPinCodeOpen) => { return Promise.reject(new Error('auth.invalid_credentials')); }; -export const loginWithSC2 = async (code, isPinCodeOpen) => { +export const loginWithSC2 = async (code) => { const scTokens = await getSCAccessToken(code); await hsApi.setAccessToken(get(scTokens, 'access_token', '')); const scAccount = await hsApi.me(); @@ -168,18 +164,14 @@ export const loginWithSC2 = async (code, isPinCodeOpen) => { }; const isUserLoggedIn = await isLoggedInUser(account.name); - if (isPinCodeOpen) { - account.local = userData; - } else { - const resData = { - pinCode: Config.DEFAULT_PIN, - accessToken: get(scTokens, 'access_token', ''), - }; - const updatedUserData = await getUpdatedUserData(userData, resData); + const resData = { + pinCode: Config.DEFAULT_PIN, + accessToken: get(scTokens, 'access_token', ''), + }; + const updatedUserData = await getUpdatedUserData(userData, resData); - account.local = updatedUserData; - account.local.avatar = avatar; - } + account.local = updatedUserData; + account.local.avatar = avatar; if (isUserLoggedIn) { reject(new Error('auth.already_logged')); @@ -306,12 +298,13 @@ export const verifyPinCode = async (data) => { // This is migration for new pin structure, it will remove v2.2 if (!pinHash) { try { - if (get(userData, 'authType', '') === AUTH_TYPE.STEEM_CONNECT) { - decryptKey(get(userData, 'accessToken'), get(data, 'pinCode')); + //if decrypt fails, means key is invalid + if (userData.accessToken === AUTH_TYPE.STEEM_CONNECT) { + decryptKey(userData.accessToken, data.pinCode); } else { - decryptKey(userData.masterKey, get(data, 'pinCode')); + decryptKey(userData.masterKey, data.pinCode); } - await setPinCode(get(data, 'pinCode')); + await setPinCode(data.pinCode); } catch (error) { return Promise.reject(new Error('Invalid pin code, please check and try again')); } diff --git a/src/screens/login/container/loginContainer.js b/src/screens/login/container/loginContainer.js index 800b88d82..fc94cdff2 100644 --- a/src/screens/login/container/loginContainer.js +++ b/src/screens/login/container/loginContainer.js @@ -60,7 +60,7 @@ class LoginContainer extends PureComponent { this.setState({ isLoading: true }); - login(username, password, isPinCodeOpen) + login(username, password) .then((result) => { if (result) { const persistAccountData = persistAccountGenerator(result); @@ -75,11 +75,12 @@ class LoginContainer extends PureComponent { userActivity(20); setExistUser(true); this._setPushToken(result.name); + const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY); + dispatch(setPinCode(encryptedPin)); + if (isPinCodeOpen) { dispatch(openPinCodeModal({ navigateTo: ROUTES.DRAWER.MAIN })); } else { - const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY); - dispatch(setPinCode(encryptedPin)); navigation.navigate({ routeName: ROUTES.DRAWER.MAIN, }); diff --git a/src/screens/steem-connect/hiveSigner.js b/src/screens/steem-connect/hiveSigner.js index dafa35304..f2eb90793 100644 --- a/src/screens/steem-connect/hiveSigner.js +++ b/src/screens/steem-connect/hiveSigner.js @@ -40,7 +40,7 @@ class HiveSigner extends PureComponent { if (!isLoading) { this.setState({ isLoading: true }); handleOnModalClose(); - loginWithSC2(code[1], isPinCodeOpen) + loginWithSC2(code[1]) .then((result) => { if (result) { const persistAccountData = persistAccountGenerator(result); From d05f06f8c7d4a29aa0554a056ed9271e522c6c59 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 17:38:10 +0500 Subject: [PATCH 10/18] simplified verifyPinCode routine --- .../pinCode/container/pinCodeContainer.tsx | 135 ++---------------- 1 file changed, 9 insertions(+), 126 deletions(-) diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index 400ee2ae4..a46d21ac4 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -282,10 +282,11 @@ class PinCodeContainer extends Component { - //verifies is the pin entered is right or wrong - _verifyPinCodeNew = async (pin, { shouldUpdateRealm } = {}) => { + //verifies is the pin entered is right or wrong, also migrates to newer locking method + _verifyPinCode = async (pin) => { try { const { + intl, currentAccount, dispatch, encUnlockPin, @@ -300,7 +301,9 @@ class PinCodeContainer extends Component { //check if pins match if (unlockPin !== pin) { - throw new Error("Invalid pin added"); + throw new Error(intl.formatMessage({ + id: 'alert.invalid_pincode', + }),); } //migrate data to default pin if encUnlockPin is not set. @@ -329,94 +332,6 @@ class PinCodeContainer extends Component { } } - - - _verifyPinCode = (pin, { shouldUpdateRealm } = {}) => - new Promise((resolve, reject) => { - const { - currentAccount, - dispatch, - pinCodeParams: { navigateTo, navigateParams, accessToken, callback }, - } = this.props; - const { oldPinCode } = this.state; - - // If the user is exist, we are just checking to pin and navigating to feed screen - const pinData = { - pinCode: pin, - password: currentAccount ? currentAccount.password : '', - username: currentAccount ? currentAccount.name : '', - accessToken, - }; - verifyPinCode(pinData) - .then(() => { - this._savePinCode(pin); - getUserDataWithUsername(currentAccount.name).then(async (realmData) => { - if (shouldUpdateRealm) { - this._updatePinCodeRealm(pinData).then(() => { - dispatch(closePinCodeModal()); - }); - } else { - let _currentAccount = currentAccount; - _currentAccount.username = _currentAccount.name; - [_currentAccount.local] = realmData; - - try { - const pinHash = encryptKey(pin, Config.PIN_KEY); - //migration script for previously mast key based logged in user not having access token - if ( - realmData[0].authType !== AUTH_TYPE.STEEM_CONNECT && - realmData[0].accessToken === '' - ) { - _currentAccount = await migrateToMasterKeyWithAccessToken( - _currentAccount, - realmData[0], - pinHash, - ); - } - - //refresh access token - const encryptedAccessToken = await refreshSCToken(_currentAccount.local, pin); - _currentAccount.local.accessToken = encryptedAccessToken; - } catch (error) { - this._onRefreshTokenFailed(error); - } - - //get unread notifications - try { - _currentAccount.unread_activity_count = await getUnreadNotificationCount(); - _currentAccount.pointsSummary = await getPointsSummary(_currentAccount.username); - _currentAccount.mutes = await getMutes(_currentAccount.username); - } catch (err) { - console.warn( - 'Optional user data fetch failed, account can still function without them', - err, - ); - } - - dispatch(updateCurrentAccount({ ..._currentAccount })); - dispatch(fetchSubscribedCommunities(_currentAccount.username)); - dispatch(closePinCodeModal()); - } - - //on successful code verification run requested operation passed as props - if (callback) { - callback(pin, oldPinCode); - } - if (navigateTo) { - navigate({ - routeName: navigateTo, - params: navigateParams, - }); - } - resolve(); - }); - }) - .catch((err) => { - console.warn('code verification for login failed: ', err); - reject(err); - }); - }); - _savePinCode = (pin) => { const { dispatch } = this.props; const encryptedPin = encryptKey(pin, Config.PIN_KEY); @@ -439,7 +354,6 @@ class PinCodeContainer extends Component { dispatch(logoutDone()); dispatch(closePinCodeModal()); dispatch(isPinCodeOpen(false)); - setPinCodeOpen(false); }) .catch((err) => { console.warn('Failed to remove user data', err); @@ -505,47 +419,16 @@ class PinCodeContainer extends Component { const { isExistUser } = this.state; try { - const realmData = await getUserDataWithUsername(currentAccount.name); - const userData = realmData[0]; // check if reset routine is triggered by user, reroute code to reset hanlder if (isReset) { await this._resetPinCode(pin); - return true; + } else { + await this._verifyPinCode(pin); } - //user is logged in and is not reset routine... - if (isExistUser) { - if (!userData.accessToken && !userData.masterKey && applicationPinCode) { - const verifiedPin = decryptKey(applicationPinCode, Config.PIN_KEY, this._onDecryptFail); - if (verifiedPin === undefined) { - return true; - } - if (verifiedPin === pin) { - await this._setFirstPinCode(pin); - } else { - Alert.alert( - intl.formatMessage({ - id: 'alert.warning', - }), - intl.formatMessage({ - id: 'alert.invalid_pincode', - }), - ); - } - } else { - await this._verifyPinCodeNew(pin); - } - return true; - } + return true - //means this is not reset routine and user do not exist - //only possible option left is user logging in, - //verifyPinCode then and update realm as well. - else { - await this._verifyPinCode(pin, { shouldUpdateRealm: true }); - return true; - } } catch (error) { return this._handleFailedAttempt(error); } From b76ad6b543de7211fb2741b984b1c422f4d86eae Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 17:38:30 +0500 Subject: [PATCH 11/18] fixed bug with setting new pin old pin check --- src/screens/pinCode/container/pinCodeContainer.tsx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index a46d21ac4..5962c70e8 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -194,17 +194,9 @@ class PinCodeContainer extends Component { //check if pins match if (unlockPin !== pin) { - const err = new Error("Invalid pin added"); - console.warn('Failed to verify pin code', err); - Alert.alert( - intl.formatMessage({ - id: 'alert.warning', - }), - intl.formatMessage({ - id: err.message, - }), - ); + const err = new Error('alert.invalid_pincode'); reject(err); + return; } From a271b30d00f0e132bda1c4ef0720f6d56d240905 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 17:45:04 +0500 Subject: [PATCH 12/18] code clean up --- src/redux/reducers/applicationReducer.ts | 4 +- .../pinCode/container/pinCodeContainer.tsx | 119 ++++-------------- 2 files changed, 29 insertions(+), 94 deletions(-) diff --git a/src/redux/reducers/applicationReducer.ts b/src/redux/reducers/applicationReducer.ts index 3efe2aacc..03dda02d5 100644 --- a/src/redux/reducers/applicationReducer.ts +++ b/src/redux/reducers/applicationReducer.ts @@ -63,10 +63,10 @@ interface State { }, upvotePercent: number; nsfw: string; - pin: string|null; + pin: string|null; //encrypted pin used for encrypting sensitive user data isPinCodeOpen: boolean; isRenderRequired: boolean; - encUnlockPin: string; + encUnlockPin: string; //ecryped pin used for user defined lock screen pass code lastAppVersion:string; settingsMigratedV2: boolean; hidePostsThumbnails: boolean; diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index 5962c70e8..46b46e018 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -5,17 +5,11 @@ import { injectIntl } from 'react-intl'; import Config from 'react-native-config'; import get from 'lodash/get'; -//Contstants -import AUTH_TYPE from '../../../constants/authType'; // Actions & Services import { navigate } from '../../../navigation/service'; import { - setUserDataWithPinCode, - verifyPinCode, updatePinCode, - migrateToMasterKeyWithAccessToken, - refreshSCToken, } from '../../../providers/hive/auth'; import { closePinCodeModal, @@ -24,21 +18,15 @@ import { logout, logoutDone, setEncryptedUnlockPin, - setPinCode as savePinCode, } from '../../../redux/actions/applicationActions'; import { getExistUser, setExistUser, - getUserDataWithUsername, removeAllUserData, removePinCode, setAuthStatus, - setPinCodeOpen, } from '../../../realm/realm'; import { updateCurrentAccount, removeOtherAccount } from '../../../redux/actions/accountAction'; -import { getDigitPinCode, getMutes, getUser } from '../../../providers/hive/dhive'; -import { getPointsSummary } from '../../../providers/ecency/ePoint'; - // Utils import { encryptKey, decryptKey } from '../../../utils/crypto'; @@ -46,8 +34,7 @@ import MigrationHelpers from '../../../utils/migrationHelpers'; // Component import PinCodeScreen from '../screen/pinCodeScreen'; -import { getUnreadNotificationCount } from '../../../providers/ecency/ecency'; -import { fetchSubscribedCommunities } from '../../../redux/actions/communitiesAction'; + class PinCodeContainer extends Component { constructor(props) { @@ -62,43 +49,30 @@ class PinCodeContainer extends Component { }; } - // TODO: if check for decide to set to pin or verify to pin page - // TODO: these text should move to view! + + //sets initial pin code screen label based on oldPinVerified param/state componentDidMount() { // this.props.dispatch(setEncryptedUnlockPin(undefined)) - this._getDataFromStorage().then(() => { - const { intl } = this.props; - const { isOldPinVerified } = this.state; + const { intl } = this.props; + const { isOldPinVerified } = this.state; - if (!isOldPinVerified) { - this.setState({ - informationText: intl.formatMessage({ - id: 'pincode.enter_text', - }), - }); - } else { - this.setState({ - informationText: intl.formatMessage({ - id: 'pincode.set_new', - }), - }); - } - }); - } - - _getDataFromStorage = () => - new Promise((resolve) => { - getExistUser().then((isExistUser) => { - this.setState( - { - isExistUser, - }, - resolve, - ); + if (!isOldPinVerified) { + this.setState({ + informationText: intl.formatMessage({ + id: 'pincode.enter_text', + }), }); - }); + } else { + this.setState({ + informationText: intl.formatMessage({ + id: 'pincode.set_new', + }), + }); + } + + } //this function updates realm with appropriate master key required for encyrption //this function is important: must run while chaning pin @@ -121,7 +95,8 @@ class PinCodeContainer extends Component { }; - + //routine for checking and setting new pin code, same routine is used for + //setting pin for the first time _resetPinCode = (pin) => new Promise((resolve, reject) => { const { @@ -215,46 +190,6 @@ class PinCodeContainer extends Component { - _setFirstPinCode = (pin) => - new Promise((resolve) => { - const { - currentAccount, - dispatch, - pinCodeParams: { navigateTo, navigateParams, accessToken, callback }, - } = this.props; - const { oldPinCode } = this.state; - - const pinData = { - pinCode: pin, - password: currentAccount ? currentAccount.password : '', - username: currentAccount ? currentAccount.name : '', - accessToken, - }; - setUserDataWithPinCode(pinData).then((response) => { - getUser(currentAccount.name).then((user) => { - const _currentAccount = user; - _currentAccount.local = response; - - dispatch(updateCurrentAccount({ ..._currentAccount })); - - setExistUser(true).then(() => { - this._savePinCode(pin); - if (callback) { - callback(pin, oldPinCode); - } - dispatch(closePinCodeModal()); - if (navigateTo) { - navigate({ - routeName: navigateTo, - params: navigateParams, - }); - } - resolve(); - }); - }); - }); - }); - _onRefreshTokenFailed = (error) => { setTimeout(() => { const { dispatch, intl } = this.props; @@ -295,7 +230,7 @@ class PinCodeContainer extends Component { if (unlockPin !== pin) { throw new Error(intl.formatMessage({ id: 'alert.invalid_pincode', - }),); + })); } //migrate data to default pin if encUnlockPin is not set. @@ -324,12 +259,16 @@ class PinCodeContainer extends Component { } } + + //encryptes and saved unlockPin _savePinCode = (pin) => { const { dispatch } = this.props; const encryptedPin = encryptKey(pin, Config.PIN_KEY); dispatch(setEncryptedUnlockPin(encryptedPin)); }; + + _forgotPinCode = async () => { const { otherAccounts, dispatch } = this.props; @@ -407,11 +346,7 @@ class PinCodeContainer extends Component { }; _setPinCode = async (pin, isReset) => { - const { intl, currentAccount, applicationPinCode } = this.props; - const { isExistUser } = this.state; - try { - // check if reset routine is triggered by user, reroute code to reset hanlder if (isReset) { await this._resetPinCode(pin); @@ -449,7 +384,7 @@ class PinCodeContainer extends Component { intl, pinCodeParams: { isReset }, } = this.props; - const { informationText, isOldPinVerified, isExistUser } = this.state; + const { informationText, isOldPinVerified } = this.state; return ( Date: Wed, 27 Jul 2022 17:48:40 +0500 Subject: [PATCH 13/18] commented unused auth.js verifyPinCode code --- src/providers/hive/auth.js | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/providers/hive/auth.js b/src/providers/hive/auth.js index 812792827..4ee1e4e2b 100644 --- a/src/providers/hive/auth.js +++ b/src/providers/hive/auth.js @@ -288,38 +288,38 @@ export const updatePinCode = (data) => } }); -export const verifyPinCode = async (data) => { - try { - const pinHash = await getPinCode(); +// export const verifyPinCode = async (data) => { +// try { +// const pinHash = await getPinCode(); - const result = await getUserDataWithUsername(data.username); - const userData = result[0]; +// const result = await getUserDataWithUsername(data.username); +// const userData = result[0]; - // This is migration for new pin structure, it will remove v2.2 - if (!pinHash) { - try { - //if decrypt fails, means key is invalid - if (userData.accessToken === AUTH_TYPE.STEEM_CONNECT) { - decryptKey(userData.accessToken, data.pinCode); - } else { - decryptKey(userData.masterKey, data.pinCode); - } - await setPinCode(data.pinCode); - } catch (error) { - return Promise.reject(new Error('Invalid pin code, please check and try again')); - } - } +// // This is migration for new pin structure, it will remove v2.2 +// if (!pinHash) { +// try { +// //if decrypt fails, means key is invalid +// if (userData.accessToken === AUTH_TYPE.STEEM_CONNECT) { +// decryptKey(userData.accessToken, data.pinCode); +// } else { +// decryptKey(userData.masterKey, data.pinCode); +// } +// await setPinCode(data.pinCode); +// } catch (error) { +// return Promise.reject(new Error('Invalid pin code, please check and try again')); +// } +// } - if (sha256(get(data, 'pinCode')).toString() !== pinHash) { - return Promise.reject(new Error('auth.invalid_pin')); - } +// if (sha256(get(data, 'pinCode')).toString() !== pinHash) { +// return Promise.reject(new Error('auth.invalid_pin')); +// } - return true; - } catch (err) { - console.warn('Failed to verify pin in auth: ', data, err); - return Promise.reject(err); - } -}; +// return true; +// } catch (err) { +// console.warn('Failed to verify pin in auth: ', data, err); +// return Promise.reject(err); +// } +// }; export const refreshSCToken = async (userData, pinCode) => { const scAccount = await getSCAccount(userData.username); From c1dae1a977dd1c4c5416956970a8b819a271e7ca Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 17:50:50 +0500 Subject: [PATCH 14/18] added todo for checking and updating pin verification method --- src/screens/pinCode/container/pinCodeContainer.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index 46b46e018..185c5a534 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -227,6 +227,10 @@ class PinCodeContainer extends Component { //check if pins match + //TODO: assess if this snippet can be used to match pin + // if (sha256(get(data, 'pinCode')).toString() !== pinHash) { + // return Promise.reject(new Error('auth.invalid_pin')); + // } if (unlockPin !== pin) { throw new Error(intl.formatMessage({ id: 'alert.invalid_pincode', From 007b98acb92c7621e4467216894892bfa3fad7cc Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Wed, 27 Jul 2022 18:09:43 +0500 Subject: [PATCH 15/18] fixed hsToken not refreshing after pinCode migration --- src/screens/application/container/applicationContainer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screens/application/container/applicationContainer.tsx b/src/screens/application/container/applicationContainer.tsx index c771b8f00..c15448174 100644 --- a/src/screens/application/container/applicationContainer.tsx +++ b/src/screens/application/container/applicationContainer.tsx @@ -703,14 +703,14 @@ class ApplicationContainer extends Component { }; _fetchUserDataFromDsteem = async (realmObject) => { - const { dispatch, intl, pinCode, isPinCodeOpen } = this.props; + const { dispatch, intl, pinCode, isPinCodeOpen, encUnlockPin } = this.props; try { let accountData = await getUser(realmObject.username); accountData.local = realmObject; //cannot migrate or refresh token since pin would null while pin code modal is open - if (!isPinCodeOpen) { + if (!isPinCodeOpen || encUnlockPin) { //migration script for previously mast key based logged in user not having access token if (realmObject.authType !== AUTH_TYPE.STEEM_CONNECT && realmObject.accessToken === '') { accountData = await migrateToMasterKeyWithAccessToken(accountData, realmObject, pinCode); From 229820558aaacbcb1446facd45e0ecd6e86f0cd7 Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Thu, 28 Jul 2022 11:26:11 +0500 Subject: [PATCH 16/18] removing pin code requirement on logout if no otherAccount is available --- src/screens/application/container/applicationContainer.tsx | 5 +++++ src/screens/pinCode/container/pinCodeContainer.tsx | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/screens/application/container/applicationContainer.tsx b/src/screens/application/container/applicationContainer.tsx index c15448174..4622ce651 100644 --- a/src/screens/application/container/applicationContainer.tsx +++ b/src/screens/application/container/applicationContainer.tsx @@ -69,6 +69,8 @@ import { setPinCode as savePinCode, isRenderRequired, logout, + isPinCodeOpen, + setEncryptedUnlockPin, } from '../../../redux/actions/applicationActions'; import { setAvatarCacheStamp, @@ -792,6 +794,7 @@ class ApplicationContainer extends Component { currentAccount: { name, local }, dispatch, intl, + } = this.props; removeUserData(name) @@ -812,6 +815,8 @@ class ApplicationContainer extends Component { isLoggedIn: false, }); setExistUser(false); + dispatch(isPinCodeOpen(false)); + dispatch(setEncryptedUnlockPin(encryptKey(Config.DEFAULT_KEU, Config.PIN_KEY))) if (local.authType === AUTH_TYPE.STEEM_CONNECT) { removeSCAccount(name); } diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index 185c5a534..46b46e018 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -227,10 +227,6 @@ class PinCodeContainer extends Component { //check if pins match - //TODO: assess if this snippet can be used to match pin - // if (sha256(get(data, 'pinCode')).toString() !== pinHash) { - // return Promise.reject(new Error('auth.invalid_pin')); - // } if (unlockPin !== pin) { throw new Error(intl.formatMessage({ id: 'alert.invalid_pincode', From 8224e121df13b1a1b1e5c792cd4024e78c6f052f Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Thu, 28 Jul 2022 12:45:15 +0500 Subject: [PATCH 17/18] added support encUnlockPin in biometric process --- src/screens/pinCode/container/pinCodeContainer.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index 076dabe9c..118c307ee 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -75,6 +75,7 @@ class PinCodeContainer extends Component { }); } + this._processBiometric(); } _processBiometric = async () => { @@ -83,6 +84,7 @@ class PinCodeContainer extends Component { intl, pinCodeParams: { isReset }, applicationPinCode, + encUnlockPin, isBiometricEnabled, } = this.props; @@ -100,7 +102,8 @@ class PinCodeContainer extends Component { //code gets here means biometeric succeeded if (this.screenRef) { - const verifiedPin = decryptKey(applicationPinCode, Config.PIN_KEY, this._onDecryptFail); + const encPin = encUnlockPin || applicationPinCode; + const verifiedPin = decryptKey(encPin, Config.PIN_KEY, this._onDecryptFail); this.screenRef.setPinThroughBiometric(verifiedPin); } } catch (err) { From 5992ffdc1be177dc6ed1dd345f52ea34c5c7b28f Mon Sep 17 00:00:00 2001 From: Nouman Tahir Date: Thu, 28 Jul 2022 12:45:29 +0500 Subject: [PATCH 18/18] removed unused code --- src/screens/pinCode/container/pinCodeContainer.tsx | 12 +----------- src/screens/settings/container/settingsContainer.tsx | 6 ------ 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/screens/pinCode/container/pinCodeContainer.tsx b/src/screens/pinCode/container/pinCodeContainer.tsx index 118c307ee..8e6a15681 100644 --- a/src/screens/pinCode/container/pinCodeContainer.tsx +++ b/src/screens/pinCode/container/pinCodeContainer.tsx @@ -56,8 +56,6 @@ class PinCodeContainer extends Component { //sets initial pin code screen label based on oldPinVerified param/state componentDidMount() { - // this.props.dispatch(setEncryptedUnlockPin(undefined)) - const { intl } = this.props; const { isOldPinVerified } = this.state; @@ -140,21 +138,13 @@ class PinCodeContainer extends Component { _resetPinCode = (pin) => new Promise((resolve, reject) => { const { - currentAccount, dispatch, - pinCodeParams: { navigateTo, navigateParams, accessToken, callback }, + pinCodeParams: { navigateTo, navigateParams, callback }, encUnlockPin, intl, } = this.props; const { isOldPinVerified, oldPinCode, newPinCode } = this.state; - const pinData = { - pinCode: pin, - password: currentAccount ? currentAccount.password : '', - username: currentAccount ? currentAccount.name : '', - accessToken, - oldPinCode, - }; //if old pin already verified, check new pin setup conditions. if (isOldPinVerified) { diff --git a/src/screens/settings/container/settingsContainer.tsx b/src/screens/settings/container/settingsContainer.tsx index c0c3b433c..213b3254f 100644 --- a/src/screens/settings/container/settingsContainer.tsx +++ b/src/screens/settings/container/settingsContainer.tsx @@ -18,13 +18,10 @@ import { setLanguage as setLanguage2DB, setNsfw as setNsfw2DB, setTheme, - setPinCodeOpen, - removeUserData, removePinCode, setAuthStatus, setExistUser, removeAllUserData, - getTheme, } from '../../../realm/realm'; // Services and Actions @@ -38,10 +35,8 @@ import { openPinCodeModal, setNsfw, isPinCodeOpen, - setPinCode as savePinCode, login, logoutDone, - closePinCodeModal, setColorTheme, setIsBiometricEnabled, setEncryptedUnlockPin, @@ -49,7 +44,6 @@ import { import { toastNotification } from '../../../redux/actions/uiAction'; import { setPushToken, getNodes } from '../../../providers/ecency/ecency'; import { checkClient } from '../../../providers/hive/dhive'; -import { updatePinCode } from '../../../providers/hive/auth'; import { removeOtherAccount, updateCurrentAccount } from '../../../redux/actions/accountAction'; // Middleware