fix(@desktop/wallet): migrate non profile keypair and delete account fix

Due to changes done in https://github.com/status-im/status-go/pull/3133
we had to update procedure for adding migration keypair (which includes
local keystor files deletion for the accounts being migrated) and procedure
for account deletion, cause in order to delete local keystore file for the
acount which is being deleted, we have to provide a password now (states
only for non keycard accounts, keycard accounts use empty password).
This commit is contained in:
Sale Djenic 2023-01-31 20:33:56 +01:00 committed by Anthony Laibe
parent dc3bcd7da1
commit 1818347da3
9 changed files with 60 additions and 45 deletions

View File

@ -479,8 +479,7 @@ proc buildAndRegisterUserProfile(self: AppController) =
keycardLocked: false,
accountsAddresses: @[defaultWalletAddress],
keyUid: loggedInAccount.keyUid)
let keystoreDir = self.accountsService.getKeyStoreDir()
discard self.walletAccountService.addMigratedKeyPair(keyPair, keystoreDir)
discard self.walletAccountService.addMigratedKeyPair(keyPair)
if self.syncKeycardBasedOnAppWalletState:
let allAccounts = self.walletAccountService.fetchAccounts()
let accountsForLoggedInUser = allAccounts.filter(a => a.keyUid == loggedInAccount.keyUid)
@ -505,8 +504,7 @@ proc buildAndRegisterUserProfile(self: AppController) =
let (_, kcEvent) = self.keycardService.getLastReceivedKeycardData()
if kcEvent.instanceUID.len > 0:
keyPair.keycardUid = kcEvent.instanceUID
let keystoreDir = self.accountsService.getKeyStoreDir()
discard self.walletAccountService.addMigratedKeyPair(keyPair, keystoreDir)
discard self.walletAccountService.addMigratedKeyPair(keyPair)
if self.changedKeycardUids.len > 0:
let oldUid = self.changedKeycardUids[0].oldKcUid

View File

@ -90,8 +90,8 @@ proc addAccountsFromSeed*(self: Controller, seedPhrase: string, password: string
proc addWatchOnlyAccount*(self: Controller, address: string, accountName: string, color: string, emoji: string): string =
return self.walletAccountService.addWatchOnlyAccount(address, accountName, color, emoji)
proc deleteAccount*(self: Controller, address: string, keyPairMigratedToKeycard: bool) =
self.walletAccountService.deleteAccount(address, keyPairMigratedToKeycard)
proc deleteAccount*(self: Controller, address: string, password = "") =
self.walletAccountService.deleteAccount(address, password)
proc fetchDerivedAddressDetails*(self: Controller, address: string) =
self.walletAccountService.fetchDerivedAddressDetails(address)
@ -109,7 +109,7 @@ proc validSeedPhrase*(self: Controller, seedPhrase: string): bool =
let err = self.accountsService.validateMnemonic(seedPhrase)
return err.len == 0
proc authenticateUser*(self: Controller, keyUid = "") =
proc authenticateKeyPair*(self: Controller, keyUid = "") =
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_WALLET_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER,
keyUid: keyUid)
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)

View File

