feat(@desktop/keycard): create a 12-digit personal unblocking key (PUK)

Fixes: #7037
This commit is contained in:
Sale Djenic 2022-10-17 12:44:09 +02:00 committed by saledjenic
parent 9b2a63c400
commit 7377526553
37 changed files with 491 additions and 114 deletions

View File

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

View File

@ -155,8 +155,12 @@ method runChangePinPopup*(self: Module, keycardUid: string, keyUid: string) =
method runCreateBackupCopyOfAKeycardPopup*(self: Module) =
info "TODO: Create a Backup Copy of a Keycard..."
method runCreatePukPopup*(self: Module) =
info "TODO: Create PUK for a Keycard..."
method runCreatePukPopup*(self: Module, keycardUid: string, keyUid: string) =
self.createSharedKeycardModule()
if self.keycardSharedModule.isNil:
return
self.keycardSharedModule.setUidOfAKeycardWhichNeedToBeProcessed(keycardUid)
self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.ChangeKeycardPuk, keyUid)
method runCreateNewPairingCodePopup*(self: Module) =
info "TODO: Create New Pairing Code for a Keycard..."

View File

@ -73,8 +73,8 @@ QtObject:
proc runCreateBackupCopyOfAKeycardPopup*(self: View) {.slot.} =
self.delegate.runCreateBackupCopyOfAKeycardPopup()
proc runCreatePukPopup*(self: View) {.slot.} =
self.delegate.runCreatePukPopup()
proc runCreatePukPopup*(self: View, keycardUid: string, keyUid: string) {.slot.} =
self.delegate.runCreatePukPopup(keycardUid, keyUid)
proc runCreateNewPairingCodePopup*(self: View) {.slot.} =
self.delegate.runCreateNewPairingCodePopup()

View File

@ -35,6 +35,7 @@ type
tmpPin: string
tmpPinMatch: bool
tmpPuk: string
tmpPukMatch: bool
tmpValidPuk: bool
tmpPassword: string
tmpKeycardName: string
@ -167,6 +168,12 @@ proc setPukValid*(self: Controller, value: bool) =
proc getValidPuk*(self: Controller): bool =
return self.tmpValidPuk
proc setPukMatch*(self: Controller, value: bool) =
self.tmpPukMatch = value
proc getPukMatch*(self: Controller): bool =
return self.tmpPukMatch
proc setUsePinFromBiometrics*(self: Controller, value: bool) =
self.tmpUsePinFromBiometrics = value
@ -304,6 +311,10 @@ proc runChangePinFlow*(self: Controller) =
self.cancelCurrentFlow()
self.keycardService.startChangePinFlow()
proc runChangePukFlow*(self: Controller) =
self.cancelCurrentFlow()
self.keycardService.startChangePukFlow()
proc runStoreMetadataFlow*(self: Controller, cardName: string, pin: string, walletPaths: seq[string]) =
self.cancelCurrentFlow()
self.keycardService.startStoreMetadataFlow(cardName, pin, walletPaths)
@ -415,6 +426,9 @@ proc enterKeycardPuk*(self: Controller, puk: string) =
proc storePinToKeycard*(self: Controller, pin: string, puk: string) =
self.keycardService.storePin(pin, puk)
proc storePukToKeycard*(self: Controller, puk: string) =
self.keycardService.storePuk(puk)
proc storeSeedPhraseToKeycard*(self: Controller, seedPhraseLength: int, seedPhrase: string) =
self.keycardService.storeSeedPhrase(seedPhraseLength, seedPhrase)

View File

