From 3dd1a534d3ccbeb653391317527eed8da7cc16b2 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Thu, 5 Aug 2021 13:53:41 +1000 Subject: [PATCH] fix delete all on network request --- ts/session/utils/syncUtils.ts | 218 +++++++++++++++++----------------- ts/util/accountManager.ts | 11 +- 2 files changed, 113 insertions(+), 116 deletions(-) diff --git a/ts/session/utils/syncUtils.ts b/ts/session/utils/syncUtils.ts index b2191d4d7..c634c76cd 100644 --- a/ts/session/utils/syncUtils.ts +++ b/ts/session/utils/syncUtils.ts @@ -128,13 +128,14 @@ export const forceSyncConfigurationNowIfNeeded = async (waitForMessageSent = fal const getNetworkTime = async (snode: Snode): Promise => { const response: any = await snodeRpc('info', {}, snode); const body = JSON.parse(response.body); - const timestamp = body.timestamp; + const timestamp = body?.timestamp; if (!timestamp) { throw new Error(`getNetworkTime returned invalid timestamp: ${timestamp}`); } return timestamp; }; +// tslint:disable-next-line: max-func-body-length export const forceNetworkDeletion = async (): Promise | null> => { const sodium = await getSodium(); const userX25519PublicKey = UserUtils.getOurPubKeyFromCache(); @@ -147,131 +148,124 @@ export const forceNetworkDeletion = async (): Promise | nul } const edKeyPriv = userED25519KeyPair.privKey; - console.warn({ userED25519KeyPair }); - console.warn({ edKeyPriv }); + return pRetry(async () => { + const userSwarm = await getSwarmFor(userX25519PublicKey.key); + const snodeToMakeRequestTo: Snode | undefined = _.sample(userSwarm); + const edKeyPrivBytes = fromHexToArray(edKeyPriv); - return pRetry( - async () => { - const userSwarm = await getSwarmFor(userX25519PublicKey.key); - const snodeToMakeRequestTo: Snode | undefined = _.sample(userSwarm); - const edKeyPrivBytes = fromHexToArray(edKeyPriv); + if (!snodeToMakeRequestTo) { + window.log.warn('Cannot forceNetworkDeletion, without a valid swarm node.'); + return null; + } - if (!snodeToMakeRequestTo) { - window.log.warn('Cannot forceNetworkDeletion, without a valid swarm node.'); - return null; - } + return pRetry( + async () => { + const timestamp = await getNetworkTime(snodeToMakeRequestTo); + + const verificationData = StringUtils.encode(`delete_all${timestamp}`, 'utf8'); + const message = new Uint8Array(verificationData); + const signature = sodium.crypto_sign_detached(message, edKeyPrivBytes); + const signatureBase64 = fromUInt8ArrayToBase64(signature); + + const deleteMessageParams = { + pubkey: userX25519PublicKey.key, + pubkey_ed25519: userED25519KeyPair.pubKey.toUpperCase(), + timestamp, + signature: signatureBase64, + }; + + const ret = await snodeRpc( + 'delete_all', + deleteMessageParams, + snodeToMakeRequestTo, + userX25519PublicKey.key + ); - // FIXME audric pretry getNetworkTime separately too - return pRetry( - async () => { - const timestamp = await getNetworkTime(snodeToMakeRequestTo); - - const verificationData = StringUtils.encode(`delete_all${timestamp}`, 'utf8'); - const message = new Uint8Array(verificationData); - const signature = sodium.crypto_sign_detached(message, edKeyPrivBytes); - const signatureBase64 = fromUInt8ArrayToBase64(signature); - - const deleteMessageParams = { - pubkey: userX25519PublicKey.key, - pubkey_ed25519: userED25519KeyPair.pubKey.toUpperCase(), - timestamp, - signature: signatureBase64, - }; - - const ret = await snodeRpc( - 'delete_all', - deleteMessageParams, - snodeToMakeRequestTo, - userX25519PublicKey.key + if (!ret) { + throw new Error( + `Empty response got for delete_all on snode ${ed25519Str( + snodeToMakeRequestTo.pubkey_ed25519 + )}` ); + } + + try { + const parsedResponse = JSON.parse(ret.body); + const { swarm } = parsedResponse; - if (!ret) { + if (!swarm) { throw new Error( - `Empty response got for delete_all on snode ${ed25519Str( + `Invalid JSON swarm response got for delete_all on snode ${ed25519Str( snodeToMakeRequestTo.pubkey_ed25519 - )}` + )}, ${ret?.body}` ); } - - try { - const parsedResponse = JSON.parse(ret.body); - const { swarm } = parsedResponse; - - if (!swarm) { - throw new Error( - `Invalid JSON swarm response got for delete_all on snode ${ed25519Str( - snodeToMakeRequestTo.pubkey_ed25519 - )}, ${ret?.body}` - ); - } - const swarmAsArray = Object.entries(swarm) as Array>; - if (!swarmAsArray.length) { - throw new Error( - `Invalid JSON swarmAsArray response got for delete_all on snode ${ed25519Str( - snodeToMakeRequestTo.pubkey_ed25519 - )}, ${ret?.body}` - ); - } - const results: Map = new Map( - swarmAsArray.map(snode => { - const snodePubkey = snode[0]; - const snodeJson = snode[1]; - console.warn({ snodePubkey, snodeJson }); - - const isFailed = snodeJson.failed || false; - - if (isFailed) { - const reason = snodeJson.reason; - const statusCode = snodeJson.code; - if (reason && statusCode) { - window.log.warn( - `Could not delete data from ${ed25519Str( - snodeToMakeRequestTo.pubkey_ed25519 - )} due to error: ${reason}: ${statusCode}` - ); - } else { - window.log.warn( - `Could not delete data from ${ed25519Str(snodeToMakeRequestTo.pubkey_ed25519)}` - ); - } - return [snodePubkey, false]; - } - - const hashes = snodeJson.deleted as Array; - const signatureSnode = snodeJson.signature as string; - // The signature format is ( PUBKEY_HEX || TIMESTAMP || DELETEDHASH[0] || ... || DELETEDHASH[N] ) - const dataToVerify = `${userX25519PublicKey.key}${timestamp}${hashes.join('')}`; - const dataToVerifyUtf8 = StringUtils.encode(dataToVerify, 'utf8'); - const isValid = sodium.crypto_sign_verify_detached( - fromBase64ToArray(signatureSnode), - new Uint8Array(dataToVerifyUtf8), - fromHexToArray(snodePubkey) - ); - return [snodePubkey, isValid]; - }) - ); - - return results; - } catch (e) { + const swarmAsArray = Object.entries(swarm) as Array>; + if (!swarmAsArray.length) { throw new Error( - `Invalid JSON response got for delete_all on snode ${ed25519Str( + `Invalid JSON swarmAsArray response got for delete_all on snode ${ed25519Str( snodeToMakeRequestTo.pubkey_ed25519 )}, ${ret?.body}` ); } - }, - { - retries: 3, - minTimeout: 500, - onFailedAttempt: e => { - window?.log?.warn( - `delete_all request attempt #${e.attemptNumber} failed. ${e.retriesLeft} retries left...` - ); - }, - }, - } - ); + const results: Map = new Map( + swarmAsArray.map(snode => { + const snodePubkey = snode[0]; + const snodeJson = snode[1]; + + const isFailed = snodeJson.failed || false; + + if (isFailed) { + const reason = snodeJson.reason; + const statusCode = snodeJson.code; + if (reason && statusCode) { + window.log.warn( + `Could not delete data from ${ed25519Str( + snodeToMakeRequestTo.pubkey_ed25519 + )} due to error: ${reason}: ${statusCode}` + ); + } else { + window.log.warn( + `Could not delete data from ${ed25519Str(snodeToMakeRequestTo.pubkey_ed25519)}` + ); + } + return [snodePubkey, false]; + } + + const hashes = snodeJson.deleted as Array; + const signatureSnode = snodeJson.signature as string; + // The signature format is ( PUBKEY_HEX || TIMESTAMP || DELETEDHASH[0] || ... || DELETEDHASH[N] ) + const dataToVerify = `${userX25519PublicKey.key}${timestamp}${hashes.join('')}`; + const dataToVerifyUtf8 = StringUtils.encode(dataToVerify, 'utf8'); + const isValid = sodium.crypto_sign_verify_detached( + fromBase64ToArray(signatureSnode), + new Uint8Array(dataToVerifyUtf8), + fromHexToArray(snodePubkey) + ); + return [snodePubkey, isValid]; + }) + ); + return results; + } catch (e) { + throw new Error( + `Invalid JSON response got for delete_all on snode ${ed25519Str( + snodeToMakeRequestTo.pubkey_ed25519 + )}, ${ret?.body}` + ); + } + }, + { + retries: 3, + minTimeout: 500, + onFailedAttempt: e => { + window?.log?.warn( + `delete_all request attempt #${e.attemptNumber} failed. ${e.retriesLeft} retries left...` + ); + }, + } + ); + }, {}); }; const getActiveOpenGroupV2CompleteUrls = async ( @@ -319,7 +313,7 @@ const getValidClosedGroups = async (convos: Array) => { } return new ConfigurationMessageClosedGroup({ - publicKey: groupPubKey as string, + publicKey: groupPubKey, name: c.get('name') || '', members: c.get('members') || [], admins: c.get('groupAdmins') || [], diff --git a/ts/util/accountManager.ts b/ts/util/accountManager.ts index 233c0a092..386c922c9 100644 --- a/ts/util/accountManager.ts +++ b/ts/util/accountManager.ts @@ -4,7 +4,10 @@ import { UserUtils } from '../session/utils'; import { fromArrayBufferToBase64, fromHex, toHex } from '../session/utils/String'; import { getOurPubKeyStrFromCache } from '../session/utils/User'; import { trigger } from '../shims/events'; -import { forceNetworkDeletion, forceSyncConfigurationNowIfNeeded } from '../session/utils/syncUtils'; +import { + forceNetworkDeletion, + forceSyncConfigurationNowIfNeeded, +} from '../session/utils/syncUtils'; import { actions as userActions } from '../state/ducks/user'; import { mn_decode, mn_encode } from '../session/crypto/mnemonic'; import { ConversationTypeEnum } from '../models/conversation'; @@ -140,9 +143,9 @@ async function bouncyDeleteAccount(reason?: string) { try { window?.log?.info('DeleteAccount => Sending a last SyncConfiguration'); - // send deletion message to the network - await forceNetworkDeletion(); + const ret = await forceNetworkDeletion(); + debugger; // be sure to wait for the message being effectively sent. Otherwise we won't be able to encrypt it for our devices ! await forceSyncConfigurationNowIfNeeded(true); @@ -157,7 +160,7 @@ async function bouncyDeleteAccount(reason?: string) { error && error.stack ? error.stack : error ); debugger; - return; + return; try { await deleteEverything(); } catch (e) {