@ -180,15 +180,24 @@ method addAccountsFromSeed*(self: Module, seedPhrase: string, password: string,
method addWatchOnlyAccount*(self: Module, address: string, accountName: string, color: string, emoji: string): string =
return self.controller.addWatchOnlyAccount(address, accountName, color, emoji)
method deleteAccount*(self: Module, keyUid: string, address: string) =
proc authenticateActivityForKeyUid(self: Module, keyUid: string, reason: AuthenticationReason) =
self.authentiactionReason = reason
let keyPair = self.controller.getMigratedKeyPairByKeyUid(keyUid)
let keyPairMigratedToKeycard = keyPair.len > 0
if not keyPairMigratedToKeycard:
self.controller.deleteAccount(address, keyPairMigratedToKeycard)
if keyPairMigratedToKeycard:
self.controller.authenticateKeyPair(keyUid)
else:
self.authentiactionReason = AuthenticationReason.DeleteAccountAuthentication
self.processingWalletAccount = WalletAccountDetails(keyUid: keyUid, address: address)
self.controller.authenticateUser(keyUid)
if singletonInstance.userProfile.getIsKeycardUser():
## We're here in case the keypair we're conducting an action for is not migrated to a keycard, but
## profile keypair is migrated, then we're authenticating profile keypair (logged in user).
self.processingWalletAccount.keyUid = singletonInstance.userProfile.getKeyUid()
self.controller.authenticateKeyPair(singletonInstance.userProfile.getKeyUid())
else:
self.controller.authenticateKeyPair()
method deleteAccount*(self: Module, keyUid: string, address: string) =
self.processingWalletAccount = WalletAccountDetails(keyUid: keyUid, address: address)
self.authenticateActivityForKeyUid(keyUid, AuthenticationReason.DeleteAccountAuthentication)
method getDerivedAddressList*(self: Module, password: string, derivedFrom: string, path: string, pageSize: int, pageNumber: int, hashPassword: bool) =
self.controller.getDerivedAddressList(password, derivedFrom, path, pageSize, pageNumber, hashPassword)
@ -203,12 +212,7 @@ method validSeedPhrase*(self: Module, value: string): bool =
return self.controller.validSeedPhrase(value)
method authenticateUser*(self: Module) =
self.authentiactionReason = AuthenticationReason.LoggedInUserAuthentication
if singletonInstance.userProfile.getIsKeycardUser():
let keyUid = singletonInstance.userProfile.getKeyUid()
self.controller.authenticateUser(keyUid)
else:
self.controller.authenticateUser()
self.authenticateActivityForKeyUid(singletonInstance.userProfile.getKeyUid(), AuthenticationReason.LoggedInUserAuthentication)
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string) =
if self.authentiactionReason == AuthenticationReason.LoggedInUserAuthentication or
@ -219,8 +223,13 @@ method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid:
self.view.userAuthentiactionFail()
elif self.authentiactionReason == AuthenticationReason.DeleteAccountAuthentication:
if self.processingWalletAccount.keyUid == keyUid:
self.controller.deleteAccount(self.processingWalletAccount.address, true)
self.tryKeycardSync(keyUid, pin)
# keycard keypair authentication
self.controller.deleteAccount(self.processingWalletAccount.address)
if pin.len == PINLengthForStatusApp:
self.tryKeycardSync(keyUid, pin)
if password.len > 0 and keyUid.len == 0:
# regular keypair authentication
self.controller.deleteAccount(self.processingWalletAccount.address, password)
method createSharedKeycardModule*(self: Module) =
if self.keycardSharedModule.isNil:

View File

@ -612,8 +612,7 @@ proc addMigratedKeyPair*(self: Controller, keyPair: KeyPairDto) =
return
if not serviceApplicable(self.accountsService):
return
let keystoreDir = self.accountsService.getKeyStoreDir()
self.walletAccountService.addMigratedKeyPairAsync(keyPair, keystoreDir)
self.walletAccountService.addMigratedKeyPairAsync(keyPair, self.getPassword())
proc removeMigratedAccountsForKeycard*(self: Controller, keyUid: string, keycardUid: string, accountsToRemove: seq[string]) =
if not serviceApplicable(self.walletAccountService):

View File

