feat(desktop/profile) adding password changed modal

Implemented new change password succcess confirmation
popup

Closes #3432
This commit is contained in:
Alexandra Betouni 2021-09-09 17:04:05 +03:00 committed by Iuri Matias
parent d3c9564d91
commit 22994a4a14
4 changed files with 126 additions and 82 deletions

View File

@ -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)

View File

@ -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;
}
} }
} ]
} }

View File

@ -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();

View File

@ -51,6 +51,13 @@ Item {
ChangePasswordModal { ChangePasswordModal {
id: changePasswordModal id: changePasswordModal
anchors.centerIn: parent
successPopup: successPopup
}
ChangePasswordSuccessModal {
id: successPopup
anchors.centerIn: parent
} }
Item { Item {