fix(onboarding): show warning when trying to re-encrypt existing account
Fixes #5029
This commit is contained in:
parent
c0096453db
commit
d35344834e
|
@ -37,7 +37,7 @@ proc init*(self: Controller) =
|
|||
self.events.on(SignalType.NodeLogin.event) do(e:Args):
|
||||
let signal = NodeSignal(e)
|
||||
if signal.event.error != "":
|
||||
self.delegate.setupAccountError()
|
||||
self.delegate.setupAccountError(signal.event.error)
|
||||
|
||||
proc getGeneratedAccounts*(self: Controller): seq[GeneratedAccountDto] =
|
||||
return self.accountsService.generatedAccounts()
|
||||
|
@ -53,18 +53,20 @@ proc setDisplayName*(self: Controller, displayName: string) =
|
|||
self.displayName = displayName
|
||||
|
||||
proc storeSelectedAccountAndLogin*(self: Controller, password: string) =
|
||||
if(not self.accountsService.setupAccount(self.selectedAccountId, password, self.displayName)):
|
||||
self.delegate.setupAccountError()
|
||||
let error = self.accountsService.setupAccount(self.selectedAccountId, password, self.displayName)
|
||||
if error != "":
|
||||
self.delegate.setupAccountError(error)
|
||||
|
||||
proc validateMnemonic*(self: Controller, mnemonic: string): string =
|
||||
return self.accountsService.validateMnemonic(mnemonic)
|
||||
|
||||
proc importMnemonic*(self: Controller, mnemonic: string) =
|
||||
if(self.accountsService.importMnemonic(mnemonic)):
|
||||
let error = self.accountsService.importMnemonic(mnemonic)
|
||||
if(error == ""):
|
||||
self.selectedAccountId = self.getImportedAccount().id
|
||||
self.delegate.importAccountSuccess()
|
||||
else:
|
||||
self.delegate.importAccountError()
|
||||
self.delegate.importAccountError(error)
|
||||
|
||||
method getPasswordStrengthScore*(self: Controller, password, userName: string): int =
|
||||
return self.generalService.getPasswordStrengthScore(password, userName)
|
||||
|
|
|
@ -12,10 +12,10 @@ method load*(self: AccessInterface) {.base.} =
|
|||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setupAccountError*(self: AccessInterface) {.base.} =
|
||||
method setupAccountError*(self: AccessInterface, error: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method importAccountError*(self: AccessInterface) {.base.} =
|
||||
method importAccountError*(self: AccessInterface, error: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method importAccountSuccess*(self: AccessInterface) {.base.} =
|
||||
|
|
|
@ -61,8 +61,8 @@ method setDisplayName*(self: Module, displayName: string) =
|
|||
method storeSelectedAccountAndLogin*(self: Module, password: string) =
|
||||
self.controller.storeSelectedAccountAndLogin(password)
|
||||
|
||||
method setupAccountError*(self: Module) =
|
||||
self.view.setupAccountError()
|
||||
method setupAccountError*(self: Module, error: string) =
|
||||
self.view.setupAccountError(error)
|
||||
|
||||
method getImportedAccount*(self: Module): GeneratedAccountDto =
|
||||
return self.controller.getImportedAccount()
|
||||
|
@ -73,8 +73,8 @@ method validateMnemonic*(self: Module, mnemonic: string): string =
|
|||
method importMnemonic*(self: Module, mnemonic: string) =
|
||||
self.controller.importMnemonic(mnemonic)
|
||||
|
||||
method importAccountError*(self: Module) =
|
||||
self.view.importAccountError()
|
||||
method importAccountError*(self: Module, error: string) =
|
||||
self.view.importAccountError(error)
|
||||
|
||||
method importAccountSuccess*(self: Module) =
|
||||
self.view.importAccountSuccess()
|
||||
|
|
|
@ -76,10 +76,10 @@ QtObject:
|
|||
proc storeSelectedAccountAndLogin*(self: View, password: string) {.slot.} =
|
||||
self.delegate.storeSelectedAccountAndLogin(password)
|
||||
|
||||
proc accountSetupError*(self: View) {.signal.}
|
||||
proc accountSetupError*(self: View, error: string) {.signal.}
|
||||
|
||||
proc setupAccountError*(self: View) =
|
||||
self.accountSetupError()
|
||||
proc setupAccountError*(self: View, error: string) =
|
||||
self.accountSetupError(error)
|
||||
|
||||
proc validateMnemonic*(self: View, mnemonic: string): string {.slot.} =
|
||||
return self.delegate.validateMnemonic(mnemonic)
|
||||
|
@ -87,15 +87,18 @@ QtObject:
|
|||
proc importMnemonic*(self: View, mnemonic: string) {.slot.} =
|
||||
self.delegate.importMnemonic(mnemonic)
|
||||
|
||||
proc accountImportError*(self: View) {.signal.}
|
||||
proc accountImportError*(self: View, error: string) {.signal.}
|
||||
|
||||
proc importAccountError*(self: View) =
|
||||
proc importAccountError*(self: View, error: string) =
|
||||
# In QML we can connect to this signal and notify a user
|
||||
# before refactoring we didn't have this signal
|
||||
self.accountImportError()
|
||||
self.accountImportError(error)
|
||||
|
||||
proc accountImportSuccess*(self: View) {.signal.}
|
||||
|
||||
proc importAccountSuccess*(self: View) =
|
||||
self.importedAccountChanged()
|
||||
self.accountImportSuccess()
|
||||
|
||||
proc getPasswordStrengthScore*(self: View, password: string, userName: string): int {.slot.} =
|
||||
return self.delegate.getPasswordStrengthScore(password, userName)
|
||||
|
|
|
@ -47,3 +47,9 @@ proc toAccountDto*(jsonObj: JsonNode): AccountDto =
|
|||
if(jsonObj.getProp("images", imagesObj) and imagesObj.kind == JArray):
|
||||
for imgObj in imagesObj:
|
||||
result.images.add(toImage(imgObj))
|
||||
|
||||
proc contains*(accounts: seq[AccountDto], keyUid: string): bool =
|
||||
for account in accounts:
|
||||
if (account.keyUid == keyUid):
|
||||
return true
|
||||
return false
|
|
@ -18,11 +18,13 @@ logScope:
|
|||
topics = "accounts-service"
|
||||
|
||||
const PATHS = @[PATH_WALLET_ROOT, PATH_EIP_1581, PATH_WHISPER, PATH_DEFAULT_WALLET]
|
||||
const ACCOUNT_ALREADY_EXISTS_ERROR = "account already exists"
|
||||
|
||||
type
|
||||
Service* = ref object of RootObj
|
||||
fleetConfiguration: FleetConfiguration
|
||||
generatedAccounts: seq[GeneratedAccountDto]
|
||||
accounts: seq[AccountDto]
|
||||
loggedInAccount: AccountDto
|
||||
importedAccount: GeneratedAccountDto
|
||||
isFirstTimeAccountLogin: bool
|
||||
|
@ -98,21 +100,21 @@ proc openedAccounts*(self: Service): seq[AccountDto] =
|
|||
try:
|
||||
let response = status_account.openedAccounts(main_constants.STATUSGODIR)
|
||||
|
||||
let accounts = map(response.result.getElems(), proc(x: JsonNode): AccountDto = toAccountDto(x))
|
||||
self.accounts = map(response.result.getElems(), proc(x: JsonNode): AccountDto = toAccountDto(x))
|
||||
|
||||
return accounts
|
||||
return self.accounts
|
||||
|
||||
except Exception as e:
|
||||
error "error: ", procName="openedAccounts", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc storeDerivedAccounts(self: Service, accountId, hashedPassword: string,
|
||||
paths: seq[string]): DerivedAccounts =
|
||||
try:
|
||||
let response = status_account.storeDerivedAccounts(accountId, hashedPassword, paths)
|
||||
result = toDerivedAccounts(response.result)
|
||||
let response = status_account.storeDerivedAccounts(accountId, hashedPassword, paths)
|
||||
|
||||
except Exception as e:
|
||||
error "error: ", procName="storeDerivedAccounts", errName = e.name, errDesription = e.msg
|
||||
if response.result.contains("error"):
|
||||
raise newException(Exception, response.result["error"].getStr)
|
||||
|
||||
result = toDerivedAccounts(response.result)
|
||||
|
||||
proc saveAccountAndLogin(self: Service, hashedPassword: string, account,
|
||||
subaccounts, settings, config: JsonNode): AccountDto =
|
||||
|
@ -250,7 +252,7 @@ proc getDefaultNodeConfig*(self: Service, installationId: string): JsonNode =
|
|||
# TODO: commented since it's not necessary (we do the connections thru C bindings). Enable it thru an option once status-nodes are able to be configured in desktop
|
||||
# result["ListenAddr"] = if existsEnv("STATUS_PORT"): newJString("0.0.0.0:" & $getEnv("STATUS_PORT")) else: newJString("0.0.0.0:30305")
|
||||
|
||||
proc setupAccount*(self: Service, accountId, password, displayName: string): bool =
|
||||
proc setupAccount*(self: Service, accountId, password, displayName: string): string =
|
||||
try:
|
||||
let installationId = $genUUID()
|
||||
let accountDataJson = self.getAccountDataForAccountId(accountId, displayName)
|
||||
|
@ -262,36 +264,41 @@ proc setupAccount*(self: Service, accountId, password, displayName: string): boo
|
|||
nodeConfigJson.isNil):
|
||||
let description = "at least one json object is not prepared well"
|
||||
error "error: ", procName="setupAccount", errDesription = description
|
||||
return false
|
||||
return description
|
||||
|
||||
let hashedPassword = hashString(password)
|
||||
discard self.storeDerivedAccounts(accountId, hashedPassword, PATHS)
|
||||
|
||||
self.loggedInAccount = self.saveAccountAndLogin(hashedPassword, accountDataJson, subaccountDataJson, settingsJson,
|
||||
nodeConfigJson)
|
||||
|
||||
return self.getLoggedInAccount.isValid()
|
||||
self.loggedInAccount = self.saveAccountAndLogin(hashedPassword, accountDataJson,
|
||||
subaccountDataJson, settingsJson, nodeConfigJson)
|
||||
|
||||
if self.getLoggedInAccount.isValid():
|
||||
return ""
|
||||
else:
|
||||
return "logged in account is not valid"
|
||||
except Exception as e:
|
||||
error "error: ", procName="setupAccount", errName = e.name, errDesription = e.msg
|
||||
return false
|
||||
return e.msg
|
||||
|
||||
proc importMnemonic*(self: Service, mnemonic: string): bool =
|
||||
proc importMnemonic*(self: Service, mnemonic: string): string =
|
||||
try:
|
||||
let response = status_account.multiAccountImportMnemonic(mnemonic)
|
||||
self.importedAccount = toGeneratedAccountDto(response.result)
|
||||
|
||||
if (self.accounts.contains(self.importedAccount.keyUid)):
|
||||
return ACCOUNT_ALREADY_EXISTS_ERROR
|
||||
|
||||
let responseDerived = status_account.deriveAccounts(self.importedAccount.id, PATHS)
|
||||
self.importedAccount.derivedAccounts = toDerivedAccounts(responseDerived.result)
|
||||
|
||||
self.importedAccount.alias= generateAliasFromPk(self.importedAccount.derivedAccounts.whisper.publicKey)
|
||||
self.importedAccount.identicon = generateIdenticonFromPk(self.importedAccount.derivedAccounts.whisper.publicKey)
|
||||
|
||||
return self.importedAccount.isValid()
|
||||
|
||||
if (not self.importedAccount.isValid()):
|
||||
return "imported account is not valid"
|
||||
except Exception as e:
|
||||
error "error: ", procName="importMnemonic", errName = e.name, errDesription = e.msg
|
||||
return false
|
||||
return e.msg
|
||||
|
||||
proc login*(self: Service, account: AccountDto, password: string): string =
|
||||
try:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Dialogs 1.3
|
||||
|
||||
import shared.controls 1.0
|
||||
import shared 1.0
|
||||
|
@ -130,6 +131,35 @@ OnboardingBasePage {
|
|||
pause.start();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: onboardingModule
|
||||
onAccountSetupError: {
|
||||
if (error === Constants.existingAccountError) {
|
||||
importLoginError.title = qsTr("Keys for this account already exist")
|
||||
importLoginError.text = qsTr("Keys for this account already exist and can't be added again. If you've lost your password, passcode or Keycard, uninstall the app, reinstall and access your keys by entering your seed phrase")
|
||||
} else {
|
||||
//% "Login failed"
|
||||
importLoginError.title = qsTrId("login-failed")
|
||||
//% "Login failed. Please re-enter your password and try again."
|
||||
importLoginError.text = qsTrId("login-failed.-please-re-enter-your-password-and-try-again.")
|
||||
}
|
||||
importLoginError.open()
|
||||
}
|
||||
}
|
||||
|
||||
MessageDialog {
|
||||
id: importLoginError
|
||||
//% "Login failed"
|
||||
title: qsTrId("login-failed")
|
||||
//% "Login failed. Please re-enter your password and try again."
|
||||
text: qsTrId("login-failed.-please-re-enter-your-password-and-try-again.")
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
onVisibilityChanged: {
|
||||
submitBtn.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
|
||||
import utils 1.0
|
||||
|
||||
|
@ -19,14 +20,35 @@ Item {
|
|||
enterSeedPhraseModal.open()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: onboardingModule
|
||||
onAccountImportError: {
|
||||
if (error === Constants.existingAccountError) {
|
||||
importSeedError.title = qsTr("Keys for this account already exist")
|
||||
importSeedError.text = qsTr("Keys for this account already exist and can't be added again. If you've lost your password, passcode or Keycard, uninstall the app, reinstall and access your keys by entering your seed phrase")
|
||||
} else {
|
||||
importSeedError.title = qsTr("Error importing seed")
|
||||
importSeedError.text = error
|
||||
}
|
||||
importSeedError.open()
|
||||
}
|
||||
onAccountImportSuccess: {
|
||||
enterSeedPhraseModal.wentNext = true
|
||||
enterSeedPhraseModal.close()
|
||||
recoverySuccessModal.open()
|
||||
}
|
||||
}
|
||||
MessageDialog {
|
||||
id: importSeedError
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
EnterSeedPhraseModal {
|
||||
property bool wentNext: false
|
||||
id: enterSeedPhraseModal
|
||||
onConfirmSeedClick: function (mnemonic) {
|
||||
wentNext = true
|
||||
enterSeedPhraseModal.close()
|
||||
OnboardingStore.importMnemonic(mnemonic)
|
||||
recoverySuccessModal.open()
|
||||
}
|
||||
onClosed: function () {
|
||||
if (!wentNext) {
|
||||
|
|
|
@ -247,4 +247,6 @@ QtObject {
|
|||
}
|
||||
|
||||
readonly property bool isCppApp: typeof cppApp !== "undefined" ? cppApp : false
|
||||
|
||||
readonly property string existingAccountError: "account already exists"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue