fix(@desktop/keycard): updates to the onboarding/login flow
- login states updated so they can resolve enter pin state from each state that flow may be in - not a keycard state added - login plugin state added
This commit is contained in:
parent
3042a0cffa
commit
405171dad7
|
@ -10,10 +10,7 @@ proc delete*(self: LoginKeycardEmptyState) =
|
|||
|
||||
method executePrimaryCommand*(self: LoginKeycardEmptyState, controller: Controller) =
|
||||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
else:
|
||||
controller.runLoadAccountFlow(factoryReset = true)
|
||||
controller.runLoadAccountFlow(factoryReset = true)
|
||||
|
||||
method getNextSecondaryState*(self: LoginKeycardEmptyState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
|
|
|
@ -12,6 +12,12 @@ method executePrimaryCommand*(self: LoginKeycardInsertKeycardState, controller:
|
|||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
elif not controller.keychainErrorOccurred() and controller.getPin().len == PINLengthForStatusApp:
|
||||
controller.enterKeycardPin(controller.getPin())
|
||||
|
||||
method getNextPrimaryState*(self: LoginKeycardInsertKeycardState, controller: Controller): State =
|
||||
if controller.keychainErrorOccurred():
|
||||
return createState(StateType.LoginKeycardEnterPin, self.flowType, nil)
|
||||
|
||||
method getNextSecondaryState*(self: LoginKeycardInsertKeycardState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
|
|
|
@ -12,11 +12,6 @@ method executeBackCommand*(self: LoginKeycardMaxPinRetriesReachedState, controll
|
|||
if self.flowType == FlowType.AppLogin and controller.isKeycardCreatedAccountSelectedOne():
|
||||
controller.runLoginFlow()
|
||||
|
||||
method executePrimaryCommand*(self: LoginKeycardMaxPinRetriesReachedState, controller: Controller) =
|
||||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
|
||||
method getNextPrimaryState*(self: LoginKeycardMaxPinRetriesReachedState, controller: Controller): State =
|
||||
return createState(StateType.KeycardRecover, self.flowType, self)
|
||||
|
||||
|
@ -27,3 +22,7 @@ method getNextSecondaryState*(self: LoginKeycardMaxPinRetriesReachedState, contr
|
|||
method getNextTertiaryState*(self: LoginKeycardMaxPinRetriesReachedState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
return createState(StateType.WelcomeOldStatusUser, self.flowType, self)
|
||||
|
||||
method resolveKeycardNextState*(self: LoginKeycardMaxPinRetriesReachedState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
return ensureReaderAndCardPresenceAndResolveNextLoginState(self, keycardFlowType, keycardEvent, controller)
|
|
@ -12,3 +12,7 @@ method getNextPrimaryState*(self: LoginKeycardMaxPukRetriesReachedState, control
|
|||
if self.flowType == FlowType.AppLogin:
|
||||
controller.setRecoverUsingSeedPhraseWhileLogin(true)
|
||||
return createState(StateType.UserProfileEnterSeedPhrase, self.flowType, nil)
|
||||
|
||||
method resolveKeycardNextState*(self: LoginKeycardMaxPukRetriesReachedState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
return ensureReaderAndCardPresenceAndResolveNextLoginState(self, keycardFlowType, keycardEvent, controller)
|
|
@ -14,7 +14,7 @@ method executePrimaryCommand*(self: LoginKeycardReadingKeycardState, controller:
|
|||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
elif not controller.keychainErrorOccurred():
|
||||
elif not controller.keychainErrorOccurred() and controller.getPin().len == PINLengthForStatusApp:
|
||||
controller.enterKeycardPin(controller.getPin())
|
||||
|
||||
method getNextPrimaryState*(self: LoginKeycardReadingKeycardState, controller: Controller): State =
|
||||
|
|
|
@ -12,6 +12,12 @@ method executePrimaryCommand*(self: LoginKeycardWrongKeycardState, controller: C
|
|||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
elif not controller.keychainErrorOccurred() and controller.getPin().len == PINLengthForStatusApp:
|
||||
controller.enterKeycardPin(controller.getPin())
|
||||
|
||||
method getNextPrimaryState*(self: LoginKeycardWrongKeycardState, controller: Controller): State =
|
||||
if controller.keychainErrorOccurred():
|
||||
return createState(StateType.LoginKeycardEnterPin, self.flowType, nil)
|
||||
|
||||
method getNextSecondaryState*(self: LoginKeycardWrongKeycardState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
|
@ -20,3 +26,7 @@ method getNextSecondaryState*(self: LoginKeycardWrongKeycardState, controller: C
|
|||
method getNextTertiaryState*(self: LoginKeycardWrongKeycardState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
return createState(StateType.WelcomeOldStatusUser, self.flowType, self)
|
||||
|
||||
method resolveKeycardNextState*(self: LoginKeycardWrongKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
return ensureReaderAndCardPresenceAndResolveNextLoginState(self, keycardFlowType, keycardEvent, controller)
|
|
@ -14,9 +14,13 @@ method executePrimaryCommand*(self: LoginKeycardWrongPinState, controller: Contr
|
|||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
elif controller.getPin().len == PINLengthForStatusApp:
|
||||
elif not controller.keychainErrorOccurred() and controller.getPin().len == PINLengthForStatusApp:
|
||||
controller.enterKeycardPin(controller.getPin())
|
||||
|
||||
method getNextPrimaryState*(self: LoginKeycardWrongPinState, controller: Controller): State =
|
||||
if controller.keychainErrorOccurred():
|
||||
return createState(StateType.LoginKeycardEnterPin, self.flowType, nil)
|
||||
|
||||
method getNextSecondaryState*(self: LoginKeycardWrongPinState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
return createState(StateType.WelcomeNewStatusUser, self.flowType, self)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
type
|
||||
LoginNotKeycardState* = ref object of State
|
||||
|
||||
proc newLoginNotKeycardState*(flowType: FlowType, backState: State): LoginNotKeycardState =
|
||||
result = LoginNotKeycardState()
|
||||
result.setup(flowType, StateType.LoginNotKeycard, backState)
|
||||
|
||||
proc delete*(self: LoginNotKeycardState) =
|
||||
self.State.delete
|
||||
|
||||
method executePrimaryCommand*(self: LoginNotKeycardState, controller: Controller) =
|
||||
if self.flowType == FlowType.AppLogin:
|
||||
controller.runLoadAccountFlow(factoryReset = true)
|
||||
|
||||
method getNextSecondaryState*(self: LoginNotKeycardState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
return createState(StateType.WelcomeNewStatusUser, self.flowType, self)
|
||||
|
||||
method getNextTertiaryState*(self: LoginNotKeycardState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
return createState(StateType.WelcomeOldStatusUser, self.flowType, self)
|
||||
|
||||
method resolveKeycardNextState*(self: LoginNotKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
return ensureReaderAndCardPresenceAndResolveNextLoginState(self, keycardFlowType, keycardEvent, controller)
|
|
@ -0,0 +1,32 @@
|
|||
type
|
||||
LoginPluginState* = ref object of State
|
||||
|
||||
proc newLoginPluginState*(flowType: FlowType, backState: State): LoginPluginState =
|
||||
result = LoginPluginState()
|
||||
result.setup(flowType, StateType.LoginPlugin, backState)
|
||||
|
||||
proc delete*(self: LoginPluginState) =
|
||||
self.State.delete
|
||||
|
||||
method executePrimaryCommand*(self: LoginPluginState, controller: Controller) =
|
||||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
elif not controller.keychainErrorOccurred() and controller.getPin().len == PINLengthForStatusApp:
|
||||
controller.enterKeycardPin(controller.getPin())
|
||||
|
||||
method getNextPrimaryState*(self: LoginPluginState, controller: Controller): State =
|
||||
if controller.keychainErrorOccurred():
|
||||
return createState(StateType.LoginKeycardEnterPin, self.flowType, nil)
|
||||
|
||||
method getNextSecondaryState*(self: LoginPluginState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
return createState(StateType.WelcomeNewStatusUser, self.flowType, self)
|
||||
|
||||
method getNextTertiaryState*(self: LoginPluginState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
return createState(StateType.WelcomeOldStatusUser, self.flowType, self)
|
||||
|
||||
method resolveKeycardNextState*(self: LoginPluginState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
return ensureReaderAndCardPresenceAndResolveNextLoginState(self, keycardFlowType, keycardEvent, controller)
|
|
@ -12,6 +12,12 @@ method executePrimaryCommand*(self: LoginState, controller: Controller) =
|
|||
if self.flowType == FlowType.AppLogin:
|
||||
if not controller.isSelectedLoginAccountKeycardAccount():
|
||||
controller.login()
|
||||
elif not controller.keychainErrorOccurred() and controller.getPin().len == PINLengthForStatusApp:
|
||||
controller.enterKeycardPin(controller.getPin())
|
||||
|
||||
method getNextPrimaryState*(self: LoginState, controller: Controller): State =
|
||||
if controller.keychainErrorOccurred():
|
||||
return createState(StateType.LoginKeycardEnterPin, self.flowType, nil)
|
||||
|
||||
method getNextSecondaryState*(self: LoginState, controller: Controller): State =
|
||||
controller.cancelCurrentFlow()
|
||||
|
|
|
@ -47,6 +47,7 @@ type StateType* {.pure.} = enum
|
|||
KeycardMaxPinRetriesReached = "KeycardMaxPinRetriesReached"
|
||||
KeycardMaxPukRetriesReached = "KeycardMaxPukRetriesReached"
|
||||
Login = "Login"
|
||||
LoginPlugin = "LoginPlugin"
|
||||
LoginKeycardInsertKeycard = "LoginKeycardInsertKeycard"
|
||||
LoginKeycardReadingKeycard = "LoginKeycardReadingKeycard"
|
||||
LoginKeycardEnterPin = "LoginKeycardEnterPin"
|
||||
|
@ -55,6 +56,7 @@ type StateType* {.pure.} = enum
|
|||
LoginKeycardMaxPinRetriesReached = "LoginKeycardMaxPinRetriesReached"
|
||||
LoginKeycardMaxPukRetriesReached = "LoginKeycardMaxPukRetriesReached"
|
||||
LoginKeycardEmpty = "LoginKeycardEmpty"
|
||||
LoginNotKeycard = "LoginNotKeycard"
|
||||
|
||||
|
||||
## This is the base class for all state we may have in onboarding/login flow.
|
||||
|
|
|
@ -47,6 +47,7 @@ include welcome_state_new_user
|
|||
include welcome_state_old_user
|
||||
include welcome_state
|
||||
include login_state
|
||||
include login_plugin_state
|
||||
include login_keycard_insert_keycard_state
|
||||
include login_keycard_reading_keycard_state
|
||||
include login_keycard_enter_pin_state
|
||||
|
@ -55,6 +56,7 @@ include login_keycard_wrong_pin_state
|
|||
include login_keycard_max_pin_retries_reached_state
|
||||
include login_keycard_max_puk_retries_reached_state
|
||||
include login_keycard_empty_state
|
||||
include login_not_keycard_state
|
||||
|
||||
proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: State): State =
|
||||
if stateToBeCreated == StateType.AllowNotifications:
|
||||
|
@ -119,6 +121,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
|
|||
return newKeycardMaxPukRetriesReachedState(flowType, backState)
|
||||
if stateToBeCreated == StateType.Login:
|
||||
return newLoginState(flowType, backState)
|
||||
if stateToBeCreated == StateType.LoginPlugin:
|
||||
return newLoginPluginState(flowType, backState)
|
||||
if stateToBeCreated == StateType.LoginKeycardInsertKeycard:
|
||||
return newLoginKeycardInsertKeycardState(flowType, backState)
|
||||
if stateToBeCreated == StateType.LoginKeycardReadingKeycard:
|
||||
|
@ -135,6 +139,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
|
|||
return newLoginKeycardMaxPukRetriesReachedState(flowType, backState)
|
||||
if stateToBeCreated == StateType.LoginKeycardEmpty:
|
||||
return newLoginKeycardEmptyState(flowType, backState)
|
||||
if stateToBeCreated == StateType.LoginNotKeycard:
|
||||
return newLoginNotKeycardState(flowType, backState)
|
||||
|
||||
error "No implementation available for state ", state=stateToBeCreated
|
||||
|
||||
|
@ -161,9 +167,9 @@ proc ensureReaderAndCardPresenceLogin*(state: State, keycardFlowType: string, ke
|
|||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorConnection:
|
||||
controller.resumeCurrentFlowLater()
|
||||
if state.stateType == StateType.Login:
|
||||
if state.stateType == StateType.LoginPlugin:
|
||||
return nil
|
||||
return createState(StateType.Login, state.flowType, state)
|
||||
return createState(StateType.LoginPlugin, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueInsertCard and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorConnection:
|
||||
|
@ -279,10 +285,10 @@ proc ensureReaderAndCardPresenceAndResolveNextLoginState*(state: State, keycardF
|
|||
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
|
||||
return createState(StateType.LoginKeycardMaxPinRetriesReached, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueSwapCard and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorNoKeys:
|
||||
return createState(StateType.LoginKeycardEmpty, state.flowType, nil)
|
||||
if keycardFlowType == ResponseTypeValueSwapCard and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == RequestParamPUKRetries:
|
||||
return createState(StateType.LoginKeycardMaxPukRetriesReached, state.flowType, nil)
|
||||
keycardEvent.error.len > 0:
|
||||
if keycardEvent.error == ErrorNoKeys:
|
||||
return createState(StateType.LoginKeycardEmpty, state.flowType, nil)
|
||||
if keycardEvent.error == ErrorNotAKeycard:
|
||||
return createState(StateType.LoginNotKeycard, state.flowType, nil)
|
||||
if keycardEvent.error == RequestParamPUKRetries:
|
||||
return createState(StateType.LoginKeycardMaxPukRetriesReached, state.flowType, nil)
|
|
@ -99,7 +99,6 @@ method load*[T](self: Module[T]) =
|
|||
error "cannot run the app in login flow cause list of login accounts is empty"
|
||||
quit() # quit the app
|
||||
self.setSelectedLoginAccount(items[0])
|
||||
self.view.setCurrentStartupState(newLoginState(FlowType.AppLogin, nil))
|
||||
self.delegate.startupDidLoad()
|
||||
|
||||
method getKeycardSharedModule*[T](self: Module[T]): QVariant =
|
||||
|
@ -228,8 +227,8 @@ method importAccountSuccess*[T](self: Module[T]) =
|
|||
method setSelectedLoginAccount*[T](self: Module[T], item: login_acc_item.Item) =
|
||||
self.controller.cancelCurrentFlow()
|
||||
self.controller.setSelectedLoginAccount(item.getKeyUid(), item.getKeycardCreatedAccount())
|
||||
self.view.setCurrentStartupState(newLoginState(FlowType.AppLogin, nil))
|
||||
if item.getKeycardCreatedAccount():
|
||||
self.view.setCurrentStartupState(newLoginState(FlowType.AppLogin, nil)) # nim garbage collector will handle all abandoned state objects
|
||||
self.controller.runLoginFlow()
|
||||
else:
|
||||
self.controller.tryToObtainDataFromKeychain()
|
||||
|
|
|
@ -64,6 +64,7 @@ OnboardingBasePage {
|
|||
return seedPhraseInputViewComponent
|
||||
}
|
||||
if (root.startupStore.currentStartupState.stateType === Constants.startupState.login ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginPlugin ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardInsertKeycard ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardReadingKeycard ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardEnterPin ||
|
||||
|
@ -71,7 +72,8 @@ OnboardingBasePage {
|
|||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardWrongPin ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardMaxPinRetriesReached ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardMaxPukRetriesReached ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardEmpty)
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginKeycardEmpty ||
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginNotKeycard)
|
||||
{
|
||||
return loginViewComponent
|
||||
}
|
||||
|
|
|
@ -518,6 +518,49 @@ Item {
|
|||
target: pinSection
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: ""
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: button
|
||||
text: ""
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: link
|
||||
text: ""
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.startupState.loginPlugin
|
||||
when: root.startupStore.selectedLoginAccount.keycardCreatedAccount &&
|
||||
root.startupStore.currentStartupState.stateType === Constants.startupState.loginPlugin
|
||||
PropertyChanges {
|
||||
target: image
|
||||
source: Style.svg("keycard/card3@2x")
|
||||
Layout.preferredHeight: sourceSize.height
|
||||
Layout.preferredWidth: sourceSize.width
|
||||
}
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: ""
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: passwordSection
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: pinSection
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
text: qsTr("Plug in Keycard reader...")
|
||||
|
@ -908,6 +951,53 @@ Item {
|
|||
text: qsTr("Generate keys for a new Keycard")
|
||||
visible: true
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: Constants.startupState.loginNotKeycard
|
||||
when: root.startupStore.currentStartupState.stateType === Constants.startupState.loginNotKeycard
|
||||
PropertyChanges {
|
||||
target: image
|
||||
source: Style.svg("keycard/card-wrong3@2x")
|
||||
Layout.preferredHeight: sourceSize.height
|
||||
Layout.preferredWidth: sourceSize.width
|
||||
}
|
||||
PropertyChanges {
|
||||
target: title
|
||||
text: ""
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: passwordSection
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: pinSection
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: info
|
||||
text: qsTr("This is not a Keycard")
|
||||
visible: true
|
||||
font.pixelSize: Constants.keycard.general.fontSize2
|
||||
color: Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: message
|
||||
text: qsTr("The card inserted is not a recognised Keycard,\nplease remove and try and again")
|
||||
visible: true
|
||||
font.pixelSize: Constants.keycard.general.fontSize2
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: button
|
||||
text: ""
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: link
|
||||
text: ""
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ QtObject {
|
|||
readonly property string keycardMaxPinRetriesReached: "KeycardMaxPinRetriesReached"
|
||||
readonly property string keycardMaxPukRetriesReached: "KeycardMaxPukRetriesReached"
|
||||
readonly property string login: "Login"
|
||||
readonly property string loginPlugin: "LoginPlugin"
|
||||
readonly property string loginKeycardInsertKeycard: "LoginKeycardInsertKeycard"
|
||||
readonly property string loginKeycardReadingKeycard: "LoginKeycardReadingKeycard"
|
||||
readonly property string loginKeycardEnterPin: "LoginKeycardEnterPin"
|
||||
|
@ -65,6 +66,7 @@ QtObject {
|
|||
readonly property string loginKeycardMaxPinRetriesReached: "LoginKeycardMaxPinRetriesReached"
|
||||
readonly property string loginKeycardMaxPukRetriesReached: "LoginKeycardMaxPukRetriesReached"
|
||||
readonly property string loginKeycardEmpty: "LoginKeycardEmpty"
|
||||
readonly property string loginNotKeycard: "LoginNotKeycard"
|
||||
}
|
||||
|
||||
readonly property QtObject predefinedKeycardData: QtObject {
|
||||
|
|
Loading…
Reference in New Issue