@ -0,0 +1,17 @@
type
ChangingKeycardPukState* = ref object of State
proc newChangingKeycardPukState*(flowType: FlowType, backState: State): ChangingKeycardPukState =
result = ChangingKeycardPukState()
result.setup(flowType, StateType.ChangingKeycardPuk, backState)
proc delete*(self: ChangingKeycardPukState) =
self.State.delete
method executeSecondaryCommand*(self: ChangingKeycardPukState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPuk:
controller.storePukToKeycard(controller.getPuk())
method resolveKeycardNextState*(self: ChangingKeycardPukState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =
return ensureReaderAndCardPresenceAndResolveNextState(self, keycardFlowType, keycardEvent, controller)

View File

@ -0,0 +1,18 @@
type
CreatePukState* = ref object of State
proc newCreatePukState*(flowType: FlowType, backState: State): CreatePukState =
result = CreatePukState()
result.setup(flowType, StateType.CreatePuk, backState)
proc delete*(self: CreatePukState) =
self.State.delete
method executeTertiaryCommand*(self: CreatePukState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method getNextSecondaryState*(self: CreatePukState, controller: Controller): State =
if self.flowType == FlowType.ChangeKeycardPuk:
if controller.getPuk().len == PUKLengthForStatusApp:
return createState(StateType.RepeatPuk, self.flowType, self)

View File

@ -21,7 +21,8 @@ method executeSecondaryCommand*(self: EnterPinState, controller: Controller) =
self.flowType == FlowType.FactoryReset or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
if controller.getPin().len == PINLengthForStatusApp:
controller.enterKeycardPin(controller.getPin())
if self.flowType == FlowType.Authentication:
@ -34,7 +35,8 @@ method executeTertiaryCommand*(self: EnterPinState, controller: Controller) =
self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: EnterPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
@ -162,5 +164,26 @@ method resolveKeycardNextState*(self: EnterPinState, keycardFlowType: string, ke
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)
if self.flowType == FlowType.ChangeKeycardPuk:
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 == ResponseTypeValueEnterNewPUK:
if keycardEvent.error == ErrorChangingCredentials:
return createState(StateType.PinVerified, self.flowType, nil)

View File

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

View File

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

View File

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

View File

@ -14,7 +14,8 @@ method executePrimaryCommand*(self: KeycardEmptyState, controller: Controller) =
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method executeTertiaryCommand*(self: KeycardEmptyState, controller: Controller) =
@ -23,5 +24,6 @@ method executeTertiaryCommand*(self: KeycardEmptyState, controller: Controller)
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

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

View File

@ -15,7 +15,8 @@ method getNextPrimaryState*(self: MaxPairingSlotsReachedState, controller: Contr
if self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.runSharedModuleFlow(FlowType.UnlockKeycard)
return nil
@ -26,5 +27,6 @@ method executeTertiaryCommand*(self: MaxPairingSlotsReachedState, controller: Co
self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -12,7 +12,8 @@ method getNextPrimaryState*(self: MaxPinRetriesReachedState, controller: Control
if self.flowType == FlowType.FactoryReset or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.runSharedModuleFlow(FlowType.UnlockKeycard)
if self.flowType == FlowType.SetupNewKeycard:
let currValue = extractPredefinedKeycardDataToNumber(controller.getKeycardData())
@ -29,7 +30,8 @@ method executeTertiaryCommand*(self: MaxPinRetriesReachedState, controller: Cont
self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
if self.flowType == FlowType.SetupNewKeycard:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseUnlockLabelForLockedState, add = false))

View File

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

View File

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

View File

@ -15,13 +15,15 @@ method getNextPrimaryState*(self: PinVerifiedState, controller: Controller): Sta
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
return createState(StateType.CreatePin, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPuk:
return createState(StateType.CreatePuk, self.flowType, 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 or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

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

View File

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

@ -23,12 +23,11 @@ method getNextSecondaryState*(self: RecognizedKeycardState, controller: Controll
return createState(StateType.CreatePin, self.flowType, self.getBackState)
if self.flowType == FlowType.UnlockKeycard:
return createState(StateType.UnlockKeycardOptions, self.flowType, nil)
if self.flowType == FlowType.DisplayKeycardContent:
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)
if self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
return createState(StateType.EnterPin, self.flowType, nil)
method executeTertiaryCommand*(self: RecognizedKeycardState, controller: Controller) =
error "recognized state must not be canceled"

View File

@ -15,9 +15,10 @@ method executeBackCommand*(self: RepeatPinState, controller: Controller) =
method executeSecondaryCommand*(self: RepeatPinState, controller: Controller) =
if not controller.getPinMatch():
return
if self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.UnlockKeycard:
controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK())
if self.flowType == FlowType.SetupNewKeycard:
controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK())
if self.flowType == FlowType.UnlockKeycard:
controller.storePinToKeycard(controller.getPin(), "")
method getNextSecondaryState*(self: RepeatPinState, controller: Controller): State =
if not controller.getPinMatch():

View File

@ -0,0 +1,23 @@
type
RepeatPukState* = ref object of State
proc newRepeatPukState*(flowType: FlowType, backState: State): RepeatPukState =
result = RepeatPukState()
result.setup(flowType, StateType.RepeatPuk, backState)
proc delete*(self: RepeatPukState) =
self.State.delete
method executeBackCommand*(self: RepeatPukState, controller: Controller) =
controller.setPuk("")
controller.setPukMatch(false)
method getNextSecondaryState*(self: RepeatPukState, controller: Controller): State =
if not controller.getPukMatch():
return
if self.flowType == FlowType.ChangeKeycardPuk:
return createState(StateType.ChangingKeycardPuk, self.flowType, nil)
method executeTertiaryCommand*(self: RepeatPukState, controller: Controller) =
if self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -59,6 +59,11 @@ type StateType* {.pure.} = enum
ChangingKeycardPin = "ChangingKeycardPin"
ChangingKeycardPinSuccess = "ChangingKeycardPinSuccess"
ChangingKeycardPinFailure = "ChangingKeycardPinFailure"
CreatePuk = "CreatePuk"
RepeatPuk = "RepeatPuk"
ChangingKeycardPuk = "ChangingKeycardPuk"
ChangingKeycardPukSuccess = "ChangingKeycardPukSuccess"
ChangingKeycardPukFailure = "ChangingKeycardPukFailure"
## This is the base class for all state we may have in onboarding/login flow.

View File

@ -33,7 +33,9 @@ include biometrics_pin_failed_state
include biometrics_pin_invalid_state
include biometrics_ready_to_sign_state
include changing_keycard_pin_state
include changing_keycard_puk_state
include create_pin_state
include create_puk_state
include enter_biometrics_password_state
include enter_keycard_name_state
include enter_password_state
@ -48,6 +50,8 @@ 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_change_puk_failure_state
include keycard_change_puk_success_state
include keycard_empty_metadata_state
include keycard_empty_state
include keycard_inserted_state
@ -68,6 +72,7 @@ include reading_keycard_state
include recognized_keycard_state
include renaming_keycard_state
include repeat_pin_state
include repeat_puk_state
include seed_phrase_display_state
include seed_phrase_enter_words_state
include select_existing_key_pair_state
@ -117,8 +122,12 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
return newBiometricsReadyToSignState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPin:
return newChangingKeycardPinState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPuk:
return newChangingKeycardPukState(flowType, backState)
if stateToBeCreated == StateType.CreatePin:
return newCreatePinState(flowType, backState)
if stateToBeCreated == StateType.CreatePuk:
return newCreatePukState(flowType, backState)
if stateToBeCreated == StateType.EnterBiometricsPassword:
return newEnterBiometricsPasswordState(flowType, backState)
if stateToBeCreated == StateType.EnterKeycardName:
@ -147,6 +156,10 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
return newChangingKeycardPinFailureState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPinSuccess:
return newChangingKeycardPinSuccessState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPukFailure:
return newChangingKeycardPukFailureState(flowType, backState)
if stateToBeCreated == StateType.ChangingKeycardPukSuccess:
return newChangingKeycardPukSuccessState(flowType, backState)
if stateToBeCreated == StateType.KeycardInserted:
return newKeycardInsertedState(flowType, backState)
if stateToBeCreated == StateType.KeycardEmptyMetadata:
@ -191,6 +204,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
return newRenamingKeycardState(flowType, backState)
if stateToBeCreated == StateType.RepeatPin:
return newRepeatPinState(flowType, backState)
if stateToBeCreated == StateType.RepeatPuk:
return newRepeatPukState(flowType, backState)
if stateToBeCreated == StateType.SeedPhraseDisplay:
return newSeedPhraseDisplayState(flowType, backState)
if stateToBeCreated == StateType.SeedPhraseEnterWords:
@ -221,7 +236,8 @@ proc ensureReaderAndCardPresence*(state: State, keycardFlowType: string, keycard
state.flowType == FlowType.UnlockKeycard or
state.flowType == FlowType.DisplayKeycardContent or
state.flowType == FlowType.RenameKeycard or
state.flowType == FlowType.ChangeKeycardPin:
state.flowType == FlowType.ChangeKeycardPin or
state.flowType == FlowType.ChangeKeycardPuk:
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorConnection:
@ -485,3 +501,34 @@ proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowTy
if keycardEvent.error.len == 0:
return createState(StateType.ChangingKeycardPinSuccess, state.flowType, nil)
return createState(StateType.ChangingKeycardPinFailure, state.flowType, nil)
if state.flowType == FlowType.ChangeKeycardPuk:
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.ChangingKeycardPukSuccess, state.flowType, nil)
return createState(StateType.ChangingKeycardPukFailure, state.flowType, nil)

View File

@ -11,12 +11,14 @@ proc delete*(self: WrongKeycardState) =
method executePrimaryCommand*(self: WrongKeycardState, controller: Controller) =
if self.flowType == FlowType.UnlockKeycard or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
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 or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)

View File

@ -17,7 +17,8 @@ method getNextPrimaryState*(self: WrongPinState, controller: Controller): State
controller.enterKeycardPin(controller.getPin())
if self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.runSharedModuleFlow(FlowType.FactoryReset)
method executeSecondaryCommand*(self: WrongPinState, controller: Controller) =
@ -25,7 +26,8 @@ method executeSecondaryCommand*(self: WrongPinState, controller: Controller) =
self.flowType == FlowType.SetupNewKeycard or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
if controller.getPin().len == PINLengthForStatusApp:
controller.enterKeycardPin(controller.getPin())
if self.flowType == FlowType.Authentication:
@ -38,7 +40,8 @@ method executeTertiaryCommand*(self: WrongPinState, controller: Controller) =
self.flowType == FlowType.Authentication or
self.flowType == FlowType.DisplayKeycardContent or
self.flowType == FlowType.RenameKeycard or
self.flowType == FlowType.ChangeKeycardPin:
self.flowType == FlowType.ChangeKeycardPin or
self.flowType == FlowType.ChangeKeycardPuk:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
@ -142,4 +145,21 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterNewPIN:
if keycardEvent.error == ErrorChangingCredentials:
return createState(StateType.PinVerified, self.flowType, nil)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPuk:
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 == ResponseTypeValueEnterNewPUK:
if keycardEvent.error == ErrorChangingCredentials:
return createState(StateType.PinVerified, self.flowType, nil)

View File

@ -59,6 +59,7 @@ type FlowType* {.pure.} = enum
DisplayKeycardContent = "DisplayKeycardContent"
RenameKeycard = "RenameKeycard"
ChangeKeycardPin = "ChangeKeycardPin"
ChangeKeycardPuk = "ChangeKeycardPuk"
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
@ -111,6 +112,9 @@ method setKeycarName*(self: AccessInterface, value: string) {.base.} =
method checkRepeatedKeycardPinWhileTyping*(self: AccessInterface, pin: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method checkRepeatedKeycardPukWhileTyping*(self: AccessInterface, puk: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method getMnemonic*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -96,6 +96,21 @@ method checkRepeatedKeycardPinWhileTyping*[T](self: Module[T], pin: string): boo
self.controller.setPinMatch(match)
return match
method checkRepeatedKeycardPukWhileTyping*[T](self: Module[T], puk: string): bool =
self.controller.setPukMatch(false)
let storedPuk = self.controller.getPuk()
if puk.len > storedPuk.len:
return false
elif puk.len < storedPuk.len:
for i in 0 ..< puk.len:
if puk[i] != storedPuk[i]:
return false
return true
else:
let match = puk == storedPuk
self.controller.setPukMatch(match)
return match
method getMnemonic*[T](self: Module[T]): string =
return self.controller.getMnemonic()
@ -381,6 +396,11 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.controller.runChangePinFlow()
return
if flowToRun == FlowType.ChangeKeycardPuk:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.controller.runChangePukFlow()
return
method setSelectedKeyPair*[T](self: Module[T], item: KeyPairItem) =
var paths: seq[string]

View File

@ -204,6 +204,9 @@ QtObject:
proc checkRepeatedKeycardPinWhileTyping*(self: View, pin: string): bool {.slot.} =
return self.delegate.checkRepeatedKeycardPinWhileTyping(pin)
proc checkRepeatedKeycardPukWhileTyping*(self: View, puk: string): bool {.slot.} =
return self.delegate.checkRepeatedKeycardPukWhileTyping(puk)
proc getMnemonic*(self: View): string {.slot.} =
return self.delegate.getMnemonic()

View File

@ -227,6 +227,11 @@ QtObject:
self.currentFlow = KCSFlowType.ChangePIN
self.startFlow(payload)
proc startChangePukFlow*(self: Service) =
var payload = %* { }
self.currentFlow = KCSFlowType.ChangePUK
self.startFlow(payload)
proc startStoreMetadataFlow*(self: Service, cardName: string, pin: string, walletPaths: seq[string]) =
var name = cardName
if cardName.len > CardNameLength:
@ -274,6 +279,17 @@ QtObject:
}
self.resumeFlow(payload)
proc storePuk*(self: Service, puk: string) =
if puk.len == 0:
error "empty puk provided"
return
var payload = %* {
RequestParamOverwrite: true,
RequestParamPUK: puk,
RequestParamNewPUK: puk
}
self.resumeFlow(payload)
proc enterPuk*(self: Service, puk: string) =
if puk.len == 0:
error "empty puk provided"

View File

@ -46,8 +46,8 @@ QtObject {
root.keycardModule.runCreateBackupCopyOfAKeycardPopup()
}
function runCreatePukPopup() {
root.keycardModule.runCreatePukPopup()
function runCreatePukPopup(keycardUid, keyUid) {
root.keycardModule.runCreatePukPopup(keycardUid, keyUid)
}
function runCreateNewPairingCodePopup() {

View File

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

View File

@ -64,6 +64,9 @@ StatusModal {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return qsTr("Change pin")
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPuk) {
return qsTr("Create a 12-digit personal unblocking key (PUK)")
}
return ""
}
@ -75,6 +78,7 @@ StatusModal {
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.changingKeycardPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateSuccess &&
root.sharedKeycardModule.migratingProfileKeyPair())
@ -106,6 +110,9 @@ StatusModal {
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.changingKeycardPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukFailure ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty ||
@ -148,7 +155,9 @@ StatusModal {
{
return keycardPinComponent
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPuk ||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.createPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk)
{
return keycardPukComponent
@ -467,6 +476,23 @@ StatusModal {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached)
return qsTr("Cancel")
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPuk) {
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.createPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPuk ||
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 ""
}
@ -475,7 +501,8 @@ StatusModal {
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.changingKeycardPin) {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk) {
if (d.disablePopupClose) {
return false
}
@ -527,7 +554,8 @@ StatusModal {
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.changingKeycardPin) {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk) {
if (d.disablePopupClose) {
return false
}
@ -755,6 +783,24 @@ StatusModal {
return qsTr("Unlock Keycard")
}
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPuk) {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukFailure)
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 ""
}
@ -763,7 +809,8 @@ StatusModal {
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.changingKeycardPin) {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk) {
if (d.disablePopupClose) {
return false
}

View File

@ -32,7 +32,8 @@ Item {
id: timer
interval: 1000
running: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk
onTriggered: {
root.sharedKeycardModule.currentState.doSecondaryAction()
}
@ -145,7 +146,8 @@ Item {
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.changingKeycardPin
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk
}
StatusBaseText {
id: title
@ -230,6 +232,17 @@ Item {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard)
return true
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPuk && !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
}
@ -311,6 +324,17 @@ Item {
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard)
return keyPairForProcessingComponent
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPuk) {
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
}
@ -403,7 +427,8 @@ Item {
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.changingKeycardPin
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk
PropertyChanges {
target: title
text: {
@ -419,6 +444,9 @@ Item {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin) {
return qsTr("Updating PIN")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk) {
return qsTr("Setting your Keycard PUK...")
}
return ""
}
font.pixelSize: Constants.keycard.general.fontSize2
@ -517,7 +545,8 @@ Item {
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.renameKeycard ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin ||
root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPuk) {
return qsTr("Keycard inserted does not match the Keycard below")
}
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {
@ -668,31 +697,6 @@ Item {
text: ""
}
},
State {
name: Constants.keycardSharedState.unlockKeycardSuccess
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardSuccess
PropertyChanges {
target: title
text: qsTr("Unlock successful")
font.pixelSize: Constants.keycard.general.fontSize1
font.weight: Font.Bold
color: Theme.palette.directColor1
}
PropertyChanges {
target: image
pattern: "keycard/strong_success/img-%1"
source: ""
startImgIndexForTheFirstLoop: 0
startImgIndexForOtherLoops: 0
endImgIndex: 20
duration: 1000
loops: 1
}
PropertyChanges {
target: message
text: ""
}
},
State {
name: Constants.keycardSharedState.recognizedKeycard
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.recognizedKeycard
@ -718,50 +722,33 @@ Item {
text: ""
}
},
State {
name: Constants.keycardSharedState.factoryResetSuccess
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess
PropertyChanges {
target: title
text: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard?
qsTr("Your Keycard has been reset") :
qsTr("Keycard successfully factory reset")
font.pixelSize: Constants.keycard.general.fontSize1
font.weight: Font.Bold
color: Theme.palette.directColor1
}
PropertyChanges {
target: image
pattern: "keycard/strong_success/img-%1"
source: ""
startImgIndexForTheFirstLoop: 0
startImgIndexForOtherLoops: 0
endImgIndex: 20
duration: 1000
loops: 1
}
PropertyChanges {
target: message
text: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard?
qsTr("You can now create a new key pair on this Keycard") :
qsTr("You can now use this Keycard as if it\nwas a brand new empty Keycard")
font.pixelSize: Constants.keycard.general.fontSize2
color: Theme.palette.directColor1
}
},
State {
name: "processing-success"
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameSuccess
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameSuccess ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukSuccess
PropertyChanges {
target: title
text: {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateSuccess) {
return qsTr("Key pair successfully migrated")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess) {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard)
return qsTr("Your Keycard has been reset")
return qsTr("Keycard successfully factory reset")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardSuccess) {
return qsTr("Unlock successful")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameSuccess) {
return qsTr("Keycard successfully renamed")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukSuccess) {
return qsTr("Keycards PUK successfully set")
}
return ""
}
font.pixelSize: Constants.keycard.general.fontSize1
@ -775,7 +762,7 @@ Item {
startImgIndexForTheFirstLoop: 0
startImgIndexForOtherLoops: 0
endImgIndex: 20
duration: 1000
duration: 1300
loops: 1
}
PropertyChanges {
@ -784,6 +771,11 @@ Item {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateSuccess) {
return qsTr("To complete migration close Status and log in with your new Keycard")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess) {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard)
return qsTr("You can now create a new key pair on this Keycard")
return qsTr("You can now use this Keycard as if it\nwas a brand new empty Keycard")
}
return ""
}
font.pixelSize: Constants.keycard.general.fontSize2
@ -793,7 +785,8 @@ Item {
State {
name: "processing-failure"
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateFailure ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukFailure
PropertyChanges {
target: title
text: {
@ -803,6 +796,9 @@ Item {
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure) {
return qsTr("Keycard renaming failed")
}
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukFailure) {
return qsTr("Setting Keycards PUK failed")
}
return ""
}
font.pixelSize: Constants.keycard.general.fontSize1

View File

@ -127,8 +127,8 @@ Item {
enabled: !d.useFakePin
onPinInputChanged: {
root.pinUpdated(pinInput)
if (root.sharedKeycardModule.currentState.stateType !== Constants.keycardSharedState.wrongPin ||
root.sharedKeycardModule.currentState.stateType === 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) {
@ -392,7 +392,7 @@ Item {
target: info
text: {
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.changeKeycardPin) {
return
return d.message2
}
return d.message1
}

View File

@ -64,14 +64,29 @@ Item {
onPinInputChanged: {
root.pukUpdated(pinInput)
if (root.sharedKeycardModule.currentState.stateType !== Constants.keycardSharedState.enterPuk &&
root.sharedKeycardModule.currentState.stateType !== Constants.keycardSharedState.wrongPuk) {
image.source = Style.png("keycard/card-inserted")
}
if(pinInput.length == 0) {
return
}
if(root.state === Constants.keycardSharedState.enterPuk ||
root.state === Constants.keycardSharedState.wrongPuk) {
if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.createPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPuk ||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk) {
root.sharedKeycardModule.setPuk(pinInput)
root.sharedKeycardModule.currentState.doSecondaryAction()
}
else if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPuk) {
let pukMatch = root.sharedKeycardModule.checkRepeatedKeycardPukWhileTyping(pinInput)
if (pukMatch) {
info.text = ""
root.sharedKeycardModule.currentState.doSecondaryAction()
} else {
info.text = qsTr("The PUK doesnt match")
image.source = Style.png("keycard/plain-error")
}
}
}
}
@ -148,6 +163,54 @@ Item {
Theme.palette.baseColor1
font.pixelSize: Constants.keycard.general.fontSize3
}
},
State {
name: Constants.keycardSharedState.createPuk
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.createPuk
PropertyChanges {
target: image
source: Style.png("keycard/card-inserted")
pattern: ""
}
PropertyChanges {
target: title
text: qsTr("Choose a Keycard PUK")
font.pixelSize: Constants.keycard.general.fontSize1
color: Theme.palette.directColor1
}
PropertyChanges {
target: info
text: ""
}
PropertyChanges {
target: message
text: ""
}
},
State {
name: Constants.keycardSharedState.repeatPuk
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPuk
PropertyChanges {
target: image
source: Style.png("keycard/card-inserted")
pattern: ""
}
PropertyChanges {
target: title
text: qsTr("Repeat your Keycard PUK")
font.pixelSize: Constants.keycard.general.fontSize1
color: Theme.palette.directColor1
}
PropertyChanges {
target: info
text: ""
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize3
}
PropertyChanges {
target: message
text: ""
}
}
]
}

View File

@ -98,6 +98,7 @@ QtObject {
readonly property string displayKeycardContent: "DisplayKeycardContent"
readonly property string renameKeycard: "RenameKeycard"
readonly property string changeKeycardPin: "ChangeKeycardPin"
readonly property string changeKeycardPuk: "ChangeKeycardPuk"
}
readonly property QtObject keycardSharedState: QtObject {
@ -154,6 +155,11 @@ QtObject {
readonly property string changingKeycardPin: "ChangingKeycardPin"
readonly property string changingKeycardPinSuccess: "ChangingKeycardPinSuccess"
readonly property string changingKeycardPinFailure: "ChangingKeycardPinFailure"
readonly property string createPuk: "CreatePuk"
readonly property string repeatPuk: "RepeatPuk"
readonly property string changingKeycardPuk: "ChangingKeycardPuk"
readonly property string changingKeycardPukSuccess: "ChangingKeycardPukSuccess"
readonly property string changingKeycardPukFailure: "ChangingKeycardPukFailure"
}
readonly property QtObject keychain: QtObject {