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 get from 'lodash/get';
import { cryptoUtils } from '@hiveio/dhive';
import { getUser } from './dhive';
import { getDigitPinCode, getUser } from './dhive';
import {
setUserData,
setAuthStatus,
@ -64,17 +64,9 @@ export const login = async (username, password, isPinCodeOpen) => {
}
});
// Prepare hivesigner code
const signer = (message) => {
const hash = cryptoUtils.sha256(message);
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 signerPrivateKey = privateKeys.ownerKey || privateKeys.activeKey || privateKeys.postingKey
const code = await makeHsCode(account.name, signerPrivateKey);
const scTokens = await getSCAccessToken(code);
let jsonMetadata;
@ -411,3 +403,45 @@ const isLoggedInUser = async (username) => {
}
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,
} from '../../../realm/realm';
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 { navigate } from '../../../navigation/service';
@ -632,21 +632,27 @@ class ApplicationContainer extends Component {
};
_fetchUserDataFromDsteem = async (realmObject) => {
const { dispatch, intl } = this.props;
const { dispatch, intl, pinCode } = this.props;
await getUser(realmObject.username)
.then((accountData) => {
accountData.local = realmObject;
try{
let accountData = await getUser(realmObject.username)
accountData.local = realmObject;
dispatch(updateCurrentAccount(accountData));
//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));
this._connectNotificationServer(accountData.name);
}catch(err){
Alert.alert(
`${intl.formatMessage({ id: 'alert.fetch_error' })} \n${err.message.substr(0, 20)}`,
);
}
this._connectNotificationServer(accountData.name);
})
.catch((err) => {
Alert.alert(
`${intl.formatMessage({ id: 'alert.fetch_error' })} \n${err.message.substr(0, 20)}`,
);
});
};
_getSettings = async () => {
@ -803,10 +809,15 @@ class ApplicationContainer extends Component {
const accountData = await switchAccount(targetAccount.username);
const realmData = await getUserDataWithUsername(targetAccount.username);
const _currentAccount = accountData;
let _currentAccount = accountData;
_currentAccount.username = accountData.name;
[_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));
};

View File

@ -1,4 +1,5 @@
import { b64uEnc } from "./b64";
import { cryptoUtils, PrivateKey } from '@hiveio/dhive';
export interface HiveSignerMessage {
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 messageObj: HiveSignerMessage = {signed_message: {type: 'code', app: "ecency.app"}, authors: [account], timestamp};
const message = JSON.stringify(messageObj);
const signature = await signer(message);
const signature = signer(message, privateKey);
messageObj.signatures = [signature];
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
}