diff --git a/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim index f756f28fad..8644563e7a 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim @@ -19,12 +19,12 @@ method getNextPrimaryState*(self: PinSetState, controller: Controller): State = if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: return createState(StateType.EnterKeycardName, self.flowType, nil) if self.flowType == FlowType.UnlockKeycard: - if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata: + if controller.unlockUsingSeedPhrase(): + return createState(StateType.UnlockingKeycard, self.flowType, nil) + else: if controller.getValidPuk(): - return createState(StateType.UnlockKeycardSuccess, self.flowType, nil) + return createState(StateType.UnlockingKeycard, self.flowType, nil) return createState(StateType.WrongPuk, self.flowType, self.getBackState) - if controller.getCurrentKeycardServiceFlow() == KCSFlowType.StoreMetadata: - return createState(StateType.UnlockKeycardSuccess, self.flowType, nil) method executeCancelCommand*(self: PinSetState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim index 22a7e704f8..505f1730d2 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim @@ -20,16 +20,17 @@ method executePreSecondaryStateCommand*(self: RepeatPinState, controller: Contro self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK()) if self.flowType == FlowType.UnlockKeycard: - if controller.unlockUsingSeedPhrase(): - controller.runGetMetadataFlow() - return - controller.storePinToKeycard(controller.getPin(), "") + if not controller.unlockUsingSeedPhrase(): + controller.storePinToKeycard(controller.getPin(), "") method getNextSecondaryState*(self: RepeatPinState, controller: Controller): State = if not controller.getPinMatch(): return if self.flowType == FlowType.ChangeKeycardPin: return createState(StateType.ChangingKeycardPin, self.flowType, nil) + if self.flowType == FlowType.UnlockKeycard: + if controller.unlockUsingSeedPhrase(): + return createState(StateType.UnlockingKeycard, self.flowType, nil) method executeCancelCommand*(self: RepeatPinState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or @@ -79,27 +80,4 @@ method resolveKeycardNextState*(self: RepeatPinState, keycardFlowType: string, k return createState(StateType.MaxPukRetriesReached, self.flowType, nil) if keycardFlowType == ResponseTypeValueKeycardFlowResult: controller.setPukValid(true) - controller.updateKeycardUid(keycardEvent.keyUid, keycardEvent.instanceUID) - return createState(StateType.PinSet, self.flowType, nil) - else: - if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata: - controller.setMetadataFromKeycard(keycardEvent.cardMetadata) - if keycardFlowType == ResponseTypeValueKeycardFlowResult: - if keycardEvent.error.len == 0: - controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), controller.getPin(), puk = "", - factoryReset = true) - return - if controller.getCurrentKeycardServiceFlow() == KCSFlowType.LoadAccount: - if keycardFlowType == ResponseTypeValueKeycardFlowResult: - if controller.getKeyPairForProcessing().getKeyUid() != keycardEvent.keyUid: - error "load account keyUid and keyUid being unlocked do not match" - controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) - return - controller.updateKeycardUid(keycardEvent.keyUid, keycardEvent.instanceUID) - let md = controller.getMetadataFromKeycard() - let paths = md.walletAccounts.map(a => a.path) - controller.runStoreMetadataFlow(cardName = md.name, pin = controller.getPin(), walletPaths = paths) - if controller.getCurrentKeycardServiceFlow() == KCSFlowType.StoreMetadata: - if keycardFlowType == ResponseTypeValueKeycardFlowResult and - keycardEvent.instanceUID.len > 0: - return createState(StateType.PinSet, self.flowType, nil) \ No newline at end of file + return createState(StateType.PinSet, self.flowType, nil) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state.nim b/src/app/modules/shared_modules/keycard_popup/internal/state.nim index 91cc56e1b6..44a5186267 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state.nim @@ -32,6 +32,8 @@ type StateType* {.pure.} = enum KeycardLocked = "KeycardLocked" KeycardAlreadyUnlocked = "KeycardAlreadyUnlocked" UnlockKeycardOptions = "UnlockKeycardOptions" + UnlockingKeycard = "UnlockingKeycard" + UnlockKeycardFailure = "UnlockKeycardFailure" UnlockKeycardSuccess = "UnlockKeycardSuccess" NotKeycard = "NotKeycard" WrongKeycard = "WrongKeycard" diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim b/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim index fd1b165327..eebdbcadaa 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim @@ -105,6 +105,8 @@ include seed_phrase_display_state include seed_phrase_enter_words_state include select_existing_key_pair_state include unlock_keycard_options_state +include unlocking_keycard_state +include unlock_keycard_failure_state include unlock_keycard_success_state include wrong_biometrics_password_state include wrong_keycard_state diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim b/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim index 9e0c5c7788..aafab26588 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim @@ -131,6 +131,10 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St return newKeycardAlreadyUnlockedState(flowType, backState) if stateToBeCreated == StateType.UnlockKeycardOptions: return newUnlockKeycardOptionsState(flowType, backState) + if stateToBeCreated == StateType.UnlockingKeycard: + return newUnlockingKeycardState(flowType, backState) + if stateToBeCreated == StateType.UnlockKeycardFailure: + return newUnlockKeycardFailureState(flowType, backState) if stateToBeCreated == StateType.UnlockKeycardSuccess: return newUnlockKeycardSuccessState(flowType, backState) if stateToBeCreated == StateType.MaxPinRetriesReached: diff --git a/src/app/modules/shared_modules/keycard_popup/internal/unlock_keycard_failure_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/unlock_keycard_failure_state.nim new file mode 100644 index 0000000000..b28a541c2b --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/unlock_keycard_failure_state.nim @@ -0,0 +1,17 @@ +type + UnlockKeycardFailureState* = ref object of State + +proc newUnlockKeycardFailureState*(flowType: FlowType, backState: State): UnlockKeycardFailureState = + result = UnlockKeycardFailureState() + result.setup(flowType, StateType.UnlockKeycardFailure, backState) + +proc delete*(self: UnlockKeycardFailureState) = + self.State.delete + +method executePrePrimaryStateCommand*(self: UnlockKeycardFailureState, controller: Controller) = + if self.flowType == FlowType.UnlockKeycard: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) + +method executeCancelCommand*(self: UnlockKeycardFailureState, controller: Controller) = + if self.flowType == FlowType.UnlockKeycard: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/unlocking_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/unlocking_keycard_state.nim new file mode 100644 index 0000000000..2226988298 --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/unlocking_keycard_state.nim @@ -0,0 +1,52 @@ +type + UnlockingKeycardState* = ref object of State + +proc newUnlockingKeycardState*(flowType: FlowType, backState: State): UnlockingKeycardState = + result = UnlockingKeycardState() + result.setup(flowType, StateType.UnlockingKeycard, backState) + +proc delete*(self: UnlockingKeycardState) = + self.State.delete + +method executePrePrimaryStateCommand*(self: UnlockingKeycardState, controller: Controller) = + if self.flowType == FlowType.UnlockKeycard: + if controller.unlockUsingSeedPhrase(): + controller.runGetMetadataFlow() + else: + let (_, flowEvent) = controller.getLastReceivedKeycardData() + controller.updateKeycardUid(flowEvent.keyUid, flowEvent.instanceUID) + +method getNextPrimaryState*(self: UnlockingKeycardState, controller: Controller): State = + if self.flowType == FlowType.UnlockKeycard: + if not controller.unlockUsingSeedPhrase(): + return createState(StateType.UnlockKeycardSuccess, self.flowType, nil) + +method resolveKeycardNextState*(self: UnlockingKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent, + controller: Controller): State = + let state = ensureReaderAndCardPresence(self, keycardFlowType, keycardEvent, controller) + if not state.isNil: + return state + if self.flowType == FlowType.UnlockKeycard: + if controller.unlockUsingSeedPhrase(): + if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata: + controller.setMetadataFromKeycard(keycardEvent.cardMetadata) + if keycardFlowType == ResponseTypeValueKeycardFlowResult: + if keycardEvent.error.len == 0: + controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), controller.getPin(), puk = "", + factoryReset = true) + return + if controller.getCurrentKeycardServiceFlow() == KCSFlowType.LoadAccount: + if keycardFlowType == ResponseTypeValueKeycardFlowResult: + if controller.getKeyPairForProcessing().getKeyUid() != keycardEvent.keyUid: + error "load account keyUid and keyUid being unlocked do not match" + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) + return + controller.updateKeycardUid(keycardEvent.keyUid, keycardEvent.instanceUID) + let md = controller.getMetadataFromKeycard() + let paths = md.walletAccounts.map(a => a.path) + controller.runStoreMetadataFlow(cardName = md.name, pin = controller.getPin(), walletPaths = paths) + if controller.getCurrentKeycardServiceFlow() == KCSFlowType.StoreMetadata: + if keycardFlowType == ResponseTypeValueKeycardFlowResult and + keycardEvent.instanceUID.len > 0: + return createState(StateType.UnlockKeycardSuccess, self.flowType, nil) + return createState(StateType.UnlockKeycardFailure, self.flowType, nil) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/wrong_puk_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/wrong_puk_state.nim index ab1b183016..1be8d2799c 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/wrong_puk_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/wrong_puk_state.nim @@ -38,5 +38,4 @@ method resolveKeycardNextState*(self: WrongPukState, keycardFlowType: string, ke if keycardFlowType == ResponseTypeValueKeycardFlowResult: if keycardEvent.error.len == 0: controller.setPukValid(true) - controller.updateKeycardUid(keycardEvent.keyUid, keycardEvent.instanceUID) - return createState(StateType.UnlockKeycardSuccess, self.flowType, nil) \ No newline at end of file + return createState(StateType.UnlockingKeycard, self.flowType, nil) \ No newline at end of file diff --git a/ui/imports/shared/popups/keycard/KeycardPopupContent.qml b/ui/imports/shared/popups/keycard/KeycardPopupContent.qml index b9572607a8..08cdbe1dab 100644 --- a/ui/imports/shared/popups/keycard/KeycardPopupContent.qml +++ b/ui/imports/shared/popups/keycard/KeycardPopupContent.qml @@ -57,6 +57,8 @@ Item { case Constants.keycardSharedState.keycardAlreadyUnlocked: case Constants.keycardSharedState.notKeycard: case Constants.keycardSharedState.unlockKeycardOptions: + case Constants.keycardSharedState.unlockingKeycard: + case Constants.keycardSharedState.unlockKeycardFailure: case Constants.keycardSharedState.unlockKeycardSuccess: case Constants.keycardSharedState.wrongKeycard: case Constants.keycardSharedState.biometricsReadyToSign: diff --git a/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml b/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml index 02fa1bc8b9..34b00d4cc7 100644 --- a/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml +++ b/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml @@ -25,6 +25,7 @@ QtObject { case Constants.keycardSharedState.readingKeycard: case Constants.keycardSharedState.recognizedKeycard: case Constants.keycardSharedState.renamingKeycard: + case Constants.keycardSharedState.unlockingKeycard: case Constants.keycardSharedState.changingKeycardPin: case Constants.keycardSharedState.changingKeycardPuk: case Constants.keycardSharedState.changingKeycardPairingCode: @@ -764,6 +765,8 @@ QtObject { case Constants.keycardSharedState.keycardEmptyMetadata: case Constants.keycardSharedState.keycardAlreadyUnlocked: case Constants.keycardSharedState.wrongKeycard: + case Constants.keycardSharedState.unlockingKeycard: + case Constants.keycardSharedState.unlockKeycardFailure: case Constants.keycardSharedState.unlockKeycardSuccess: return qsTr("Done") diff --git a/ui/imports/shared/popups/keycard/states/KeycardInit.qml b/ui/imports/shared/popups/keycard/states/KeycardInit.qml index aa75625bd2..828d623342 100644 --- a/ui/imports/shared/popups/keycard/states/KeycardInit.qml +++ b/ui/imports/shared/popups/keycard/states/KeycardInit.qml @@ -21,6 +21,7 @@ Item { root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.importingFromKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.copyingKeycard) { root.sharedKeycardModule.currentState.doPrimaryAction() } @@ -35,6 +36,7 @@ Item { root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.importingFromKeycard || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.copyingKeycard } @@ -132,6 +134,7 @@ Item { root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.importingFromKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPairingCode || @@ -555,6 +558,7 @@ Item { root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.importingFromKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPairingCode || @@ -580,6 +584,9 @@ Item { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard) { return qsTr("Renaming keycard...") } + if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockingKeycard) { + return qsTr("Unlocking keycard...") + } if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin) { return qsTr("Updating PIN") } @@ -1009,6 +1016,7 @@ Item { root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.importingFromKeycardFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPairingCodeFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.copyingKeycardFailure @@ -1030,6 +1038,9 @@ Item { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure) { return qsTr("Keycard renaming failed") } + if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardFailure) { + return qsTr("Unlock a Keycard failed") + } if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukFailure) { return qsTr("Setting Keycard’s PUK failed") } diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index 94793526dd..4c8ffa86be 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -147,6 +147,8 @@ QtObject { readonly property string keycardAlreadyUnlocked: "KeycardAlreadyUnlocked" readonly property string notKeycard: "NotKeycard" readonly property string unlockKeycardOptions: "UnlockKeycardOptions" + readonly property string unlockingKeycard: "UnlockingKeycard" + readonly property string unlockKeycardFailure: "UnlockKeycardFailure" readonly property string unlockKeycardSuccess: "UnlockKeycardSuccess" readonly property string wrongKeycard: "WrongKeycard" readonly property string recognizedKeycard: "RecognizedKeycard"