From 4088edfa14092e9fd60604c7d1a237388168e591 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Thu, 27 Jul 2023 15:20:40 +0200 Subject: [PATCH] fix: changes needed to support recovering from waku in case recovering is done using keycard, but stored data refers to a regular profile and vice versa --- api/geth_backend.go | 8 ++++++ multiaccounts/accounts/database.go | 22 ++++++++------ protocol/messenger_backup_handler.go | 12 +++++++- protocol/messenger_handler.go | 43 +++++++++++++++++++++------- 4 files changed, 64 insertions(+), 21 deletions(-) diff --git a/api/geth_backend.go b/api/geth_backend.go index e10e22f69..3c764d60e 100644 --- a/api/geth_backend.go +++ b/api/geth_backend.go @@ -1372,7 +1372,15 @@ func (b *GethStatusBackend) saveAccountsAndSettings(settings settings.Settings, LastUsedDerivationIndex: 0, } + // When creating a new account, the chat account should have position -1, cause it doesn't participate + // in the wallet view and default wallet account should be at position 0. for _, acc := range subaccs { + if acc.Chat { + acc.Position = -1 + } + if acc.Wallet { + acc.Position = 0 + } acc.Operable = accounts.AccountFullyOperable keypair.Accounts = append(keypair.Accounts, acc) } diff --git a/multiaccounts/accounts/database.go b/multiaccounts/accounts/database.go index 96fca9a3a..99f7d3b14 100644 --- a/multiaccounts/accounts/database.go +++ b/multiaccounts/accounts/database.go @@ -433,9 +433,10 @@ func (db *Database) processRows(rows *sql.Rows) ([]*Keypair, []*Account, error) // If `includeRemoved` is true and `keyUID` is empty, then all keypairs will be returned (regardless how they are flagged). func (db *Database) getKeypairs(tx *sql.Tx, keyUID string, includeRemoved bool) ([]*Keypair, error) { var ( - rows *sql.Rows - err error - where string + rows *sql.Rows + err error + mainQueryWhere string + subQueryWhere string ) if tx == nil { tx, err = db.db.Begin() @@ -452,12 +453,16 @@ func (db *Database) getKeypairs(tx *sql.Tx, keyUID string, includeRemoved bool) } if keyUID != "" { - where = "WHERE k.key_uid = ?" + mainQueryWhere = "WHERE k.key_uid = ?" if !includeRemoved { - where += " AND k.removed = 0" + mainQueryWhere += " AND k.removed = 0" } } else if !includeRemoved { - where = "WHERE k.removed = 0" + mainQueryWhere = "WHERE k.removed = 0" + } + + if !includeRemoved { + subQueryWhere = "WHERE removed = 0" } query := fmt.Sprintf( // nolint: gosec @@ -486,14 +491,13 @@ func (db *Database) getKeypairs(tx *sql.Tx, keyUID string, includeRemoved bool) SELECT * FROM keypairs_accounts - WHERE - removed = 0 + %s ) AS ka ON k.key_uid = ka.key_uid %s ORDER BY - ka.position`, where) + ka.position`, subQueryWhere, mainQueryWhere) stmt, err := tx.Prepare(query) if err != nil { diff --git a/protocol/messenger_backup_handler.go b/protocol/messenger_backup_handler.go index 9ea20100a..d33040dd8 100644 --- a/protocol/messenger_backup_handler.go +++ b/protocol/messenger_backup_handler.go @@ -201,6 +201,16 @@ func (m *Messenger) handleKeypair(message *protobuf.SyncKeypair) error { return nil } + multiAcc, err := m.multiAccounts.GetAccount(message.KeyUid) + if err != nil { + return err + } + // If user is recovering his account via seed phrase, but the backed up messages indicate that the profile keypair + // is a keycard related profile, then we need to remove related profile keycards (only profile, other keycards should remain). + if multiAcc != nil && multiAcc.KeyUID == message.KeyUid && multiAcc.KeycardPairing == "" && len(message.Keycards) > 0 { + message.Keycards = []*protobuf.SyncKeycard{} + } + keypair, err := m.handleSyncKeypair(message) if err != nil { if err == ErrTryingToStoreOldKeypair { @@ -225,7 +235,7 @@ func (m *Messenger) handleWatchOnlyAccount(message *protobuf.SyncAccount) error return nil } - acc, err := m.handleSyncWatchOnlyAccount(message) + acc, err := m.handleSyncWatchOnlyAccount(message, true) if err != nil { if err == ErrTryingToStoreOldWalletAccount { return nil diff --git a/protocol/messenger_handler.go b/protocol/messenger_handler.go index dd4161ad0..6e10aa274 100644 --- a/protocol/messenger_handler.go +++ b/protocol/messenger_handler.go @@ -3085,7 +3085,7 @@ func (m *Messenger) resolveAccountOperability(syncAcc *protobuf.SyncAccount, syn return accountsOperability, nil } -func (m *Messenger) handleSyncWatchOnlyAccount(message *protobuf.SyncAccount) (*accounts.Account, error) { +func (m *Messenger) handleSyncWatchOnlyAccount(message *protobuf.SyncAccount, fromBackup bool) (*accounts.Account, error) { if message.KeyUid != "" { return nil, ErrNotWatchOnlyAccount } @@ -3108,9 +3108,15 @@ func (m *Messenger) handleSyncWatchOnlyAccount(message *protobuf.SyncAccount) (* if err != nil { return nil, err } - err = m.settings.ResolveAccountsPositions(message.Clock) + // if keypair is retrieved from backed up data, no need for resolving accounts positions + if !fromBackup { + err = m.settings.ResolveAccountsPositions(message.Clock) + if err != nil { + return nil, err + } + } dbAccount.Removed = true - return dbAccount, err + return dbAccount, nil } } @@ -3193,6 +3199,15 @@ func (m *Messenger) handleSyncKeypair(message *protobuf.SyncKeypair) (*accounts. for _, sAcc := range message.Accounts { syncKpMigratedToKeycard := len(message.Keycards) > 0 + if message.SyncedFrom == accounts.SyncedFromBackup && kp.Type == accounts.KeypairTypeProfile { + // if a profile keypair is coming from backup, we're handling within this block the case when a recovering + // was inititiated via keycard, while backed up profile keypair data refers to a regular profile + multiAcc, err := m.multiAccounts.GetAccount(kp.KeyUID) + if err != nil { + return nil, err + } + syncKpMigratedToKeycard = multiAcc != nil && multiAcc.KeycardPairing != "" + } accountOperability, err := m.resolveAccountOperability(sAcc, syncKpMigratedToKeycard, accountReceivedFromLocalPairing) if err != nil { return nil, err @@ -3236,9 +3251,12 @@ func (m *Messenger) handleSyncKeypair(message *protobuf.SyncKeypair) (*accounts. // if entire keypair was removed, there is no point to continue if kp.Removed { - err = m.settings.ResolveAccountsPositions(message.Clock) - if err != nil { - return nil, err + // if keypair is retrieved from backed up data, no need for resolving accounts positions + if message.SyncedFrom != accounts.SyncedFromBackup { + err = m.settings.ResolveAccountsPositions(message.Clock) + if err != nil { + return nil, err + } } return kp, nil } @@ -3249,10 +3267,13 @@ func (m *Messenger) handleSyncKeypair(message *protobuf.SyncKeypair) (*accounts. return nil, err } - // then resolve accounts positions, cause some accounts might be removed - err = m.settings.ResolveAccountsPositions(message.Clock) - if err != nil { - return nil, err + // if keypair is retrieved from backed up data, no need for resolving accounts positions + if message.SyncedFrom != accounts.SyncedFromBackup { + // then resolve accounts positions, cause some accounts might be removed + err = m.settings.ResolveAccountsPositions(message.Clock) + if err != nil { + return nil, err + } } for _, sKc := range message.Keycards { @@ -3292,7 +3313,7 @@ func (m *Messenger) HandleSyncAccountsPositions(state *ReceivedMessageState, mes } func (m *Messenger) HandleSyncWatchOnlyAccount(state *ReceivedMessageState, message protobuf.SyncAccount) error { - acc, err := m.handleSyncWatchOnlyAccount(&message) + acc, err := m.handleSyncWatchOnlyAccount(&message, false) if err != nil { if err == ErrTryingToStoreOldWalletAccount { return nil