Skip to content

Commit

Permalink
feat(LoginWithKeycardFlow): implement "Unlock with recovery phrase"
Browse files Browse the repository at this point in the history
- instead of the factory reset when the keycard is locked
  • Loading branch information
caybro committed Jan 6, 2025
1 parent 917d074 commit e505b50
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 7 deletions.
32 changes: 32 additions & 0 deletions ui/app/AppLayouts/Onboarding2/LoginWithKeycardFlow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ SQUtils.QObject {
required property int keycardState
required property var tryToSetPinFunction
required property int remainingAttempts
required property var isSeedPhraseValid

property bool displayKeycardPromoBanner

signal keycardPinEntered(string pin)
signal keycardPinCreated(string pin)
signal seedphraseSubmitted(string seedphrase)
signal reloadKeycardRequested
signal keycardFactoryResetRequested
signal createProfileWithEmptyKeycardRequested
Expand Down Expand Up @@ -53,9 +56,11 @@ SQUtils.QObject {
KeycardIntroPage {
keycardState: root.keycardState
displayPromoBanner: root.displayKeycardPromoBanner
unlockUsingSeedphrase: true

onReloadKeycardRequested: d.reload()
onKeycardFactoryResetRequested: root.keycardFactoryResetRequested()
onUnlockWithSeedphraseRequested: root.stackView.push(seedphrasePage)
onEmptyKeycardDetected: root.stackView.replace(keycardEmptyPage)
onNotEmptyKeycardDetected: root.stackView.replace(keycardEnterPinPage)
}
Expand All @@ -78,6 +83,7 @@ SQUtils.QObject {
KeycardEnterPinPage {
tryToSetPinFunction: root.tryToSetPinFunction
remainingAttempts: root.remainingAttempts
unlockUsingSeedphrase: true

onKeycardPinEntered: {
root.keycardPinEntered(pin)
Expand All @@ -86,6 +92,32 @@ SQUtils.QObject {

onReloadKeycardRequested: d.reload()
onKeycardFactoryResetRequested: root.keycardFactoryResetRequested()
onUnlockWithSeedphraseRequested: root.stackView.push(seedphrasePage)
}
}

Component {
id: seedphrasePage

SeedphrasePage {
title: qsTr("Unlock Keycard using the recovery phrase")
btnContinueText: qsTr("Unlock")
isSeedPhraseValid: root.isSeedPhraseValid
onSeedphraseSubmitted: (seedphrase) => {
root.seedphraseSubmitted(seedphrase)
root.stackView.push(keycardCreatePinPage)
}
}
}

Component {
id: keycardCreatePinPage

KeycardCreatePinPage {
onKeycardPinCreated: {
root.keycardPinCreated(pin)
root.finished()
}
}
}
}
6 changes: 6 additions & 0 deletions ui/app/AppLayouts/Onboarding2/OnboardingFlow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ SQUtils.QObject {
signal seedphraseSubmitted(string seedphrase)
signal setPasswordRequested(string password)
signal reloadKeycardRequested
signal keycardFactoryResetRequested

signal finished(int flow)

Expand Down Expand Up @@ -162,6 +163,7 @@ SQUtils.QObject {
splashScreenDurationMs: root.splashScreenDurationMs

onReloadKeycardRequested: root.reloadKeycardRequested()
onKeycardFactoryResetRequested: root.keycardFactoryResetRequested()
onKeycardPinCreated: (pin) => root.keycardPinCreated(pin)
onLoginWithKeycardRequested: loginWithKeycardFlow.init()

Expand Down Expand Up @@ -214,10 +216,14 @@ SQUtils.QObject {
remainingAttempts: root.remainingAttempts
displayKeycardPromoBanner: root.displayKeycardPromoBanner
tryToSetPinFunction: root.tryToSetPinFunction
isSeedPhraseValid: root.isSeedPhraseValid

onKeycardPinEntered: (pin) => root.keycardPinEntered(pin)
onKeycardPinCreated: (pin) => root.keycardPinCreated(pin)
onSeedphraseSubmitted: (seedphrase) => root.seedphraseSubmitted(seedphrase)
onReloadKeycardRequested: root.reloadKeycardRequested()
onCreateProfileWithEmptyKeycardRequested: keycardCreateProfileFlow.init()
onKeycardFactoryResetRequested: root.keycardFactoryResetRequested()

onFinished: {
d.flow = Onboarding.SecondaryFlow.LoginWithKeycard
Expand Down
3 changes: 2 additions & 1 deletion ui/app/AppLayouts/Onboarding2/pages/KeycardCreatePinPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Backpressure 0.1

import AppLayouts.Onboarding2.controls 1.0

Expand Down Expand Up @@ -103,7 +104,7 @@ KeycardBasePage {
StateChangeScript {
script: {
pinInput.setPin(d.pin)
root.keycardPinCreated(d.pin)
Backpressure.debounce(root, 2000, () => root.keycardPinCreated(d.pin))()
}
}
},
Expand Down
19 changes: 15 additions & 4 deletions ui/app/AppLayouts/Onboarding2/pages/KeycardEnterPinPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ KeycardBasePage {

property var tryToSetPinFunction: (pin) => { console.error("tryToSetPinFunction: IMPLEMENT ME"); return false }
required property int remainingAttempts
property bool unlockUsingSeedphrase

signal keycardPinEntered(string pin)
signal reloadKeycardRequested()
signal unlockWithSeedphraseRequested()
signal keycardFactoryResetRequested()

pageClassName: "KeycardEnterPinPage"
Expand Down Expand Up @@ -63,6 +65,13 @@ KeycardBasePage {
text: qsTr("Factory reset Keycard")
onClicked: root.keycardFactoryResetRequested()
},
StatusButton {
id: btnUnlockWithSeedphrase
visible: false
text: qsTr("Unlock with recovery phrase")
anchors.horizontalCenter: parent.horizontalCenter
onClicked: root.unlockWithSeedphraseRequested()
},
StatusButton {
id: btnReload
width: 320
Expand Down Expand Up @@ -96,7 +105,11 @@ KeycardBasePage {
}
PropertyChanges {
target: btnFactoryReset
visible: true
visible: !root.unlockUsingSeedphrase
}
PropertyChanges {
target: btnUnlockWithSeedphrase
visible: root.unlockUsingSeedphrase
}
PropertyChanges {
target: btnReload
Expand Down Expand Up @@ -135,9 +148,7 @@ KeycardBasePage {
}
StateChangeScript {
script: {
Backpressure.debounce(root, 2000, function() {
root.keycardPinEntered(pinInput.pinInput)
})()
Backpressure.debounce(root, 2000, () => root.keycardPinEntered(pinInput.pinInput))()
}
}
},
Expand Down
18 changes: 16 additions & 2 deletions ui/app/AppLayouts/Onboarding2/pages/KeycardIntroPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ KeycardBasePage {

required property int keycardState // cf Onboarding.KeycardState
property bool displayPromoBanner
property bool unlockUsingSeedphrase

signal keycardFactoryResetRequested()
signal unlockWithSeedphraseRequested()
signal reloadKeycardRequested()
signal emptyKeycardDetected()
signal notEmptyKeycardDetected()
Expand Down Expand Up @@ -87,6 +89,13 @@ KeycardBasePage {
anchors.horizontalCenter: parent.horizontalCenter
onClicked: root.keycardFactoryResetRequested()
},
MaybeOutlineButton {
id: btnUnlockWithSeedphrase
visible: false
text: qsTr("Unlock with recovery phrase")
anchors.horizontalCenter: parent.horizontalCenter
onClicked: root.unlockWithSeedphraseRequested()
},
MaybeOutlineButton {
id: btnReload
visible: false
Expand Down Expand Up @@ -190,12 +199,17 @@ KeycardBasePage {
PropertyChanges {
target: root
title: "<font color='%1'>".arg(Theme.palette.dangerColor1) + qsTr("Keycard locked") + "</font>"
subtitle: qsTr("The Keycard you have inserted is locked, you will need to factory reset it or insert a different one")
subtitle: root.unlockUsingSeedphrase ? qsTr("The Keycard you have inserted is locked, you will need to unlock it using the recovery phrase or insert a different one")
: qsTr("The Keycard you have inserted is locked, you will need to factory reset it or insert a different one")
image.source: Theme.png("onboarding/keycard/error")
}
PropertyChanges {
target: btnFactoryReset
visible: true
visible: !root.unlockUsingSeedphrase
}
PropertyChanges {
target: btnUnlockWithSeedphrase
visible: root.unlockUsingSeedphrase
}
PropertyChanges {
target: btnReload
Expand Down
2 changes: 2 additions & 0 deletions ui/app/AppLayouts/Onboarding2/pages/SeedphrasePage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ OnboardingPage {

title: qsTr("Create profile using a recovery phrase")
property string subtitle: qsTr("Enter your 12, 18 or 24 word recovery phrase")
property alias btnContinueText: btnContinue.text

property var isSeedPhraseValid: (mnemonic) => { console.error("isSeedPhraseValid IMPLEMENT ME"); return false }

Expand Down Expand Up @@ -53,6 +54,7 @@ OnboardingPage {
}

StatusButton {
id: btnContinue
objectName: "btnContinue"
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: -Theme.halfPadding
Expand Down

0 comments on commit e505b50

Please sign in to comment.