feat: add validation to private key and watchonly modal
This commit is contained in:
parent
ad2a318c85
commit
300caf22a2
|
@ -9,6 +9,35 @@ ModalPopup {
|
||||||
|
|
||||||
property int marginBetweenInputs: 38
|
property int marginBetweenInputs: 38
|
||||||
property string selectedColor: Constants.accountColors[0]
|
property string selectedColor: Constants.accountColors[0]
|
||||||
|
property string passwordValidationError: ""
|
||||||
|
property string privateKeyValidationError: ""
|
||||||
|
property string accountNameValidationError: ""
|
||||||
|
|
||||||
|
function validate() {
|
||||||
|
if (passwordInput.text === "") {
|
||||||
|
passwordValidationError = qsTr("You need to enter a password")
|
||||||
|
} else if (passwordInput.text.length < 4) {
|
||||||
|
passwordValidationError = qsTr("Password needs to be 4 characters or more")
|
||||||
|
} else {
|
||||||
|
passwordValidationError = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accountNameInput.text === "") {
|
||||||
|
accountNameValidationError = qsTr("You need to enter an account name")
|
||||||
|
} else {
|
||||||
|
accountNameValidationError = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accountPKeyInput.text === "") {
|
||||||
|
privateKeyValidationError = qsTr("You need to enter a private key")
|
||||||
|
} else if (!Utils.isPrivateKey(accountPKeyInput.text)) {
|
||||||
|
privateKeyValidationError = qsTr("Enter a valid private key (64 characters hexadecimal string)")
|
||||||
|
} else {
|
||||||
|
privateKeyValidationError = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return passwordValidationError === "" && privateKeyValidationError === "" && accountNameValidationError === ""
|
||||||
|
}
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
passwordInput.text = ""
|
passwordInput.text = ""
|
||||||
|
@ -20,6 +49,7 @@ ModalPopup {
|
||||||
placeholderText: qsTr("Enter your password…")
|
placeholderText: qsTr("Enter your password…")
|
||||||
label: qsTr("Password")
|
label: qsTr("Password")
|
||||||
textField.echoMode: TextInput.Password
|
textField.echoMode: TextInput.Password
|
||||||
|
validationError: popup.passwordValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +60,7 @@ ModalPopup {
|
||||||
placeholderText: qsTr("Paste the contents of your private key")
|
placeholderText: qsTr("Paste the contents of your private key")
|
||||||
label: qsTr("Private key")
|
label: qsTr("Private key")
|
||||||
customHeight: 88
|
customHeight: 88
|
||||||
|
validationError: popup.privateKeyValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
Input {
|
Input {
|
||||||
|
@ -38,6 +69,7 @@ ModalPopup {
|
||||||
anchors.topMargin: marginBetweenInputs
|
anchors.topMargin: marginBetweenInputs
|
||||||
placeholderText: qsTr("Enter an account name...")
|
placeholderText: qsTr("Enter an account name...")
|
||||||
label: qsTr("Account name")
|
label: qsTr("Account name")
|
||||||
|
validationError: popup.accountNameValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
Select {
|
Select {
|
||||||
|
@ -60,16 +92,16 @@ ModalPopup {
|
||||||
|
|
||||||
footer: StyledButton {
|
footer: StyledButton {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: Theme.padding
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Theme.padding
|
anchors.rightMargin: Theme.padding
|
||||||
label: qsTr("Add account >")
|
label: qsTr("Add account >")
|
||||||
|
|
||||||
disabled: passwordInput.text === "" || accountNameInput.text === "" || accountPKeyInput.textAreaText === ""
|
disabled: passwordInput.text === "" || accountNameInput.text === "" || accountPKeyInput.text === ""
|
||||||
|
|
||||||
onClicked : {
|
onClicked : {
|
||||||
// TODO add message to show validation errors
|
if (!validate()) {
|
||||||
if (passwordInput.text === "" || accountNameInput.text === "" || accountPKeyInput.textAreaText === "") return;
|
return
|
||||||
|
}
|
||||||
|
|
||||||
walletModel.addAccountsFromPrivateKey(accountPKeyInput.text, passwordInput.text, accountNameInput.text, selectedColor)
|
walletModel.addAccountsFromPrivateKey(accountPKeyInput.text, passwordInput.text, accountNameInput.text, selectedColor)
|
||||||
// TODO manage errors adding account
|
// TODO manage errors adding account
|
||||||
|
|
|
@ -8,6 +8,26 @@ ModalPopup {
|
||||||
|
|
||||||
property int marginBetweenInputs: 38
|
property int marginBetweenInputs: 38
|
||||||
property string selectedColor: Constants.accountColors[0]
|
property string selectedColor: Constants.accountColors[0]
|
||||||
|
property string addressError: ""
|
||||||
|
property string accountNameValidationError: ""
|
||||||
|
|
||||||
|
function validate() {
|
||||||
|
if (addressInput.text === "") {
|
||||||
|
addressError = qsTr("You need to enter an address")
|
||||||
|
} else if (!Utils.isAddress(addressInput.text)) {
|
||||||
|
addressError = qsTr("This needs to be a valid address (starting with 0x)")
|
||||||
|
} else {
|
||||||
|
addressError = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accountNameInput.text === "") {
|
||||||
|
accountNameValidationError = qsTr("You need to enter an account name")
|
||||||
|
} else {
|
||||||
|
accountNameValidationError = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return addressError === "" && accountNameValidationError === ""
|
||||||
|
}
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
addressInput.text = "";
|
addressInput.text = "";
|
||||||
|
@ -19,6 +39,7 @@ ModalPopup {
|
||||||
// TODO add QR code reader for the address
|
// TODO add QR code reader for the address
|
||||||
placeholderText: qsTr("Enter address...")
|
placeholderText: qsTr("Enter address...")
|
||||||
label: qsTr("Account address")
|
label: qsTr("Account address")
|
||||||
|
validationError: popup.addressError
|
||||||
}
|
}
|
||||||
|
|
||||||
Input {
|
Input {
|
||||||
|
@ -27,6 +48,7 @@ ModalPopup {
|
||||||
anchors.topMargin: marginBetweenInputs
|
anchors.topMargin: marginBetweenInputs
|
||||||
placeholderText: qsTr("Enter an account name...")
|
placeholderText: qsTr("Enter an account name...")
|
||||||
label: qsTr("Account name")
|
label: qsTr("Account name")
|
||||||
|
validationError: popup.accountNameValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
Select {
|
Select {
|
||||||
|
@ -49,7 +71,6 @@ ModalPopup {
|
||||||
|
|
||||||
footer: StyledButton {
|
footer: StyledButton {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: Theme.padding
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Theme.padding
|
anchors.rightMargin: Theme.padding
|
||||||
label: "Add account >"
|
label: "Add account >"
|
||||||
|
@ -57,8 +78,10 @@ ModalPopup {
|
||||||
disabled: addressInput.text === "" || accountNameInput.text === ""
|
disabled: addressInput.text === "" || accountNameInput.text === ""
|
||||||
|
|
||||||
onClicked : {
|
onClicked : {
|
||||||
// TODO add message to show validation errors
|
if (!validate()) {
|
||||||
if (addressInput.text === "" || accountNameInput.text === "") return;
|
return
|
||||||
|
}
|
||||||
|
|
||||||
walletModel.addWatchOnlyAccount(addressInput.text, accountNameInput.text, selectedColor);
|
walletModel.addWatchOnlyAccount(addressInput.text, accountNameInput.text, selectedColor);
|
||||||
// TODO manage errors adding account
|
// TODO manage errors adding account
|
||||||
popup.close();
|
popup.close();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import QtQuick 2.13
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
function isHex(value) {
|
function isHex(value) {
|
||||||
return /^[0-9a-f]*$/i.test(value)
|
return /^(-0x|0x)?[0-9a-f]*$/i.test(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function startsWith0x(value) {
|
function startsWith0x(value) {
|
||||||
|
@ -14,4 +14,13 @@ QtObject {
|
||||||
function isChatKey(value) {
|
function isChatKey(value) {
|
||||||
return startsWith0x(value) && isHex(value) && value.length === 132
|
return startsWith0x(value) && isHex(value) && value.length === 132
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isAddress(value) {
|
||||||
|
return startsWith0x(value) && isHex(value) && value.length === 42
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPrivateKey(value) {
|
||||||
|
return isHex(value) && ((startsWith0x(value) && value.length === 66) ||
|
||||||
|
(!startsWith0x(value) && value.length === 64))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ Item {
|
||||||
property alias textField: textArea
|
property alias textField: textArea
|
||||||
property string placeholderText: "My placeholder"
|
property string placeholderText: "My placeholder"
|
||||||
property alias text: textArea.text
|
property alias text: textArea.text
|
||||||
|
property string validationError: ""
|
||||||
// property string label: "My Label"
|
// property string label: "My Label"
|
||||||
property string label: ""
|
property string label: ""
|
||||||
readonly property bool hasLabel: label !== ""
|
readonly property bool hasLabel: label !== ""
|
||||||
|
@ -19,7 +20,7 @@ Item {
|
||||||
property int customHeight: 44
|
property int customHeight: 44
|
||||||
|
|
||||||
id: inputBox
|
id: inputBox
|
||||||
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0)
|
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0) + (!!validationError ? validationErrorText.height : 0)
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
||||||
|
@ -44,6 +45,8 @@ Item {
|
||||||
anchors.topMargin: inputBox.hasLabel ? inputBox.labelMargin : 0
|
anchors.topMargin: inputBox.hasLabel ? inputBox.labelMargin : 0
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
border.width: !!validationError ? 1 : 0
|
||||||
|
border.color: Theme.red
|
||||||
|
|
||||||
TextArea {
|
TextArea {
|
||||||
id: textArea
|
id: textArea
|
||||||
|
@ -58,14 +61,27 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
font.family: Theme.fontRegular.name
|
font.family: Theme.fontRegular.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
textArea.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
TextEdit {
|
||||||
id: mouseArea
|
visible: !!validationError
|
||||||
anchors.fill: parent
|
id: validationErrorText
|
||||||
onClicked: {
|
text: validationError
|
||||||
textArea.forceActiveFocus(Qt.MouseFocusReason)
|
anchors.top: inputRectangle.bottom
|
||||||
}
|
anchors.topMargin: 1
|
||||||
|
selectByMouse: true
|
||||||
|
readOnly: true
|
||||||
|
font.pixelSize: 12
|
||||||
|
color: Theme.red
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue