parent
cf7bc0325b
commit
a3b71c7d91
|
@ -30,8 +30,11 @@ type
|
|||
keychainConnectionIds: seq[UUID]
|
||||
connectionKeycardResponse: UUID
|
||||
tmpKeycardContainsMetadata: bool
|
||||
tmpCardMetadata: CardMetadata
|
||||
tmpPin: string
|
||||
tmpPinMatch: bool
|
||||
tmpPuk: string
|
||||
tmpValidPuk: bool
|
||||
tmpPassword: string
|
||||
tmpSelectedKeyPairIsProfile: bool
|
||||
tmpSelectedKeyPairDto: KeyPairDto
|
||||
|
@ -39,7 +42,9 @@ type
|
|||
tmpSeedPhrase: string
|
||||
tmpSeedPhraseLength: int
|
||||
tmpKeyUidWhichIsBeingAuthenticating: string
|
||||
tmpKeyUidWhichIsBeingUnlocking: string
|
||||
tmpUsePinFromBiometrics: bool
|
||||
tmpKeycardUid: string
|
||||
|
||||
proc newController*(delegate: io_interface.AccessInterface,
|
||||
uniqueIdentifier: string,
|
||||
|
@ -63,6 +68,7 @@ proc newController*(delegate: io_interface.AccessInterface,
|
|||
result.keychainService = keychainService
|
||||
result.tmpKeycardContainsMetadata = false
|
||||
result.tmpPinMatch = false
|
||||
result.tmpValidPuk = false
|
||||
result.tmpSeedPhraseLength = 0
|
||||
result.tmpSelectedKeyPairIsProfile = false
|
||||
result.tmpUsePinFromBiometrics = false
|
||||
|
@ -140,6 +146,18 @@ proc setPin*(self: Controller, value: string) =
|
|||
proc getPin*(self: Controller): string =
|
||||
return self.tmpPin
|
||||
|
||||
proc setPuk*(self: Controller, value: string) =
|
||||
self.tmpPuk = value
|
||||
|
||||
proc getPuk*(self: Controller): string =
|
||||
return self.tmpPuk
|
||||
|
||||
proc setPukValid*(self: Controller, value: bool) =
|
||||
self.tmpValidPuk = value
|
||||
|
||||
proc getValidPuk*(self: Controller): bool =
|
||||
return self.tmpValidPuk
|
||||
|
||||
proc setUsePinFromBiometrics*(self: Controller, value: bool) =
|
||||
self.tmpUsePinFromBiometrics = value
|
||||
|
||||
|
@ -161,6 +179,12 @@ proc getPassword*(self: Controller): string =
|
|||
proc getKeyUidWhichIsBeingAuthenticating*(self: Controller): string =
|
||||
self.tmpKeyUidWhichIsBeingAuthenticating
|
||||
|
||||
proc getKeyUidWhichIsBeingUnlocking*(self: Controller): string =
|
||||
self.tmpKeyUidWhichIsBeingUnlocking
|
||||
|
||||
proc setKeyUidWhichIsBeingUnlocking*(self: Controller, keyUid: string) =
|
||||
self.tmpKeyUidWhichIsBeingUnlocking = keyUid
|
||||
|
||||
proc setSelectedKeyPairIsProfile*(self: Controller, value: bool) =
|
||||
self.tmpSelectedKeyPairIsProfile = value
|
||||
|
||||
|
@ -173,9 +197,15 @@ proc setSelectedKeyPairDto*(self: Controller, keyPairDto: KeyPairDto) =
|
|||
proc getSelectedKeyPairDto*(self: Controller): KeyPairDto =
|
||||
return self.tmpSelectedKeyPairDto
|
||||
|
||||
proc setKeycardUid*(self: Controller, value: string) =
|
||||
proc setKeycardUidTheSelectedKeypairIsMigratedTo*(self: Controller, value: string) =
|
||||
self.tmpSelectedKeyPairDto.keycardUid = value
|
||||
|
||||
proc setKeycardUid*(self: Controller, value: string) =
|
||||
self.tmpKeycardUid = value
|
||||
|
||||
proc getKeycardUid*(self: Controller): string =
|
||||
return self.tmpKeycardUid
|
||||
|
||||
proc setSelectedKeyPairWalletPaths*(self: Controller, paths: seq[string]) =
|
||||
self.tmpSelectedKeyPairWalletPaths = paths
|
||||
|
||||
|
@ -197,6 +227,10 @@ proc validSeedPhrase*(self: Controller, seedPhrase: string): bool =
|
|||
let err = self.accountsService.validateMnemonic(seedPhrase)
|
||||
return err.len == 0
|
||||
|
||||
proc getKeyUidForSeedPhrase*(self: Controller, seedPhrase: string): string =
|
||||
let acc = self.accountsService.createAccountFromMnemonic(seedPhrase)
|
||||
return acc.keyUid
|
||||
|
||||
proc seedPhraseRefersToSelectedKeyPair*(self: Controller, seedPhrase: string): bool =
|
||||
let acc = self.accountsService.createAccountFromMnemonic(seedPhrase)
|
||||
return acc.keyUid == self.tmpSelectedKeyPairDto.keyUid
|
||||
|
@ -217,8 +251,16 @@ proc getCurrentKeycardServiceFlow*(self: Controller): keycard_service.KCSFlowTyp
|
|||
proc getLastReceivedKeycardData*(self: Controller): tuple[flowType: string, flowEvent: KeycardEvent] =
|
||||
return self.keycardService.getLastReceivedKeycardData()
|
||||
|
||||
proc setMetadataFromKeycard*(self: Controller, cardMetadata: CardMetadata) =
|
||||
self.delegate.setKeyPairStoredOnKeycard(cardMetadata)
|
||||
proc getMetadataFromKeycard*(self: Controller): CardMetadata =
|
||||
return self.tmpCardMetadata
|
||||
|
||||
proc setMetadataFromKeycard*(self: Controller, cardMetadata: CardMetadata, updateKeyPair = false) =
|
||||
self.tmpCardMetadata = cardMetadata
|
||||
if updateKeyPair:
|
||||
self.delegate.setKeyPairStoredOnKeycard(cardMetadata)
|
||||
|
||||
proc runSharedModuleFlow*(self: Controller, flowToRun: FlowType) =
|
||||
self.delegate.runFlow(flowToRun)
|
||||
|
||||
proc cancelCurrentFlow*(self: Controller) =
|
||||
self.keycardService.cancelCurrentFlow()
|
||||
|
@ -230,17 +272,17 @@ proc runGetAppInfoFlow*(self: Controller, factoryReset = false) =
|
|||
self.cancelCurrentFlow()
|
||||
self.keycardService.startGetAppInfoFlow(factoryReset)
|
||||
|
||||
proc runGetMetadataFlow*(self: Controller) =
|
||||
proc runGetMetadataFlow*(self: Controller, resolveAddress = false) =
|
||||
self.cancelCurrentFlow()
|
||||
self.keycardService.startGetMetadataFlow()
|
||||
self.keycardService.startGetMetadataFlow(resolveAddress)
|
||||
|
||||
proc runStoreMetadataFlow*(self: Controller, cardName: string, pin: string, walletPaths: seq[string]) =
|
||||
self.cancelCurrentFlow()
|
||||
self.keycardService.startStoreMetadataFlow(cardName, pin, walletPaths)
|
||||
|
||||
proc runLoadAccountFlow*(self: Controller, factoryReset = false) =
|
||||
proc runLoadAccountFlow*(self: Controller, seedPhraseLength = 0, seedPhrase = "", puk = "", factoryReset = false) =
|
||||
self.cancelCurrentFlow()
|
||||
self.keycardService.startLoadAccountFlow(factoryReset)
|
||||
self.keycardService.startLoadAccountFlow(seedPhraseLength, seedPhrase, puk, factoryReset)
|
||||
|
||||
proc runSignFlow*(self: Controller, keyUid = "", bip44Path = "", txHash = "") =
|
||||
## For signing a transaction we need to provide a key uid of a keypair that an account we want to sign a transaction
|
||||
|
@ -260,6 +302,7 @@ proc readyToDisplayPopup*(self: Controller) =
|
|||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_DISPLAY_POPUP, data)
|
||||
|
||||
proc terminateCurrentFlow*(self: Controller, lastStepInTheCurrentFlow: bool) =
|
||||
self.cancelCurrentFlow()
|
||||
let (_, flowEvent) = self.getLastReceivedKeycardData()
|
||||
var data = SharedKeycarModuleFlowTerminatedArgs(uniqueIdentifier: self.uniqueIdentifier,
|
||||
lastStepInTheCurrentFlow: lastStepInTheCurrentFlow)
|
||||
|
@ -301,6 +344,27 @@ proc getMigratedKeyPairByKeyUid*(self: Controller, keyUid: string): seq[KeyPairD
|
|||
return
|
||||
return self.walletAccountService.getMigratedKeyPairByKeyUid(keyUid)
|
||||
|
||||
proc setCurrentKeycardStateToLocked*(self: Controller, keycardUid: string) =
|
||||
if not serviceApplicable(self.walletAccountService):
|
||||
return
|
||||
if not self.walletAccountService.setKeycardLocked(keycardUid):
|
||||
info "updating keycard locked state failed", keycardUid=keycardUid
|
||||
|
||||
proc setCurrentKeycardStateToUnlocked*(self: Controller, keycardUid: string) =
|
||||
if not serviceApplicable(self.walletAccountService):
|
||||
return
|
||||
if not self.walletAccountService.setKeycardUnlocked(keycardUid):
|
||||
info "updating keycard unlocked state failed", keycardUid=keycardUid
|
||||
|
||||
proc updateKeycardUid*(self: Controller, keycardUid: string) =
|
||||
if not serviceApplicable(self.walletAccountService):
|
||||
return
|
||||
self.setCurrentKeycardStateToUnlocked(self.tmpKeycardUid)
|
||||
if self.tmpKeycardUid != keycardUid:
|
||||
if not self.walletAccountService.updateKeycardUid(self.tmpKeycardUid, keycardUid):
|
||||
self.tmpKeycardUid = keycardUid
|
||||
info "update keycard uid failed", oldKeycardUid=self.tmpKeycardUid, newKeycardUid=keycardUid
|
||||
|
||||
proc getSigningPhrase*(self: Controller): string =
|
||||
if not serviceApplicable(self.settingsService):
|
||||
return
|
||||
|
@ -309,6 +373,9 @@ proc getSigningPhrase*(self: Controller): string =
|
|||
proc enterKeycardPin*(self: Controller, pin: string) =
|
||||
self.keycardService.enterPin(pin)
|
||||
|
||||
proc enterKeycardPuk*(self: Controller, puk: string) =
|
||||
self.keycardService.enterPuk(puk)
|
||||
|
||||
proc storePinToKeycard*(self: Controller, pin: string, puk: string) =
|
||||
self.keycardService.storePin(pin, puk)
|
||||
|
||||
|
|
|
@ -16,11 +16,12 @@ method executeBackCommand*(self: CreatePinState, controller: Controller) =
|
|||
controller.cancelCurrentFlow()
|
||||
|
||||
method executeTertiaryCommand*(self: CreatePinState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
if self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method getNextSecondaryState*(self: CreatePinState, controller: Controller): State =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
if controller.getPin().len == PINLengthForStatusApp:
|
||||
return createState(StateType.RepeatPin, self.flowType, self)
|
||||
return nil
|
||||
if self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getPin().len == PINLengthForStatusApp:
|
||||
return createState(StateType.RepeatPin, self.flowType, self)
|
|
@ -18,7 +18,7 @@ method executePrimaryCommand*(self: EnterBiometricsPasswordState, controller: Co
|
|||
controller.tryToStoreDataToKeychain(password)
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||
else:
|
||||
controller.setKeycardData("wrong-pass")
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongPassword, add = true))
|
||||
|
||||
method getNextPrimaryState*(self: EnterBiometricsPasswordState, controller: Controller): State =
|
||||
if self.flowType == FlowType.Authentication:
|
||||
|
|
|
@ -17,7 +17,7 @@ method executePrimaryCommand*(self: EnterPasswordState, controller: Controller)
|
|||
if self.success:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||
else:
|
||||
controller.setKeycardData("wrong-pass")
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongPassword, add = true))
|
||||
|
||||
method getNextPrimaryState*(self: EnterPasswordState, controller: Controller): State =
|
||||
if self.flowType == FlowType.Authentication:
|
||||
|
|
|
@ -52,7 +52,7 @@ method resolveKeycardNextState*(self: EnterPinState, keycardFlowType: string, ke
|
|||
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
|
||||
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata, updateKeyPair = true)
|
||||
return createState(StateType.PinVerified, self.flowType, nil)
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN and
|
||||
|
@ -61,16 +61,19 @@ method resolveKeycardNextState*(self: EnterPinState, keycardFlowType: string, ke
|
|||
controller.setKeycardData($keycardEvent.pinRetries)
|
||||
if keycardEvent.pinRetries > 0:
|
||||
return createState(StateType.WrongPin, self.flowType, nil)
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseUnlockLabelForLockedState, add = true))
|
||||
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN and
|
||||
keycardEvent.error.len == 0:
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseUnlockLabelForLockedState, 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.UseUnlockLabelForLockedState, add = true))
|
||||
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata, updateKeyPair = true)
|
||||
return createState(StateType.PinVerified, self.flowType, nil)
|
||||
if self.flowType == FlowType.Authentication:
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN and
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
type
|
||||
EnterPukState* = ref object of State
|
||||
|
||||
proc newEnterPukState*(flowType: FlowType, backState: State): EnterPukState =
|
||||
result = EnterPukState()
|
||||
result.setup(flowType, StateType.EnterPuk, backState)
|
||||
|
||||
proc delete*(self: EnterPukState) =
|
||||
self.State.delete
|
||||
|
||||
method executePrimaryCommand*(self: EnterPukState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getPuk().len == PUKLengthForStatusApp:
|
||||
controller.enterKeycardPuk(controller.getPuk())
|
||||
|
||||
method executeTertiaryCommand*(self: EnterPukState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: EnterPukState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
let state = ensureReaderAndCardPresence(self, keycardFlowType, keycardEvent, controller)
|
||||
if not state.isNil:
|
||||
return state
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if keycardFlowType == ResponseTypeValueEnterNewPIN and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorUnblocking:
|
||||
return createState(StateType.CreatePin, self.flowType, self.getBackState)
|
||||
if keycardFlowType == ResponseTypeValueEnterPUK and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == RequestParamPUK:
|
||||
controller.setKeycardData($keycardEvent.pukRetries)
|
||||
if keycardEvent.pukRetries > 0:
|
||||
return createState(StateType.WrongPuk, self.flowType, self.getBackState)
|
||||
return createState(StateType.MaxPukRetriesReached, self.flowType, nil)
|
|
@ -17,16 +17,25 @@ method executePrimaryCommand*(self: EnterSeedPhraseState, controller: Controller
|
|||
if self.verifiedSeedPhrase:
|
||||
controller.storeSeedPhraseToKeycard(controller.getSeedPhraseLength(), controller.getSeedPhrase())
|
||||
else:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = true))
|
||||
|
||||
method executeTertiaryCommand*(self: EnterSeedPhraseState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = true))
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
self.verifiedSeedPhrase = controller.validSeedPhrase(controller.getSeedPhrase()) and
|
||||
controller.getKeyUidForSeedPhrase(controller.getSeedPhrase()) == controller.getKeyUidWhichIsBeingUnlocking()
|
||||
if self.verifiedSeedPhrase:
|
||||
controller.runGetMetadataFlow()
|
||||
else:
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = true))
|
||||
|
||||
method getNextPrimaryState*(self: EnterSeedPhraseState, controller: Controller): State =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
if not self.verifiedSeedPhrase:
|
||||
return createState(StateType.WrongSeedPhrase, self.flowType, nil)
|
||||
if self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
if not self.verifiedSeedPhrase:
|
||||
return createState(StateType.WrongSeedPhrase, self.flowType, nil)
|
||||
|
||||
method executeTertiaryCommand*(self: EnterSeedPhraseState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: EnterSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
|
@ -37,3 +46,15 @@ method resolveKeycardNextState*(self: EnterSeedPhraseState, keycardFlowType: str
|
|||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.keyUid.len > 0:
|
||||
return createState(StateType.MigratingKeyPair, self.flowType, nil)
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata:
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
if keycardEvent.error.len == 0:
|
||||
controller.setKeycardUid(keycardEvent.instanceUID)
|
||||
controller.runLoadAccountFlow(seedPhraseLength = controller.getSeedPhraseLength(), seedPhrase = controller.getSeedPhrase(), puk = "", factoryReset = true)
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.LoadAccount:
|
||||
if keycardFlowType == ResponseTypeValueEnterNewPIN and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorRequireInit:
|
||||
return createState(StateType.CreatePin, self.flowType, nil)
|
||||
|
|
|
@ -12,7 +12,7 @@ method executePrimaryCommand*(self: FactoryResetConfirmationDisplayMetadataState
|
|||
if self.flowType == FlowType.FactoryReset:
|
||||
controller.runGetAppInfoFlow(factoryReset = true)
|
||||
elif self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
|
||||
controller.runGetAppInfoFlow(factoryReset = true)
|
||||
|
||||
method executeTertiaryCommand*(self: FactoryResetConfirmationDisplayMetadataState, controller: Controller) =
|
||||
|
|
|
@ -12,7 +12,7 @@ method executePrimaryCommand*(self: FactoryResetConfirmationState, controller: C
|
|||
if self.flowType == FlowType.FactoryReset:
|
||||
controller.runGetAppInfoFlow(factoryReset = true)
|
||||
elif self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
|
||||
controller.runGetAppInfoFlow(factoryReset = true)
|
||||
|
||||
method executeTertiaryCommand*(self: FactoryResetConfirmationState, controller: Controller) =
|
||||
|
|
|
@ -13,15 +13,11 @@ method executeBackCommand*(self: InsertKeycardState, controller: Controller) =
|
|||
if not self.getBackState.isNil and self.getBackState.stateType == StateType.SelectExistingKeyPair:
|
||||
controller.cancelCurrentFlow()
|
||||
|
||||
method executePrimaryCommand*(self: InsertKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method executeTertiaryCommand*(self: InsertKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication:
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: InsertKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
|
@ -32,10 +28,10 @@ method resolveKeycardNextState*(self: InsertKeycardState, keycardFlowType: strin
|
|||
if keycardFlowType == ResponseTypeValueInsertCard and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorConnection:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = true))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = true))
|
||||
return nil
|
||||
if keycardFlowType == ResponseTypeValueCardInserted:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
return createState(StateType.KeycardInserted, self.flowType, self.getBackState)
|
||||
return createState(StateType.KeycardInserted, self.flowType, nil)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
type
|
||||
KeycardAlreadyUnlockedState* = ref object of State
|
||||
|
||||
proc newKeycardAlreadyUnlockedState*(flowType: FlowType, backState: State): KeycardAlreadyUnlockedState =
|
||||
result = KeycardAlreadyUnlockedState()
|
||||
result.setup(flowType, StateType.KeycardAlreadyUnlocked, backState)
|
||||
|
||||
proc delete*(self: KeycardAlreadyUnlockedState) =
|
||||
self.State.delete
|
||||
|
||||
method executePrimaryCommand*(self: KeycardAlreadyUnlockedState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||
|
||||
method executeTertiaryCommand*(self: KeycardAlreadyUnlockedState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -11,5 +11,6 @@ proc delete*(self: KeycardEmptyState) =
|
|||
method executeTertiaryCommand*(self: KeycardEmptyState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication:
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -23,5 +23,6 @@ method getNextSecondaryState*(self: KeycardInsertedState, controller: Controller
|
|||
method executeTertiaryCommand*(self: KeycardInsertedState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication:
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
type
|
||||
KeycardLockedState* = ref object of State
|
||||
|
||||
proc newKeycardLockedState*(flowType: FlowType, backState: State): KeycardLockedState =
|
||||
result = KeycardLockedState()
|
||||
result.setup(flowType, StateType.KeycardLocked, backState)
|
||||
|
||||
proc delete*(self: KeycardLockedState) =
|
||||
self.State.delete
|
||||
|
||||
method getNextPrimaryState*(self: KeycardLockedState, controller: Controller): State =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
return createState(StateType.FactoryResetConfirmation, self.flowType, self)
|
||||
|
||||
method executeTertiaryCommand*(self: KeycardLockedState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -10,8 +10,8 @@ proc delete*(self: KeycardNotEmptyState) =
|
|||
|
||||
method executePrimaryCommand*(self: KeycardNotEmptyState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
|
||||
controller.runGetMetadataFlow()
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
|
||||
controller.runGetMetadataFlow(resolveAddress = true)
|
||||
|
||||
method executeTertiaryCommand*(self: KeycardNotEmptyState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
type
|
||||
MaxPairingSlotsReachedState* = ref object of State
|
||||
|
||||
proc newMaxPairingSlotsReachedState*(flowType: FlowType, backState: State): MaxPairingSlotsReachedState =
|
||||
result = MaxPairingSlotsReachedState()
|
||||
result.setup(flowType, StateType.MaxPairingSlotsReached, backState)
|
||||
|
||||
proc delete*(self: MaxPairingSlotsReachedState) =
|
||||
self.State.delete
|
||||
|
||||
method getNextPrimaryState*(self: MaxPairingSlotsReachedState, controller: Controller): State =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard:
|
||||
return createState(StateType.FactoryResetConfirmation, self.flowType, self)
|
||||
if self.flowType == FlowType.Authentication:
|
||||
debug "Run Unlock Keycard flow... (not developed yet)"
|
||||
return nil
|
||||
|
||||
method executeTertiaryCommand*(self: MaxPairingSlotsReachedState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -19,6 +19,8 @@ method getNextPrimaryState*(self: MaxPinRetriesReachedState, controller: Control
|
|||
|
||||
method executeTertiaryCommand*(self: MaxPinRetriesReachedState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseUnlockLabelForLockedState, add = false))
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -0,0 +1,25 @@
|
|||
type
|
||||
MaxPukRetriesReachedState* = ref object of State
|
||||
|
||||
proc newMaxPukRetriesReachedState*(flowType: FlowType, backState: State): MaxPukRetriesReachedState =
|
||||
result = MaxPukRetriesReachedState()
|
||||
result.setup(flowType, StateType.MaxPukRetriesReached, backState)
|
||||
|
||||
proc delete*(self: MaxPukRetriesReachedState) =
|
||||
self.State.delete
|
||||
|
||||
method getNextPrimaryState*(self: MaxPukRetriesReachedState, controller: Controller): State =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard:
|
||||
return createState(StateType.FactoryResetConfirmation, self.flowType, self)
|
||||
if self.flowType == FlowType.Authentication:
|
||||
debug "Run Unlock Keycard flow... (not developed yet)"
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
return createState(StateType.EnterSeedPhrase, self.flowType, self)
|
||||
|
||||
method executeTertiaryCommand*(self: MaxPukRetriesReachedState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -11,5 +11,6 @@ proc delete*(self: NotKeycardState) =
|
|||
method executeTertiaryCommand*(self: NotKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication:
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -14,7 +14,13 @@ method getNextPrimaryState*(self: PinSetState, controller: Controller): State =
|
|||
return createState(StateType.EnterSeedPhrase, self.flowType, nil)
|
||||
else:
|
||||
return createState(StateType.SeedPhraseDisplay, self.flowType, nil)
|
||||
return nil
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata:
|
||||
if controller.getValidPuk():
|
||||
return createState(StateType.UnlockKeycardSuccess, self.flowType, nil)
|
||||
return createState(StateType.WrongPuk, self.flowType, self.getBackState)
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.StoreMetadata:
|
||||
return createState(StateType.UnlockKeycardSuccess, self.flowType, nil)
|
||||
|
||||
method executeTertiaryCommand*(self: PinSetState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
|
|
|
@ -16,7 +16,8 @@ method executeBackCommand*(self: PluginReaderState, controller: Controller) =
|
|||
method executeTertiaryCommand*(self: PluginReaderState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication:
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: PluginReaderState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
|
|
|
@ -16,7 +16,8 @@ method executeBackCommand*(self: ReadingKeycardState, controller: Controller) =
|
|||
method executeTertiaryCommand*(self: ReadingKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.Authentication:
|
||||
self.flowType == FlowType.Authentication or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method getNextSecondaryState*(self: ReadingKeycardState, controller: Controller): State =
|
||||
|
|
|
@ -13,11 +13,6 @@ method executeBackCommand*(self: RecognizedKeycardState, controller: Controller)
|
|||
if not self.getBackState.isNil and self.getBackState.stateType == StateType.SelectExistingKeyPair:
|
||||
controller.cancelCurrentFlow()
|
||||
|
||||
method executeTertiaryCommand*(self: RecognizedKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method getNextSecondaryState*(self: RecognizedKeycardState, controller: Controller): State =
|
||||
if self.flowType == FlowType.FactoryReset:
|
||||
if controller.containsMetadata():
|
||||
|
@ -25,4 +20,12 @@ method getNextSecondaryState*(self: RecognizedKeycardState, controller: Controll
|
|||
else:
|
||||
return createState(StateType.FactoryResetConfirmation, self.flowType, nil)
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
return createState(StateType.CreatePin, self.flowType, self.getBackState)
|
||||
return createState(StateType.CreatePin, self.flowType, self.getBackState)
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
return createState(StateType.UnlockKeycardOptions, self.flowType, nil)
|
||||
|
||||
method executeTertiaryCommand*(self: RecognizedKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.FactoryReset or
|
||||
self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -15,12 +15,14 @@ method executeBackCommand*(self: RepeatPinState, controller: Controller) =
|
|||
method executeSecondaryCommand*(self: RepeatPinState, controller: Controller) =
|
||||
if not controller.getPinMatch():
|
||||
return
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK())
|
||||
if self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK())
|
||||
|
||||
method executeTertiaryCommand*(self: RepeatPinState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
if self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: RepeatPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
|
@ -31,5 +33,33 @@ method resolveKeycardNextState*(self: RepeatPinState, keycardFlowType: string, k
|
|||
if keycardFlowType == ResponseTypeValueEnterMnemonic and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorLoadingKeys:
|
||||
controller.setKeycardUid(keycardEvent.instanceUID)
|
||||
return createState(StateType.PinSet, self.flowType, nil)
|
||||
controller.setKeycardUidTheSelectedKeypairIsMigratedTo(keycardEvent.instanceUID)
|
||||
return createState(StateType.PinSet, self.flowType, nil)
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata:
|
||||
if keycardFlowType == ResponseTypeValueEnterPUK and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == RequestParamPUK:
|
||||
controller.setKeycardData($keycardEvent.pukRetries)
|
||||
controller.setPukValid(false)
|
||||
if keycardEvent.pukRetries > 0:
|
||||
return createState(StateType.PinSet, self.flowType, nil)
|
||||
return createState(StateType.MaxPukRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
controller.setPukValid(true)
|
||||
controller.updateKeycardUid(keycardEvent.instanceUID)
|
||||
return createState(StateType.PinSet, self.flowType, nil)
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.LoadAccount:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
if controller.getKeyUidWhichIsBeingUnlocking() != keycardEvent.keyUid:
|
||||
error "load account keyUid and keyUid being unlocked do not match"
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
return
|
||||
let md = controller.getMetadataFromKeycard()
|
||||
let paths = md.walletAccounts.map(a => a.path)
|
||||
controller.runStoreMetadataFlow(cardName = md.name, pin = controller.getPin(), walletPaths = paths)
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.StoreMetadata:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.instanceUID.len > 0:
|
||||
controller.updateKeycardUid(keycardEvent.instanceUID)
|
||||
return createState(StateType.PinSet, self.flowType, nil)
|
|
@ -16,8 +16,12 @@ type StateType* {.pure.} = enum
|
|||
PinVerified = "PinVerified"
|
||||
EnterPin = "EnterPin"
|
||||
WrongPin = "WrongPin"
|
||||
EnterPuk = "EnterPuk"
|
||||
WrongPuk = "WrongPuk"
|
||||
WrongKeychainPin = "WrongKeychainPin"
|
||||
MaxPinRetriesReached = "MaxPinRetriesReached"
|
||||
MaxPukRetriesReached = "MaxPukRetriesReached"
|
||||
MaxPairingSlotsReached = "MaxPairingSlotsReached"
|
||||
FactoryResetConfirmation = "FactoryResetConfirmation"
|
||||
FactoryResetConfirmationDisplayMetadata = "FactoryResetConfirmationDisplayMetadata"
|
||||
FactoryResetSuccess = "FactoryResetSuccess"
|
||||
|
@ -26,6 +30,9 @@ type StateType* {.pure.} = enum
|
|||
KeycardEmpty = "KeycardEmpty"
|
||||
KeycardNotEmpty = "KeycardNotEmpty"
|
||||
KeycardLocked = "KeycardLocked"
|
||||
KeycardAlreadyUnlocked = "KeycardAlreadyUnlocked"
|
||||
UnlockKeycardOptions = "UnlockKeycardOptions"
|
||||
UnlockKeycardSuccess = "UnlockKeycardSuccess"
|
||||
NotKeycard = "NotKeycard"
|
||||
WrongKeycard = "WrongKeycard"
|
||||
RecognizedKeycard = "RecognizedKeycard"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import parseutils, chronicles
|
||||
import parseutils, sequtils, sugar, chronicles
|
||||
import ../../../../../app_service/service/keycard/constants
|
||||
import ../controller
|
||||
from ../../../../../app_service/service/keycard/service import KCSFlowType
|
||||
|
@ -14,10 +14,14 @@ type PredefinedKeycardData* {.pure.} = enum
|
|||
WronglyInsertedCard = 1
|
||||
HideKeyPair = 2
|
||||
WrongSeedPhrase = 4
|
||||
WrongPassword = 8
|
||||
OfferPukForUnlock = 16
|
||||
UseUnlockLabelForLockedState = 32
|
||||
|
||||
# Forward declaration
|
||||
proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: State): State
|
||||
proc getPredefinedKeycardData*(currValue: string, value: PredefinedKeycardData, add: bool): string
|
||||
proc extractPredefinedKeycardDataToNumber*(currValue: string): int
|
||||
proc updatePredefinedKeycardData*(currValue: string, value: PredefinedKeycardData, add: bool): string
|
||||
proc ensureReaderAndCardPresence*(state: State, keycardFlowType: string, keycardEvent: KeycardEvent, controller: Controller): State
|
||||
proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowType: string, keycardEvent: KeycardEvent, controller: Controller): State
|
||||
|
||||
|
@ -29,6 +33,7 @@ include create_pin_state
|
|||
include enter_biometrics_password_state
|
||||
include enter_password_state
|
||||
include enter_pin_state
|
||||
include enter_puk_state
|
||||
include enter_seed_phrase_state
|
||||
include factory_reset_confirmation_displayed_metadata_state
|
||||
include factory_reset_confirmation_state
|
||||
|
@ -41,8 +46,10 @@ include keycard_empty_state
|
|||
include keycard_inserted_state
|
||||
include keycard_metadata_display_state
|
||||
include keycard_not_empty_state
|
||||
include keycard_locked_state
|
||||
include keycard_already_unlocked_state
|
||||
include max_pin_retries_reached_state
|
||||
include max_puk_retries_reached_state
|
||||
include max_pairing_slots_reached_state
|
||||
include migrating_key_pair_state
|
||||
include not_keycard_state
|
||||
include pin_set_state
|
||||
|
@ -54,14 +61,26 @@ include repeat_pin_state
|
|||
include seed_phrase_display_state
|
||||
include seed_phrase_enter_words_state
|
||||
include select_existing_key_pair_state
|
||||
include unlock_keycard_options_state
|
||||
include unlock_keycard_success_state
|
||||
include wrong_biometrics_password_state
|
||||
include wrong_keycard_state
|
||||
include wrong_password_state
|
||||
include wrong_pin_state
|
||||
include wrong_puk_state
|
||||
include wrong_keychain_pin_state
|
||||
include wrong_seed_phrase_state
|
||||
|
||||
proc getPredefinedKeycardData*(currValue: string, value: PredefinedKeycardData, add: bool): string =
|
||||
proc extractPredefinedKeycardDataToNumber*(currValue: string): int =
|
||||
var currNum: int
|
||||
try:
|
||||
if parseInt(currValue, currNum) == 0:
|
||||
return 0
|
||||
return currNum
|
||||
except:
|
||||
return 0
|
||||
|
||||
proc updatePredefinedKeycardData*(currValue: string, value: PredefinedKeycardData, add: bool): string =
|
||||
var currNum: int
|
||||
try:
|
||||
if add:
|
||||
|
@ -94,6 +113,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
|
|||
return newEnterPasswordState(flowType, backState)
|
||||
if stateToBeCreated == StateType.EnterPin:
|
||||
return newEnterPinState(flowType, backState)
|
||||
if stateToBeCreated == StateType.EnterPuk:
|
||||
return newEnterPukState(flowType, backState)
|
||||
if stateToBeCreated == StateType.EnterSeedPhrase:
|
||||
return newEnterSeedPhraseState(flowType, backState)
|
||||
if stateToBeCreated == StateType.FactoryResetConfirmationDisplayMetadata:
|
||||
|
@ -118,10 +139,18 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
|
|||
return newKeycardMetadataDisplayState(flowType, backState)
|
||||
if stateToBeCreated == StateType.KeycardNotEmpty:
|
||||
return newKeycardNotEmptyState(flowType, backState)
|
||||
if stateToBeCreated == StateType.KeycardLocked:
|
||||
return newKeycardLockedState(flowType, backState)
|
||||
if stateToBeCreated == StateType.KeycardAlreadyUnlocked:
|
||||
return newKeycardAlreadyUnlockedState(flowType, backState)
|
||||
if stateToBeCreated == StateType.UnlockKeycardOptions:
|
||||
return newUnlockKeycardOptionsState(flowType, backState)
|
||||
if stateToBeCreated == StateType.UnlockKeycardSuccess:
|
||||
return newUnlockKeycardSuccessState(flowType, backState)
|
||||
if stateToBeCreated == StateType.MaxPinRetriesReached:
|
||||
return newMaxPinRetriesReachedState(flowType, backState)
|
||||
if stateToBeCreated == StateType.MaxPukRetriesReached:
|
||||
return newMaxPukRetriesReachedState(flowType, backState)
|
||||
if stateToBeCreated == StateType.MaxPairingSlotsReached:
|
||||
return newMaxPairingSlotsReachedState(flowType, backState)
|
||||
if stateToBeCreated == StateType.MigratingKeyPair:
|
||||
return newMigratingKeyPairState(flowType, backState)
|
||||
if stateToBeCreated == StateType.NotKeycard:
|
||||
|
@ -152,6 +181,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
|
|||
return newWrongPasswordState(flowType, backState)
|
||||
if stateToBeCreated == StateType.WrongPin:
|
||||
return newWrongPinState(flowType, backState)
|
||||
if stateToBeCreated == StateType.WrongPuk:
|
||||
return newWrongPukState(flowType, backState)
|
||||
if stateToBeCreated == StateType.WrongKeychainPin:
|
||||
return newWrongKeychainPinState(flowType, backState)
|
||||
if stateToBeCreated == StateType.WrongSeedPhrase:
|
||||
|
@ -160,9 +191,10 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
|
|||
error "No implementation available for state ", state=stateToBeCreated
|
||||
|
||||
proc ensureReaderAndCardPresence*(state: State, keycardFlowType: string, keycardEvent: KeycardEvent, controller: Controller): State =
|
||||
## Handling factory reset or authentication flow
|
||||
## Handling factory reset or authentication or unlock keycard flow
|
||||
if state.flowType == FlowType.FactoryReset or
|
||||
state.flowType == FlowType.Authentication:
|
||||
state.flowType == FlowType.Authentication or
|
||||
state.flowType == FlowType.UnlockKeycard:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorConnection:
|
||||
|
@ -177,7 +209,7 @@ proc ensureReaderAndCardPresence*(state: State, keycardFlowType: string, keycard
|
|||
return nil
|
||||
return createState(StateType.InsertKeycard, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueCardInserted:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
|
||||
return createState(StateType.KeycardInserted, state.flowType, nil)
|
||||
|
||||
## Handling setup new keycard flow
|
||||
|
@ -198,7 +230,7 @@ proc ensureReaderAndCardPresence*(state: State, keycardFlowType: string, keycard
|
|||
return createState(StateType.InsertKeycard, state.flowType, state)
|
||||
return createState(StateType.InsertKeycard, state.flowType, state.getBackState)
|
||||
if keycardFlowType == ResponseTypeValueCardInserted:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
|
||||
if state.stateType == StateType.SelectExistingKeyPair:
|
||||
return createState(StateType.InsertKeycard, state.flowType, state)
|
||||
return createState(StateType.KeycardInserted, state.flowType, state.getBackState)
|
||||
|
@ -214,11 +246,15 @@ proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowTy
|
|||
if keycardFlowType == ResponseTypeValueEnterPUK and
|
||||
keycardEvent.error.len == 0:
|
||||
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
|
||||
return createState(StateType.MaxPinRetriesReached, state.flowType, nil)
|
||||
return createState(StateType.FactoryResetConfirmation, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueSwapCard and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorNotAKeycard:
|
||||
keycardEvent.error.len > 0:
|
||||
if keycardEvent.error == ErrorNotAKeycard:
|
||||
return createState(StateType.NotKeycard, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorFreePairingSlots:
|
||||
return createState(StateType.FactoryResetConfirmation, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorPUKRetries:
|
||||
return createState(StateType.FactoryResetConfirmation, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
if keycardEvent.error.len > 0:
|
||||
if keycardEvent.error == ErrorOk:
|
||||
|
@ -241,7 +277,9 @@ proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowTy
|
|||
if keycardEvent.error == ErrorHasKeys:
|
||||
return createState(StateType.KeycardNotEmpty, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorFreePairingSlots:
|
||||
return createState(StateType.KeycardLocked, state.flowType, nil)
|
||||
return createState(StateType.MaxPairingSlotsReached, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorPUKRetries:
|
||||
return createState(StateType.MaxPukRetriesReached, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN:
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata:
|
||||
return createState(StateType.EnterPin, state.flowType, nil)
|
||||
|
@ -274,6 +312,10 @@ proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowTy
|
|||
return createState(StateType.NotKeycard, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorNoKeys:
|
||||
return createState(StateType.KeycardEmpty, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorFreePairingSlots:
|
||||
return createState(StateType.MaxPairingSlotsReached, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorPUKRetries:
|
||||
return createState(StateType.MaxPukRetriesReached, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN:
|
||||
if keycardEvent.keyUid == controller.getKeyUidWhichIsBeingAuthenticating():
|
||||
if controller.loggedInUserUsesBiometricLogin():
|
||||
|
@ -295,4 +337,30 @@ proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowTy
|
|||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
if keycardEvent.error.len == 0:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||
return nil
|
||||
return nil
|
||||
|
||||
## Handling unlock keycard flow
|
||||
if state.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata:
|
||||
controller.setKeyUidWhichIsBeingUnlocking(keycardEvent.keyUid)
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN and
|
||||
keycardEvent.error.len == 0:
|
||||
return createState(StateType.KeycardAlreadyUnlocked, 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:
|
||||
return createState(StateType.RecognizedKeycard, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorPUKRetries:
|
||||
return createState(StateType.RecognizedKeycard, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueEnterPUK and
|
||||
keycardEvent.error.len == 0:
|
||||
controller.setKeycardUid(keycardEvent.instanceUID)
|
||||
return createState(StateType.RecognizedKeycard, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult or
|
||||
keycardEvent.error.len > 0:
|
||||
if keycardEvent.error == ErrorNoKeys:
|
||||
return createState(StateType.KeycardEmpty, state.flowType, nil)
|
|
@ -0,0 +1,21 @@
|
|||
type
|
||||
UnlockKeycardOptionsState* = ref object of State
|
||||
|
||||
proc newUnlockKeycardOptionsState*(flowType: FlowType, backState: State): UnlockKeycardOptionsState =
|
||||
result = UnlockKeycardOptionsState()
|
||||
result.setup(flowType, StateType.UnlockKeycardOptions, backState)
|
||||
|
||||
proc delete*(self: UnlockKeycardOptionsState) =
|
||||
self.State.delete
|
||||
|
||||
method getNextPrimaryState*(self: UnlockKeycardOptionsState, controller: Controller): State =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
return createState(StateType.EnterSeedPhrase, self.flowType, self)
|
||||
|
||||
method getNextSecondaryState*(self: UnlockKeycardOptionsState, controller: Controller): State =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
return createState(StateType.EnterPuk, self.flowType, self)
|
||||
|
||||
method executeTertiaryCommand*(self: UnlockKeycardOptionsState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
|
@ -0,0 +1,17 @@
|
|||
type
|
||||
UnlockKeycardSuccessState* = ref object of State
|
||||
|
||||
proc newUnlockKeycardSuccessState*(flowType: FlowType, backState: State): UnlockKeycardSuccessState =
|
||||
result = UnlockKeycardSuccessState()
|
||||
result.setup(flowType, StateType.UnlockKeycardSuccess, backState)
|
||||
|
||||
proc delete*(self: UnlockKeycardSuccessState) =
|
||||
self.State.delete
|
||||
|
||||
method executePrimaryCommand*(self: UnlockKeycardSuccessState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||
|
||||
method executeTertiaryCommand*(self: UnlockKeycardSuccessState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
|
@ -12,14 +12,14 @@ proc delete*(self: WrongBiometricsPasswordState) =
|
|||
|
||||
method executePrimaryCommand*(self: WrongBiometricsPasswordState, controller: Controller) =
|
||||
if self.flowType == FlowType.Authentication:
|
||||
controller.setKeycardData("")
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongPassword, add = false))
|
||||
let password = controller.getPassword()
|
||||
self.success = controller.verifyPassword(password)
|
||||
if self.success:
|
||||
controller.tryToStoreDataToKeychain(password)
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||
else:
|
||||
controller.setKeycardData("wrong-pass")
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongPassword, add = true))
|
||||
|
||||
method executeTertiaryCommand*(self: WrongBiometricsPasswordState, controller: Controller) =
|
||||
if self.flowType == FlowType.Authentication:
|
||||
|
|
|
@ -12,13 +12,13 @@ proc delete*(self: WrongPasswordState) =
|
|||
|
||||
method executePrimaryCommand*(self: WrongPasswordState, controller: Controller) =
|
||||
if self.flowType == FlowType.Authentication:
|
||||
controller.setKeycardData("")
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongPassword, add = false))
|
||||
let password = controller.getPassword()
|
||||
self.success = controller.verifyPassword(password)
|
||||
if self.success:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||
else:
|
||||
controller.setKeycardData("wrong-pass")
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongPassword, add = true))
|
||||
|
||||
method executeSecondaryCommand*(self: WrongPasswordState, controller: Controller) =
|
||||
if self.flowType == FlowType.Authentication:
|
||||
|
|
|
@ -50,7 +50,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
|
|||
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
|
||||
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata, updateKeyPair = true)
|
||||
return createState(StateType.PinVerified, self.flowType, nil)
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN and
|
||||
|
@ -59,13 +59,15 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
|
|||
controller.setKeycardData($keycardEvent.pinRetries)
|
||||
if keycardEvent.pinRetries > 0:
|
||||
return self
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseUnlockLabelForLockedState, 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.UseUnlockLabelForLockedState, add = true))
|
||||
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata, updateKeyPair = true)
|
||||
return createState(StateType.PinVerified, self.flowType, nil)
|
||||
if self.flowType == FlowType.Authentication:
|
||||
if keycardFlowType == ResponseTypeValueEnterPIN and
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
type
|
||||
WrongPukState* = ref object of State
|
||||
|
||||
proc newWrongPukState*(flowType: FlowType, backState: State): WrongPukState =
|
||||
result = WrongPukState()
|
||||
result.setup(flowType, StateType.WrongPuk, backState)
|
||||
|
||||
proc delete*(self: WrongPukState) =
|
||||
self.State.delete
|
||||
|
||||
method executePrimaryCommand*(self: WrongPukState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getPuk().len == PUKLengthForStatusApp:
|
||||
controller.enterKeycardPuk(controller.getPuk())
|
||||
|
||||
method executeTertiaryCommand*(self: WrongPukState, controller: Controller) =
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: WrongPukState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
let state = ensureReaderAndCardPresence(self, keycardFlowType, keycardEvent, controller)
|
||||
if not state.isNil:
|
||||
return state
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if keycardFlowType == ResponseTypeValueEnterPUK and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == RequestParamPUK:
|
||||
controller.setKeycardData($keycardEvent.pukRetries)
|
||||
controller.setPukValid(false)
|
||||
if keycardEvent.pukRetries > 0:
|
||||
return nil
|
||||
return createState(StateType.MaxPukRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueSwapCard and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == RequestParamPUKRetries:
|
||||
return createState(StateType.MaxPukRetriesReached, self.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
if keycardEvent.error.len == 0:
|
||||
controller.setPukValid(true)
|
||||
controller.updateKeycardUid(keycardEvent.instanceUID)
|
||||
return createState(StateType.UnlockKeycardSuccess, self.flowType, nil)
|
|
@ -14,18 +14,28 @@ proc delete*(self: WrongSeedPhraseState) =
|
|||
|
||||
method executePrimaryCommand*(self: WrongSeedPhraseState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = false))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = false))
|
||||
sleep(500) # just to shortly remove text on the UI side
|
||||
self.verifiedSeedPhrase = controller.validSeedPhrase(controller.getSeedPhrase()) and
|
||||
controller.seedPhraseRefersToSelectedKeyPair(controller.getSeedPhrase())
|
||||
if self.verifiedSeedPhrase:
|
||||
controller.storeSeedPhraseToKeycard(controller.getSeedPhraseLength(), controller.getSeedPhrase())
|
||||
else:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = true))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = true))
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = false))
|
||||
sleep(500) # just to shortly remove text on the UI side
|
||||
self.verifiedSeedPhrase = controller.validSeedPhrase(controller.getSeedPhrase()) and
|
||||
controller.getKeyUidForSeedPhrase(controller.getSeedPhrase()) == controller.getKeyUidWhichIsBeingUnlocking()
|
||||
if self.verifiedSeedPhrase:
|
||||
controller.runGetMetadataFlow()
|
||||
else:
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = true))
|
||||
|
||||
method executeTertiaryCommand*(self: WrongSeedPhraseState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
if self.flowType == FlowType.SetupNewKeycard or
|
||||
self.flowType == FlowType.UnlockKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: WrongSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
|
@ -35,5 +45,17 @@ method resolveKeycardNextState*(self: WrongSeedPhraseState, keycardFlowType: str
|
|||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.keyUid.len > 0:
|
||||
controller.setKeycardData(getPredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = false))
|
||||
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = false))
|
||||
return createState(StateType.MigratingKeyPair, self.flowType, nil)
|
||||
if self.flowType == FlowType.UnlockKeycard:
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata:
|
||||
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
|
||||
if keycardEvent.error.len == 0:
|
||||
controller.setKeycardUid(keycardEvent.instanceUID)
|
||||
controller.runLoadAccountFlow(seedPhraseLength = controller.getSeedPhraseLength(), seedPhrase = controller.getSeedPhrase(), puk = "", factoryReset = true)
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.LoadAccount:
|
||||
if keycardFlowType == ResponseTypeValueEnterNewPIN and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorRequireInit:
|
||||
return createState(StateType.CreatePin, self.flowType, nil)
|
||||
|
|
|
@ -35,6 +35,7 @@ type FlowType* {.pure.} = enum
|
|||
FactoryReset = "FactoryReset"
|
||||
SetupNewKeycard = "SetupNewKeycard"
|
||||
Authentication = "Authentication"
|
||||
UnlockKeycard = "UnlockKeycard"
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
@ -72,6 +73,9 @@ method runFlow*(self: AccessInterface, flowToRun: FlowType, keyUid = "", bip44Pa
|
|||
method setPin*(self: AccessInterface, value: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setPuk*(self: AccessInterface, value: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setPassword*(self: AccessInterface, value: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ proc initKeyPairItem*(
|
|||
proc `$`*(self: KeyPairItem): string =
|
||||
result = fmt"""KeyPairItem[
|
||||
pubKey: {self.pubkey},
|
||||
keyUid: {self.keyUid},
|
||||
name: {self.name},
|
||||
image: {self.image},
|
||||
icon: {self.icon},
|
||||
|
|
|
@ -69,6 +69,9 @@ method setKeycardData*[T](self: Module[T], value: string) =
|
|||
method setPin*[T](self: Module[T], value: string) =
|
||||
self.controller.setPin(value)
|
||||
|
||||
method setPuk*[T](self: Module[T], value: string) =
|
||||
self.controller.setPuk(value)
|
||||
|
||||
method setPassword*[T](self: Module[T], value: string) =
|
||||
self.controller.setPassword(value)
|
||||
|
||||
|
@ -111,11 +114,25 @@ method isProfileKeyPairMigrated*[T](self: Module[T]): bool =
|
|||
method getSigningPhrase*[T](self: Module[T]): string =
|
||||
return self.controller.getSigningPhrase()
|
||||
|
||||
proc authenticationKeyPairUpdate[T](self: Module[T], currFlowType: FlowType, nextStateType: StateType) =
|
||||
## special check only for authentication flow
|
||||
proc preStateActivities[T](self: Module[T], currFlowType: FlowType, nextStateType: StateType) =
|
||||
if nextStateType == StateType.MaxPinRetriesReached or
|
||||
nextStateType == StateType.MaxPukRetriesReached or
|
||||
nextStateType == StateType.MaxPairingSlotsReached or
|
||||
nextStateType == StateType.UnlockKeycardOptions:
|
||||
## in case the card is locked on another device, we're updating its state in the DB
|
||||
let (_, flowEvent) = self.controller.getLastReceivedKeycardData()
|
||||
self.controller.setCurrentKeycardStateToLocked(flowEvent.instanceUID)
|
||||
|
||||
if currFlowType == FlowType.Authentication:
|
||||
self.view.setLockedPropForKeyPairForAuthentication(nextStateType == StateType.MaxPinRetriesReached)
|
||||
|
||||
if currFlowType == FlowType.UnlockKeycard:
|
||||
if nextStateType == StateType.UnlockKeycardOptions:
|
||||
let (_, flowEvent) = self.controller.getLastReceivedKeycardData()
|
||||
self.controller.setKeycardData(updatePredefinedKeycardData(self.controller.getKeycardData(), PredefinedKeycardData.OfferPukForUnlock, add = false))
|
||||
if flowEvent.pinRetries == 0 and flowEvent.pukRetries > 0:
|
||||
self.controller.setKeycardData(updatePredefinedKeycardData(self.controller.getKeycardData(), PredefinedKeycardData.OfferPukForUnlock, add = true))
|
||||
|
||||
method onBackActionClicked*[T](self: Module[T]) =
|
||||
let currStateObj = self.view.currentStateObj()
|
||||
if currStateObj.isNil:
|
||||
|
@ -124,7 +141,7 @@ method onBackActionClicked*[T](self: Module[T]) =
|
|||
debug "sm_back_action", currFlow=currStateObj.flowType(), currState=currStateObj.stateType()
|
||||
currStateObj.executeBackCommand(self.controller)
|
||||
let backState = currStateObj.getBackState()
|
||||
self.authenticationKeyPairUpdate(backState.flowType(), backState.stateType())
|
||||
self.preStateActivities(backState.flowType(), backState.stateType())
|
||||
self.view.setCurrentState(backState)
|
||||
debug "sm_back_action - set state", setCurrFlow=backState.flowType(), newCurrState=backState.stateType()
|
||||
currStateObj.delete()
|
||||
|
@ -139,7 +156,7 @@ method onPrimaryActionClicked*[T](self: Module[T]) =
|
|||
let nextState = currStateObj.getNextPrimaryState(self.controller)
|
||||
if nextState.isNil:
|
||||
return
|
||||
self.authenticationKeyPairUpdate(nextState.flowType(), nextState.stateType())
|
||||
self.preStateActivities(nextState.flowType(), nextState.stateType())
|
||||
self.view.setCurrentState(nextState)
|
||||
debug "sm_primary_action - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType()
|
||||
|
||||
|
@ -153,7 +170,7 @@ method onSecondaryActionClicked*[T](self: Module[T]) =
|
|||
let nextState = currStateObj.getNextSecondaryState(self.controller)
|
||||
if nextState.isNil:
|
||||
return
|
||||
self.authenticationKeyPairUpdate(nextState.flowType(), nextState.stateType())
|
||||
self.preStateActivities(nextState.flowType(), nextState.stateType())
|
||||
self.view.setCurrentState(nextState)
|
||||
debug "sm_secondary_action - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType()
|
||||
|
||||
|
@ -167,33 +184,36 @@ method onTertiaryActionClicked*[T](self: Module[T]) =
|
|||
let nextState = currStateObj.getNextTertiaryState(self.controller)
|
||||
if nextState.isNil:
|
||||
return
|
||||
self.authenticationKeyPairUpdate(nextState.flowType(), nextState.stateType())
|
||||
self.preStateActivities(nextState.flowType(), nextState.stateType())
|
||||
self.view.setCurrentState(nextState)
|
||||
debug "sm_tertiary_action - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType()
|
||||
|
||||
method onKeycardResponse*[T](self: Module[T], keycardFlowType: string, keycardEvent: KeycardEvent) =
|
||||
let currStateObj = self.view.currentStateObj()
|
||||
if currStateObj.isNil:
|
||||
if self.tmpLocalState.isNil:
|
||||
error "sm_cannot resolve current state"
|
||||
return
|
||||
## Check local state first, in case postponed flow is run
|
||||
if not self.tmpLocalState.isNil:
|
||||
let nextState = self.tmpLocalState.resolveKeycardNextState(keycardFlowType, keycardEvent, self.controller)
|
||||
self.tmpLocalState.delete
|
||||
self.tmpLocalState = nil
|
||||
if nextState.isNil:
|
||||
return
|
||||
self.authenticationKeyPairUpdate(nextState.flowType(), nextState.stateType())
|
||||
self.preStateActivities(nextState.flowType(), nextState.stateType())
|
||||
self.view.setCurrentState(nextState)
|
||||
self.controller.readyToDisplayPopup()
|
||||
debug "sm_on_keycard_response - from_local - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType()
|
||||
return
|
||||
## Check regular flows
|
||||
let currStateObj = self.view.currentStateObj()
|
||||
if currStateObj.isNil:
|
||||
return
|
||||
debug "sm_on_keycard_response", currFlow=currStateObj.flowType(), currState=currStateObj.stateType()
|
||||
let nextState = currStateObj.resolveKeycardNextState(keycardFlowType, keycardEvent, self.controller)
|
||||
if nextState.isNil:
|
||||
return
|
||||
self.authenticationKeyPairUpdate(nextState.flowType(), nextState.stateType())
|
||||
self.preStateActivities(nextState.flowType(), nextState.stateType())
|
||||
self.view.setCurrentState(nextState)
|
||||
debug "sm_on_keycard_response - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType()
|
||||
|
||||
proc buildKeyPairsList[T](self: Module[T]): seq[KeyPairItem] =
|
||||
proc buildKeyPairsList[T](self: Module[T], excludeAlreadyMigratedPairs: bool): seq[KeyPairItem] =
|
||||
let keyPairMigrated = proc(keyUid: string): bool =
|
||||
result = false
|
||||
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
|
||||
|
@ -218,12 +238,10 @@ proc buildKeyPairsList[T](self: Module[T]): seq[KeyPairItem] =
|
|||
let accounts = self.controller.getWalletAccounts()
|
||||
var items: seq[KeyPairItem]
|
||||
for a in accounts:
|
||||
if a.isChat or a.walletType == WalletTypeWatch or keyPairMigrated(a.keyUid):
|
||||
if a.isChat or a.walletType == WalletTypeWatch or (excludeAlreadyMigratedPairs and keyPairMigrated(a.keyUid)):
|
||||
continue
|
||||
var item = findItemByDerivedFromAddress(items, a.derivedfrom)
|
||||
if a.walletType == WalletTypeDefaultStatusAccount or a.walletType == WalletTypeGenerated:
|
||||
if self.isProfileKeyPairMigrated():
|
||||
continue
|
||||
if item.isNil:
|
||||
item = initKeyPairItem(pubKey = a.publicKey,
|
||||
keyUid = a.keyUid,
|
||||
|
@ -274,7 +292,7 @@ proc buildKeyPairsList[T](self: Module[T]): seq[KeyPairItem] =
|
|||
proc prepareKeyPairItemForAuthentication[T](self: Module[T], keyUid: string) =
|
||||
var item = initKeyPairItem()
|
||||
self.view.createKeyPairForAuthentication()
|
||||
let items = self.buildKeyPairsList()
|
||||
let items = self.buildKeyPairsList(excludeAlreadyMigratedPairs = false)
|
||||
for it in items:
|
||||
if it.keyUid == keyUid:
|
||||
item = it
|
||||
|
@ -299,13 +317,13 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path
|
|||
self.initialized = true
|
||||
self.controller.init()
|
||||
if flowToRun == FlowType.FactoryReset:
|
||||
let items = self.buildKeyPairsList()
|
||||
let items = self.buildKeyPairsList(excludeAlreadyMigratedPairs = false)
|
||||
self.view.createKeyPairModel(items)
|
||||
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
|
||||
self.controller.runGetMetadataFlow()
|
||||
self.controller.runGetMetadataFlow(resolveAddress = true)
|
||||
return
|
||||
if flowToRun == FlowType.SetupNewKeycard:
|
||||
let items = self.buildKeyPairsList()
|
||||
let items = self.buildKeyPairsList(excludeAlreadyMigratedPairs = true)
|
||||
self.view.createKeyPairModel(items)
|
||||
self.view.setCurrentState(newSelectExistingKeyPairState(flowToRun, nil))
|
||||
self.controller.readyToDisplayPopup()
|
||||
|
@ -324,6 +342,10 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path
|
|||
self.authenticationPopupIsAlreadyRunning = true
|
||||
self.controller.readyToDisplayPopup()
|
||||
return
|
||||
if flowToRun == FlowType.UnlockKeycard:
|
||||
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
|
||||
self.controller.runGetMetadataFlow(resolveAddress = true)
|
||||
return
|
||||
|
||||
method setSelectedKeyPair*[T](self: Module[T], item: KeyPairItem) =
|
||||
var paths: seq[string]
|
||||
|
|
|
@ -165,6 +165,9 @@ QtObject:
|
|||
proc setPin*(self: View, value: string) {.slot.} =
|
||||
self.delegate.setPin(value)
|
||||
|
||||
proc setPuk*(self: View, value: string) {.slot.} =
|
||||
self.delegate.setPuk(value)
|
||||
|
||||
proc setPassword*(self: View, value: string) {.slot.} =
|
||||
self.delegate.setPassword(value)
|
||||
|
||||
|
|
|
@ -369,19 +369,20 @@ proc loginAccountKeycard*(self: Controller) =
|
|||
if(error.len > 0):
|
||||
self.delegate.emitAccountLoginError(error)
|
||||
|
||||
proc seedPhraseRefersToSelectedKeyPair*(self: Controller, seedPhrase: string): bool =
|
||||
let selectedAccount = self.getSelectedLoginAccount()
|
||||
let accFromSP = self.accountsService.createAccountFromMnemonic(seedPhrase)
|
||||
return selectedAccount.keyUid == accFromSP.keyUid
|
||||
|
||||
proc cancelCurrentFlow*(self: Controller) =
|
||||
self.keycardService.cancelCurrentFlow()
|
||||
# in most cases we're running another flow after canceling the current one,
|
||||
# this way we're giving to the keycard some time to cancel the current flow
|
||||
sleep(200)
|
||||
|
||||
proc runLoadAccountFlow*(self: Controller, factoryReset = false) =
|
||||
proc runLoadAccountFlow*(self: Controller, seedPhraseLength = 0, seedPhrase = "", puk = "", factoryReset = false) =
|
||||
self.cancelCurrentFlow() # before running into any flow we're making sure that the previous flow is canceled
|
||||
self.keycardService.startLoadAccountFlow(factoryReset)
|
||||
|
||||
proc runLoadAccountFlowWithSeedPhrase*(self: Controller, seedPhraseLength: int, seedPhrase: string, factoryReset = false) =
|
||||
self.cancelCurrentFlow() # before running into any flow we're making sure that the previous flow is canceled
|
||||
self.keycardService.startLoadAccountFlowWithSeedPhrase(seedPhraseLength, seedPhrase, factoryReset)
|
||||
self.keycardService.startLoadAccountFlow(seedPhraseLength, seedPhrase, puk, factoryReset)
|
||||
|
||||
proc runLoginFlow*(self: Controller) =
|
||||
self.cancelCurrentFlow() # before running into any flow we're making sure that the previous flow is canceled
|
||||
|
@ -391,9 +392,9 @@ proc startLoginFlowAutomatically*(self: Controller, pin: string) =
|
|||
self.cancelCurrentFlow() # before running into any flow we're making sure that the previous flow is canceled
|
||||
self.keycardService.startLoginFlowAutomatically(pin)
|
||||
|
||||
proc runRecoverAccountFlow*(self: Controller) =
|
||||
proc runRecoverAccountFlow*(self: Controller, seedPhraseLength = 0, seedPhrase = "", puk = "", factoryReset = false) =
|
||||
self.cancelCurrentFlow() # before running into any flow we're making sure that the previous flow is canceled
|
||||
self.keycardService.startRecoverAccountFlow()
|
||||
self.keycardService.startRecoverAccountFlow(seedPhraseLength, seedPhrase, puk, factoryReset)
|
||||
|
||||
proc resumeCurrentFlow*(self: Controller) =
|
||||
self.keycardService.resumeCurrentFlow()
|
||||
|
|
|
@ -10,7 +10,7 @@ proc delete*(self: LoginKeycardEmptyState) =
|
|||
|
||||
method executePrimaryCommand*(self: LoginKeycardEmptyState, controller: Controller) =
|
||||
if self.flowType == FlowType.AppLogin:
|
||||
controller.runLoadAccountFlow(factoryReset = true)
|
||||
controller.runLoadAccountFlow(seedPhraseLength = 0, seedPhrase = "", puk = "", factoryReset = true)
|
||||
|
||||
method getNextSecondaryState*(self: LoginKeycardEmptyState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
|
|
|
@ -10,7 +10,7 @@ proc delete*(self: LoginNotKeycardState) =
|
|||
|
||||
method executePrimaryCommand*(self: LoginNotKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.AppLogin:
|
||||
controller.runLoadAccountFlow(factoryReset = true)
|
||||
controller.runLoadAccountFlow(seedPhraseLength = 0, seedPhrase = "", puk = "", factoryReset = true)
|
||||
|
||||
method getNextSecondaryState*(self: LoginNotKeycardState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
|
|
|
@ -23,14 +23,17 @@ method getNextPrimaryState*(self: UserProfileEnterSeedPhraseState, controller: C
|
|||
|
||||
method executePrimaryCommand*(self: UserProfileEnterSeedPhraseState, controller: Controller) =
|
||||
if self.flowType == FlowType.AppLogin:
|
||||
controller.runLoadAccountFlowWithSeedPhrase(controller.getSeedPhraseLength(), controller.getSeedPhrase(), factoryReset = true)
|
||||
self.successfulImport = controller.validMnemonic(controller.getSeedPhrase()) and
|
||||
controller.seedPhraseRefersToSelectedKeyPair(controller.getSeedPhrase())
|
||||
if self.successfulImport:
|
||||
controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), puk = "", factoryReset = true)
|
||||
else:
|
||||
self.successfulImport = controller.importMnemonic()
|
||||
if self.successfulImport:
|
||||
if self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
|
||||
controller.runLoadAccountFlowWithSeedPhrase(controller.getSeedPhraseLength(), controller.getSeedPhrase(), factoryReset = true)
|
||||
controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), puk = "", factoryReset = true)
|
||||
elif self.flowType == FlowType.FirstRunOldUserKeycardImport:
|
||||
controller.runLoadAccountFlowWithSeedPhrase(controller.getSeedPhraseLength(), controller.getSeedPhrase(), factoryReset = true)
|
||||
controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), puk = "", factoryReset = true)
|
||||
|
||||
method resolveKeycardNextState*(self: UserProfileEnterSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
|
|
|
@ -17,6 +17,7 @@ const ErrorStoreMeta* = "storing-metadata"
|
|||
const ErrorNoData* = "no-data"
|
||||
const ErrorFreePairingSlots* = "free-pairing-slots"
|
||||
const ErrorPIN* = "pin"
|
||||
const ErrorPUKRetries* = "puk-retries"
|
||||
|
||||
const RequestParamAppInfo* = "application-info"
|
||||
const RequestParamInstanceUID* = "instance-uid"
|
||||
|
|
|
@ -60,12 +60,6 @@ QtObject:
|
|||
lastReceivedKeycardData: tuple[flowType: string, flowEvent: KeycardEvent]
|
||||
setPayloadForCurrentFlow: JsonNode
|
||||
|
||||
#################################################
|
||||
# Forward declaration section
|
||||
proc startGetMetadataFlow*(self: Service)
|
||||
|
||||
#################################################
|
||||
|
||||
proc setup(self: Service) =
|
||||
self.QObject.setup
|
||||
|
||||
|
@ -164,23 +158,16 @@ QtObject:
|
|||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc startLoadAccountFlow*(self: Service, factoryReset: bool) =
|
||||
var payload = %* { }
|
||||
if factoryReset:
|
||||
payload[RequestParamFactoryReset] = %* factoryReset
|
||||
self.currentFlow = KCSFlowType.LoadAccount
|
||||
self.startFlow(payload)
|
||||
|
||||
proc startLoadAccountFlowWithSeedPhrase*(self: Service, seedPhraseLength: int, seedPhrase: string, factoryReset: bool) =
|
||||
if seedPhrase.len == 0:
|
||||
error "empty seed phrase provided"
|
||||
return
|
||||
proc startLoadAccountFlow*(self: Service, seedPhraseLength: int, seedPhrase: string, puk: string, factoryReset: bool) =
|
||||
var payload = %* {
|
||||
RequestParamOverwrite: true,
|
||||
RequestParamMnemonicLen: seedPhraseLength,
|
||||
RequestParamNewPUK: self.generateRandomPUK(),
|
||||
RequestParamMnemonic: seedPhrase
|
||||
RequestParamOverwrite: true
|
||||
}
|
||||
if seedPhrase.len > 0 and seedPhraseLength > 0:
|
||||
payload[RequestParamMnemonic] = %* seedPhrase
|
||||
payload[RequestParamMnemonicLen] = %* seedPhraseLength
|
||||
payload[RequestParamNewPUK] = %* self.generateRandomPUK()
|
||||
if puk.len > 0:
|
||||
payload[RequestParamNewPUK] = %* puk
|
||||
if factoryReset:
|
||||
payload[RequestParamFactoryReset] = %* factoryReset
|
||||
self.currentFlow = KCSFlowType.LoadAccount
|
||||
|
@ -198,8 +185,18 @@ QtObject:
|
|||
self.currentFlow = KCSFlowType.Login
|
||||
self.startFlow(payload)
|
||||
|
||||
proc startRecoverAccountFlow*(self: Service) =
|
||||
let payload = %* { }
|
||||
proc startRecoverAccountFlow*(self: Service, seedPhraseLength: int, seedPhrase: string, puk: string, factoryReset: bool) =
|
||||
var payload = %* {
|
||||
RequestParamOverwrite: true
|
||||
}
|
||||
if seedPhrase.len > 0 and seedPhraseLength > 0:
|
||||
payload[RequestParamMnemonic] = %* seedPhrase
|
||||
payload[RequestParamMnemonicLen] = %* seedPhraseLength
|
||||
payload[RequestParamNewPUK] = %* self.generateRandomPUK()
|
||||
if puk.len > 0:
|
||||
payload[RequestParamNewPUK] = %* puk
|
||||
if factoryReset:
|
||||
payload[RequestParamFactoryReset] = %* factoryReset
|
||||
self.currentFlow = KCSFlowType.RecoverAccount
|
||||
self.startFlow(payload)
|
||||
|
||||
|
@ -210,10 +207,10 @@ QtObject:
|
|||
self.currentFlow = KCSFlowType.GetAppInfo
|
||||
self.startFlow(payload)
|
||||
|
||||
proc startGetMetadataFlow*(self: Service) =
|
||||
let payload = %* {
|
||||
RequestParamResolveAddr: true
|
||||
}
|
||||
proc startGetMetadataFlow*(self: Service, resolveAddress: bool) =
|
||||
var payload = %* { }
|
||||
if resolveAddress:
|
||||
payload[RequestParamResolveAddr] = %* resolveAddress
|
||||
self.currentFlow = KCSFlowType.GetMetadata
|
||||
self.startFlow(payload)
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ StatusModal {
|
|||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication) {
|
||||
return qsTr("Authenticate")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {
|
||||
return qsTr("Unlock Keycard")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -85,11 +88,15 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardNotEmpty ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardLocked ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardAlreadyUnlocked ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.notKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardOptions ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardSuccess ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsReadyToSign ||
|
||||
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.recognizedKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPasswordFailed ||
|
||||
|
@ -117,6 +124,11 @@ StatusModal {
|
|||
{
|
||||
return keycardPinComponent
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPuk ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk)
|
||||
{
|
||||
return keycardPukComponent
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterSeedPhrase ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongSeedPhrase)
|
||||
{
|
||||
|
@ -197,6 +209,21 @@ StatusModal {
|
|||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: keycardPukComponent
|
||||
KeycardPuk {
|
||||
sharedKeycardModule: root.sharedKeycardModule
|
||||
|
||||
Component.onCompleted: {
|
||||
d.primaryButtonEnabled = false
|
||||
}
|
||||
|
||||
onPukUpdated: {
|
||||
d.primaryButtonEnabled = puk.length === Constants.keycard.general.keycardPukLength
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: enterSeedPhraseComponent
|
||||
EnterSeedPhrase {
|
||||
|
@ -275,34 +302,44 @@ StatusModal {
|
|||
StatusButton {
|
||||
id: tertiaryButton
|
||||
height: Constants.keycard.general.footerButtonsHeight
|
||||
text: qsTr("Cancel")
|
||||
visible: {
|
||||
text: {
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.selectExistingKeyPair ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardNotEmpty ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardLocked ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.notKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPin ||
|
||||
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.factoryResetConfirmation ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay) {
|
||||
return true
|
||||
return qsTr("Cancel")
|
||||
}
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.factoryReset) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified ||
|
||||
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.keycardEmpty ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.notKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinVerified ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPin ||
|
||||
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.keycardMetadataDisplay ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetConfirmation) {
|
||||
return true
|
||||
return qsTr("Cancel")
|
||||
}
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication) {
|
||||
|
@ -315,6 +352,8 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeychainPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsReadyToSign ||
|
||||
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.notKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPassword ||
|
||||
|
@ -325,10 +364,34 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterBiometricsPassword ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongBiometricsPassword ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin)
|
||||
return true
|
||||
return qsTr("Cancel")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {
|
||||
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.enterPuk ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.notKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardOptions ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterSeedPhrase)
|
||||
return qsTr("Cancel")
|
||||
}
|
||||
|
||||
return false
|
||||
return ""
|
||||
}
|
||||
visible: text !== ""
|
||||
enabled: {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair) {
|
||||
if (d.disablePopupClose) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
|
@ -362,32 +425,21 @@ StatusModal {
|
|||
return qsTr("Use PIN")
|
||||
}
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardOptions)
|
||||
return qsTr("Unlock using PUK")
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
visible: {
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication) {
|
||||
if (root.sharedKeycardModule.loggedInUserUsesBiometricLogin()) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pluginReader ||
|
||||
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.enterPassword ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPasswordFailed ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPinFailed ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPinInvalid ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPassword ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsReadyToSign ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.notKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty)
|
||||
return true
|
||||
visible: text !== ""
|
||||
enabled: {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair) {
|
||||
if (d.disablePopupClose) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
enabled: {
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication) {
|
||||
if (root.sharedKeycardModule.loggedInUserUsesBiometricLogin() &&
|
||||
(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pluginReader ||
|
||||
|
@ -399,6 +451,10 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty))
|
||||
return false
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardOptions)
|
||||
return root.sharedKeycardModule.keycardData & Constants.predefinedKeycardData.offerPukForUnlock
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -442,7 +498,6 @@ StatusModal {
|
|||
return qsTr("Factory reset this Keycard")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.selectExistingKeyPair ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardLocked ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.seedPhraseDisplay ||
|
||||
|
@ -450,8 +505,13 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay) {
|
||||
return qsTr("Next")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached) {
|
||||
return qsTr("Unlock Keycard")
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached) {
|
||||
let a = root.sharedKeycardModule.keycardData & Constants.predefinedKeycardData.useUnlockLabelForLockedState
|
||||
if (root.sharedKeycardModule.keycardData & Constants.predefinedKeycardData.useUnlockLabelForLockedState)
|
||||
return qsTr("Unlock Keycard")
|
||||
return qsTr("Next")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateFailure) {
|
||||
|
@ -462,7 +522,6 @@ StatusModal {
|
|||
return qsTr("Restart app & sign in using your new Keycard")
|
||||
return qsTr("Done")
|
||||
}
|
||||
return qsTr("Cancel")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.factoryReset) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin ||
|
||||
|
@ -478,14 +537,14 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata) {
|
||||
return qsTr("Next")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached) {
|
||||
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")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess) {
|
||||
return qsTr("Done")
|
||||
}
|
||||
return qsTr("Cancel")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pluginReader ||
|
||||
|
@ -514,12 +573,35 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPinInvalid) {
|
||||
return qsTr("Try biometrics again")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardAlreadyUnlocked ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardSuccess)
|
||||
return qsTr("Done")
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardOptions)
|
||||
return qsTr("Unlock using seed phrase")
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.createPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.pinSet ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterSeedPhrase ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPuk ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk)
|
||||
return qsTr("Next")
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongSeedPhrase) {
|
||||
return qsTr("Try entering seed phrase again")
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached) {
|
||||
return qsTr("Unlock Keycard")
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
visible: text !== ""
|
||||
enabled: {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair) {
|
||||
|
@ -568,9 +650,15 @@ StatusModal {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPin) {
|
||||
return d.primaryButtonEnabled
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.unlockKeycard) {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterSeedPhrase ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPuk ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk)
|
||||
return d.primaryButtonEnabled
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.createPin ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.repeatPin)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -42,8 +42,10 @@ Item {
|
|||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property bool wrongPassword: root.kcData & Constants.predefinedKeycardData.wrongPassword
|
||||
|
||||
function updatePasswordValidation() {
|
||||
root.passwordValid(password.text !== "" && root.kcData === "")
|
||||
root.passwordValid(password.text !== "" && !d.wrongPassword)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +154,7 @@ Item {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
text: root.kcData !== ""? qsTr("Password incorrect") : ""
|
||||
text: d.wrongPassword? qsTr("Password incorrect") : ""
|
||||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
},
|
||||
|
@ -177,7 +179,7 @@ Item {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
text: root.kcData !== ""? qsTr("Password incorrect") : ""
|
||||
text: d.wrongPassword? qsTr("Password incorrect") : ""
|
||||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
},
|
||||
|
@ -202,7 +204,7 @@ Item {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
text: root.kcData !== ""? qsTr("Password incorrect") : ""
|
||||
text: d.wrongPassword? qsTr("Password incorrect") : ""
|
||||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,6 +173,8 @@ Item {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty ||
|
||||
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.biometricsReadyToSign ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPinFailed ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPinInvalid ||
|
||||
|
@ -215,6 +217,8 @@ Item {
|
|||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmpty ||
|
||||
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.biometricsReadyToSign ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPinFailed ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.biometricsPinInvalid ||
|
||||
|
@ -366,6 +370,31 @@ Item {
|
|||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.keycardSharedState.unlockKeycardOptions
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardOptions
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: qsTr("Unlock this Keycard")
|
||||
font.pixelSize: Constants.keycard.general.fontSize1
|
||||
font.weight: Font.Bold
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: image
|
||||
pattern: "keycard/strong_error/img-%1"
|
||||
source: ""
|
||||
startImgIndexForTheFirstLoop: 0
|
||||
startImgIndexForOtherLoops: 18
|
||||
endImgIndex: 29
|
||||
duration: 1300
|
||||
loops: -1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: ""
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.keycardSharedState.wrongKeycard
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongKeycard
|
||||
|
@ -388,35 +417,6 @@ Item {
|
|||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.keycardSharedState.maxPinRetriesReached
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: qsTr("Keycard locked")
|
||||
font.pixelSize: Constants.keycard.general.fontSize1
|
||||
font.weight: Font.Bold
|
||||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: image
|
||||
pattern: "keycard/strong_error/img-%1"
|
||||
source: ""
|
||||
startImgIndexForTheFirstLoop: 0
|
||||
startImgIndexForOtherLoops: 18
|
||||
endImgIndex: 29
|
||||
duration: 1300
|
||||
loops: -1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication?
|
||||
qsTr("You will need to unlock it before proceeding") :
|
||||
qsTr("Pin entered incorrectly too many times")
|
||||
font.pixelSize: Constants.keycard.general.fontSize2
|
||||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.keycardSharedState.keycardEmptyMetadata
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardEmptyMetadata
|
||||
|
@ -447,21 +447,18 @@ Item {
|
|||
text: qsTr("Keycard is empty")
|
||||
font.pixelSize: Constants.keycard.general.fontSize1
|
||||
font.weight: Font.Bold
|
||||
color: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication?
|
||||
Theme.palette.dangerColor1 : Theme.palette.directColor1
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: image
|
||||
source: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication?
|
||||
Style.png("keycard/plain-error") : Style.png("keycard/card-empty")
|
||||
source: Style.png("keycard/card-empty")
|
||||
pattern: ""
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: qsTr("There is no key pair on this Keycard")
|
||||
font.pixelSize: Constants.keycard.general.fontSize2
|
||||
color: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication?
|
||||
Theme.palette.dangerColor1 : Theme.palette.directColor1
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
},
|
||||
State {
|
||||
|
@ -490,14 +487,18 @@ Item {
|
|||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.keycardSharedState.keycardLocked
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardLocked
|
||||
name: "sharedLockedState"
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached ||
|
||||
root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: qsTr("Keycard locked and already stores keys")
|
||||
text: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard?
|
||||
qsTr("Keycard locked and already stores keys") : qsTr("Keycard locked")
|
||||
font.pixelSize: Constants.keycard.general.fontSize1
|
||||
font.weight: Font.Bold
|
||||
color: Theme.palette.directColor1
|
||||
color: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard?
|
||||
Theme.palette.directColor1 : Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: image
|
||||
|
@ -511,10 +512,73 @@ Item {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: qsTr("The Keycard you have inserted is locked,\nyou will need to factory reset it before proceeding")
|
||||
text: {
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard)
|
||||
return qsTr("The Keycard you have inserted is locked,\nyou will need to factory reset it before proceeding")
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication)
|
||||
return qsTr("You will need to unlock it before proceeding")
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPinRetriesReached)
|
||||
return qsTr("Pin entered incorrectly too many times")
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPukRetriesReached)
|
||||
return qsTr("Puk entered incorrectly too many times")
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.maxPairingSlotsReached)
|
||||
return qsTr("Max pairing slots reached for the entered keycard")
|
||||
return ""
|
||||
}
|
||||
font.pixelSize: Constants.keycard.general.fontSize2
|
||||
color: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard?
|
||||
Theme.palette.directColor1 : Theme.palette.dangerColor1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.keycardSharedState.keycardAlreadyUnlocked
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardAlreadyUnlocked
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: qsTr("Your Keycard is already unlocked!")
|
||||
font.pixelSize: Constants.keycard.general.fontSize1
|
||||
font.weight: Font.Bold
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: image
|
||||
pattern: "keycard/success/img-%1"
|
||||
source: ""
|
||||
startImgIndexForTheFirstLoop: 0
|
||||
startImgIndexForOtherLoops: 0
|
||||
endImgIndex: 29
|
||||
duration: 1300
|
||||
loops: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
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
|
||||
|
|
|
@ -83,7 +83,8 @@ Item {
|
|||
anchors.bottomMargin: Style.current.halfPadding
|
||||
anchors.leftMargin: Style.current.xlPadding
|
||||
anchors.rightMargin: Style.current.xlPadding
|
||||
spacing: Style.current.halfPadding
|
||||
spacing: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.authentication?
|
||||
Style.current.halfPadding : Style.current.padding
|
||||
|
||||
KeycardImage {
|
||||
id: image
|
||||
|
@ -108,7 +109,6 @@ Item {
|
|||
StatusPinInput {
|
||||
id: pinInputField
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillHeight: !info.visble && !message.visible? true : false
|
||||
validator: StatusIntValidator{bottom: 0; top: 999999;}
|
||||
pinLen: Constants.keycard.general.keycardPinLength
|
||||
enabled: root.sharedKeycardModule.currentState.stateType !== Constants.keycardSharedState.pinSet &&
|
||||
|
@ -148,7 +148,6 @@ Item {
|
|||
StatusBaseText {
|
||||
id: info
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.fillHeight: info.visble && !message.visible? true : false
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
@ -156,12 +155,12 @@ Item {
|
|||
StatusBaseText {
|
||||
id: message
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.fillHeight: message.visible? true : false
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
Layout.preferredWidth: parent.width
|
||||
active: {
|
||||
if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard) {
|
||||
|
@ -201,6 +200,13 @@ Item {
|
|||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: spacer
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: !loader.active
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQuick.Controls 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../helpers"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property var sharedKeycardModule
|
||||
|
||||
property int remainingAttempts: parseInt(root.sharedKeycardModule.keycardData, 10)
|
||||
|
||||
signal pukUpdated(string puk)
|
||||
|
||||
onRemainingAttemptsChanged: {
|
||||
if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk) {
|
||||
pukInputField.statesInitialization()
|
||||
pukInputField.forceFocus()
|
||||
}
|
||||
}
|
||||
|
||||
onStateChanged: {
|
||||
pukInputField.statesInitialization()
|
||||
pukInputField.forceFocus()
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: Style.current.xlPadding
|
||||
anchors.bottomMargin: Style.current.halfPadding
|
||||
anchors.leftMargin: Style.current.xlPadding
|
||||
anchors.rightMargin: Style.current.xlPadding
|
||||
spacing: Style.current.padding
|
||||
|
||||
KeycardImage {
|
||||
id: image
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredHeight: Constants.keycard.shared.imageHeight
|
||||
Layout.preferredWidth: Constants.keycard.shared.imageWidth
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: title
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
font.weight: Font.Bold
|
||||
}
|
||||
|
||||
StatusPinInput {
|
||||
id: pukInputField
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
validator: StatusRegularExpressionValidator { regularExpression: /[0-9]+/ }
|
||||
pinLen: Constants.keycard.general.keycardPukLength
|
||||
additionalSpacing: Constants.keycard.general.keycardPukAdditionalSpacing
|
||||
additionalSpacingOnEveryNItems: Constants.keycard.general.keycardPukAdditionalSpacingOnEvery4Items
|
||||
|
||||
onPinInputChanged: {
|
||||
root.pukUpdated(pinInput)
|
||||
if(pinInput.length == 0) {
|
||||
return
|
||||
}
|
||||
if(root.state === Constants.keycardSharedState.enterPuk ||
|
||||
root.state === Constants.keycardSharedState.wrongPuk) {
|
||||
root.sharedKeycardModule.setPuk(pinInput)
|
||||
root.sharedKeycardModule.currentState.doSecondaryAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: info
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: message
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
||||
Item {
|
||||
id: spacer
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: Constants.keycardSharedState.enterPuk
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterPuk
|
||||
PropertyChanges {
|
||||
target: image
|
||||
source: Style.png("keycard/card-inserted")
|
||||
pattern: ""
|
||||
}
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: qsTr("Enter PUK")
|
||||
font.pixelSize: Constants.keycard.general.fontSize1
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
text: ""
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: ""
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.keycardSharedState.wrongPuk
|
||||
when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.wrongPuk
|
||||
PropertyChanges {
|
||||
target: image
|
||||
source: Style.png("keycard/plain-error")
|
||||
pattern: ""
|
||||
}
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: qsTr("Enter PUK")
|
||||
font.pixelSize: Constants.keycard.general.fontSize1
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
text: qsTr("The PUK is incorrect, try entering it again")
|
||||
color: Theme.palette.dangerColor1
|
||||
font.pixelSize: Constants.keycard.general.fontSize3
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: qsTr("%n attempt(s) remaining", "", root.remainingAttempts)
|
||||
color: root.remainingAttempts === 1?
|
||||
Theme.palette.dangerColor1 :
|
||||
Theme.palette.baseColor1
|
||||
font.pixelSize: Constants.keycard.general.fontSize3
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -73,6 +73,9 @@ QtObject {
|
|||
readonly property int wronglyInsertedCard: 1
|
||||
readonly property int hideKeyPair: 2
|
||||
readonly property int wrongSeedPhrase: 4
|
||||
readonly property int wrongPassword: 8
|
||||
readonly property int offerPukForUnlock: 16
|
||||
readonly property int useUnlockLabelForLockedState: 32
|
||||
}
|
||||
|
||||
readonly property QtObject keycardSharedFlow: QtObject {
|
||||
|
@ -80,6 +83,7 @@ QtObject {
|
|||
readonly property string factoryReset: "FactoryReset"
|
||||
readonly property string setupNewKeycard: "SetupNewKeycard"
|
||||
readonly property string authentication: "Authentication"
|
||||
readonly property string unlockKeycard: "UnlockKeycard"
|
||||
}
|
||||
|
||||
readonly property QtObject keycardSharedState: QtObject {
|
||||
|
@ -94,8 +98,12 @@ QtObject {
|
|||
readonly property string pinVerified: "PinVerified"
|
||||
readonly property string enterPin: "EnterPin"
|
||||
readonly property string wrongPin: "WrongPin"
|
||||
readonly property string enterPuk: "EnterPuk"
|
||||
readonly property string wrongPuk: "WrongPuk"
|
||||
readonly property string wrongKeychainPin: "WrongKeychainPin"
|
||||
readonly property string maxPinRetriesReached: "MaxPinRetriesReached"
|
||||
readonly property string maxPukRetriesReached: "MaxPukRetriesReached"
|
||||
readonly property string maxPairingSlotsReached: "MaxPairingSlotsReached"
|
||||
readonly property string factoryResetConfirmation: "FactoryResetConfirmation"
|
||||
readonly property string factoryResetConfirmationDisplayMetadata: "FactoryResetConfirmationDisplayMetadata"
|
||||
readonly property string factoryResetSuccess: "FactoryResetSuccess"
|
||||
|
@ -103,8 +111,10 @@ QtObject {
|
|||
readonly property string keycardMetadataDisplay: "KeycardMetadataDisplay"
|
||||
readonly property string keycardEmpty: "KeycardEmpty"
|
||||
readonly property string keycardNotEmpty: "KeycardNotEmpty"
|
||||
readonly property string keycardLocked: "KeycardLocked"
|
||||
readonly property string keycardAlreadyUnlocked: "KeycardAlreadyUnlocked"
|
||||
readonly property string notKeycard: "NotKeycard"
|
||||
readonly property string unlockKeycardOptions: "UnlockKeycardOptions"
|
||||
readonly property string unlockKeycardSuccess: "UnlockKeycardSuccess"
|
||||
readonly property string wrongKeycard: "WrongKeycard"
|
||||
readonly property string recognizedKeycard: "RecognizedKeycard"
|
||||
readonly property string selectExistingKeyPair: "SelectExistingKeyPair"
|
||||
|
@ -367,6 +377,9 @@ QtObject {
|
|||
readonly property QtObject general: QtObject {
|
||||
readonly property int footerWrapperHeight: 125
|
||||
readonly property int keycardPinLength: 6
|
||||
readonly property int keycardPukLength: 12
|
||||
readonly property int keycardPukAdditionalSpacingOnEvery4Items: 4
|
||||
readonly property int keycardPukAdditionalSpacing: 32
|
||||
readonly property int fontSize1: 22
|
||||
readonly property int fontSize2: 15
|
||||
readonly property int fontSize3: 12
|
||||
|
|
Loading…
Reference in New Issue