feat(desktop/profile) adding password changed modal
Implemented new change password succcess confirmation popup Closes #3432
This commit is contained in:
parent
d3c9564d91
commit
22994a4a14
|
@ -10,7 +10,7 @@ import status/status
|
||||||
import status/ens as status_ens
|
import status/ens as status_ens
|
||||||
import status/chat/chat
|
import status/chat/chat
|
||||||
import status/types/[setting, os_notification]
|
import status/types/[setting, os_notification]
|
||||||
import status/constants as accountConstants
|
import ../../constants
|
||||||
import status/notifications/[os_notifications]
|
import status/notifications/[os_notifications]
|
||||||
import ../../app_service/[main]
|
import ../../app_service/[main]
|
||||||
import qrcode/qrcode
|
import qrcode/qrcode
|
||||||
|
@ -126,9 +126,16 @@ QtObject:
|
||||||
read = getEnsManager
|
read = getEnsManager
|
||||||
|
|
||||||
proc changePassword(self: ProfileView, password: string, newPassword: string): bool {.slot.} =
|
proc changePassword(self: ProfileView, password: string, newPassword: string): bool {.slot.} =
|
||||||
|
let
|
||||||
|
defaultAccount = status_accounts.getDefaultAccount()
|
||||||
|
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR)
|
||||||
|
if not isPasswordOk:
|
||||||
|
return false
|
||||||
|
|
||||||
if self.status.accounts.changePassword(self.profile.address, password, newPassword):
|
if self.status.accounts.changePassword(self.profile.address, password, newPassword):
|
||||||
quit(QuitSuccess) # quits the app TODO: change this to logout instead when supported
|
return true
|
||||||
return false
|
else:
|
||||||
|
return false
|
||||||
|
|
||||||
proc getLinkPreviewWhitelist*(self: ProfileView): string {.slot.} =
|
proc getLinkPreviewWhitelist*(self: ProfileView): string {.slot.} =
|
||||||
result = $(self.status.profile.getLinkPreviewWhitelist())
|
result = $(self.status.profile.getLinkPreviewWhitelist())
|
||||||
|
@ -205,4 +212,4 @@ QtObject:
|
||||||
)
|
)
|
||||||
|
|
||||||
self.appService.osNotificationService.showNotification(title, message,
|
self.appService.osNotificationService.showNotification(title, message,
|
||||||
details, useOSNotifications)
|
details, useOSNotifications)
|
||||||
|
|
|
@ -1,103 +1,102 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import "../../../../imports"
|
import "../../../../imports"
|
||||||
import "../../../../shared"
|
import "../../../../shared"
|
||||||
|
|
||||||
ModalPopup {
|
import StatusQ.Popups 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
|
StatusModal {
|
||||||
id: popup
|
id: popup
|
||||||
title: qsTr("Change password")
|
width: 480
|
||||||
height: 510
|
height: 510
|
||||||
|
closePolicy: Popup.NoAutoClose
|
||||||
|
header.title: qsTr("Change password")
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
reset()
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool loading: false
|
property var successPopup
|
||||||
property bool firstPasswordFieldValid: false
|
property string indicationText: ""
|
||||||
property bool repeatPasswordFieldValid: false
|
property bool passwordInputValid
|
||||||
property string passwordValidationError: ""
|
property bool currPasswordInputValid
|
||||||
property string repeatPasswordValidationError: ""
|
property string currPasswordValidationError: ""
|
||||||
property string changePasswordError: ""
|
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
currentPasswordField.text = ""
|
passwordInput.text = "";
|
||||||
firstPasswordField.text = ""
|
currentPasswordInput.text = "";
|
||||||
repeatPasswordField.text = ""
|
currentPasswordInput.forceActiveFocus(Qt.MouseFocusReason);
|
||||||
currentPasswordField.forceActiveFocus(Qt.MouseFocusReason)
|
popup.indicationText = "At least 6 characters. Your password protects your keys. You need it to unlock Status and transact.";
|
||||||
|
popup.currPasswordValidationError = "";
|
||||||
firstPasswordFieldValid = false
|
passwordInput.validationError = "";
|
||||||
repeatPasswordFieldValid = false
|
popup.passwordInputValid = false;
|
||||||
passwordValidationError = ""
|
popup.currPasswordInputValid = false;
|
||||||
repeatPasswordValidationError = ""
|
|
||||||
changePasswordError = ""
|
|
||||||
loading = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
|
id: contentItem
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Style.current.xlPadding
|
anchors {
|
||||||
spacing: Style.current.xlPadding
|
topMargin: (Style.current.xlPadding + popup.topPadding)
|
||||||
|
leftMargin: Style.current.xlPadding
|
||||||
|
rightMargin: Style.current.xlPadding
|
||||||
|
bottomMargin: (Style.current.xlPadding + popup.bottomPadding)
|
||||||
|
}
|
||||||
|
spacing: Style.current.padding
|
||||||
|
|
||||||
|
//TODO replace with StatusInput as soon as it supports password
|
||||||
Input {
|
Input {
|
||||||
id: currentPasswordField
|
id: currentPasswordInput
|
||||||
anchors.left: undefined
|
anchors.left: undefined
|
||||||
anchors.right: undefined
|
anchors.right: undefined
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
placeholderText: qsTr("Current password")
|
placeholderText: ""
|
||||||
|
label: qsTr("Current password")
|
||||||
textField.echoMode: TextInput.Password
|
textField.echoMode: TextInput.Password
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
changePasswordError = ""
|
popup.currPasswordInputValid = (currentPasswordInput.text.length >= 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO replace with StatusInput as soon as it supports password
|
||||||
Input {
|
Input {
|
||||||
id: firstPasswordField
|
id: passwordInput
|
||||||
anchors.left: undefined
|
anchors.left: undefined
|
||||||
anchors.right: undefined
|
anchors.right: undefined
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
//% "New password..."
|
placeholderText: ""
|
||||||
placeholderText: qsTrId("new-password...")
|
label: qsTrId("new-password...")
|
||||||
textField.echoMode: TextInput.Password
|
textField.echoMode: TextInput.Password
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
[firstPasswordFieldValid, passwordValidationError] =
|
popup.passwordInputValid = ((passwordInput.text !== "") && (passwordInput.text.length >= 6));
|
||||||
Utils.validatePasswords("first", firstPasswordField, repeatPasswordField);
|
//setting validationError so that input becomes red
|
||||||
|
passwordInput.validationError = (!popup.passwordInputValid) ? " " : "";
|
||||||
|
popup.indicationText = (!popup.passwordInputValid ? "<font color=\"#FF2D55\">" : "")
|
||||||
|
+ "At least 6 characters." + (!popup.passwordInputValid ? "</font>" : "")
|
||||||
|
+ "Your password protects your keys. You need it to unlock Status and transact."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Input {
|
Item {
|
||||||
id: repeatPasswordField
|
Layout.fillHeight: true
|
||||||
anchors.left: undefined
|
|
||||||
anchors.right: undefined
|
|
||||||
Layout.fillWidth: true
|
|
||||||
enabled: firstPasswordFieldValid
|
|
||||||
//% "Confirm password…"
|
|
||||||
placeholderText: qsTrId("confirm-password…")
|
|
||||||
textField.echoMode: TextInput.Password
|
|
||||||
Keys.onReturnPressed: function(event) {
|
|
||||||
if (submitBtn.enabled) {
|
|
||||||
submitBtn.clicked(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onTextChanged: {
|
|
||||||
[repeatPasswordFieldValid, repeatPasswordValidationError] =
|
|
||||||
Utils.validatePasswords("repeat", firstPasswordField, repeatPasswordField);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: validationError
|
id: validationError
|
||||||
text: passwordValidationError || repeatPasswordValidationError || changePasswordError
|
Layout.preferredWidth: parent.width
|
||||||
Layout.preferredWidth: 340
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
color: Style.current.danger
|
visible: (text !== "")
|
||||||
font.pixelSize: Style.current.tertiaryTextFontSize
|
font.pixelSize: Style.current.tertiaryTextFontSize
|
||||||
|
color: Style.current.danger
|
||||||
|
text: popup.currPasswordValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: qsTr("Status app will be terminated after password change. You need to restart it to login using the new password.")
|
text: qsTr(indicationText)
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.preferredWidth: 340
|
Layout.preferredWidth: 340
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
@ -107,26 +106,39 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: Item {
|
rightButtons: [
|
||||||
width: parent.width
|
|
||||||
height: submitBtn.height
|
|
||||||
|
|
||||||
StatusButton {
|
StatusButton {
|
||||||
id: submitBtn
|
id: submitBtn
|
||||||
anchors.right: parent.right
|
|
||||||
text: qsTr("Change password")
|
text: qsTr("Change password")
|
||||||
enabled: popup.firstPasswordFieldValid && popup.repeatPasswordFieldValid && !popup.loading
|
enabled: (popup.passwordInputValid && popup.currPasswordInputValid && !submitBtn.loading)
|
||||||
state: popup.loading ? "pending" : "default"
|
|
||||||
|
|
||||||
onClicked: {
|
property Timer sim: Timer {
|
||||||
popup.loading = true
|
id: pause
|
||||||
if (profileModel.changePassword(currentPasswordField.text, firstPasswordField.text)) {
|
interval: 20
|
||||||
popup.close()
|
onTriggered: {
|
||||||
} else {
|
submitBtn.changePasswordBegin();
|
||||||
reset()
|
|
||||||
changePasswordError = qsTr("Failed to change password.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
submitBtn.loading = true;
|
||||||
|
//changePassword operation blocks the UI so loading = true; will never
|
||||||
|
//have any affect until changePassword is done. Getting around it with a
|
||||||
|
//small pause (timer) in order to get the desired behavior
|
||||||
|
pause.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function changePasswordBegin() {
|
||||||
|
if (profileModel.changePassword(currentPasswordInput.text, passwordInput.text)) {
|
||||||
|
popup.successPopup.open();
|
||||||
|
submitBtn.enabled = false;
|
||||||
|
} else {
|
||||||
|
reset();
|
||||||
|
passwordInput.validationError = " ";
|
||||||
|
popup.currPasswordValidationError = qsTr("Incorrect password");
|
||||||
|
}
|
||||||
|
submitBtn.loading = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,50 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import "../../../../imports"
|
import "../../../../imports"
|
||||||
import "../../../../shared"
|
import "../../../../shared"
|
||||||
|
|
||||||
ModalPopup {
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Popups 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
|
StatusModal {
|
||||||
id: root
|
id: root
|
||||||
width: 400
|
width: 400
|
||||||
height: 248
|
height: 248
|
||||||
|
|
||||||
closePolicy: Popup.NoAutoClose
|
closePolicy: Popup.NoAutoClose
|
||||||
|
|
||||||
contentItem: Column {
|
showHeader: false
|
||||||
implicitWidth: root.width
|
contentItem: ColumnLayout {
|
||||||
implicitHeight: root.height
|
anchors.fill: parent
|
||||||
spacing: 8
|
anchors.margins: 45
|
||||||
|
spacing: Style.current.halfPadding
|
||||||
StatusIcon {
|
StatusIcon {
|
||||||
icon: "check"
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.preferredWidth: 26
|
||||||
|
Layout.preferredHeight: 26
|
||||||
|
icon: "checkmark"
|
||||||
|
color: Style.current.green
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
font.pixelSize: 18
|
||||||
|
text: qsTr("<b>Password changed</b>")
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
font.pixelSize: 13
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
text: qsTr("You need to sign in again using the new password.")
|
text: qsTr("You need to sign in again using the new password.")
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusButton {
|
StatusButton {
|
||||||
id: submitBtn
|
id: submitBtn
|
||||||
anchors.right: parent.right
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: qsTr("Log out")
|
text: qsTr("Sign out & Quit")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
//quits the app TODO: change this to logout instead when supported
|
//quits the app TODO: change this to logout instead when supported
|
||||||
Qt.quit();
|
Qt.quit();
|
||||||
|
|
|
@ -51,6 +51,13 @@ Item {
|
||||||
|
|
||||||
ChangePasswordModal {
|
ChangePasswordModal {
|
||||||
id: changePasswordModal
|
id: changePasswordModal
|
||||||
|
anchors.centerIn: parent
|
||||||
|
successPopup: successPopup
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangePasswordSuccessModal {
|
||||||
|
id: successPopup
|
||||||
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
Loading…
Reference in New Issue