feat(@desktop/keycard): change pin flow added

Fixes: #7034
This commit is contained in:
Sale Djenic 2022-10-17 12:12:22 +02:00 committed by saledjenic
parent 48d1ae5cd1
commit 9b2a63c400
36 changed files with 406 additions and 74 deletions

View File

@ -50,7 +50,7 @@ method runFactoryResetPopup*(self: AccessInterface) {.base.} =
method runRenameKeycardPopup*(self: AccessInterface, keycardUid: string, keyUid: string) {.base.} =
raise newException(ValueError, "No implementation available")
method runChangePinPopup*(self: AccessInterface) {.base.} =
method runChangePinPopup*(self: AccessInterface, keycardUid: string, keyUid: string) {.base.} =
raise newException(ValueError, "No implementation available")
method runCreateBackupCopyOfAKeycardPopup*(self: AccessInterface) {.base.} =

View File

@ -145,8 +145,12 @@ method runRenameKeycardPopup*(self: Module, keycardUid: string, keyUid: string)
self.keycardSharedModule.setUidOfAKeycardWhichNeedToBeProcessed(keycardUid)
self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.RenameKeycard, keyUid)
method runChangePinPopup*(self: Module) =
info "TODO: Change PIN for a Keycard..."
method runChangePinPopup*(self: Module, keycardUid: string, keyUid: string) =
self.createSharedKeycardModule()
if self.keycardSharedModule.isNil:
return
self.keycardSharedModule.setUidOfAKeycardWhichNeedToBeProcessed(keycardUid)
self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.ChangeKeycardPin, keyUid)
method runCreateBackupCopyOfAKeycardPopup*(self: Module) =
info "TODO: Create a Backup Copy of a Keycard..."

View File

@ -67,8 +67,8 @@ QtObject:
proc runRenameKeycardPopup*(self: View, keycardUid: string, keyUid: string) {.slot.} =
self.delegate.runRenameKeycardPopup(keycardUid, keyUid)
proc runChangePinPopup*(self: View) {.slot.} =
self.delegate.runChangePinPopup()
proc runChangePinPopup*(self: View, keycardUid: string, keyUid: string) {.slot.} =
self.delegate.runChangePinPopup(keycardUid, keyUid)
proc runCreateBackupCopyOfAKeycardPopup*(self: View) {.slot.} =
self.delegate.runCreateBackupCopyOfAKeycardPopup()

View File

@ -300,6 +300,10 @@ proc runGetMetadataFlow*(self: Controller, resolveAddress = false) =
self.cancelCurrentFlow()
self.keycardService.startGetMetadataFlow(resolveAddress)
proc runChangePinFlow*(self: Controller) =
self.cancelCurrentFlow()
self.keycardService.startChangePinFlow()
proc runStoreMetadataFlow*(self: Controller, cardName: string, pin: string, walletPaths: seq[string]) =
self.cancelCurrentFlow()
self.keycardService.startStoreMetadataFlow(cardName, pin, walletPaths)

View File

