added master key auth access token migration script

This commit is contained in:
Nouman Tahir 2021-06-29 13:54:51 +05:00
parent 18000df7f7
commit 4ecb8da9ab
3 changed files with 84 additions and 29 deletions

View File

@ -3,8 +3,8 @@ import sha256 from 'crypto-js/sha256';
import Config from 'react-native-config'; import Config from 'react-native-config';
import get from 'lodash/get'; import get from 'lodash/get';
import { cryptoUtils } from '@hiveio/dhive';
import { getUser } from './dhive'; import { getDigitPinCode, getUser } from './dhive';
import { import {
setUserData, setUserData,
setAuthStatus, setAuthStatus,
@ -64,17 +64,9 @@ export const login = async (username, password, isPinCodeOpen) => {
} }
}); });
// Prepare hivesigner code
const signer = (message) => { const signerPrivateKey = privateKeys.ownerKey || privateKeys.activeKey || privateKeys.postingKey
const hash = cryptoUtils.sha256(message); const code = await makeHsCode(account.name, signerPrivateKey);
return new Promise((resolve) => {
const key = privateKeys.ownerKey || privateKeys.activeKey || privateKeys.postingKey;
const signedKey = key.sign(hash);
const signedStr = signedKey.toString();
resolve(signedStr);
});
};
const code = await makeHsCode(account.name, signer);
const scTokens = await getSCAccessToken(code); const scTokens = await getSCAccessToken(code);
let jsonMetadata; let jsonMetadata;
@ -411,3 +403,45 @@ const isLoggedInUser = async (username) => {
} }
return false; return false;
}; };
/**
* This migration snippet is used to update access token for users logged in using masterKey
* accessToken is required for all ecency api calls even for non hivesigner users.
*/
export const migrateToMasterKeyWithAccessToken = async (account, pinHash) => {
//get username, user local data from account;
const username = account.name;
const userData = account.local;
if(userData.accessToken){
//skipping migration as access token already preset;
return account;
}
//decrypt password from local data
const pinCode = getDigitPinCode(pinHash);
const password = decryptKey(userData.masterKey, pinCode)
// Set private keys of user
const privateKeys = getPrivateKeys(username, password);
const signerPrivateKey = privateKeys.ownerKey || privateKeys.activeKey || privateKeys.postingKey
const code = await makeHsCode(account.name, signerPrivateKey);
const scTokens = await getSCAccessToken(code);
await setSCAccount(scTokens);
const accessToken = scTokens.access_token;
//update data
const localData = {
...userData,
accessToken: encryptKey(accessToken, pinCode),
}
//update realm
await updateUserData(localData);
//return account with update local data
account.local = localData
return account;
}

View File

@ -42,7 +42,7 @@ import {
setVersionForWelcomeModal, setVersionForWelcomeModal,
} from '../../../realm/realm'; } from '../../../realm/realm';
import { getUser, getPost } from '../../../providers/hive/dhive'; import { getUser, getPost } from '../../../providers/hive/dhive';
import { switchAccount } from '../../../providers/hive/auth'; import { migrateToMasterKeyWithAccessToken, switchAccount } from '../../../providers/hive/auth';
import { setPushToken, markActivityAsRead } from '../../../providers/ecency/ecency'; import { setPushToken, markActivityAsRead } from '../../../providers/ecency/ecency';
import { navigate } from '../../../navigation/service'; import { navigate } from '../../../navigation/service';
@ -632,21 +632,27 @@ class ApplicationContainer extends Component {
}; };
_fetchUserDataFromDsteem = async (realmObject) => { _fetchUserDataFromDsteem = async (realmObject) => {
const { dispatch, intl } = this.props; const { dispatch, intl, pinCode } = this.props;
await getUser(realmObject.username) try{
.then((accountData) => { let accountData = await getUser(realmObject.username)
accountData.local = realmObject; accountData.local = realmObject;
//migration script for previously mast key based logged in user not having access token
if(realmObject.authType === AUTH_TYPE.MASTER_KEY && realmObject.accessToken === ''){
accountData = await migrateToMasterKeyWithAccessToken(accountData, pinCode)
}
dispatch(updateCurrentAccount(accountData)); dispatch(updateCurrentAccount(accountData));
this._connectNotificationServer(accountData.name); this._connectNotificationServer(accountData.name);
})
.catch((err) => { }catch(err){
Alert.alert( Alert.alert(
`${intl.formatMessage({ id: 'alert.fetch_error' })} \n${err.message.substr(0, 20)}`, `${intl.formatMessage({ id: 'alert.fetch_error' })} \n${err.message.substr(0, 20)}`,
); );
}); }
}; };
_getSettings = async () => { _getSettings = async () => {
@ -803,10 +809,15 @@ class ApplicationContainer extends Component {
const accountData = await switchAccount(targetAccount.username); const accountData = await switchAccount(targetAccount.username);
const realmData = await getUserDataWithUsername(targetAccount.username); const realmData = await getUserDataWithUsername(targetAccount.username);
const _currentAccount = accountData; let _currentAccount = accountData;
_currentAccount.username = accountData.name; _currentAccount.username = accountData.name;
[_currentAccount.local] = realmData; [_currentAccount.local] = realmData;
//migreate account to use access token for master key auth type
if(realmData.authType === AUTH_TYPE.MASTER_KEY && realmData.accessToken){
_currentAccount = await migrateToMasterKeyWithAccessToken(_currentAccount, pinCode)
}
dispatch(updateCurrentAccount(_currentAccount)); dispatch(updateCurrentAccount(_currentAccount));
}; };

View File

@ -1,4 +1,5 @@
import { b64uEnc } from "./b64"; import { b64uEnc } from "./b64";
import { cryptoUtils, PrivateKey } from '@hiveio/dhive';
export interface HiveSignerMessage { export interface HiveSignerMessage {
signed_message: { signed_message: {
@ -11,11 +12,20 @@ export interface HiveSignerMessage {
} }
export const makeHsCode = async (account: string, signer: (message: string) => Promise<string>): Promise<string> => { export const makeHsCode = async (account: string, privateKey:PrivateKey): Promise<string> => {
const timestamp = new Date().getTime() / 1000; const timestamp = new Date().getTime() / 1000;
const messageObj: HiveSignerMessage = {signed_message: {type: 'code', app: "ecency.app"}, authors: [account], timestamp}; const messageObj: HiveSignerMessage = {signed_message: {type: 'code', app: "ecency.app"}, authors: [account], timestamp};
const message = JSON.stringify(messageObj); const message = JSON.stringify(messageObj);
const signature = await signer(message); const signature = signer(message, privateKey);
messageObj.signatures = [signature]; messageObj.signatures = [signature];
return b64uEnc(JSON.stringify(messageObj)); return b64uEnc(JSON.stringify(messageObj));
} }
export const signer = (message:any, privateKey:PrivateKey) => {
const hash = cryptoUtils.sha256(message);
const key = privateKey;
const signedKey = key.sign(hash);
const signedStr = signedKey.toString();
return signedStr
}