From 44ce2bf3d92b86f03496dc9603577ca0be0a3381 Mon Sep 17 00:00:00 2001 From: piotrpdev Date: Tue, 7 Nov 2023 18:25:09 +0000 Subject: [PATCH 1/2] fix: migrate pre-commit config --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ce035860..84e74fb2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,4 @@ +repos: - repo: local hooks: - id: qmllint From 7b419c74d62c9d557287440d9e658b059abd4eae Mon Sep 17 00:00:00 2001 From: piotrpdev Date: Tue, 7 Nov 2023 18:25:41 +0000 Subject: [PATCH 2/2] feat: add keyboard layout option --- ykman-gui/qml/OtpStaticPasswordView.qml | 69 +++++++++++++++++-------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/ykman-gui/qml/OtpStaticPasswordView.qml b/ykman-gui/qml/OtpStaticPasswordView.qml index ef2a63f5..9fe24f8a 100644 --- a/ykman-gui/qml/OtpStaticPasswordView.qml +++ b/ykman-gui/qml/OtpStaticPasswordView.qml @@ -6,7 +6,8 @@ import QtQuick.Controls.Material 2.2 ColumnLayout { - property string keyboardLayout: allowNonModhex.checked ? 'US' : 'MODHEX' + property string keyboardLayoutName: "MODHEX" + property RegExpValidator keyboardLayoutValidator: modHexValidator function finish() { if (views.selectedSlotConfigured()) { @@ -18,7 +19,7 @@ ColumnLayout { function programStaticPassword() { yubiKey.programStaticPassword(views.selectedSlot, passwordInput.text, - keyboardLayout, function (resp) { + keyboardLayoutName, function (resp) { if (resp.success) { views.otp() snackbarSuccess.show( @@ -35,7 +36,7 @@ ColumnLayout { } function generatePassword() { - yubiKey.generateStaticPw(keyboardLayout, function (resp) { + yubiKey.generateStaticPw(keyboardLayoutName, function (resp) { if (resp.success) { passwordInput.text = resp.password } else { @@ -44,15 +45,17 @@ ColumnLayout { }) } - RegExpValidator { - id: modHexValidator - regExp: /[cbdefghijklnrtuvCBDEFGHIJKLMNRTUV]{1,38}$/ - } - - RegExpValidator { - id: usLayoutValidator - regExp: /[ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#\$%&'\\`\(\)\*\+,-\.\/:;<=>\?@\[\]\^_{}\|~]{1,38}$/ - } + // Update these if the ykman scancodes change: https://github.com/Yubico/yubikey-manager/tree/51a7ae438c923189788a1e31d3de18d452131942/ykman/scancodes + RegExpValidator { id: modHexValidator; regExp: /[bcdefghijklnrtuvBCDEFGHIJKLNRTUV]{1,38}$/ } + RegExpValidator { id: usLayoutValidator; regExp: /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"\#\$%\&'`\(\)\*\+,\-\.\/:;<=>\?@\[\\\]\^_\{\}\|\~\ ]{1,38}$/ } + RegExpValidator { id: ukLayoutValidator; regExp: /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@£\$%\&'`\(\)\*\+,\-\.\/:;<=>\?"\[\#\]\^_\{\}\~¬\ ]{1,38}$/ } + RegExpValidator { id: deLayoutValidator; regExp: /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"\#\$%\&'\(\)\*\+,\-\.\/:;<=>\?\^_\ `§´ÄÖÜßäöü]{1,38}$/ } + // U+007F : DELETE [DEL] ("") is here because neither \x{007F} nor \u007F worked + RegExpValidator { id: frLayoutValidator; regExp: /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\ !"\$%\&'\(\)\*\+,\-\.\/:;<=_£§°²µàçèéù]{1,38}$/ } + RegExpValidator { id: itLayoutValidator; regExp: /[\ !"\#\$%\&'\(\)\*\+,\-\.\/0123456789:;<=>\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\\^_`abcdefghijklmnopqrstuvwxyz\|£§°çèéàìòù]{1,38}$/ } + // U+00A0 : NO-BREAK SPACE [NBSP] (" ") is here because neither \x{00A0} nor \u00A0 worked + RegExpValidator { id: bepoLayoutValidator; regExp: /[\ !"\#\$%'\(\)\*\+,\-\.\/0123456789:;=\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ`abcdefghijklmnopqrstuvwxyz «°»ÀÇÈÉÊàçèéê]{1,38}$/ } + RegExpValidator { id: normanLayoutValidator; regExp: /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"\#\$%\&'`\(\)\*\+,\-\.\/:;<=>\?@\[\\\]\^_\{\}\|\~\ ]{1,38}$/ } CustomContentColumn { @@ -71,7 +74,7 @@ ColumnLayout { CustomTextField { id: passwordInput Layout.fillWidth: true - validator: allowNonModhex.checked ? usLayoutValidator : modHexValidator + validator: keyboardLayoutValidator } CustomButton { id: generatePasswordBtn @@ -80,15 +83,37 @@ ColumnLayout { toolTipText: qsTr("Generate a random password") } } - CheckBox { - id: allowNonModhex - text: qsTr("Allow any character") - onCheckedChanged: passwordInput.text = "" - font.pixelSize: constants.h3 - Material.foreground: yubicoBlue - ToolTip.delay: 1000 - ToolTip.visible: hovered - ToolTip.text: qsTr("By default only modhex characters are allowed, enable this option to allow any (US Layout) characters") + + RowLayout { + spacing: 15 + Label { + text: qsTr("Keyboard Layout") + font.pixelSize: constants.h3 + color: yubicoBlue + } + ComboBox { + textRole: "text" + valueRole: "value" + currentIndex: 0 + model: ListModel { + // https://stackoverflow.com/a/33161093/19020549 + Component.onCompleted: { + append({"text": "MODHEX", value: modHexValidator}); + append({"text": "US", value: usLayoutValidator}); + append({"text": "UK", value: ukLayoutValidator}); + append({"text": "DE", value: deLayoutValidator}); + append({"text": "FR", value: frLayoutValidator}); + append({"text": "IT", value: itLayoutValidator}); + append({"text": "BEPO", value: bepoLayoutValidator}); + append({"text": "NORMAN", value: normanLayoutValidator}); + } + } + onActivated: { + keyboardLayoutName = currentText + keyboardLayoutValidator = currentValue + passwordInput.text = "" + } + } } ButtonsBar {