UI/UX to ask for the accounts password on start up

With this change Keysmith now prompts the user to either:

 - setup a new password
 - supply an existing password (if detected)

Additionally the organisation/structure of the QML is cleaned up a bit.
All QML pages are dedicated QML files and a few signals are introduced
to provide slightly better encapsulation/decouple interdependencies.
master
Johan Ouwerkerk 2020-02-29 23:49:44 +01:00
parent f16eba4505
commit d048adf921
5 changed files with 151 additions and 4 deletions

View File

@ -31,11 +31,12 @@ target_link_libraries(keysmith
if(ANDROID)
kirigami_package_breeze_icons(ICONS
go-next
answer-correct
edit-delete
edit-undo
go-next
list-add
answer-correct
unlock
)
endif()

View File

@ -0,0 +1,62 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
*/
import QtQuick 2.1
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.0 as Controls
import org.kde.kirigami 2.8 as Kirigami
import Keysmith.Application 1.0
import Keysmith.Models 1.0 as Models
Kirigami.Page {
id: root
title: i18nc("@title:window", "Password")
property bool bannerTextError : false
property string bannerText : i18n("Get started by choosing a password to protect your accounts")
property string failedToApplyNewPassword : i18n("Failed to set up your password")
property Models.PasswordRequestModel passwordRequest: Keysmith.passwordRequest()
ColumnLayout {
anchors {
horizontalCenter: parent.horizontalCenter
}
Controls.Label {
text: bannerText
color: bannerTextError ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.textColor
}
Kirigami.FormLayout {
Kirigami.PasswordField {
id: newPassword
text: ""
Kirigami.FormData.label: i18nc("@label:textbox", "New password:")
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhSensitiveData | Qt.ImhHiddenText
}
Kirigami.PasswordField {
id: newPasswordCopy
text: ""
Kirigami.FormData.label: i18nc("@label:textbox", "Verify password:")
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhSensitiveData | Qt.ImhHiddenText
}
}
}
actions.main : Kirigami.Action {
text: i18n("Apply")
iconName: "answer-correct"
enabled: newPassword.text === newPasswordCopy.text && newPassword.text && newPassword.text.length > 0
onTriggered: {
// TODO convert to C++ helper, have proper logging?
if (passwordRequest) {
if (!passwordRequest.provideBothPasswords(newPassword.text, newPasswordCopy.text)) {
bannerText = failedToApplyNewPassword;
bannerTextError = true;
}
}
// TODO warn if not
}
}
}

View File

@ -0,0 +1,56 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
*/
import QtQuick 2.1
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.0 as Controls
import org.kde.kirigami 2.8 as Kirigami
import Keysmith.Application 1.0
import Keysmith.Models 1.0 as Models
Kirigami.Page {
id: root
title: i18nc("@title:window", "Password")
property bool bannerTextError : false
property string bannerText : i18n("Please provide the password to unlock your accounts")
property string failedToApplyPassword : i18n("Failed to unlock your accounts")
property Models.PasswordRequestModel passwordRequest: Keysmith.passwordRequest()
ColumnLayout {
anchors {
horizontalCenter: parent.horizontalCenter
}
Controls.Label {
text: bannerText
color: bannerTextError ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.textColor
}
Kirigami.FormLayout {
Kirigami.PasswordField {
id: existingPassword
text: ""
Kirigami.FormData.label: i18nc("@label:textbox", "Password:")
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhSensitiveData | Qt.ImhHiddenText
}
}
}
actions.main : Kirigami.Action {
text: i18n("Unlock")
iconName: "unlock"
enabled: existingPassword.text && existingPassword.text.length > 0
onTriggered: {
// TODO convert to C++ helper, have proper logging?
if (passwordRequest) {
if (!passwordRequest.providePassword(existingPassword.text)) {
bannerText = failedToApplyPassword;
bannerTextError = true;
}
}
// TODO warn if not
}
}
}

View File

@ -15,10 +15,23 @@ import org.kde.kirigami 2.4 as Kirigami
Kirigami.ApplicationWindow {
id: root
pageStack.initialPage: accountsOverviewPage
property bool addActionEnabled: true
property Models.AccountListModel accounts: Keysmith.accountListModel()
property Models.PasswordRequestModel passwordRequest: Keysmith.passwordRequest()
pageStack.initialPage: passwordRequest.previouslyDefined ? unlockAccountsPage : setupPasswordPage
Component {
id: setupPasswordPage
SetupPassword {
}
}
Component {
id: unlockAccountsPage
UnlockAccounts {
}
}
Component {
id: accountsOverviewPage
@ -42,4 +55,17 @@ Kirigami.ApplicationWindow {
}
}
}
// TODO maybe have a onPasswordProvided handler to push a "progress" page to provide visual feedback for devices where key derivation is slow?
Connections {
target: passwordRequest
onDerivedKey : {
// TODO convert to C++ helper, have proper logging?
if (passwordRequest.keyAvailable) {
pageStack.pop();
pageStack.push(accountsOverviewPage);
}
// TODO warn if not
}
}
}

View File

@ -10,5 +10,7 @@
<file alias="AccountEntryView.qml">contents/ui/AccountEntryView.qml</file>
<file alias="AccountsOverview.qml">contents/ui/AccountsOverview.qml</file>
<file alias="AddAccount.qml">contents/ui/AddAccount.qml</file>
<file alias="UnlockAccounts.qml">contents/ui/UnlockAccounts.qml</file>
<file alias="SetupPassword.qml">contents/ui/SetupPassword.qml</file>
</qresource>
</RCC>