@ -0,0 +1,17 @@
type
ChangingKeycardPinState* = ref object of State
proc newChangingKeycardPinState*(flowType: FlowType, backState: State): ChangingKeycardPinState =
result = ChangingKeycardPinState()
result.setup(flowType, StateType.ChangingKeycardPin, backState)
proc delete*(self: ChangingKeycardPinState) =
self.State.delete
method executeSecondaryCommand*(self: ChangingKeycardPinState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPin:
controller.storePinToKeycard(controller.getPin(), "")
method resolveKeycardNextState*(self: ChangingKeycardPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =
return ensureReaderAndCardPresenceAndResolveNextState(self, keycardFlowType, keycardEvent, controller)

View File

@ -17,11 +17,13 @@ method executeBackCommand*(self: CreatePinState, controller: Controller) =
method executeTertiaryCommand*(self: CreatePinState, controller: Controller) =
if self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.UnlockKeycard:
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method getNextSecondaryState*(self: CreatePinState, controller: Controller): State =
if self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.UnlockKeycard:
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.ChangeKeycardPin:
if controller.getPin().len == PINLengthForStatusApp:
return createState(StateType.RepeatPin, self.flowType, self)

View File

@ -20,7 +20,8 @@ method executeSecondaryCommand*(self: EnterPinState, controller: Controller) =
if self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.FactoryReset or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
if controller.getPin().len == PINLengthForStatusApp:
controller.enterKeycardPin(controller.getPin())
if self.flowType == FlowType.Authentication:
@ -32,7 +33,8 @@ method executeTertiaryCommand*(self: EnterPinState, controller: Controller) =
self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: EnterPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
@ -140,4 +142,25 @@ method resolveKeycardNextState*(self: EnterPinState, keycardFlowType: string, ke
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setMetadataFromKeycard(keycardEvent.cardMetadata, updateKeyPair = true)
return createState(StateType.PinVerified, self.flowType, nil)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPin:
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setKeycardData($keycardEvent.pinRetries)
if keycardEvent.pinRetries > 0:
return createState(StateType.WrongPin, self.flowType, nil)
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len == 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterNewPIN:
if keycardEvent.error == ErrorChangingCredentials:
return createState(StateType.PinVerified, self.flowType, nil)

View File

@ -18,7 +18,9 @@ method executeTertiaryCommand*(self: InsertKeycardState, controller: Controller)
self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent:
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: InsertKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,

View File

@ -0,0 +1,17 @@
type
ChangingKeycardPinFailureState* = ref object of State
proc newChangingKeycardPinFailureState*(flowType: FlowType, backState: State): ChangingKeycardPinFailureState =
result = ChangingKeycardPinFailureState()
result.setup(flowType, StateType.ChangingKeycardPinFailure, backState)
proc delete*(self: ChangingKeycardPinFailureState) =
self.State.delete
method executePrimaryCommand*(self: ChangingKeycardPinFailureState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
method executeTertiaryCommand*(self: ChangingKeycardPinFailureState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)

View File

@ -0,0 +1,17 @@
type
ChangingKeycardPinSuccessState* = ref object of State
proc newChangingKeycardPinSuccessState*(flowType: FlowType, backState: State): ChangingKeycardPinSuccessState =
result = ChangingKeycardPinSuccessState()
result.setup(flowType, StateType.ChangingKeycardPinSuccess, backState)
proc delete*(self: ChangingKeycardPinSuccessState) =
self.State.delete
method executePrimaryCommand*(self: ChangingKeycardPinSuccessState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
method executeTertiaryCommand*(self: ChangingKeycardPinSuccessState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)

View File

@ -13,7 +13,8 @@ method executePrimaryCommand*(self: KeycardEmptyState, controller: Controller) =
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method executeTertiaryCommand*(self: KeycardEmptyState, controller: Controller) =
@ -21,5 +22,6 @@ method executeTertiaryCommand*(self: KeycardEmptyState, controller: Controller)
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -26,5 +26,6 @@ method executeTertiaryCommand*(self: KeycardInsertedState, controller: Controlle
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -14,7 +14,8 @@ method getNextPrimaryState*(self: MaxPairingSlotsReachedState, controller: Contr
return createState(StateType.FactoryResetConfirmation, self.flowType, self)
if self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.runSharedModuleFlow(FlowType.UnlockKeycard)
return nil
@ -24,5 +25,6 @@ method executeTertiaryCommand*(self: MaxPairingSlotsReachedState, controller: Co
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -11,7 +11,8 @@ proc delete*(self: MaxPinRetriesReachedState) =
method getNextPrimaryState*(self: MaxPinRetriesReachedState, controller: Controller): State =
if self.flowType == FlowType.FactoryReset or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.runSharedModuleFlow(FlowType.UnlockKeycard)
if self.flowType == FlowType.SetupNewKeycard:
let currValue = extractPredefinedKeycardDataToNumber(controller.getKeycardData())
@ -27,7 +28,8 @@ method executeTertiaryCommand*(self: MaxPinRetriesReachedState, controller: Cont
if self.flowType == FlowType.FactoryReset or
self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
if self.flowType == FlowType.SetupNewKeycard:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseUnlockLabelForLockedState, add = false))

View File

@ -14,7 +14,8 @@ method getNextPrimaryState*(self: MaxPukRetriesReachedState, controller: Control
return createState(StateType.FactoryResetConfirmation, self.flowType, self)
if self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.runSharedModuleFlow(FlowType.UnlockKeycard)
if self.flowType == FlowType.UnlockKeycard:
return createState(StateType.EnterSeedPhrase, self.flowType, self)
@ -25,5 +26,6 @@ method executeTertiaryCommand*(self: MaxPukRetriesReachedState, controller: Cont
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -14,5 +14,6 @@ method executeTertiaryCommand*(self: NotKeycardState, controller: Controller) =
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -14,11 +14,14 @@ method getNextPrimaryState*(self: PinVerifiedState, controller: Controller): Sta
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
return createState(StateType.KeycardMetadataDisplay, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPin:
return createState(StateType.CreatePin, self.flowType, nil)
return nil
method executeTertiaryCommand*(self: PinVerifiedState, controller: Controller) =
if self.flowType == FlowType.FactoryReset or
self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -19,7 +19,8 @@ method executeTertiaryCommand*(self: PluginReaderState, controller: Controller)
self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: PluginReaderState, keycardFlowType: string, keycardEvent: KeycardEvent,

View File

@ -24,7 +24,8 @@ method getNextSecondaryState*(self: ReadingKeycardState, controller: Controller)
method resolveKeycardNextState*(self: ReadingKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =
if self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
# 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

View File

@ -27,6 +27,8 @@ method getNextSecondaryState*(self: RecognizedKeycardState, controller: Controll
return createState(StateType.EnterPin, self.flowType, nil)
if self.flowType == FlowType.RenameKeycard:
return createState(StateType.EnterPin, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPin:
return createState(StateType.EnterPin, self.flowType, nil)
method executeTertiaryCommand*(self: RecognizedKeycardState, controller: Controller) =
error "recognized state must not be canceled"

View File

@ -17,11 +17,18 @@ method executeSecondaryCommand*(self: RepeatPinState, controller: Controller) =
return
if self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.UnlockKeycard:
controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK())
controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK())
method getNextSecondaryState*(self: RepeatPinState, controller: Controller): State =
if not controller.getPinMatch():
return
if self.flowType == FlowType.ChangeKeycardPin:
return createState(StateType.ChangingKeycardPin, self.flowType, nil)
method executeTertiaryCommand*(self: RepeatPinState, controller: Controller) =
if self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.UnlockKeycard:
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: RepeatPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
@ -62,4 +69,4 @@ method resolveKeycardNextState*(self: RepeatPinState, keycardFlowType: string, k
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
keycardEvent.instanceUID.len > 0:
controller.updateKeycardUid(keycardEvent.instanceUID)
return createState(StateType.PinSet, self.flowType, nil)
return createState(StateType.PinSet, self.flowType, nil)

View File

@ -56,6 +56,9 @@ type StateType* {.pure.} = enum
RenamingKeycard = "RenamingKeycard"
KeycardRenameSuccess = "KeycardRenameSuccess"
KeycardRenameFailure = "KeycardRenameFailure"
ChangingKeycardPin = "ChangingKeycardPin"
ChangingKeycardPinSuccess = "ChangingKeycardPinSuccess"
ChangingKeycardPinFailure = "ChangingKeycardPinFailure"
## This is the base class for all state we may have in onboarding/login flow.

View File

@ -32,6 +32,7 @@ include biometrics_password_failed_state
include biometrics_pin_failed_state
include biometrics_pin_invalid_state
include biometrics_ready_to_sign_state
include changing_keycard_pin_state
include create_pin_state
include enter_biometrics_password_state
include enter_keycard_name_state
@ -45,6 +46,8 @@ include factory_reset_success_state
include insert_keycard_state
include key_pair_migrate_failure_state
include key_pair_migrate_success_state
include keycard_change_pin_failure_state
include keycard_change_pin_success_state
include keycard_empty_metadata_state
include keycard_empty_state
include keycard_inserted_state
@ -112,6 +115,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
return newBiometricsPinInvalidState(flowType, backState)
if stateToBeCreated == StateType.BiometricsReadyToSign:
return newBiometricsReadyToSignState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPin:
return newChangingKeycardPinState(flowType, backState)
if stateToBeCreated == StateType.CreatePin:
return newCreatePinState(flowType, backState)
if stateToBeCreated == StateType.EnterBiometricsPassword:
@ -138,6 +143,10 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
return newKeyPairMigrateFailureState(flowType, backState)
if stateToBeCreated == StateType.KeyPairMigrateSuccess:
return newKeyPairMigrateSuccessState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPinFailure:
return newChangingKeycardPinFailureState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPinSuccess:
return newChangingKeycardPinSuccessState(flowType, backState)
if stateToBeCreated == StateType.KeycardInserted:
return newKeycardInsertedState(flowType, backState)
if stateToBeCreated == StateType.KeycardEmptyMetadata:
@ -211,7 +220,8 @@ proc ensureReaderAndCardPresence*(state: State, keycardFlowType: string, keycard
state.flowType == FlowType.Authentication or
state.flowType == FlowType.UnlockKeycard or
state.flowType == FlowType.DisplayKeycardContent or
state.flowType == FlowType.RenameKeycard:
state.flowType == FlowType.RenameKeycard or
state.flowType == FlowType.ChangeKeycardPin:
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorConnection:
@ -444,3 +454,34 @@ proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowTy
return createState(StateType.KeycardEmpty, state.flowType, nil)
if keycardEvent.error == ErrorNoData:
return createState(StateType.KeycardEmptyMetadata, state.flowType, nil)
if state.flowType == FlowType.ChangeKeycardPin:
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len == 0:
return createState(StateType.RecognizedKeycard, state.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseGeneralMessageForLockedState, add = true))
return createState(StateType.MaxPinRetriesReached, state.flowType, nil)
if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error.len > 0:
if keycardEvent.error == ErrorNotAKeycard:
return createState(StateType.NotKeycard, state.flowType, nil)
if keycardEvent.error == ErrorNoKeys:
return createState(StateType.KeycardEmpty, state.flowType, nil)
if keycardEvent.error == ErrorFreePairingSlots:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseGeneralMessageForLockedState, add = true))
return createState(StateType.MaxPairingSlotsReached, state.flowType, nil)
if keycardEvent.error == ErrorPUKRetries:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseGeneralMessageForLockedState, add = true))
return createState(StateType.MaxPukRetriesReached, state.flowType, nil)
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
if keycardEvent.error.len > 0:
if keycardEvent.error == ErrorNoKeys:
return createState(StateType.KeycardEmpty, state.flowType, nil)
if keycardEvent.error == ErrorNoData:
return createState(StateType.KeycardEmptyMetadata, state.flowType, nil)
if keycardEvent.error.len == 0:
return createState(StateType.ChangingKeycardPinSuccess, state.flowType, nil)
return createState(StateType.ChangingKeycardPinFailure, state.flowType, nil)

View File

@ -10,11 +10,13 @@ proc delete*(self: WrongKeycardState) =
method executePrimaryCommand*(self: WrongKeycardState, controller: Controller) =
if self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
method executeTertiaryCommand*(self: WrongKeycardState, controller: Controller) =
if self.flowType == FlowType.Authentication or
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -16,14 +16,16 @@ method getNextPrimaryState*(self: WrongPinState, controller: Controller): State
if controller.getPin().len == PINLengthForStatusApp:
controller.enterKeycardPin(controller.getPin())
if self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.runSharedModuleFlow(FlowType.FactoryReset)
method executeSecondaryCommand*(self: WrongPinState, controller: Controller) =
if self.flowType == FlowType.FactoryReset or
self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
if controller.getPin().len == PINLengthForStatusApp:
controller.enterKeycardPin(controller.getPin())
if self.flowType == FlowType.Authentication:
@ -35,7 +37,8 @@ method executeTertiaryCommand*(self: WrongPinState, controller: Controller) =
self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard:
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
@ -122,4 +125,21 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setMetadataFromKeycard(keycardEvent.cardMetadata, updateKeyPair = true)
return createState(StateType.PinVerified, self.flowType, nil)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPin:
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setKeycardData($keycardEvent.pinRetries)
if keycardEvent.pinRetries > 0:
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterNewPIN:
if keycardEvent.error == ErrorChangingCredentials:
return createState(StateType.PinVerified, self.flowType, nil)

View File

@ -58,6 +58,7 @@ type FlowType* {.pure.} = enum
UnlockKeycard = "UnlockKeycard"
DisplayKeycardContent = "DisplayKeycardContent"
RenameKeycard = "RenameKeycard"
ChangeKeycardPin = "ChangeKeycardPin"
type
AccessInterface* {.pure inheritable.} = ref object of RootObj

View File

@ -44,6 +44,12 @@ QtObject:
self.endResetModel()
self.countChanged()
proc addItem*(self: KeycardModel, item: KeycardItem) =
self.beginInsertRows(newQModelIndex(), self.items.len, self.items.len)
self.items.add(item)
self.endInsertRows()
self.countChanged()
proc `$`*(self: KeycardModel): string =
for i in 0 ..< self.items.len:
result &= fmt"""KeycardModel:

View File

@ -320,7 +320,8 @@ proc prepareKeyPairForProcessing[T](self: Module[T], keyUid: string) =
error "sm_cannot find keypair among migrated keypairs for the given keyUid for processing", keyUid=keyUid
else:
item.setLocked(keyPairs[0].keycardLocked)
item.setIcon("keycard")
if item.pairType != KeyPairType.Profile:
item.setIcon("keycard")
self.view.setKeyPairForProcessing(item)
method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path = "", txHash = "") =
@ -375,6 +376,11 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true) # we're firstly displaying the keycard content
return
if flowToRun == FlowType.ChangeKeycardPin:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.controller.runChangePinFlow()
return
method setSelectedKeyPair*[T](self: Module[T], item: KeyPairItem) =
var paths: seq[string]

View File

@ -11,7 +11,7 @@ const ErrorPairing* = "pairing"
const ErrorUnblocking* = "unblocking"
const ErrorSigning* = "signing"
const ErrorExporting* = "exporting"
const ErrorChanging* = "changing-credentials"
const ErrorChangingCredentials* = "changing-credentials"
const ErrorLoadingKeys* = "loading-keys"
const ErrorStoreMeta* = "storing-metadata"
const ErrorNoData* = "no-data"

View File

@ -222,6 +222,11 @@ QtObject:
self.currentFlow = KCSFlowType.GetMetadata
self.startFlow(payload)
proc startChangePinFlow*(self: Service) =
var payload = %* { }
self.currentFlow = KCSFlowType.ChangePIN
self.startFlow(payload)
proc startStoreMetadataFlow*(self: Service, cardName: string, pin: string, walletPaths: seq[string]) =
var name = cardName
if cardName.len > CardNameLength:

View File

@ -38,8 +38,8 @@ QtObject {
root.keycardModule.runRenameKeycardPopup(keycardUid, keyUid)
}
function runChangePinPopup() {
root.keycardModule.runChangePinPopup()
function runChangePinPopup(keycardUid, keyUid) {
root.keycardModule.runChangePinPopup(keycardUid, keyUid)
}
function runCreateBackupCopyOfAKeycardPopup() {

View File

@ -99,7 +99,7 @@ ColumnLayout {
}
]
onClicked: {
root.keycardStore.runChangePinPopup()
root.keycardStore.runChangePinPopup(root.keycardUid, d.keyUid)
}
}

View File

@ -61,6 +61,9 @@ StatusModal {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.renameKeycard) {
return qsTr("Rename Keycard")
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return qsTr("Change pin")
}
return ""
}
@ -71,6 +74,7 @@ StatusModal {
readonly property bool disablePopupClose: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateSuccess &&
root.sharedKeycardModule.migratingProfileKeyPair())
@ -101,6 +105,7 @@ StatusModal {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty ||
@ -136,6 +141,8 @@ StatusModal {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeychainPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinFailure ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinSet ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified)
{
@ -443,6 +450,23 @@ StatusModal {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached)
return qsTr("Cancel")
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pluginReader ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.insertKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardInserted ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.createPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.notKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached)
return qsTr("Cancel")
}
return ""
}
@ -450,7 +474,8 @@ StatusModal {
enabled: {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard) {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin) {
if (d.disablePopupClose) {
return false
}
@ -501,7 +526,8 @@ StatusModal {
enabled: {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard) {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin) {
if (d.disablePopupClose) {
return false
}
@ -711,13 +737,33 @@ StatusModal {
return qsTr("Rename this Keycard")
}
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinFailure)
return qsTr("Done")
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPin) {
return qsTr("I dont know the PIN")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified) {
return qsTr("Next")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached) {
return qsTr("Unlock Keycard")
}
}
return ""
}
visible: text !== ""
enabled: {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard) {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin) {
if (d.disablePopupClose) {
return false
}

View File

@ -31,7 +31,8 @@ Item {
Timer {
id: timer
interval: 1000
running: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard
running: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin
onTriggered: {
root.sharedKeycardModule.currentState.doSecondaryAction()
}
@ -143,7 +144,8 @@ Item {
id: loading
visible: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin
}
StatusBaseText {
id: title
@ -217,6 +219,17 @@ Item {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure)
return true
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin && !d.hideKeyPair) {
if(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.maxPinRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard)
return true
}
return false
}
@ -287,6 +300,17 @@ Item {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard)
return keyPairForProcessingComponent
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
if(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.maxPinRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard)
return keyPairForProcessingComponent
}
return undefined
}
@ -378,7 +402,8 @@ Item {
name: "processing"
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin
PropertyChanges {
target: title
text: {
@ -391,6 +416,9 @@ Item {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard) {
return qsTr("Renaming keycard...")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin) {
return qsTr("Updating PIN")
}
return ""
}
font.pixelSize: Constants.keycard.general.fontSize2
@ -488,7 +516,8 @@ Item {
target: message
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.renameKeycard) {
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.renameKeycard ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return qsTr("Keycard inserted does not match the Keycard below")
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {

View File

@ -30,8 +30,7 @@ Item {
}
onStateChanged: {
if(state === Constants.keycardSharedState.pinSet ||
state === Constants.keycardSharedState.pinVerified) {
if(d.useFakePin) {
pinInputField.setPin("123456") // we are free to set fake pin in this case
} else {
pinInputField.statesInitialization()
@ -39,7 +38,11 @@ Item {
}
}
Component.onCompleted: timer.start()
Component.onCompleted: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication) {
timer.start()
}
}
Timer {
id: timer
@ -50,6 +53,16 @@ Item {
}
}
QtObject {
id: d
readonly property bool useFakePin: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinSet ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinFailure
readonly property string message1: qsTr("It is very important that you do not lose this PIN")
readonly property string message2: qsTr("Dont lose your PIN! If you do, you may lose\naccess to your funds.")
}
Component {
id: keyPairComponent
KeyPairItem {
@ -111,31 +124,32 @@ Item {
Layout.alignment: Qt.AlignHCenter
validator: StatusIntValidator{bottom: 0; top: 999999;}
pinLen: Constants.keycard.general.keycardPinLength
enabled: root.sharedKeycardModule.currentState.stateType !== Constants.keycardSharedState.pinSet &&
root.sharedKeycardModule.currentState.stateType !== Constants.keycardSharedState.pinVerified
enabled: !d.useFakePin
onPinInputChanged: {
root.pinUpdated(pinInput)
if (root.state !== Constants.keycardSharedState.wrongPin ||
root.state === Constants.keycardSharedState.wrongKeychainPin) {
if (root.sharedKeycardModule.currentState.stateType !== Constants.keycardSharedState.wrongPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeychainPin) {
image.source = Style.png("keycard/enter-pin-%1".arg(pinInput.length))
}
if(pinInput.length == 0) {
return
}
if(root.state === Constants.keycardSharedState.createPin ||
root.state === Constants.keycardSharedState.enterPin ||
root.state === Constants.keycardSharedState.wrongPin ||
root.state === Constants.keycardSharedState.wrongKeychainPin) {
if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.createPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeychainPin) {
root.sharedKeycardModule.setPin(pinInput)
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication)
return
root.sharedKeycardModule.currentState.doSecondaryAction()
}
else if(root.state === Constants.keycardSharedState.repeatPin) {
else if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPin) {
let pinsMatch = root.sharedKeycardModule.checkRepeatedKeycardPinWhileTyping(pinInput)
if (pinsMatch) {
info.text = qsTr("It is very important that you do not lose this PIN")
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin)
info.text = d.message2
else
info.text = d.message1
root.sharedKeycardModule.currentState.doSecondaryAction()
} else {
info.text = qsTr("PINs don't match")
@ -148,6 +162,7 @@ Item {
StatusBaseText {
id: info
Layout.alignment: Qt.AlignCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
visible: text !== ""
}
@ -155,6 +170,7 @@ Item {
StatusBaseText {
id: message
Layout.alignment: Qt.AlignCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
visible: text !== ""
}
@ -220,7 +236,12 @@ Item {
}
PropertyChanges {
target: title
text: qsTr("Enter this Keycards PIN")
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return qsTr("Enter the Keycard PIN")
}
return qsTr("Enter this Keycards PIN")
}
font.pixelSize: Constants.keycard.general.fontSize1
color: Theme.palette.directColor1
}
@ -315,7 +336,12 @@ Item {
}
PropertyChanges {
target: title
text: qsTr("Choose a Keycard PIN")
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return qsTr("Enter new Keycard PIN")
}
return qsTr("Choose a Keycard PIN")
}
font.pixelSize: Constants.keycard.general.fontSize1
color: Theme.palette.directColor1
}
@ -325,7 +351,12 @@ Item {
}
PropertyChanges {
target: info
text: qsTr("It is very important that you do not lose this PIN")
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return d.message2
}
return d.message1
}
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize3
}
@ -344,7 +375,12 @@ Item {
}
PropertyChanges {
target: title
text: qsTr("Repeat Keycard PIN")
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return qsTr("Repeat new Keycard PIN")
}
return qsTr("Repeat Keycard PIN")
}
font.pixelSize: Constants.keycard.general.fontSize1
color: Theme.palette.directColor1
}
@ -354,7 +390,12 @@ Item {
}
PropertyChanges {
target: info
text: qsTr("It is very important that you do not lose this PIN")
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return
}
return d.message1
}
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize3
}
@ -364,8 +405,10 @@ Item {
}
},
State {
name: Constants.keycardSharedState.pinSet
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinSet
name: "success-state"
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinSet ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinSuccess
PropertyChanges {
target: image
pattern: "keycard/strong_success/img-%1"
@ -378,7 +421,18 @@ Item {
}
PropertyChanges {
target: title
text: qsTr("Keycard PIN set")
text: {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinSet) {
return qsTr("Keycard PIN set")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified) {
return qsTr("Keycard PIN verified!")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinSuccess) {
return qsTr("PIN successfully changed")
}
return ""
}
font.pixelSize: Constants.keycard.general.fontSize1
color: Theme.palette.directColor1
}
@ -396,21 +450,26 @@ Item {
}
},
State {
name: Constants.keycardSharedState.pinVerified
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified
name: "error-state"
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinFailure
PropertyChanges {
target: image
pattern: "keycard/strong_success/img-%1"
pattern: "keycard/strong_error/img-%1"
source: ""
startImgIndexForTheFirstLoop: 0
startImgIndexForOtherLoops: 0
endImgIndex: 20
startImgIndexForOtherLoops: 18
endImgIndex: 29
duration: 1300
loops: 1
}
PropertyChanges {
target: title
text: qsTr("Keycard PIN verified!")
text: {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPinFailure) {
return qsTr("Changing PIN failed")
}
return ""
}
font.pixelSize: Constants.keycard.general.fontSize1
color: Theme.palette.directColor1
}

View File

@ -97,6 +97,7 @@ QtObject {
readonly property string unlockKeycard: "UnlockKeycard"
readonly property string displayKeycardContent: "DisplayKeycardContent"
readonly property string renameKeycard: "RenameKeycard"
readonly property string changeKeycardPin: "ChangeKeycardPin"
}
readonly property QtObject keycardSharedState: QtObject {
@ -150,6 +151,9 @@ QtObject {
readonly property string renamingKeycard: "RenamingKeycard"
readonly property string keycardRenameSuccess: "KeycardRenameSuccess"
readonly property string keycardRenameFailure: "KeycardRenameFailure"
readonly property string changingKeycardPin: "ChangingKeycardPin"
readonly property string changingKeycardPinSuccess: "ChangingKeycardPinSuccess"
readonly property string changingKeycardPinFailure: "ChangingKeycardPinFailure"
}
readonly property QtObject keychain: QtObject {