feat(@desktop/wallet): adding factory reset keycard flow as a continuation to the stop-using keycard flow

Part 2 of: #11737
This commit is contained in:
Sale Djenic 2023-08-30 17:54:41 +02:00 committed by saledjenic
parent c59f6d72d8
commit 45f7299202
11 changed files with 86 additions and 47 deletions

View File

@ -37,7 +37,7 @@ proc init*(self: Controller) =
let args = SharedKeycarModuleFlowTerminatedArgs(e)
if args.uniqueIdentifier != UNIQUE_SETTING_KEYCARD_MODULE_IDENTIFIER:
return
self.delegate.onSharedKeycarModuleFlowTerminated(args.lastStepInTheCurrentFlow)
self.delegate.onSharedKeycarModuleFlowTerminated(args.lastStepInTheCurrentFlow, args.continueWithNextFlow)
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_DISPLAY_POPUP) do(e: Args):
let args = SharedKeycarModuleBaseArgs(e)

View File

@ -1,5 +1,6 @@
import NimQml
import app_service/service/wallet_account/dto/keypair_dto
import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
@ -23,7 +24,8 @@ method getKeycardSharedModule*(self: AccessInterface): QVariant {.base.} =
method onDisplayKeycardSharedModuleFlow*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onSharedKeycarModuleFlowTerminated*(self: AccessInterface, lastStepInTheCurrentFlow: bool) {.base.} =
method onSharedKeycarModuleFlowTerminated*(self: AccessInterface, lastStepInTheCurrentFlow: bool,
nextFlow: FlowType) {.base.} =
raise newException(ValueError, "No implementation available")
method runSetupKeycardPopup*(self: AccessInterface, keyUid: string) {.base.} =

View File

@ -105,11 +105,17 @@ proc createSharedKeycardModule(self: Module) =
self.events, self.keycardService, self.settingsService, self.networkService, self.privacyService, self.accountsService,
self.walletAccountService, self.keychainService)
method onSharedKeycarModuleFlowTerminated*(self: Module, lastStepInTheCurrentFlow: bool) =
method onSharedKeycarModuleFlowTerminated*(self: Module, lastStepInTheCurrentFlow: bool, nextFlow: keycard_shared_module.FlowType) =
echo "onSharedKeycarModuleFlowTerminated lastStepInTheCurrentFlow=", lastStepInTheCurrentFlow, " nextFlow=", nextFlow
if self.isSharedKeycardModuleFlowRunning():
self.view.emitDestroyKeycardSharedModuleFlow()
self.keycardSharedModule.delete
self.keycardSharedModule = nil
echo "onSharedKeycarModuleFlowTerminated isSharedKeycardModuleFlowRunning=true"
if nextFlow == keycard_shared_module.FlowType.General:
self.view.emitDestroyKeycardSharedModuleFlow()
self.keycardSharedModule.delete
self.keycardSharedModule = nil
return
let keyUid = self.keycardSharedModule.getKeyPairForProcessing().getKeyUid()
self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.FactoryReset, keyUid)
method onDisplayKeycardSharedModuleFlow*(self: Module) =
self.view.emitDisplayKeycardSharedModuleFlow()

View File

@ -585,12 +585,13 @@ proc finishFlowTermination(self: Controller) =
self.cleanTmpData()
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_FLOW_TERMINATED, data)
proc terminateCurrentFlow*(self: Controller, lastStepInTheCurrentFlow: bool) =
proc terminateCurrentFlow*(self: Controller, lastStepInTheCurrentFlow: bool, nextFlow = FlowType.General) =
let flowType = self.delegate.getCurrentFlowType()
self.cancelCurrentFlow()
let (_, flowEvent) = self.getLastReceivedKeycardData()
self.tmpFlowData = SharedKeycarModuleFlowTerminatedArgs(uniqueIdentifier: self.uniqueIdentifier,
lastStepInTheCurrentFlow: lastStepInTheCurrentFlow)
lastStepInTheCurrentFlow: lastStepInTheCurrentFlow,
continueWithNextFlow: nextFlow)
if lastStepInTheCurrentFlow:
var exportedEncryptionPubKey: string
if flowEvent.generatedWalletAccounts.len > 0:

View File

@ -31,4 +31,11 @@ method executePrePrimaryStateCommand*(self: KeyPairMigrateSuccessState, controll
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
if profileMigrated:
info "restart the app because of successfully migrated profile keypair"
quit() # quit the app
quit() # quit the app
method executePreSecondaryStateCommand*(self: KeyPairMigrateSuccessState, controller: Controller) =
if self.flowType == FlowType.MigrateFromKeycardToApp:
let profileMigrated = controller.getKeyPairForProcessing().getKeyUid() == singletonInstance.userProfile.getKeyUid()
if profileMigrated:
return
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true, FlowType.FactoryReset)

View File

@ -21,20 +21,22 @@ method getNextSecondaryState*(self: ReadingKeycardState, controller: Controller)
# this is used in case a keycard is not inserted in the moment when flow is run (we're animating an insertion)
return self.resolveKeycardNextState(flowType, flowEvent, controller)
method resolveKeycardNextState*(self: ReadingKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,
method resolveKeycardNextState*(self: ReadingKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =
if self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk or
self.flowType == FlowType.ChangePairingCode or
(self.flowType == FlowType.CreateCopyOfAKeycard and
not isPredefinedKeycardDataFlagSet(controller.getKeycardData(), PredefinedKeycardData.CopyFromAKeycardPartDone)):
(self.flowType == FlowType.CreateCopyOfAKeycard and
not isPredefinedKeycardDataFlagSet(controller.getKeycardData(), PredefinedKeycardData.CopyFromAKeycardPartDone)) or
self.flowType == FlowType.FactoryReset and
not controller.getKeyPairForProcessing().isNil:
# this part is only for the flows which are card specific (the card we're running a flow for is known in advance)
let ensureKeycardPresenceState = ensureReaderAndCardPresence(self, keycardFlowType, keycardEvent, controller)
if ensureKeycardPresenceState.isNil: # means the keycard is inserted
let nextState = ensureReaderAndCardPresenceAndResolveNextState(self, keycardFlowType, keycardEvent, controller)
if not nextState.isNil and
if not nextState.isNil and
(nextState.stateType == StateType.KeycardEmpty or
nextState.stateType == StateType.NotKeycard or
nextState.stateType == StateType.KeycardEmptyMetadata):

View File

@ -14,7 +14,8 @@ method executePrePrimaryStateCommand*(self: WrongKeycardState, controller: Contr
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk or
self.flowType == FlowType.ChangePairingCode or
self.flowType == FlowType.CreateCopyOfAKeycard:
self.flowType == FlowType.CreateCopyOfAKeycard or
self.flowType == FlowType.FactoryReset:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
method executeCancelCommand*(self: WrongKeycardState, controller: Controller) =
@ -24,5 +25,6 @@ method executeCancelCommand*(self: WrongKeycardState, controller: Controller) =
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk or
self.flowType == FlowType.ChangePairingCode or
self.flowType == FlowType.CreateCopyOfAKeycard:
self.flowType == FlowType.CreateCopyOfAKeycard or
self.flowType == FlowType.FactoryReset:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -4,6 +4,37 @@ from app_service/service/keycard/service import KeycardEvent, CardMetadata, KeyD
from app_service/service/wallet_account/service as wallet_account_service import WalletTokenDto
import app/modules/shared_models/keypair_item
type FlowType* {.pure.} = enum
General = "General"
FactoryReset = "FactoryReset"
SetupNewKeycard = "SetupNewKeycard"
SetupNewKeycardNewSeedPhrase = "SetupNewKeycardNewSeedPhrase"
SetupNewKeycardOldSeedPhrase = "SetupNewKeycardOldSeedPhrase"
ImportFromKeycard = "ImportFromKeycard"
Authentication = "Authentication"
UnlockKeycard = "UnlockKeycard"
DisplayKeycardContent = "DisplayKeycardContent"
RenameKeycard = "RenameKeycard"
ChangeKeycardPin = "ChangeKeycardPin"
ChangeKeycardPuk = "ChangeKeycardPuk"
ChangePairingCode = "ChangePairingCode"
CreateCopyOfAKeycard = "CreateCopyOfAKeycard"
MigrateFromKeycardToApp = "MigrateFromKeycardToApp"
# For the following flows we don't run card syncing.
const FlowsWeShouldNotTryAKeycardSyncFor* = @[
FlowType.General,
FlowType.FactoryReset,
FlowType.UnlockKeycard,
FlowType.SetupNewKeycard,
FlowType.SetupNewKeycardNewSeedPhrase,
FlowType.SetupNewKeycardOldSeedPhrase,
FlowType.ImportFromKeycard,
FlowType.Authentication,
FlowType.CreateCopyOfAKeycard,
FlowType.MigrateFromKeycardToApp
]
const SIGNAL_SHARED_KEYCARD_MODULE_DISPLAY_POPUP* = "sharedKeycarModuleDisplayPopup"
const SIGNAL_SHARED_KEYCARD_MODULE_FLOW_TERMINATED* = "sharedKeycarModuleFlowTerminated"
const SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER* = "sharedKeycarModuleAuthenticateUser"
@ -43,43 +74,13 @@ type
type
SharedKeycarModuleFlowTerminatedArgs* = ref object of SharedKeycarModuleArgs
lastStepInTheCurrentFlow*: bool
continueWithNextFlow*: FlowType
type
SharedKeycarModuleAuthenticationArgs* = ref object of SharedKeycarModuleBaseArgs
keyUid*: string
additionalBip44Paths*: seq[string] # can be used in authentication flow to export additinal paths if needed except encryption path
type FlowType* {.pure.} = enum
General = "General"
FactoryReset = "FactoryReset"
SetupNewKeycard = "SetupNewKeycard"
SetupNewKeycardNewSeedPhrase = "SetupNewKeycardNewSeedPhrase"
SetupNewKeycardOldSeedPhrase = "SetupNewKeycardOldSeedPhrase"
ImportFromKeycard = "ImportFromKeycard"
Authentication = "Authentication"
UnlockKeycard = "UnlockKeycard"
DisplayKeycardContent = "DisplayKeycardContent"
RenameKeycard = "RenameKeycard"
ChangeKeycardPin = "ChangeKeycardPin"
ChangeKeycardPuk = "ChangeKeycardPuk"
ChangePairingCode = "ChangePairingCode"
CreateCopyOfAKeycard = "CreateCopyOfAKeycard"
MigrateFromKeycardToApp = "MigrateFromKeycardToApp"
# For the following flows we don't run card syncing.
const FlowsWeShouldNotTryAKeycardSyncFor* = @[
FlowType.General,
FlowType.FactoryReset,
FlowType.UnlockKeycard,
FlowType.SetupNewKeycard,
FlowType.SetupNewKeycardNewSeedPhrase,
FlowType.SetupNewKeycardOldSeedPhrase,
FlowType.ImportFromKeycard,
FlowType.Authentication,
FlowType.CreateCopyOfAKeycard,
FlowType.MigrateFromKeycardToApp
]
type
AccessInterface* {.pure inheritable.} = ref object of RootObj

View File

@ -447,6 +447,8 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Paths
return
self.init()
if flowToRun == FlowType.FactoryReset:
if keyUid.len > 0:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true)
return

View File

@ -747,6 +747,7 @@ QtObject {
case Constants.keycardSharedState.keycardEmpty:
case Constants.keycardSharedState.factoryResetSuccess:
case Constants.keycardSharedState.wrongKeycard:
return qsTr("Done")
}
break

View File

@ -217,6 +217,13 @@ Item {
if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay) {
return true
}
if(!!root.sharedKeycardModule.keyPairForProcessing &&
(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.insertKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardInserted ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard))
return true
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication &&
!!root.sharedKeycardModule.keyPairForProcessing &&
@ -386,6 +393,13 @@ Item {
}
return unknownKeyPairCompontnt
}
if(!!root.sharedKeycardModule.keyPairForProcessing &&
(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.insertKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardInserted ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard))
return keyPairForProcessingComponent
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication) {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardInserted ||
@ -777,7 +791,8 @@ Item {
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPuk ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changePairingCode ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard) {
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.factoryReset) {
return qsTr("Keycard inserted does not match the Keycard below")
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {