feat: remove seed phrase

This commit is contained in:
Richard Ramos 2020-10-26 16:20:31 -04:00 committed by RichΛrd
parent 6c641eff42
commit 5461d6f93c
6 changed files with 221 additions and 28 deletions

View File

@ -113,6 +113,16 @@ QtObject:
read = getBlockedContacts
notify = contactListChanged
proc isMnemonicBackedUp*(self: ProfileView): bool {.slot.} =
let mnemonic = status_settings.getSetting[string](Setting.Mnemonic, "")
return mnemonic == ""
proc seedPhraseRemoved*(self: ProfileView) {.signal.}
QtProperty[bool] isMnemonicBackedUp:
read = isMnemonicBackedUp
notify = seedPhraseRemoved
proc getMnemonic*(self: ProfileView): QVariant {.slot.} =
# Do not keep the mnemonic in memory, so fetch it when necessary
let mnemonic = status_settings.getSetting[string](Setting.Mnemonic, "")
@ -120,6 +130,15 @@ QtObject:
QtProperty[QVariant] mnemonic:
read = getMnemonic
notify = seedPhraseRemoved
proc removeSeedPhrase*(self: ProfileView) {.slot.} =
discard status_settings.saveSetting(Setting.Mnemonic, "")
self.seedPhraseRemoved()
proc getMnemonicWord*(self: ProfileView, idx: int): string {.slot.} =
let mnemonics = status_settings.getSetting[string](Setting.Mnemonic, "").split(" ")
return mnemonics[idx]
proc networkChanged*(self: ProfileView) {.signal.}

View File

@ -23,6 +23,7 @@ ScrollView {
Repeater {
model: ProfileConstants.menuButtons
delegate: MenuButton {
menuItemId: modelData.id
text: modelData .text
source: "../../../img/profile/" + modelData.filename
active: profileMenu.profileCurrentIndex === modelData.id

View File

@ -1,9 +1,11 @@
import QtQuick 2.13
import "../../../../../imports"
import "../../../../../shared"
import "../constants.js" as ProfileConstants
Rectangle {
property int menuItemId: -1
property bool hovered: false
property bool active: false
property url source: "../../../../img/add_watch_only.svg"
@ -37,6 +39,23 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
visible: !profileModel.isMnemonicBackedUp && !active && ProfileConstants.PRIVACY_AND_SECURITY === menuItemId
anchors.verticalCenter: parent.verticalCenter
anchors.right: menuButton.right
anchors.rightMargin: 10
radius: 9
color: Style.current.blue
width: 18
height: 18
Text {
font.pixelSize: 12
color: Style.current.white
anchors.centerIn: parent
text: "1"
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent

View File

@ -6,12 +6,39 @@ import "../../../../shared"
ModalPopup {
id: popup
property bool showWarning: true
property int seedWord1Idx: -1;
property int seedWord2Idx: -1;
property string validationError: ""
//% "Write down your seed phrase"
title: qsTrId("write-down-your-seed-phrase")
onOpened: {
seedWord1Idx = -1;
seedWord2Idx = -1;
txtFieldWord.text = "";
validationError = "";
}
header: Item {
height: 50
StyledText {
id: lblTitle
text: qsTr("Back up seed phrase")
font.pixelSize: 17
font.bold: true
anchors.left: parent.left
}
StyledText {
anchors.top: lblTitle.bottom
anchors.topMargin: Style.current.smallPadding
text: qsTr("Step %1 of 3").arg(seedWord2Idx > -1 ? 3 : (seedWord1Idx > -1 ? 2 : 1))
font.pixelSize: 14
anchors.left: parent.left
}
}
Loader {
active: popup.opened
active: popup.opened && !showWarning && seedWord1Idx == -1
width: parent.width
height: item ? item.height : 0
@ -87,8 +114,86 @@ ModalPopup {
}
}
Item {
visible: showWarning
anchors.left: parent.left
anchors.right: parent.right
StyledText {
id: lblLoseSeed
text: qsTr("If you lose your seed phrase you lose your data and funds")
wrapMode: Text.WordWrap
font.pixelSize: 17
font.bold: true
anchors.left: parent.left
anchors.right: parent.right
}
StyledText {
anchors.top: lblLoseSeed.bottom
anchors.topMargin: Style.current.smallPadding
wrapMode: Text.WordWrap
text: qsTr("If you lose access, for example by losing your phone, you can only access your keys with your seed phrase. No one, but you has your seed phrase. Write it down. Keep it safe")
anchors.left: parent.left
anchors.right: parent.right
}
}
Item {
visible: seedWord1Idx > -1 || seedWord2Idx > -1
anchors.left: parent.left
anchors.right: parent.right
StyledText {
id: txtChk
text: qsTr("Check your seed phrase")
}
StyledText {
text: qsTr("Word #%1").arg((seedWord2Idx > -1 ? seedWord2Idx : seedWord1Idx) + 1)
anchors.left: txtChk.right
anchors.leftMargin: 5
color: Style.current.secondaryText
}
Input {
id: txtFieldWord
anchors.top: txtChk.bottom
anchors.topMargin: Style.current.padding
anchors.left: txtChk.left
anchors.right: parent.right
placeholderText: qsTr("Enter word")
text: ""
validationError: popup.validationError
}
StyledText {
anchors.top: txtFieldWord.bottom
anchors.topMargin: Style.current.padding
wrapMode: Text.WordWrap
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("In order to check if you have backed up your seed phrase correctly, enter the word #%1 above").arg((seedWord2Idx > -1 ? seedWord2Idx : seedWord1Idx) + 1)
color: Style.current.secondaryText
}
ConfirmationDialog {
id: removeSeedPhraseConfirm
title: qsTr("Are you sure?")
confirmationText: qsTr("You will not be able to see the whole seed phrase again")
onConfirmButtonClicked: {
profileModel.removeSeedPhrase()
popup.close();
removeSeedPhraseConfirm.close();
}
onClosed: {
seedWord1Idx = -1;
seedWord2Idx = -1;
txtFieldWord.text = "";
validationError = "";
}
}
}
StyledText {
id: confirmationsInfo
visible: !showWarning && seedWord1Idx == -1
//% "With this 12 words you can always get your key back. Write it down. Keep it safe, offline, and separate from this device."
text: qsTrId(
"with-this-12-words-you-can-always-get-your-key-back.-write-it-down.-keep-it-safe,-offline,-and-separate-from-this-device.")
@ -104,14 +209,46 @@ ModalPopup {
wrapMode: Text.WordWrap
}
footer: StyledButton {
//% "Done"
label: qsTrId("done")
label: showWarning ?
qsTr("Okay, continue") :
qsTrId("Next")
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.bottom: parent.bottom
onClicked: {
backupSeedModal.close()
if(showWarning){
showWarning = false;
} else {
if(seedWord1Idx == -1){
seedWord1Idx = Math.floor(Math.random() * 12);
} else {
if(seedWord2Idx == -1){
if(profileModel.getMnemonicWord(seedWord1Idx) !== txtFieldWord.text){
validationError = qsTr("Wrong word");
return;
}
validationError = "";
txtFieldWord.text = "";
do {
seedWord2Idx = Math.floor(Math.random() * 12);
} while(seedWord2Idx == seedWord1Idx);
} else {
if(profileModel.getMnemonicWord(seedWord2Idx) !== txtFieldWord.text){
validationError = qsTr("Wrong word");
return;
}
validationError = "";
txtFieldWord.text = "";
removeSeedPhraseConfirm.open();
}
}
}
}
}
}

View File

@ -44,29 +44,32 @@ Item {
//% "Backup Seed Phrase"
text: qsTrId("backup-seed-phrase")
font.pixelSize: 15
color: !badge.visible ? Style.current.darkGrey : Style.current.textColor
}
SVGImage {
id: caret
Rectangle {
id: badge
visible: !profileModel.isMnemonicBackedUp
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 0
anchors.verticalCenter: backupText.verticalCenter
source: "../../../img/caret.svg"
width: 13
height: 7
rotation: -90
}
ColorOverlay {
anchors.fill: caret
source: caret
color: Style.current.darkGrey
rotation: -90
radius: 9
color: Style.current.blue
width: 18
height: 18
Text {
font.pixelSize: 12
color: Style.current.white
anchors.centerIn: parent
text: "1"
}
}
MouseArea {
enabled: !profileModel.isMnemonicBackedUp
anchors.fill: parent
onClicked: backupSeedModal.open()
cursorShape: Qt.PointingHandCursor
cursorShape: enabled && Qt.PointingHandCursor
}
}
@ -74,11 +77,6 @@ Item {
id: backupSeedModal
}
Separator {
id: separator
anchors.top: backupSeedPhrase.bottom
anchors.topMargin: Style.current.bigPadding
}
Item {
id: dappPermissions
@ -106,7 +104,7 @@ Item {
ColorOverlay {
anchors.fill: caret2
source: caret
source: caret2
color: Style.current.darkGrey
rotation: -90
}
@ -119,7 +117,7 @@ Item {
}
Separator {
id: separator2
id: separator
anchors.top: dappPermissions.bottom
anchors.topMargin: Style.current.bigPadding
}

View File

@ -113,6 +113,25 @@ RowLayout {
anchors.topMargin: 50
anchors.horizontalCenter: parent.horizontalCenter
icon.name: "profile"
Rectangle {
id: profileBadge
visible: !profileModel.isMnemonicBackedUp && sLayout.children[sLayout.currentIndex] !== profileLayoutContainer
anchors.top: image3.top
anchors.left: image3.right
anchors.leftMargin: -10
anchors.topMargin: -5
radius: 9
color: Style.current.blue
width: 18
height: 18
Text {
font.pixelSize: 12
color: Style.current.white
anchors.centerIn: parent
text: "1"
}
}
}
StatusIconTabButton {
@ -139,6 +158,7 @@ RowLayout {
}
StackLayout {
id: sLayout
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true
@ -151,7 +171,6 @@ RowLayout {
if(this.children[currentIndex] === browserLayoutContainer && browserLayoutContainer.active == false){
browserLayoutContainer.active = true;
}
}
ChatLayout {