mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-02 01:38:00 +00:00
feat: remove seed phrase
This commit is contained in:
parent
6c641eff42
commit
5461d6f93c
@ -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.}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -7,11 +7,38 @@ import "../../../../shared"
|
||||
ModalPopup {
|
||||
id: popup
|
||||
|
||||
//% "Write down your seed phrase"
|
||||
title: qsTrId("write-down-your-seed-phrase")
|
||||
property bool showWarning: true
|
||||
property int seedWord1Idx: -1;
|
||||
property int seedWord2Idx: -1;
|
||||
property string validationError: ""
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
radius: 9
|
||||
color: Style.current.blue
|
||||
width: 18
|
||||
height: 18
|
||||
Text {
|
||||
font.pixelSize: 12
|
||||
color: Style.current.white
|
||||
anchors.centerIn: parent
|
||||
text: "1"
|
||||
}
|
||||
ColorOverlay {
|
||||
anchors.fill: caret
|
||||
source: caret
|
||||
color: Style.current.darkGrey
|
||||
rotation: -90
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user