fix(@desktop/wallet): issues with deleting wallet accounts fixed
In case an account being deleted is migrated to a Keycard keystore file it was not removed from `keycards_accounts` table and in case it was the last account for that keypair derived from keystore file was not removed as well as other keycards containing the same keypair. That's all sorted out.
This commit is contained in:
parent
61bd370b20
commit
1a919f586f
|
@ -80,7 +80,7 @@ method load*(self: Module) =
|
|||
singletonInstance.engine.setRootContextProperty("browserSectionCurrentAccount", newQVariant(self.view))
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||
if(self.view.isAddressCurrentAccount(AccountDeleted(e).account.address)):
|
||||
if(self.view.isAddressCurrentAccount(AccountDeleted(e).address)):
|
||||
self.switchAccount(0)
|
||||
self.view.connectedAccountDeleted()
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ proc init*(self: Controller) =
|
|||
let args = SharedKeycarModuleArgs(e)
|
||||
if args.uniqueIdentifier != UNIQUE_PROFILE_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER:
|
||||
return
|
||||
self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid)
|
||||
self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid, args.keycardUid)
|
||||
|
||||
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
||||
return self.walletAccountService.getWalletAccounts()
|
||||
|
@ -39,8 +39,8 @@ proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAcco
|
|||
proc updateAccount*(self: Controller, address: string, accountName: string, color: string, emoji: string) =
|
||||
discard self.walletAccountService.updateWalletAccount(address, accountName, color, emoji)
|
||||
|
||||
proc deleteAccount*(self: Controller, address: string, password = "", doPasswordHashing = false) =
|
||||
self.walletAccountService.deleteAccount(address, password, doPasswordHashing)
|
||||
proc deleteAccount*(self: Controller, address: string, password = "", keyUid = "", keycardUid = "") =
|
||||
self.walletAccountService.deleteAccount(address, password, keyUid, keycardUid)
|
||||
|
||||
proc authenticateKeyPair*(self: Controller, keyUid = "") =
|
||||
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_PROFILE_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER,
|
||||
|
|
|
@ -34,7 +34,7 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
|
|||
method authenticateUser*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
|
||||
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string, keycardUid: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||
|
|
|
@ -124,12 +124,11 @@ method deleteAccount*(self: Module, keyUid: string, address: string) =
|
|||
self.processingWalletAccount = WalletAccountDetails(keyUid: keyUid, address: address)
|
||||
self.authenticateActivityForKeyUid(keyUid, AuthenticationReason.DeleteAccountAuthentication)
|
||||
|
||||
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string) =
|
||||
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string, keycardUid: string) =
|
||||
if self.authentiactionReason == AuthenticationReason.DeleteAccountAuthentication:
|
||||
if self.processingWalletAccount.keyUid != keyUid:
|
||||
error "cannot resolve key uid of an account being deleted", keyUid=keyUid
|
||||
return
|
||||
if password.len == 0:
|
||||
return
|
||||
let doPasswordHashing = pin.len != PINLengthForStatusApp
|
||||
self.controller.deleteAccount(self.processingWalletAccount.address, password, doPasswordHashing)
|
||||
self.controller.deleteAccount(self.processingWalletAccount.address, password, keyUid, keycardUid)
|
|
@ -42,13 +42,13 @@ proc init*(self: Controller) =
|
|||
let args = SharedKeycarModuleArgs(e)
|
||||
if args.uniqueIdentifier != UNIQUE_WALLET_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER:
|
||||
return
|
||||
self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid)
|
||||
self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid, args.keycardUid)
|
||||
|
||||
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
||||
return self.walletAccountService.getWalletAccounts()
|
||||
|
||||
proc deleteAccount*(self: Controller, address: string, password = "", doPasswordHashing = false) =
|
||||
self.walletAccountService.deleteAccount(address, password, doPasswordHashing)
|
||||
proc deleteAccount*(self: Controller, address: string, password = "", keyUid = "", keycardUid = "") =
|
||||
self.walletAccountService.deleteAccount(address, password, keyUid, keycardUid)
|
||||
|
||||
proc authenticateKeyPair*(self: Controller, keyUid = "") =
|
||||
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_WALLET_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER,
|
||||
|
|
|
@ -31,5 +31,5 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
|
|||
method authenticateUser*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
|
||||
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string, keycardUid: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -141,15 +141,14 @@ method deleteAccount*(self: Module, keyUid: string, address: string) =
|
|||
self.processingWalletAccount = WalletAccountDetails(keyUid: keyUid, address: address)
|
||||
self.authenticateActivityForKeyUid(keyUid, AuthenticationReason.DeleteAccountAuthentication)
|
||||
|
||||
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string) =
|
||||
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string, keycardUid: string) =
|
||||
if self.authentiactionReason == AuthenticationReason.DeleteAccountAuthentication:
|
||||
if self.processingWalletAccount.keyUid != keyUid:
|
||||
error "cannot resolve key uid of an account being deleted", keyUid=keyUid
|
||||
return
|
||||
if password.len == 0:
|
||||
return
|
||||
let doPasswordHashing = pin.len != PINLengthForStatusApp
|
||||
self.controller.deleteAccount(self.processingWalletAccount.address, password, doPasswordHashing)
|
||||
self.controller.deleteAccount(self.processingWalletAccount.address, password, keyUid, keycardUid)
|
||||
|
||||
method updateAccount*(self: Module, address: string, accountName: string, color: string, emoji: string) =
|
||||
self.controller.updateAccount(address, accountName, color, emoji)
|
|
@ -32,7 +32,7 @@ type
|
|||
proc onTokensRebuilt(self: Module, accountsTokens: OrderedTable[string, seq[WalletTokenDto]], hasBalanceCache: bool, hasMarketValuesCache: bool)
|
||||
proc onCurrencyFormatsUpdated(self: Module)
|
||||
proc onAccountAdded(self: Module, account: WalletAccountDto)
|
||||
proc onAccountRemoved(self: Module, account: WalletAccountDto)
|
||||
proc onAccountRemoved(self: Module, address: string)
|
||||
|
||||
proc newModule*(
|
||||
delegate: delegate_interface.AccessInterface,
|
||||
|
@ -69,7 +69,7 @@ method load*(self: Module) =
|
|||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||
let args = AccountDeleted(e)
|
||||
self.onAccountRemoved(args.account)
|
||||
self.onAccountRemoved(args.address)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_UPDATED) do(e:Args):
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
@ -153,5 +153,5 @@ proc onCurrencyFormatsUpdated(self: Module) =
|
|||
proc onAccountAdded(self: Module, account: WalletAccountDto) =
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
||||
proc onAccountRemoved(self: Module, account: WalletAccountDto) =
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
proc onAccountRemoved(self: Module, address: string) =
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
|
|
@ -26,7 +26,7 @@ type
|
|||
proc onTokensRebuilt(self: Module, accountsTokens: OrderedTable[string, seq[WalletTokenDto]])
|
||||
proc onCurrencyFormatsUpdated(self: Module)
|
||||
proc onAccountAdded(self: Module, account: WalletAccountDto)
|
||||
proc onAccountRemoved(self: Module, account: WalletAccountDto)
|
||||
proc onAccountRemoved(self: Module, address: string)
|
||||
|
||||
proc newModule*(
|
||||
delegate: delegate_interface.AccessInterface,
|
||||
|
@ -56,7 +56,7 @@ method load*(self: Module) =
|
|||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||
let args = AccountDeleted(e)
|
||||
self.onAccountRemoved(args.account)
|
||||
self.onAccountRemoved(args.address)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_UPDATED) do(e:Args):
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
@ -132,6 +132,5 @@ proc onCurrencyFormatsUpdated(self: Module) =
|
|||
proc onAccountAdded(self: Module, account: WalletAccountDto) =
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
||||
proc onAccountRemoved(self: Module, account: WalletAccountDto) =
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
||||
proc onAccountRemoved(self: Module, address: string) =
|
||||
self.switchAccount(self.currentAccountIndex)
|
|
@ -190,7 +190,7 @@ QtObject:
|
|||
self.refetchAllOwnedCollectibles()
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||
self.removeAddress(AccountDeleted(e).account.address)
|
||||
self.removeAddress(AccountDeleted(e).address)
|
||||
|
||||
# needs to be re-written once cache for colletibles works
|
||||
proc areCollectionsLoaded*(self: Service, address: string): bool =
|
||||
|
|
|
@ -74,7 +74,7 @@ type AccountSaved* = ref object of Args
|
|||
account*: WalletAccountDto
|
||||
|
||||
type AccountDeleted* = ref object of Args
|
||||
account*: WalletAccountDto
|
||||
address*: string
|
||||
|
||||
type CurrencyUpdated = ref object of Args
|
||||
|
||||
|
@ -130,6 +130,8 @@ QtObject:
|
|||
proc startWallet(self: Service)
|
||||
proc handleKeycardActions(self: Service, keycardActions: seq[KeycardActionDto])
|
||||
proc handleKeycardsState(self: Service, keycardsState: seq[KeyPairDto])
|
||||
proc getAllKnownKeycards*(self: Service): seq[KeyPairDto]
|
||||
proc removeMigratedAccountsForKeycard*(self: Service, keyUid: string, keycardUid: string, accountsToRemove: seq[string])
|
||||
|
||||
proc delete*(self: Service) =
|
||||
self.closingApp = true
|
||||
|
@ -163,6 +165,18 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "error: ", procName="fetchAccounts", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc getAccountsByKeyUID*(self: Service, keyUid: string): seq[WalletAccountDto] =
|
||||
if keyUid.len == 0:
|
||||
error "error: cannot fetch accounts for an empty keyUid", procName="getAccountsByKeyUID"
|
||||
return
|
||||
try:
|
||||
let response = status_go_accounts.getAccountsByKeyUID(keyUid)
|
||||
return response.result.getElems().map(
|
||||
x => x.toWalletAccountDto()
|
||||
).filter(a => not a.isChat)
|
||||
except Exception as e:
|
||||
error "error: ", procName="getAccountsByKeyUID", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc setEnsName(self: Service, account: WalletAccountDto) =
|
||||
let chainId = self.networkService.getNetworkForEns().chainId
|
||||
try:
|
||||
|
@ -241,15 +255,6 @@ QtObject:
|
|||
proc walletAccountsContainsAddress*(self: Service, address: string): bool =
|
||||
return self.walletAccounts.hasKey(address)
|
||||
|
||||
proc removeAccount*(self: Service, address: string): WalletAccountDto =
|
||||
result = WalletAccountDto()
|
||||
if not self.walletAccountsContainsAddress(address):
|
||||
return
|
||||
result = self.walletAccounts[address]
|
||||
self.walletAccounts.del(address)
|
||||
# updating related accounts for other accounts
|
||||
self.setRelatedAccountsForAllAccounts(result.derivedFrom)
|
||||
|
||||
proc getAccountByAddress*(self: Service, address: string): WalletAccountDto =
|
||||
result = WalletAccountDto()
|
||||
if not self.walletAccountsContainsAddress(address):
|
||||
|
@ -353,6 +358,15 @@ QtObject:
|
|||
self.buildAllTokens(@[newAccount.address], store = true)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountSaved(account: newAccount))
|
||||
|
||||
proc removeAccountFromLocalStoreAndNotify(self: Service, address: string) =
|
||||
if not self.walletAccountsContainsAddress(address):
|
||||
return
|
||||
let removedAcc = self.walletAccounts[address]
|
||||
self.walletAccounts.del(address)
|
||||
# updating related accounts for other accounts
|
||||
self.setRelatedAccountsForAllAccounts(removedAcc.derivedFrom)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountDeleted(address: address))
|
||||
|
||||
## if password is not provided local keystore file won't be created
|
||||
proc addWalletAccount*(self: Service, password: string, doPasswordHashing: bool, name, keyPairName, address, path: string,
|
||||
lastUsedDerivationIndex: int, rootWalletMasterKey, publicKey, keyUid, accountType, color, emoji: string): string =
|
||||
|
@ -425,14 +439,25 @@ QtObject:
|
|||
error "error: ", procName="getRandomMnemonic", errName=e.name, errDesription=e.msg
|
||||
return ""
|
||||
|
||||
proc deleteAccount*(self: Service, address: string, password: string, doPasswordHashing: bool) =
|
||||
proc deleteAccount*(self: Service, address: string, password: string, keyUid: string, keycardUid: string) =
|
||||
try:
|
||||
let isKeycardAccount = keycardUid.len > 0
|
||||
var finalPassword = password
|
||||
if doPasswordHashing:
|
||||
if not isKeycardAccount:
|
||||
finalPassword = utils.hashPassword(password)
|
||||
discard status_go_accounts.deleteAccount(address, finalPassword)
|
||||
let accountDeleted = self.removeAccount(address)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountDeleted(account: accountDeleted))
|
||||
let response = status_go_accounts.deleteAccount(address, finalPassword)
|
||||
if not response.error.isNil:
|
||||
error "status-go error", procName="deleteAccount", errCode=response.error.code, errDesription=response.error.message
|
||||
return
|
||||
self.removeAccountFromLocalStoreAndNotify(address)
|
||||
if isKeycardAccount:
|
||||
self.removeMigratedAccountsForKeycard(keyUid, keycardUid, @[address])
|
||||
let accounts = self.getAccountsByKeyUID(keyUID)
|
||||
if accounts.len == 0:
|
||||
let allKnownKeycards = self.getAllKnownKeycards()
|
||||
for kc in allKnownKeycards:
|
||||
if kc.keyUid == keyUid:
|
||||
self.removeMigratedAccountsForKeycard(kc.keyUid, kc.keycardUid, kc.accountsAddresses)
|
||||
except Exception as e:
|
||||
error "error: ", procName="deleteAccount", errName = e.name, errDesription = e.msg
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ const WATCH* = "watch"
|
|||
proc getAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
return core.callPrivateRPC("accounts_getAccounts")
|
||||
|
||||
proc getAccountsByKeyUID*(keyUid: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [keyUid]
|
||||
return core.callPrivateRPC("accounts_getAccountsByKeyUID", payload)
|
||||
|
||||
proc deleteAccount*(address: string, password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [address, password]
|
||||
return core.callPrivateRPC("accounts_deleteAccount", payload)
|
||||
|
|
Loading…
Reference in New Issue