From 737752655371e24086430754e68b373dab125d0c Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Mon, 17 Oct 2022 12:44:09 +0200 Subject: [PATCH] feat(@desktop/keycard): create a 12-digit personal unblocking key (PUK) Fixes: #7037 --- .../profile_section/keycard/io_interface.nim | 2 +- .../main/profile_section/keycard/module.nim | 8 +- .../main/profile_section/keycard/view.nim | 4 +- .../keycard_popup/controller.nim | 14 ++ .../internal/changing_keycard_puk_state.nim | 17 +++ .../internal/create_puk_state.nim | 18 +++ .../internal/enter_pin_state.nim | 27 +++- .../internal/insert_keycard_state.nim | 3 +- .../keycard_change_puk_failure_state.nim | 17 +++ .../keycard_change_puk_success_state.nim | 17 +++ .../internal/keycard_empty_state.nim | 6 +- .../internal/keycard_inserted_state.nim | 3 +- .../max_pairing_slots_reached_state.nim | 6 +- .../max_pin_retries_reached_state.nim | 6 +- .../max_puk_retries_reached_state.nim | 6 +- .../internal/not_keycard_state.nim | 3 +- .../internal/pin_verified_state.nim | 8 +- .../internal/plugin_reader_state.nim | 3 +- .../internal/reading_keycard_state.nim | 3 +- .../internal/recognized_keycard_state.nim | 11 +- .../internal/repeat_pin_state.nim | 7 +- .../internal/repeat_puk_state.nim | 23 ++++ .../keycard_popup/internal/state.nim | 5 + .../keycard_popup/internal/state_factory.nim | 49 ++++++- .../internal/wrong_keycard_state.nim | 6 +- .../internal/wrong_pin_state.nim | 28 +++- .../keycard_popup/io_interface.nim | 4 + .../shared_modules/keycard_popup/module.nim | 20 +++ .../shared_modules/keycard_popup/view.nim | 3 + src/app_service/service/keycard/service.nim | 16 +++ .../Profile/stores/KeycardStore.qml | 4 +- .../Profile/views/keycard/DetailsView.qml | 2 +- .../shared/popups/keycard/KeycardPopup.qml | 55 +++++++- .../popups/keycard/states/KeycardInit.qml | 122 +++++++++--------- .../popups/keycard/states/KeycardPin.qml | 6 +- .../popups/keycard/states/KeycardPuk.qml | 67 +++++++++- ui/imports/utils/Constants.qml | 6 + 37 files changed, 491 insertions(+), 114 deletions(-) create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/changing_keycard_puk_state.nim create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/create_puk_state.nim create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_failure_state.nim create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_success_state.nim create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/repeat_puk_state.nim diff --git a/src/app/modules/main/profile_section/keycard/io_interface.nim b/src/app/modules/main/profile_section/keycard/io_interface.nim index c1b849ad6e..e464c53d02 100644 --- a/src/app/modules/main/profile_section/keycard/io_interface.nim +++ b/src/app/modules/main/profile_section/keycard/io_interface.nim @@ -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.} = diff --git a/src/app/modules/main/profile_section/keycard/module.nim b/src/app/modules/main/profile_section/keycard/module.nim index 1a8f004332..f7362ab028 100644 --- a/src/app/modules/main/profile_section/keycard/module.nim +++ b/src/app/modules/main/profile_section/keycard/module.nim @@ -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..." diff --git a/src/app/modules/main/profile_section/keycard/view.nim b/src/app/modules/main/profile_section/keycard/view.nim index bdc2e3c657..f7745a719b 100644 --- a/src/app/modules/main/profile_section/keycard/view.nim +++ b/src/app/modules/main/profile_section/keycard/view.nim @@ -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() diff --git a/src/app/modules/shared_modules/keycard_popup/controller.nim b/src/app/modules/shared_modules/keycard_popup/controller.nim index 6f16ec0fec..112f5d6de5 100644 --- a/src/app/modules/shared_modules/keycard_popup/controller.nim +++ b/src/app/modules/shared_modules/keycard_popup/controller.nim @@ -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) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/changing_keycard_puk_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/changing_keycard_puk_state.nim new file mode 100644 index 0000000000..d2b17f6986 --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/changing_keycard_puk_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/create_puk_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/create_puk_state.nim new file mode 100644 index 0000000000..d24b2afa55 --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/create_puk_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim index e115b636f9..34c3c901d3 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim index f8f9a1d925..23d391cd59 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim @@ -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, diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_failure_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_failure_state.nim new file mode 100644 index 0000000000..402dc7885a --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_failure_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_success_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_success_state.nim new file mode 100644 index 0000000000..4f26dca27a --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_change_puk_success_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_state.nim index 57cbf5ae56..89ad2406b9 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim index 06644ec600..a2a64bfd3e 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim @@ -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) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim index 1999418f57..3da0be266d 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim index e115e1ee40..ecade4f016 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim @@ -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)) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim index 5aa51a166b..b6f8ce3984 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim index c2d13ac234..149922b340 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim index 3866cc1e5e..75b64b7ef5 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim index e0ec5500d2..e7f94885b3 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim @@ -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, diff --git a/src/app/modules/shared_modules/keycard_popup/internal/reading_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/reading_keycard_state.nim index 55a6c8b9c2..20ef4fe094 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/reading_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/reading_keycard_state.nim @@ -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 diff --git a/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim index 6e3a003394..172cce32c4 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim @@ -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" \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim index 4a89164d78..00f47404ec 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim @@ -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(): diff --git a/src/app/modules/shared_modules/keycard_popup/internal/repeat_puk_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/repeat_puk_state.nim new file mode 100644 index 0000000000..7737f7fb98 --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/repeat_puk_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state.nim b/src/app/modules/shared_modules/keycard_popup/internal/state.nim index 4fd80801a9..3773232f18 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state.nim @@ -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. diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim b/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim index 9025f4c302..af78e878d5 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim @@ -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) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/wrong_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/wrong_keycard_state.nim index 06fb6770c1..30813958e4 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/wrong_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/wrong_keycard_state.nim @@ -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) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim index 136e05258f..387405871f 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim @@ -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) \ No newline at end of file + 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) diff --git a/src/app/modules/shared_modules/keycard_popup/io_interface.nim b/src/app/modules/shared_modules/keycard_popup/io_interface.nim index 765e7556ca..7e86808388 100644 --- a/src/app/modules/shared_modules/keycard_popup/io_interface.nim +++ b/src/app/modules/shared_modules/keycard_popup/io_interface.nim @@ -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") diff --git a/src/app/modules/shared_modules/keycard_popup/module.nim b/src/app/modules/shared_modules/keycard_popup/module.nim index fe12a39cbf..35e5731e24 100644 --- a/src/app/modules/shared_modules/keycard_popup/module.nim +++ b/src/app/modules/shared_modules/keycard_popup/module.nim @@ -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] diff --git a/src/app/modules/shared_modules/keycard_popup/view.nim b/src/app/modules/shared_modules/keycard_popup/view.nim index c4f62a06e1..1ca269748a 100644 --- a/src/app/modules/shared_modules/keycard_popup/view.nim +++ b/src/app/modules/shared_modules/keycard_popup/view.nim @@ -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() diff --git a/src/app_service/service/keycard/service.nim b/src/app_service/service/keycard/service.nim index 6b2e98761f..59d2ff0312 100644 --- a/src/app_service/service/keycard/service.nim +++ b/src/app_service/service/keycard/service.nim @@ -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" diff --git a/ui/app/AppLayouts/Profile/stores/KeycardStore.qml b/ui/app/AppLayouts/Profile/stores/KeycardStore.qml index a33ba361b5..358eea8d26 100644 --- a/ui/app/AppLayouts/Profile/stores/KeycardStore.qml +++ b/ui/app/AppLayouts/Profile/stores/KeycardStore.qml @@ -46,8 +46,8 @@ QtObject { root.keycardModule.runCreateBackupCopyOfAKeycardPopup() } - function runCreatePukPopup() { - root.keycardModule.runCreatePukPopup() + function runCreatePukPopup(keycardUid, keyUid) { + root.keycardModule.runCreatePukPopup(keycardUid, keyUid) } function runCreateNewPairingCodePopup() { diff --git a/ui/app/AppLayouts/Profile/views/keycard/DetailsView.qml b/ui/app/AppLayouts/Profile/views/keycard/DetailsView.qml index ed13588dea..2ffc0082d6 100644 --- a/ui/app/AppLayouts/Profile/views/keycard/DetailsView.qml +++ b/ui/app/AppLayouts/Profile/views/keycard/DetailsView.qml @@ -164,7 +164,7 @@ ColumnLayout { } ] onClicked: { - root.keycardStore.runCreatePukPopup() + root.keycardStore.runCreatePukPopup(root.keycardUid, d.keyUid) } } diff --git a/ui/imports/shared/popups/keycard/KeycardPopup.qml b/ui/imports/shared/popups/keycard/KeycardPopup.qml index 01fc99f05a..7cd7d44fa2 100644 --- a/ui/imports/shared/popups/keycard/KeycardPopup.qml +++ b/ui/imports/shared/popups/keycard/KeycardPopup.qml @@ -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 don’t 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 } diff --git a/ui/imports/shared/popups/keycard/states/KeycardInit.qml b/ui/imports/shared/popups/keycard/states/KeycardInit.qml index 1fc914cfb2..3177a72274 100644 --- a/ui/imports/shared/popups/keycard/states/KeycardInit.qml +++ b/ui/imports/shared/popups/keycard/states/KeycardInit.qml @@ -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("Keycard’s 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 Keycard’s PUK failed") + } return "" } font.pixelSize: Constants.keycard.general.fontSize1 diff --git a/ui/imports/shared/popups/keycard/states/KeycardPin.qml b/ui/imports/shared/popups/keycard/states/KeycardPin.qml index e9d9752a3a..519dd31b45 100644 --- a/ui/imports/shared/popups/keycard/states/KeycardPin.qml +++ b/ui/imports/shared/popups/keycard/states/KeycardPin.qml @@ -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 } diff --git a/ui/imports/shared/popups/keycard/states/KeycardPuk.qml b/ui/imports/shared/popups/keycard/states/KeycardPuk.qml index b11b6dc4e9..83d6c92b9f 100644 --- a/ui/imports/shared/popups/keycard/states/KeycardPuk.qml +++ b/ui/imports/shared/popups/keycard/states/KeycardPuk.qml @@ -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 doesn’t 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: "" + } } ] } diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index b429592f12..277d276a04 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -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 {