feat(@desktop/keycard): `unlocking` screen for unlock flow

Closes: #9259
This commit is contained in:
Sale Djenic 2023-01-27 17:04:07 +01:00 committed by Anthony Laibe
parent 841a37e930
commit bc7a4b94f7
12 changed files with 106 additions and 34 deletions

View File

@ -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

View File

@ -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)
return createState(StateType.PinSet, self.flowType, nil)

View File

@ -32,6 +32,8 @@ type StateType* {.pure.} = enum
KeycardLocked = "KeycardLocked"
KeycardAlreadyUnlocked = "KeycardAlreadyUnlocked"
UnlockKeycardOptions = "UnlockKeycardOptions"
UnlockingKeycard = "UnlockingKeycard"
UnlockKeycardFailure = "UnlockKeycardFailure"
UnlockKeycardSuccess = "UnlockKeycardSuccess"
NotKeycard = "NotKeycard"
WrongKeycard = "WrongKeycard"

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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)
return createState(StateType.UnlockingKeycard, self.flowType, nil)

View File

@ -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:

View File

@ -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")

View File

@ -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 Keycards PUK failed")
}

View File

@ -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"