Skip to content

Commit

Permalink
fix(re-encryption): make sure loading screen is shown when re-encrypting
Browse files Browse the repository at this point in the history
Fixes #10352

Adds a 1 second timer before re-encrypting, to make sure the loading screen is shown before it starts, since it can freeze.
  • Loading branch information
jrainville committed Apr 24, 2023
1 parent 435b085 commit 10b8d38
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 19 deletions.
9 changes: 6 additions & 3 deletions src/app/modules/startup/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ proc init*(self: Controller) =
self.delegate.onReencryptionProcessStarted()
self.connectionIds.add(handlerId)

handlerId = self.events.onWithUUID(SIGNAL_LOGIN_ERROR) do(e: Args):
let args = LoginErrorArgs(e)
self.delegate.emitAccountLoginError(args.error)
self.connectionIds.add(handlerId)

proc shouldStartWithOnboardingScreen*(self: Controller): bool =
return self.accountsService.openedAccounts().len == 0

Expand Down Expand Up @@ -440,9 +445,7 @@ proc isSelectedAccountAKeycardAccount*(self: Controller): bool =
proc login*(self: Controller) =
self.delegate.moveToLoadingAppState()
let selectedAccount = self.getSelectedLoginAccount()
let error = self.accountsService.login(selectedAccount, self.tmpPassword)
if(error.len > 0):
self.delegate.emitAccountLoginError(error)
self.accountsService.login(selectedAccount, self.tmpPassword)

proc loginAccountKeycard*(self: Controller, storeToKeychainValue: string, syncWalletAfterLogin = false) =
if syncWalletAfterLogin:
Expand Down
78 changes: 62 additions & 16 deletions src/app_service/service/accounts/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,21 @@ let TEST_PEER_ENR = getEnv("TEST_PEER_ENR").string
const SIGNAL_CONVERTING_PROFILE_KEYPAIR* = "convertingProfileKeypair"
const SIGNAL_DERIVED_ADDRESSES_FROM_NOT_IMPORTED_MNEMONIC_FETCHED* = "derivedAddressesFromNotImportedMnemonicFetched"
const SIGNAL_REENCRYPTION_PROCESS_STARTED* = "reencryptionProcessStarted"
const SIGNAL_LOGIN_ERROR* = "errorWhileLogin"

type ResultArgs* = ref object of Args
success*: bool

type LoginErrorArgs* = ref object of Args
error*: string

type DerivedAddressesFromNotImportedMnemonicArgs* = ref object of Args
error*: string
derivations*: Table[string, DerivedAccountDetails]

include utils
include async_tasks
include ../../common/async_tasks

QtObject:
type Service* = ref object of QObject
Expand All @@ -60,6 +65,12 @@ QtObject:
importedAccount: GeneratedAccountDto
keyStoreDir: string
defaultWalletEmoji: string
tmpAccount: AccountDto
tmpPassword: string
tmpHashedPassword: string
tmpThumbnailImage: string
tmpLargeImage: string
tmpNodeCfg: JsonNode

proc delete*(self: Service) =
self.QObject.delete
Expand Down Expand Up @@ -595,7 +606,19 @@ QtObject:
except Exception as e:
error "error: ", procName="verifyDatabasePassword", errName = e.name, errDesription = e.msg

proc login*(self: Service, account: AccountDto, password: string): string =
proc doLogin(self: Service, account: AccountDto, hashedPassword, thumbnailImage, largeImage: string, nodeCfg: JsonNode) =
let response = status_account.login(
account.name, account.keyUid, account.kdfIterations, hashedPassword, thumbnailImage, largeImage, $nodeCfg
)
if response.result{"error"}.getStr != "":
self.events.emit(SIGNAL_LOGIN_ERROR, LoginErrorArgs(error: response.result{"error"}.getStr))
return

debug "Account logged in"
self.loggedInAccount = account
self.setLocalAccountSettingsFile()

proc login*(self: Service, account: AccountDto, password: string) =
try:
let hashedPassword = hashPassword(password)
var thumbnailImage: string
Expand Down Expand Up @@ -668,27 +691,50 @@ QtObject:
"RendezvousNodes": @[],
"DiscV5BootstrapNodes": @[]
}



let isOldHashPassword = self.verifyDatabasePassword(account.keyUid, hashPassword(password, lower=false))
if isOldHashPassword:
# Start loading screen with warning
self.events.emit(SIGNAL_REENCRYPTION_PROCESS_STARTED, Args())
discard status_privacy.lowerDatabasePassword(account.keyUid, password)

# Save tmp properties so that we can login after the timer
self.tmpAccount = account
self.tmpPassword = password
self.tmpHashedPassword = hashedPassword
self.tmpThumbnailImage = thumbnailImage
self.tmpLargeImage = largeImage
self.tmpNodeCfg = nodeCfg

# Start a 1 second timer for the loading screen to appear
let arg = TimerTaskArg(
tptr: cast[ByteAddress](timerTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onWaitForReencryptionTimeout",
timeoutInMilliseconds: 1000
)
self.threadpool.start(arg)
return

let response = status_account.login(
account.name, account.keyUid, account.kdfIterations, hashedPassword, thumbnailImage, largeImage, $nodeCfg
)
if response.result{"error"}.getStr == "":
debug "Account logged in"
self.loggedInAccount = account
self.setLocalAccountSettingsFile()
return ""

return response.result{"error"}.getStr

self.doLogin(account, hashedPassword, thumbnailImage, largeImage, nodeCfg)
except Exception as e:
error "error: ", procName="login", errName = e.name, errDesription = e.msg
return e.msg
self.events.emit(SIGNAL_LOGIN_ERROR, LoginErrorArgs(error: e.msg))

proc onWaitForReencryptionTimeout(self: Service, response: string) {.slot.} =
# Reencryption (can freeze and take up to 30 minutes)
let pwd = self.tmpPassword
self.tmpPassword = "" # Clear the password from memory as fast as possible
discard status_privacy.lowerDatabasePassword(self.tmpAccount.keyUid, pwd)

# Normal login after reencryption
self.doLogin(self.tmpAccount, self.tmpHashedPassword, self.tmpThumbnailImage, self.tmpLargeImage, self.tmpNodeCfg)

# Clear out the temp properties
self.tmpAccount = AccountDto()
self.tmpHashedPassword = ""
self.tmpThumbnailImage = ""
self.tmpLargeImage = ""
self.tmpNodeCfg = JsonNode()

proc loginAccountKeycard*(self: Service, accToBeLoggedIn: AccountDto, keycardData: KeycardEvent): string =
try:
Expand Down

0 comments on commit 10b8d38

Please sign in to comment.