fix: saving/updating a keycard updates the accounts' operability
This commit skips deleting a keystore file for account which are not marked as fully operable and also skips deleting master key keystore file if a keypair is non operable. It also takes into consideration the operable property of an account when adding/updating/handling a keypair/keycard. u3
This commit is contained in:
parent
f7b342bb07
commit
57dea7b08d
|
@ -254,6 +254,27 @@ func (a *Keypair) GetChatPublicKey() types.HexBytes {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (a *Keypair) MigratedToKeycard() bool {
|
||||
return len(a.Keycards) > 0
|
||||
}
|
||||
|
||||
// Returns operability of a keypair:
|
||||
// - if any of keypair's account is not operable, then a keyapir is considered as non operable
|
||||
// - if any of keypair's account is partially operable, then a keyapir is considered as partially operable
|
||||
// - if all accounts are fully operable, then a keyapir is considered as fully operable
|
||||
func (a *Keypair) Operability() AccountOperable {
|
||||
for _, acc := range a.Accounts {
|
||||
if acc.Operable == AccountNonOperable {
|
||||
return AccountNonOperable
|
||||
}
|
||||
if acc.Operable == AccountPartiallyOperable {
|
||||
return AccountPartiallyOperable
|
||||
}
|
||||
}
|
||||
|
||||
return AccountFullyOperable
|
||||
}
|
||||
|
||||
// Database sql wrapper for operations with browser objects.
|
||||
type Database struct {
|
||||
*settings.Database
|
||||
|
@ -1287,7 +1308,8 @@ func (db *Database) GetNodeConfig() (*params.NodeConfig, error) {
|
|||
// local pairing and then imports seed/private key for the non profile keypair on one of those two devices
|
||||
// to make that keypair fully operable. In that case we need to inform other device about the change, that
|
||||
// other device may offer other options for importing that keypair on it.
|
||||
func (db *Database) MarkKeypairFullyOperable(keyUID string, clock uint64) (err error) {
|
||||
// If the clock is set to -1, do not update it.
|
||||
func (db *Database) MarkKeypairFullyOperable(keyUID string, clock uint64, updateKeypairClock bool) (err error) {
|
||||
tx, err := db.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1317,7 +1339,11 @@ func (db *Database) MarkKeypairFullyOperable(keyUID string, clock uint64) (err e
|
|||
return err
|
||||
}
|
||||
|
||||
return db.updateKeypairClock(tx, keyUID, clock)
|
||||
if updateKeypairClock {
|
||||
return db.updateKeypairClock(tx, keyUID, clock)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) MarkAccountFullyOperable(address types.Address) (err error) {
|
||||
|
|
|
@ -3105,6 +3105,11 @@ func (m *Messenger) resolveAccountOperability(syncAcc *protobuf.SyncAccount, syn
|
|||
if accountReceivedFromLocalPairing {
|
||||
return accounts.AccountOperable(syncAcc.Operable), nil
|
||||
}
|
||||
|
||||
if syncKpMigratedToKeycard {
|
||||
return accounts.AccountFullyOperable, nil
|
||||
}
|
||||
|
||||
accountsOperability := accounts.AccountNonOperable
|
||||
dbAccount, err := m.settings.GetAccountByAddress(types.BytesToAddress(syncAcc.Address))
|
||||
if err != nil && err != accounts.ErrDbAccountNotFound {
|
||||
|
@ -3129,7 +3134,7 @@ func (m *Messenger) resolveAccountOperability(syncAcc *protobuf.SyncAccount, syn
|
|||
}
|
||||
}
|
||||
|
||||
if syncKpMigratedToKeycard || syncAcc.Chat || syncAcc.Wallet {
|
||||
if syncAcc.Chat || syncAcc.Wallet {
|
||||
accountsOperability = accounts.AccountFullyOperable
|
||||
} else {
|
||||
partiallyOrFullyOperable, err := m.settings.IsAnyAccountPartiallyOrFullyOperableForKeyUID(syncAcc.KeyUid)
|
||||
|
@ -3259,8 +3264,8 @@ func (m *Messenger) handleSyncKeypair(message *protobuf.SyncKeypair, fromLocalPa
|
|||
}
|
||||
}
|
||||
|
||||
syncKpMigratedToKeycard := len(message.Keycards) > 0
|
||||
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
|
||||
|
@ -3279,27 +3284,37 @@ func (m *Messenger) handleSyncKeypair(message *protobuf.SyncKeypair, fromLocalPa
|
|||
kp.Accounts = append(kp.Accounts, acc)
|
||||
}
|
||||
|
||||
if kp.Removed {
|
||||
// delete all keystore files
|
||||
err = m.deleteKeystoreFilesForKeypair(dbKeypair)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if !fromLocalPairing && dbKeypair != nil {
|
||||
for _, dbAcc := range dbKeypair.Accounts {
|
||||
removeAcc := false
|
||||
for _, acc := range kp.Accounts {
|
||||
if dbAcc.Address == acc.Address && acc.Removed && !dbAcc.Removed {
|
||||
removeAcc = true
|
||||
break
|
||||
}
|
||||
if !fromLocalPairing {
|
||||
if kp.Removed ||
|
||||
dbKeypair != nil && !dbKeypair.MigratedToKeycard() && syncKpMigratedToKeycard {
|
||||
// delete all keystore files
|
||||
err = m.deleteKeystoreFilesForKeypair(dbKeypair)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if removeAcc {
|
||||
err = m.deleteKeystoreFileForAddress(dbAcc.Address)
|
||||
|
||||
if syncKpMigratedToKeycard {
|
||||
err = m.settings.MarkKeypairFullyOperable(dbKeypair.KeyUID, 0, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else if dbKeypair != nil {
|
||||
for _, dbAcc := range dbKeypair.Accounts {
|
||||
removeAcc := false
|
||||
for _, acc := range kp.Accounts {
|
||||
if dbAcc.Address == acc.Address && acc.Removed && !dbAcc.Removed {
|
||||
removeAcc = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if removeAcc {
|
||||
err = m.deleteKeystoreFileForAddress(dbAcc.Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ func (m *Messenger) SaveOrUpdateAccount(acc *accounts.Account) error {
|
|||
func (m *Messenger) MarkKeypairFullyOperable(keyUID string) error {
|
||||
clock, _ := m.getLastClockWithRelatedChat()
|
||||
|
||||
err := m.settings.MarkKeypairFullyOperable(keyUID, clock)
|
||||
err := m.settings.MarkKeypairFullyOperable(keyUID, clock, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ func (m *Messenger) deleteKeystoreFileForAddress(address types.Address) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if len(kp.Keycards) == 0 {
|
||||
if !kp.MigratedToKeycard() {
|
||||
err = m.accountsManager.DeleteAccount(address)
|
||||
var e *account.ErrCannotLocateKeyFile
|
||||
if err != nil && !errors.As(err, &e) {
|
||||
|
@ -225,7 +225,7 @@ func (m *Messenger) deleteKeystoreFileForAddress(address types.Address) error {
|
|||
}
|
||||
|
||||
func (m *Messenger) deleteKeystoreFilesForKeypair(keypair *accounts.Keypair) (err error) {
|
||||
if keypair == nil || len(keypair.Keycards) > 0 {
|
||||
if m.accountsManager == nil || keypair == nil || keypair.MigratedToKeycard() {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -346,7 +346,7 @@ func (api *API) MakePartiallyOperableAccoutsFullyOperable(ctx context.Context, p
|
|||
return
|
||||
}
|
||||
|
||||
if len(profileKeypair.Keycards) == 0 && !api.VerifyPassword(password) {
|
||||
if !profileKeypair.MigratedToKeycard() && !api.VerifyPassword(password) {
|
||||
err = errors.New("wrong password provided")
|
||||
return
|
||||
}
|
||||
|
@ -467,11 +467,6 @@ func (api *API) SaveOrUpdateKeycard(ctx context.Context, keycard *accounts.Keyca
|
|||
return err
|
||||
}
|
||||
|
||||
relatedKeycardsByKeyUID, err := api.db.GetKeycardsWithSameKeyUID(keycard.KeyUID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = (*api.messenger).SaveOrUpdateKeycard(ctx, keycard)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -480,9 +475,13 @@ func (api *API) SaveOrUpdateKeycard(ctx context.Context, keycard *accounts.Keyca
|
|||
if !accountsComingFromKeycard {
|
||||
// Once we migrate a keypair, corresponding keystore files need to be deleted
|
||||
// if the keypair being migrated is not already migrated (in case user is creating a copy of an existing Keycard)
|
||||
if len(relatedKeycardsByKeyUID) == 0 {
|
||||
for _, addr := range keycard.AccountsAddresses {
|
||||
err = api.manager.DeleteAccount(addr)
|
||||
// and if keypair operability is different from non operable (otherwise there are not keystore files to be deleted).
|
||||
if !kpDb.MigratedToKeycard() && kpDb.Operability() != accounts.AccountNonOperable {
|
||||
for _, acc := range kpDb.Accounts {
|
||||
if acc.Operable != accounts.AccountFullyOperable {
|
||||
continue
|
||||
}
|
||||
err = api.manager.DeleteAccount(acc.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -493,6 +492,11 @@ func (api *API) SaveOrUpdateKeycard(ctx context.Context, keycard *accounts.Keyca
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = (*api.messenger).MarkKeypairFullyOperable(keycard.KeyUID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue