mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-22 11:38:57 +00:00
feat: AuthorizationState
(#17309)
This commit is contained in:
parent
ab197d8c4b
commit
4a6543bdca
@ -72,9 +72,9 @@ proc init*(self: Controller) =
|
||||
self.delegate.onKeycardSetPinFailure(args.error)
|
||||
self.connectionIds.add(handlerId)
|
||||
|
||||
handlerId = self.events.onWithUUID(SIGNAL_KEYCARD_AUTHORIZE_FAILURE) do(e: Args):
|
||||
let args = KeycardErrorArg(e)
|
||||
self.delegate.onKeycardAuthorizeFailure(args.error)
|
||||
handlerId = self.events.onWithUUID(SIGNAL_KEYCARD_AUTHORIZE_FINISHED) do(e: Args):
|
||||
let args = KeycardAuthorizeEvent(e)
|
||||
self.delegate.onKeycardAuthorizeFinished(args.error, args.authorized)
|
||||
self.connectionIds.add(handlerId)
|
||||
|
||||
handlerId = self.events.onWithUUID(SIGNAL_KEYCARD_LOAD_MNEMONIC_FAILURE) do(e: Args):
|
||||
|
@ -58,7 +58,7 @@ method onKeycardStateUpdated*(self: AccessInterface, keycardEvent: KeycardEventD
|
||||
method onKeycardSetPinFailure*(self: AccessInterface, error: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onKeycardAuthorizeFailure*(self: AccessInterface, error: string) {.base.} =
|
||||
method onKeycardAuthorizeFinished*(self: AccessInterface, error: string, authorized: bool) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onKeycardLoadMnemonicFailure*(self: AccessInterface, error: string) {.base.} =
|
||||
|
@ -99,7 +99,7 @@ method initialize*[T](self: Module[T], pin: string) =
|
||||
self.controller.initialize(pin)
|
||||
|
||||
method authorize*[T](self: Module[T], pin: string) =
|
||||
self.view.setAuthorizationState(ProgressState.InProgress.int)
|
||||
self.view.setAuthorizationState(AuthorizationState.InProgress)
|
||||
self.controller.authorize(pin)
|
||||
|
||||
method getPasswordStrengthScore*[T](self: Module[T], password, userName: string): int =
|
||||
@ -287,20 +287,23 @@ method onKeycardStateUpdated*[T](self: Module[T], keycardEvent: KeycardEventDto)
|
||||
|
||||
if keycardEvent.state == KeycardState.Authorized and self.view.getAuthorizationState() == ProgressState.InProgress.int:
|
||||
# We just finished authorizing
|
||||
self.view.setAuthorizationState(ProgressState.Success.int)
|
||||
self.view.setAuthorizationState(AuthorizationState.Authorized)
|
||||
|
||||
method onKeycardSetPinFailure*[T](self: Module[T], error: string) =
|
||||
self.view.setPinSettingState(ProgressState.Failed.int)
|
||||
|
||||
method onKeycardAuthorizeFailure*[T](self: Module[T], error: string) =
|
||||
self.view.setAuthorizationState(ProgressState.Failed.int)
|
||||
method onKeycardAuthorizeFinished*[T](self: Module[T], error: string, authorized: bool) =
|
||||
if error != "":
|
||||
self.view.setAuthorizationState(AuthorizationState.Error)
|
||||
elif not authorized:
|
||||
self.view.setAuthorizationState(AuthorizationState.WrongPIN)
|
||||
else:
|
||||
self.view.setAuthorizationState(AuthorizationState.Authorized)
|
||||
return
|
||||
|
||||
if self.loginFlow == LoginMethod.Keycard:
|
||||
# We were trying to login and the authorization failed
|
||||
var wrongPassword = false
|
||||
if error.contains("wrong pin"):
|
||||
wrongPassword = true
|
||||
self.view.accountLoginError(error, wrongPassword)
|
||||
self.view.accountLoginError(error, not authorized)
|
||||
|
||||
method onKeycardLoadMnemonicFailure*[T](self: Module[T], error: string) =
|
||||
self.view.setAddKeyPairState(ProgressState.Failed.int)
|
||||
|
@ -23,3 +23,10 @@ type ProgressState* {.pure.} = enum
|
||||
InProgress,
|
||||
Success,
|
||||
Failed,
|
||||
|
||||
type AuthorizationState* {.pure.} = enum
|
||||
Idle
|
||||
InProgress
|
||||
Authorized
|
||||
WrongPIN
|
||||
Error
|
||||
|
@ -1,5 +1,5 @@
|
||||
import NimQml
|
||||
import io_interface
|
||||
import io_interface, states
|
||||
from app_service/service/keycardV2/dto import KeycardEventDto
|
||||
|
||||
# TODO move these files to this module when we remove the old onboarding
|
||||
@ -14,7 +14,7 @@ QtObject:
|
||||
syncState: int
|
||||
addKeyPairState: int
|
||||
pinSettingState: int
|
||||
authorizationState: int
|
||||
authorizationState: AuthorizationState
|
||||
restoreKeysExportState: int
|
||||
loginAccountsModel: login_acc_model.Model
|
||||
loginAccountsModelVariant: QVariant
|
||||
@ -60,11 +60,11 @@ QtObject:
|
||||
|
||||
proc authorizationStateChanged*(self: View) {.signal.}
|
||||
proc getAuthorizationState*(self: View): int {.slot.} =
|
||||
return self.authorizationState
|
||||
return self.authorizationState.int
|
||||
QtProperty[int] authorizationState:
|
||||
read = getAuthorizationState
|
||||
notify = authorizationStateChanged
|
||||
proc setAuthorizationState*(self: View, authorizationState: int) =
|
||||
proc setAuthorizationState*(self: View, authorizationState: AuthorizationState) =
|
||||
self.authorizationState = authorizationState
|
||||
self.authorizationStateChanged()
|
||||
|
||||
|
@ -19,7 +19,7 @@ const PUKLengthForStatusApp* = 12
|
||||
|
||||
const SIGNAL_KEYCARD_STATE_UPDATED* = "keycardStateUpdated"
|
||||
const SIGNAL_KEYCARD_SET_PIN_FAILURE* = "keycardSetPinFailure"
|
||||
const SIGNAL_KEYCARD_AUTHORIZE_FAILURE* = "keycardAuthorizeFailure"
|
||||
const SIGNAL_KEYCARD_AUTHORIZE_FINISHED* = "keycardAuthorizeFinished"
|
||||
const SIGNAL_KEYCARD_LOAD_MNEMONIC_FAILURE* = "keycardLoadMnemonicFailure"
|
||||
const SIGNAL_KEYCARD_LOAD_MNEMONIC_SUCCESS* = "keycardLoadMnemonicSuccess"
|
||||
const SIGNAL_KEYCARD_EXPORT_RESTORE_KEYS_FAILURE* = "keycardExportRestoreKeysFailure"
|
||||
@ -34,6 +34,10 @@ type
|
||||
KeycardErrorArg* = ref object of Args
|
||||
error*: string
|
||||
|
||||
KeycardAuthorizeEvent* = ref object of Args
|
||||
error*: string
|
||||
authorized*: bool
|
||||
|
||||
KeycardKeyUIDArg* = ref object of Args
|
||||
keyUID*: string
|
||||
|
||||
@ -140,9 +144,16 @@ QtObject:
|
||||
let rpcResponseObj = responseObj["response"].getStr().parseJson()
|
||||
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
|
||||
raise newException(RpcException, rpcResponseObj["error"].getStr)
|
||||
let resultObj = rpcResponseObj{"result"}
|
||||
let event = KeycardAuthorizeEvent(
|
||||
error: "",
|
||||
authorized: resultObj{"authorized"}.getBool(),
|
||||
)
|
||||
self.events.emit(SIGNAL_KEYCARD_AUTHORIZE_FINISHED, event)
|
||||
except Exception as e:
|
||||
error "error during authorize: ", msg = e.msg
|
||||
self.events.emit(SIGNAL_KEYCARD_AUTHORIZE_FAILURE, KeycardErrorArg(error: e.msg))
|
||||
let event = KeycardAuthorizeEvent(error: e.msg, authorized: false)
|
||||
self.events.emit(SIGNAL_KEYCARD_AUTHORIZE_FINISHED, event)
|
||||
|
||||
proc receiveKeycardSignalV2(self: Service, signal: string) {.slot.} =
|
||||
try:
|
||||
|
@ -40,7 +40,7 @@ SplitView {
|
||||
store.keycardState = Onboarding.KeycardState.NoPCSCService
|
||||
store.addKeyPairState = Onboarding.ProgressState.Idle
|
||||
store.pinSettingState = Onboarding.ProgressState.Idle
|
||||
store.authorizationState = Onboarding.ProgressState.Idle
|
||||
store.authorizationState = Onboarding.AuthorizationState.Idle
|
||||
store.restoreKeysExportState = Onboarding.ProgressState.Idle
|
||||
store.syncState = Onboarding.ProgressState.Idle
|
||||
store.keycardRemainingPinAttempts = Constants.onboarding.defaultPinAttempts
|
||||
@ -76,7 +76,7 @@ SplitView {
|
||||
property int keycardState: Onboarding.KeycardState.NoPCSCService
|
||||
property int addKeyPairState: Onboarding.ProgressState.Idle
|
||||
property int pinSettingState: Onboarding.ProgressState.Idle
|
||||
property int authorizationState: Onboarding.ProgressState.Idle
|
||||
property int authorizationState: Onboarding.AuthorizationState.Idle
|
||||
property int restoreKeysExportState: Onboarding.ProgressState.Idle
|
||||
property int syncState: Onboarding.ProgressState.Idle
|
||||
property var loginAccountsModel: ctrlLoginScreen.checked ? loginAccountsModel : emptyModel
|
||||
@ -111,9 +111,9 @@ SplitView {
|
||||
function authorize(pin: string) {
|
||||
logs.logEvent("OnboardingStore.authorize", ["pin"], arguments)
|
||||
if (pin === mockDriver.pin)
|
||||
authorizationState = Onboarding.ProgressState.Success
|
||||
authorizationState = Onboarding.AuthorizationState.Authorized
|
||||
else
|
||||
authorizationState = Onboarding.ProgressState.Failed
|
||||
authorizationState = Onboarding.AuthorizationState.WrongPin
|
||||
}
|
||||
|
||||
function loadMnemonic(mnemonic: string) { // -> void
|
||||
@ -578,7 +578,7 @@ SplitView {
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Onboarding.getModelFromEnum("ProgressState")
|
||||
model: Onboarding.getModelFromEnum("AuthorizationState")
|
||||
|
||||
RoundButton {
|
||||
text: modelData.name
|
||||
|
@ -25,7 +25,7 @@ Item {
|
||||
id: mockDriver
|
||||
property int keycardState // enum Onboarding.KeycardState
|
||||
property int pinSettingState // enum Onboarding.ProgressState
|
||||
property int authorizationState // enum Onboarding.ProgressState
|
||||
property int authorizationState // enum Onboarding.AuthorizationState
|
||||
property int restoreKeysExportState // enum Onboarding.ProgressState
|
||||
property bool biometricsAvailable
|
||||
property string existingPin
|
||||
@ -57,7 +57,7 @@ Item {
|
||||
onboardingStore: OnboardingStore {
|
||||
readonly property int keycardState: mockDriver.keycardState // enum Onboarding.KeycardState
|
||||
readonly property int pinSettingState: mockDriver.pinSettingState // enum Onboarding.ProgressState
|
||||
readonly property int authorizationState: mockDriver.authorizationState // enum Onboarding.ProgressState
|
||||
readonly property int authorizationState: mockDriver.authorizationState // enum Onboarding.AuthorizationState
|
||||
readonly property int restoreKeysExportState: mockDriver.restoreKeysExportState // enum Onboarding.ProgressState
|
||||
property int keycardRemainingPinAttempts: Constants.onboarding.defaultPinAttempts
|
||||
property int keycardRemainingPukAttempts: Constants.onboarding.defaultPukAttempts
|
||||
@ -172,7 +172,7 @@ Item {
|
||||
function cleanup() {
|
||||
mockDriver.keycardState = -1
|
||||
mockDriver.pinSettingState = Onboarding.ProgressState.Idle
|
||||
mockDriver.authorizationState = Onboarding.ProgressState.Idle
|
||||
mockDriver.authorizationState = Onboarding.AuthorizationState.Idle
|
||||
mockDriver.restoreKeysExportState = Onboarding.ProgressState.Idle
|
||||
mockDriver.biometricsAvailable = false
|
||||
mockDriver.existingPin = ""
|
||||
@ -479,7 +479,7 @@ Item {
|
||||
tryCompare(dynamicSpy, "count", 1)
|
||||
compare(dynamicSpy.signalArguments[0][0], newPin)
|
||||
mockDriver.pinSettingState = Onboarding.ProgressState.Success
|
||||
mockDriver.authorizationState = Onboarding.ProgressState.Success
|
||||
mockDriver.authorizationState = Onboarding.AuthorizationState.Authorized
|
||||
|
||||
// PAGE 7: Backup your recovery phrase (intro)
|
||||
dynamicSpy.setup(stack, "currentItemChanged")
|
||||
@ -637,7 +637,7 @@ Item {
|
||||
keyClickSequence(newPin + newPin) // set and repeat
|
||||
compare(dynamicSpy.signalArguments[0][0], newPin)
|
||||
mockDriver.pinSettingState = Onboarding.ProgressState.Success
|
||||
mockDriver.authorizationState = Onboarding.ProgressState.Success
|
||||
mockDriver.authorizationState = Onboarding.AuthorizationState.Authorized
|
||||
|
||||
// PAGE 8: Adding key pair to Keycard
|
||||
dynamicSpy.setup(stack, "currentItemChanged")
|
||||
@ -900,7 +900,7 @@ Item {
|
||||
compare(dynamicSpy.signalArguments[0][0], mockDriver.existingPin)
|
||||
|
||||
dynamicSpy.setup(controlUnderTest.onboardingStore, "exportRecoverKeysCalled")
|
||||
mockDriver.authorizationState = Onboarding.ProgressState.Success
|
||||
mockDriver.authorizationState = Onboarding.AuthorizationState.Authorized
|
||||
tryCompare(dynamicSpy, "count", 1)
|
||||
|
||||
// PAGE 6: Extracting keys from Keycard
|
||||
@ -1237,7 +1237,7 @@ Item {
|
||||
tryCompare(dynamicSpy, "count", 1)
|
||||
compare(dynamicSpy.signalArguments[0][0], newPin)
|
||||
mockDriver.pinSettingState = Onboarding.ProgressState.Success
|
||||
mockDriver.authorizationState = Onboarding.ProgressState.Success
|
||||
mockDriver.authorizationState = Onboarding.AuthorizationState.Authorized
|
||||
|
||||
// PAGE 6: Adding key pair to Keycard
|
||||
dynamicSpy.setup(stack, "currentItemChanged")
|
||||
|
@ -82,10 +82,19 @@ public:
|
||||
Failed
|
||||
};
|
||||
|
||||
enum class AuthorizationState {
|
||||
Idle,
|
||||
InProgress,
|
||||
Authorized,
|
||||
WrongPin,
|
||||
Error,
|
||||
};
|
||||
|
||||
private:
|
||||
Q_ENUM(PrimaryFlow)
|
||||
Q_ENUM(OnboardingFlow)
|
||||
Q_ENUM(LoginMethod)
|
||||
Q_ENUM(KeycardState)
|
||||
Q_ENUM(ProgressState)
|
||||
Q_ENUM(AuthorizationState)
|
||||
};
|
||||
|
@ -81,12 +81,11 @@ SQUtils.QObject {
|
||||
|
||||
state: {
|
||||
switch (root.authorizationState) {
|
||||
case Onboarding.ProgressState.Success:
|
||||
case Onboarding.AuthorizationState.Authorized:
|
||||
return KeycardEnterPinPage.State.Success
|
||||
case Onboarding.ProgressState.InProgress:
|
||||
case Onboarding.AuthorizationState.InProgress:
|
||||
return KeycardEnterPinPage.State.InProgress
|
||||
// workaround by mapping all failures as wrong pin (#17289)
|
||||
case Onboarding.ProgressState.Failed:
|
||||
case Onboarding.AuthorizationState.WrongPin:
|
||||
return KeycardEnterPinPage.State.WrongPin
|
||||
}
|
||||
|
||||
@ -105,7 +104,7 @@ SQUtils.QObject {
|
||||
enabled: page.visible
|
||||
|
||||
function onAuthorizationStateChanged() {
|
||||
if (root.authorizationState !== Onboarding.ProgressState.Success)
|
||||
if (root.authorizationState !== Onboarding.AuthorizationState.Authorized)
|
||||
return
|
||||
|
||||
const doNext = () => {
|
||||
|
@ -99,10 +99,17 @@ SQUtils.QObject {
|
||||
termsOfUsePopup.createObject(root.stackView).open()
|
||||
}
|
||||
|
||||
function handleKeycardFailedState(state) {
|
||||
if (state !== Onboarding.ProgressState.Failed)
|
||||
return
|
||||
function handleKeycardProgressFailedState(state) {
|
||||
if (state === Onboarding.ProgressState.Failed)
|
||||
handleKeycardFailedState()
|
||||
}
|
||||
|
||||
function handleKeycardAuthorizationErrorState(state) {
|
||||
if (state === Onboarding.AuthorizationState.Error)
|
||||
handleKeycardFailedState()
|
||||
}
|
||||
|
||||
function handleKeycardFailedState() {
|
||||
// find index of first page in the flow
|
||||
let idx = 0
|
||||
const entryItem = stackView.find((item, index) => {
|
||||
@ -111,7 +118,7 @@ SQUtils.QObject {
|
||||
return item instanceof Loader
|
||||
})
|
||||
|
||||
// when the initial page is not found, bacause e.g. the flow is not initialized
|
||||
// when the initial page is not found, because e.g. the flow is not initialized
|
||||
// or the stack was cleared
|
||||
if (!entryItem)
|
||||
return
|
||||
@ -127,24 +134,19 @@ SQUtils.QObject {
|
||||
!(root.stackView.currentItem instanceof EnableBiometricsPage)
|
||||
|
||||
function onPinSettingStateChanged() {
|
||||
d.handleKeycardFailedState(pinSettingState)
|
||||
d.handleKeycardProgressFailedState(pinSettingState)
|
||||
}
|
||||
|
||||
function onAuthorizationStateChanged() {
|
||||
// workaround for entering pin because currently there is not possible
|
||||
// to distinguish invalid pin and failed pin entering operation (#17289)
|
||||
if (root.stackView.currentItem instanceof KeycardEnterPinPage)
|
||||
return
|
||||
|
||||
d.handleKeycardFailedState(authorizationState)
|
||||
d.handleKeycardAuthorizationErrorState(authorizationState)
|
||||
}
|
||||
|
||||
function onRestoreKeysExportStateChanged() {
|
||||
d.handleKeycardFailedState(restoreKeysExportState)
|
||||
d.handleKeycardProgressFailedState(restoreKeysExportState)
|
||||
}
|
||||
|
||||
function onAddKeyPairStateChanged() {
|
||||
d.handleKeycardFailedState(addKeyPairState)
|
||||
d.handleKeycardProgressFailedState(addKeyPairState)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ SQUtils.QObject {
|
||||
|
||||
KeycardCreatePinDelayedPage {
|
||||
pinSettingState: root.pinSettingState
|
||||
authorizationState: Onboarding.ProgressState.Success // authorization not needed
|
||||
authorizationState: Onboarding.AuthorizationState.Authorized // authorization not needed
|
||||
|
||||
onSetPinRequested: root.setPinRequested(pin)
|
||||
onFinished: root.stackView.replace(keycardUnblockedPage,
|
||||
|
@ -42,7 +42,7 @@ SQUtils.QObject {
|
||||
|
||||
KeycardCreatePinDelayedPage {
|
||||
pinSettingState: root.pinSettingState
|
||||
authorizationState: Onboarding.ProgressState.Success // authorization not needed
|
||||
authorizationState: Onboarding.AuthorizationState.Authorized // authorization not needed
|
||||
|
||||
onSetPinRequested: root.setPinRequested(pin)
|
||||
onFinished: root.finished()
|
||||
|
@ -24,8 +24,8 @@ QtObject {
|
||||
// keycard
|
||||
readonly property int keycardState: d.onboardingModuleInst.keycardState // cf. enum Onboarding.KeycardState
|
||||
readonly property int pinSettingState: d.onboardingModuleInst.pinSettingState // cf. enum Onboarding.ProgressState
|
||||
readonly property int authorizationState: d.onboardingModuleInst.authorizationState // cf. enum Onboarding.ProgressState
|
||||
readonly property int restoreKeysExportState: d.onboardingModuleInst.restoreKeysExportState // cf. enum Onboarding.ProgressState
|
||||
readonly property int authorizationState: d.onboardingModuleInst.authorizationState // cf. enum Onboarding.AuthorizationState
|
||||
readonly property int restoreKeysExportState: d.onboardingModuleInst.restoreKeysExportState // cf. enum Onboarding.AuthorizationState
|
||||
readonly property int keycardRemainingPinAttempts: d.onboardingModuleInst.keycardRemainingPinAttempts
|
||||
readonly property int keycardRemainingPukAttempts: d.onboardingModuleInst.keycardRemainingPukAttempts
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user