@ -34,10 +34,7 @@ proc runStoreMetadataFlow(self: MigratingKeyPairState, controller: Controller) =
method executePrePrimaryStateCommand*(self: MigratingKeyPairState, controller: Controller) =
if self.flowType == FlowType.SetupNewKeycard:
if controller.getSelectedKeyPairIsProfile():
controller.authenticateUser()
else:
self.doMigration(controller)
controller.authenticateUser()
method executePreSecondaryStateCommand*(self: MigratingKeyPairState, controller: Controller) =
## Secondary action is called after each async action during migration process.
@ -62,6 +59,13 @@ method executePreSecondaryStateCommand*(self: MigratingKeyPairState, controller:
if self.profileConversionOk:
self.runStoreMetadataFlow(controller)
else:
if not self.authenticationDone:
self.authenticationDone = true
let password = controller.getPassword()
self.authenticationOk = controller.verifyPassword(password)
if self.authenticationOk:
self.doMigration(controller)
return
if not self.addingMigratedKeypairDone:
self.addingMigratedKeypairDone = true
self.addingMigratedKeypairOk = controller.getAddingMigratedKeypairSuccess()

View File

@ -110,7 +110,7 @@ const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
type
AddMigratedKeyPairTaskArg* = ref object of QObjectTaskArg
keyPair: KeyPairDto
keyStoreDir: string
password: string
const addMigratedKeyPairTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AddMigratedKeyPairTaskArg](argEncoded)
@ -120,7 +120,7 @@ const addMigratedKeyPairTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall
arg.keyPair.keycardName,
arg.keyPair.keyUid,
arg.keyPair.accountsAddresses,
arg.keyStoreDir
arg.password
)
let success = responseHasNoErrors("addMigratedKeyPair", response)
let responseJson = %*{

View File

@ -6,7 +6,7 @@ import ../settings/service as settings_service
import ../accounts/service as accounts_service
import ../token/service as token_service
import ../network/service as network_service
import ../../common/account_constants
import ../../common/[account_constants, string_utils]
import ../../../app/global/global_singleton
import dto, derived_address, key_pair_dto
@ -391,12 +391,12 @@ QtObject:
self.addNewAccountToLocalStore()
proc deleteAccount*(self: Service, address: string, keyPairMigrated: bool) =
proc deleteAccount*(self: Service, address: string, password = "") =
try:
if keyPairMigrated:
discard status_go_accounts.deleteAccountForMigratedKeypair(address)
else:
discard status_go_accounts.deleteAccount(address)
var hashedPassword = ""
if password.len > 0:
hashedPassword = hashString(password)
discard status_go_accounts.deleteAccount(address, hashedPassword)
let accountDeleted = self.removeAccount(address)
self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountDeleted(account: accountDeleted))
except Exception as e:
@ -558,13 +558,18 @@ QtObject:
let accounts = self.getWalletAccounts()
return accounts.map(a => a.getCurrencyBalance(chainIds, self.getCurrentCurrencyIfEmpty(currency))).foldl(a + b, 0.0)
proc addMigratedKeyPairAsync*(self: Service, keyPair: KeyPairDto, keyStoreDir: string) =
proc addMigratedKeyPairAsync*(self: Service, keyPair: KeyPairDto, password = "") =
# Providing a password corresponding local keystore file will be removed as well, though
# in some contexts we just need to add keypair to the db, so password is not needed.
var hashedPassword = ""
if password.len > 0:
hashedPassword = hashString(password)
let arg = AddMigratedKeyPairTaskArg(
tptr: cast[ByteAddress](addMigratedKeyPairTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onMigratedKeyPairAdded",
keyPair: keyPair,
keyStoreDir: keyStoreDir
password: hashedPassword
)
self.threadpool.start(arg)
@ -581,14 +586,16 @@ QtObject:
error "error handilng migrated keypair response", errDesription=e.msg
self.events.emit(SIGNAL_NEW_KEYCARD_SET, data)
proc addMigratedKeyPair*(self: Service, keyPair: KeyPairDto, keyStoreDir: string): bool =
proc addMigratedKeyPair*(self: Service, keyPair: KeyPairDto, password = ""): bool =
# Providing a password corresponding local keystore file will be removed as well, though
# in some contexts we just need to add keypair to the db, so password is not needed.
try:
let response = backend.addMigratedKeyPair(
keyPair.keycardUid,
keyPair.keycardName,
keyPair.keyUid,
keyPair.accountsAddresses,
keyStoreDir
password
)
result = responseHasNoErrors("addMigratedKeyPair", response)
if result:

View File

@ -21,11 +21,9 @@ const WATCH* = "watch"
proc getAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("accounts_getAccounts")
proc deleteAccount*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("accounts_deleteAccount", %* [address])
proc deleteAccountForMigratedKeypair*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("accounts_deleteAccountForMigratedKeypair", %* [address])
proc deleteAccount*(address: string, password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [address, password]
return core.callPrivateRPC("accounts_deleteAccount", payload)
proc saveAccount*(name, address, path, addressAccountIsDerivedFrom, publicKey, keyUid, accountType, color, emoji: string,
walletDefaultAccount: bool, chatDefaultAccount: bool):

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 9e4390582117d5df4f302e160f8af2b7fa4c1b4e
Subproject commit 242c85cd6a820f0b17d99758f7e670d12afd5e3c