From 354a2ae9fe0685c41c80c18812ab9b41d4e2c0f7 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 20 Jun 2019 22:35:19 +0200 Subject: [PATCH] Improve login page --- libnymea-app-core/jsonrpc/jsonrpcclient.cpp | 3 +- nymea-app/resources.qrc | 2 +- nymea-app/ui/appsettings/CloudLoginPage.qml | 4 +- ...ordTextField.qml => PasswordTextField.qml} | 18 +++++--- nymea-app/ui/connection/LoginPage.qml | 42 +++++-------------- 5 files changed, 28 insertions(+), 41 deletions(-) rename nymea-app/ui/components/{AWSPasswordTextField.qml => PasswordTextField.qml} (79%) diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp index 92e62dac..d511f190 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp @@ -218,6 +218,7 @@ int JsonRpcClient::authenticate(const QString &username, const QString &password params.insert("username", username); params.insert("password", password); params.insert("deviceName", deviceName); + qDebug() << "Authenticating:" << username << password << deviceName; JsonRpcReply* reply = createReply("JSONRPC.Authenticate", params, this, "processAuthenticate"); m_replies.insert(reply->commandId(), reply); m_connection->sendData(QJsonDocument::fromVariant(reply->requestMap()).toJson()); @@ -262,7 +263,7 @@ void JsonRpcClient::processAuthenticate(const QVariantMap &data) setNotificationsEnabled(true); } else { - qWarning() << "Authentication failed"; + qWarning() << "Authentication failed" << data; emit authenticationFailed(); } } diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index c37e432e..bb025d3a 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -41,7 +41,7 @@ ui/components/MainPageTile.qml ui/components/BusyOverlay.qml ui/components/SwipeDelegateGroup.qml - ui/components/AWSPasswordTextField.qml + ui/components/PasswordTextField.qml ui/components/BrightnessSlider.qml ui/components/SegmentedImage.qml ui/components/SegmentRenderer.qml diff --git a/nymea-app/ui/appsettings/CloudLoginPage.qml b/nymea-app/ui/appsettings/CloudLoginPage.qml index a4390f85..5bf12262 100644 --- a/nymea-app/ui/appsettings/CloudLoginPage.qml +++ b/nymea-app/ui/appsettings/CloudLoginPage.qml @@ -324,7 +324,7 @@ Page { Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.topMargin: app.margins text: qsTr("Password") } - AWSPasswordTextField { + PasswordTextField { id: passwordTextField Layout.leftMargin: app.margins; Layout.rightMargin: app.margins Layout.fillWidth: true @@ -564,7 +564,7 @@ Page { text: qsTr("Pick a new password:") } - AWSPasswordTextField { + PasswordTextField { id: passwordTextField Layout.fillWidth: true; Layout.leftMargin: app.margins; Layout.rightMargin: app.margins } diff --git a/nymea-app/ui/components/AWSPasswordTextField.qml b/nymea-app/ui/components/PasswordTextField.qml similarity index 79% rename from nymea-app/ui/components/AWSPasswordTextField.qml rename to nymea-app/ui/components/PasswordTextField.qml index 30fc9501..9822a037 100644 --- a/nymea-app/ui/components/AWSPasswordTextField.qml +++ b/nymea-app/ui/components/PasswordTextField.qml @@ -5,26 +5,30 @@ import QtQuick.Layouts 1.2 ColumnLayout { id: root + property int minPasswordLength: 12 + property bool signup: true + readonly property alias password: passwordTextField.text - readonly property bool isValidPassword: isLongEnough && hasLower && hasUpper && hasNumbers && hasSpecialChar && confirmationMatches + readonly property bool isValidPassword: isLongEnough && hasLower && hasUpper && hasNumbers && hasSpecialChar && (confirmationMatches || !signup) - readonly property bool isLongEnough: passwordTextField.text.length >= 12 + readonly property bool isLongEnough: passwordTextField.text.length >= minPasswordLength readonly property bool hasLower: passwordTextField.text.search(/[a-z]/) >= 0 readonly property bool hasUpper: passwordTextField.text.search(/[A-Z/]/) >= 0 readonly property bool hasNumbers: passwordTextField.text.search(/[0-9]/) >= 0 - readonly property bool hasSpecialChar: passwordTextField.text.search(/[\*!"$%&/()=?`'+#'¡^°²³¼\[\]|{}\\@]/) >= 0 + readonly property bool hasSpecialChar: passwordTextField.text.search(/[\.,\*!"$%&/()=?`'+#'¡^°²³¼\[\]|{}\\@]/) >= 0 readonly property bool confirmationMatches: passwordTextField.text === confirmationPasswordTextField.text property bool hiddenPassword: true RowLayout { + Layout.fillWidth: true TextField { id: passwordTextField Layout.fillWidth: true echoMode: root.hiddenPassword ? TextInput.Password : TextInput.Normal - placeholderText: qsTr("Pick a password") + placeholderText: root.signup ? qsTr("Pick a password") : "" } ColorIcon { Layout.preferredHeight: app.iconSize @@ -44,11 +48,13 @@ ColumnLayout { Label { Layout.fillWidth: true wrapMode: Text.WordWrap + visible: root.signup // TRANSLATORS: %1 will be replaced with the normal text color, %2 the color for the length check - text: qsTr("The password needs to be at least 12 characters long, contain lowercase, uppercase letters as well as numbers and special characters.") + text: qsTr("The password needs to be at least %3 characters long, contain lowercase, uppercase letters as well as numbers and special characters.") .arg(app.accentColor) .arg(!root.isLongEnough ? "red" : app.accentColor) + .arg(root.minPasswordLength) .arg(!root.hasLower ? "red" : app.accentColor) .arg(!root.hasUpper ? "red" : app.accentColor) .arg(!root.hasNumbers ? "red" : app.accentColor) @@ -57,6 +63,7 @@ ColumnLayout { } RowLayout { + visible: root.signup TextField { id: confirmationPasswordTextField @@ -83,6 +90,7 @@ ColumnLayout { Label { Layout.fillWidth: true wrapMode: Text.WordWrap + visible: root.signup text: root.confirmationMatches ? qsTr("The passwords match.").arg(app.accentColor) : qsTr("The passwords do not match.").arg(app.accentColor).arg("red") font.pixelSize: app.smallFont diff --git a/nymea-app/ui/connection/LoginPage.qml b/nymea-app/ui/connection/LoginPage.qml index 9c761b6f..08c3ec07 100644 --- a/nymea-app/ui/connection/LoginPage.qml +++ b/nymea-app/ui/connection/LoginPage.qml @@ -23,7 +23,7 @@ Page { popup.open(); } onCreateUserSucceeded: { - engine.jsonRpcClient.authenticate(usernameTextField.text, passwordTextField.text, "nymea-app"); + engine.jsonRpcClient.authenticate(usernameTextField.text, passwordTextField.password, "nymea-app"); } onCreateUserFailed: { @@ -82,11 +82,13 @@ Page { GridLayout { Layout.fillWidth: true Layout.leftMargin: app.margins; Layout.rightMargin: app.margins - columns: app.width > 400 ? 2 : 1 + columns: app.width > 500 ? 2 : 1 + columnSpacing: app.margins Label { text: qsTr("Your e-mail address:") Layout.fillWidth: true + Layout.minimumWidth: implicitWidth } TextField { id: usernameTextField @@ -98,50 +100,26 @@ Page { Layout.fillWidth: true text: qsTr("Password:") } - TextField { + PasswordTextField { id: passwordTextField Layout.fillWidth: true - echoMode: TextInput.Password + minPasswordLength: 8 + signup: engine.jsonRpcClient.initialSetupRequired } - - Label { - visible: engine.jsonRpcClient.initialSetupRequired - Layout.fillWidth: true - text: qsTr("Confirm password:") - } - TextField { - id: confirmPasswordTextField - visible: engine.jsonRpcClient.initialSetupRequired - Layout.fillWidth: true - echoMode: TextInput.Password - } - } - - Label { - Layout.fillWidth: true - Layout.leftMargin: app.margins; Layout.rightMargin: app.margins - visible: engine.jsonRpcClient.initialSetupRequired - opacity: (passwordTextField.text.length > 0 && passwordTextField.text.length < 8) || passwordTextField.text != confirmPasswordTextField.text ? 1 : 0 - text: passwordTextField.text.length < 8 ? qsTr("This password isn't long enought to be secure, add some more characters please.") - : qsTr("The passwords don't match.") - wrapMode: Text.WordWrap - color: app.accentColor - font.pixelSize: app.smallFont } Button { Layout.fillWidth: true Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins text: qsTr("OK") - enabled: usernameTextField.text.length >= 5 && passwordTextField.text.length >= 8 - && (!engine.jsonRpcClient.initialSetupRequired || confirmPasswordTextField.text == passwordTextField.text) + enabled: passwordTextField.isValidPassword onClicked: { if (engine.jsonRpcClient.initialSetupRequired) { print("create user") - engine.jsonRpcClient.createUser(usernameTextField.text, passwordTextField.text); + engine.jsonRpcClient.createUser(usernameTextField.text, passwordTextField.password); } else { print("authenticate", usernameTextField.text, passwordTextField.text, "nymea-app") - engine.jsonRpcClient.authenticate(usernameTextField.text, passwordTextField.text, "nymea-app"); + engine.jsonRpcClient.authenticate(usernameTextField.text, passwordTextField.password, "nymea-app"); } } }