fix(PasswordView): Password instructions missing max length requirement
- set the pass max length to 100 (via `Constants`, not with a hardcoded regexp) - delay the validation until the user hits the limit - clear the categories (lower/upper/num/sym) info if the password is cleared too - update the error messages according to latest Figma designs Fixes #16239
This commit is contained in:
parent
62f85acf31
commit
b052416666
|
@ -53,6 +53,7 @@ SplitView {
|
||||||
Switch {
|
Switch {
|
||||||
id: createNewPassword
|
id: createNewPassword
|
||||||
text: "Create new password"
|
text: "Create new password"
|
||||||
|
checked: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Switch {
|
Switch {
|
||||||
|
@ -63,9 +64,12 @@ SplitView {
|
||||||
Switch {
|
Switch {
|
||||||
id: titleVisibleSwitch
|
id: titleVisibleSwitch
|
||||||
text: "Title visible"
|
text: "Title visible"
|
||||||
|
checked: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// category: Views
|
// category: Views
|
||||||
|
|
||||||
|
// https://www.figma.com/design/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=41014-22302&node-type=frame&t=0JUvGJPEhU9e9QB9-0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
|
@ -42,7 +42,7 @@ StatusProgressBar {
|
||||||
id: control
|
id: control
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty string StatusPasswordStrengthIndicator::strength
|
\qmlproperty int StatusPasswordStrengthIndicator::strength
|
||||||
This property holds the password strength value. Possible values are:
|
This property holds the password strength value. Possible values are:
|
||||||
\list
|
\list
|
||||||
\li StatusPasswordStrengthIndicator.Strength.None
|
\li StatusPasswordStrengthIndicator.Strength.None
|
||||||
|
@ -53,7 +53,7 @@ StatusProgressBar {
|
||||||
\li StatusPasswordStrengthIndicator.Strength.Great
|
\li StatusPasswordStrengthIndicator.Strength.Great
|
||||||
\endlist
|
\endlist
|
||||||
*/
|
*/
|
||||||
property var strength
|
property int strength
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty string StatusPasswordStrengthIndicator::labelVeryWeak
|
\qmlproperty string StatusPasswordStrengthIndicator::labelVeryWeak
|
||||||
This property holds the text shown when the strength is StatusPasswordStrengthIndicator.Strength.VeryWeak.
|
This property holds the text shown when the strength is StatusPasswordStrengthIndicator.Strength.VeryWeak.
|
||||||
|
|
|
@ -74,7 +74,8 @@ ColumnLayout {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
placeholderText: qsTr("Confirm your password (again)")
|
placeholderText: qsTr("Confirm your password (again)")
|
||||||
echoMode: showPassword ? TextInput.Normal : TextInput.Password
|
echoMode: showPassword ? TextInput.Normal : TextInput.Password
|
||||||
validator: RegExpValidator { regExp: /^[!-~]{0,64}$/ } // That incudes NOT extended ASCII printable characters less space and a maximum of 64 characters allowed
|
validator: RegExpValidator { regExp: /^[!-~]+$/ } // That includes NOT extended ASCII printable characters less space
|
||||||
|
maximumLength: Constants.maxPasswordLength // a maximum of 100 characters allowed
|
||||||
rightPadding: showHideCurrentIcon.width + showHideCurrentIcon.anchors.rightMargin + Style.current.padding / 2
|
rightPadding: showHideCurrentIcon.width + showHideCurrentIcon.anchors.rightMargin + Style.current.padding / 2
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
errorTxt.text = ""
|
errorTxt.text = ""
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import shared.panels 1.0
|
|
||||||
import shared.controls 1.0
|
|
||||||
import shared.stores 1.0
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
|
@ -16,7 +13,8 @@ import StatusQ.Popups 0.1
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool ready: newPswInput.text.length >= Constants.minPasswordLength && newPswInput.text === confirmPswInput.text && errorTxt.text === ""
|
readonly property bool ready: newPswInput.text.length >= Constants.minPasswordLength && newPswInput.text === confirmPswInput.text && errorTxt.text === ""
|
||||||
|
|
||||||
property bool createNewPsw: true
|
property bool createNewPsw: true
|
||||||
property string title: createNewPsw ? qsTr("Create a password") : qsTr("Change your password")
|
property string title: createNewPsw ? qsTr("Create a password") : qsTr("Change your password")
|
||||||
property bool titleVisible: true
|
property bool titleVisible: true
|
||||||
|
@ -86,14 +84,15 @@ ColumnLayout {
|
||||||
property bool containsNumbers: false
|
property bool containsNumbers: false
|
||||||
property bool containsSymbols: false
|
property bool containsSymbols: false
|
||||||
|
|
||||||
readonly property var validatorRegexp: /^[!-~]{0,64}$/
|
readonly property var validatorRegexp: /^[!-~]+$/
|
||||||
readonly property string validatorErrMessage: qsTr("Only letters, numbers, underscores and hyphens allowed")
|
readonly property string validatorErrMessage: qsTr("Only ASCII letters, numbers, and symbols are allowed")
|
||||||
|
readonly property string passTooLongErrMessage: qsTr("Maximum %n character(s)", "", Constants.maxPasswordLength)
|
||||||
|
|
||||||
// Password strength categorization / validation
|
// Password strength categorization / validation
|
||||||
function lowerCaseValidator(text) { return (/[a-z]/.test(text)) }
|
function lowerCaseValidator(text) { return (/[a-z]/.test(text)) }
|
||||||
function upperCaseValidator(text) { return (/[A-Z]/.test(text)) }
|
function upperCaseValidator(text) { return (/[A-Z]/.test(text)) }
|
||||||
function numbersValidator(text) { return (/\d/.test(text)) }
|
function numbersValidator(text) { return (/\d/.test(text)) }
|
||||||
// That incudes NOT extended ASCII printable symbols less space:
|
// That includes NOT extended ASCII printable symbols less space:
|
||||||
function symbolsValidator(text) { return (/[!-\/:-@[-`{-~]/.test(text)) }
|
function symbolsValidator(text) { return (/[!-\/:-@[-`{-~]/.test(text)) }
|
||||||
|
|
||||||
function validateCharacterSet(text) {
|
function validateCharacterSet(text) {
|
||||||
|
@ -101,6 +100,10 @@ ColumnLayout {
|
||||||
errorTxt.text = d.validatorErrMessage
|
errorTxt.text = d.validatorErrMessage
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if(text.length > Constants.maxPasswordLength) {
|
||||||
|
errorTxt.text = d.passTooLongErrMessage
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -125,15 +128,15 @@ ColumnLayout {
|
||||||
// 3 rules to validate:
|
// 3 rules to validate:
|
||||||
// * Password is in pwnd passwords database
|
// * Password is in pwnd passwords database
|
||||||
if(isInPwndDatabase())
|
if(isInPwndDatabase())
|
||||||
errorTxt.text = qsTr("This password has been pwned and shouldn't be used")
|
errorTxt.text = qsTr("Password pwned, shouldn't be used")
|
||||||
|
|
||||||
// * Common password
|
// * Common password
|
||||||
else if(isCommonPassword())
|
else if(isCommonPassword())
|
||||||
errorTxt.text = qsTr("This password is a common word and shouldn't be used")
|
errorTxt.text = qsTr("Common password, shouldn't be used")
|
||||||
|
|
||||||
// * Password too short
|
// * Password too short
|
||||||
else if(isTooShort())
|
else if(isTooShort())
|
||||||
errorTxt.text = qsTr("Password must be at least %n character(s) long", "", Constants.minPasswordLength)
|
errorTxt.text = qsTr("Minimum %n character(s)", "", Constants.minPasswordLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInPwndDatabase() {
|
function isInPwndDatabase() {
|
||||||
|
@ -262,13 +265,13 @@ ColumnLayout {
|
||||||
// Update strength indicator:
|
// Update strength indicator:
|
||||||
strengthInditactor.strength = d.convertStrength(root.passwordStrengthScoreFunction(newPswInput.text))
|
strengthInditactor.strength = d.convertStrength(root.passwordStrengthScoreFunction(newPswInput.text))
|
||||||
|
|
||||||
if(!d.validateCharacterSet(text)) return
|
|
||||||
|
|
||||||
d.containsLower = d.lowerCaseValidator(text)
|
d.containsLower = d.lowerCaseValidator(text)
|
||||||
d.containsUpper = d.upperCaseValidator(text)
|
d.containsUpper = d.upperCaseValidator(text)
|
||||||
d.containsNumbers = d.numbersValidator(text)
|
d.containsNumbers = d.numbersValidator(text)
|
||||||
d.containsSymbols = d.symbolsValidator(text)
|
d.containsSymbols = d.symbolsValidator(text)
|
||||||
|
|
||||||
|
if(!d.validateCharacterSet(text)) return
|
||||||
|
|
||||||
if (text.length === confirmPswInput.text.length) {
|
if (text.length === confirmPswInput.text.length) {
|
||||||
root.checkPasswordMatches(false)
|
root.checkPasswordMatches(false)
|
||||||
}
|
}
|
||||||
|
@ -306,7 +309,6 @@ ColumnLayout {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.minimumHeight: 80
|
Layout.minimumHeight: 80
|
||||||
border.color: Theme.palette.baseColor2
|
border.color: Theme.palette.baseColor2
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
|
@ -1046,6 +1046,7 @@ QtObject {
|
||||||
readonly property string wrongDerivationPathError: "error parsing derivation path"
|
readonly property string wrongDerivationPathError: "error parsing derivation path"
|
||||||
|
|
||||||
readonly property int minPasswordLength: 10
|
readonly property int minPasswordLength: 10
|
||||||
|
readonly property int maxPasswordLength: 100
|
||||||
|
|
||||||
readonly property QtObject suggestedRoutesExtraParamsProperties: QtObject {
|
readonly property QtObject suggestedRoutesExtraParamsProperties: QtObject {
|
||||||
readonly property string packId: "packID"
|
readonly property string packId: "packID"
|
||||||
|
|
Loading…
Reference in New Issue