Files
purple-electrumwallet/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
T
f321x cb023e22e4 qml: 2fa: make 2fa setup qr code clickable
This will make the 2fa app open when the user clicks on the qr code,
much more convenient than manually copy pasting the secret.
2026-03-24 14:50:45 +01:00

163 lines
5.0 KiB
QML

import QtQuick 2.6
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.1
import "../../../gui/qml/components/wizard"
import "../../../gui/qml/components/controls"
WizardComponent {
valid: otpVerified
property QtObject plugin
property bool otpVerified: false
ColumnLayout {
width: parent.width
Label {
text: qsTr('Authenticator secret')
}
InfoTextArea {
id: errorBox
Layout.fillWidth: true
iconStyle: InfoTextArea.IconStyle.Error
visible: !otpVerified && plugin.remoteKeyState == 'error'
}
InfoTextArea {
Layout.fillWidth: true
iconStyle: InfoTextArea.IconStyle.Warn
visible: plugin.remoteKeyState == 'wallet_known'
text: qsTr('This wallet is already registered with TrustedCoin. ')
+ qsTr('To finalize wallet creation, please enter your Google Authenticator Code. ')
}
QRImage {
Layout.alignment: Qt.AlignHCenter
visible: plugin.remoteKeyState == 'new' || plugin.remoteKeyState == 'reset'
qrdata: encodeURI('otpauth://totp/Electrum 2FA ' + wizard_data['wallet_name']
+ '?secret=' + plugin.otpSecret + '&digits=6')
render: plugin.otpSecret
onClicked: {
if (plugin.otpSecret) {
if (AppController.isAndroid()) {
Qt.openUrlExternally(qrdata)
} else {
AppController.textToClipboard(plugin.otpSecret)
toaster.show(this, qsTr('Copied!'))
}
}
}
}
Item {
Layout.alignment: Qt.AlignHCenter
visible: plugin.otpSecret
implicitWidth: otpSecretPane.implicitWidth
implicitHeight: otpSecretPane.implicitHeight
TextHighlightPane {
id: otpSecretPane
Label {
text: plugin.otpSecret
font.family: FixedFont
font.bold: true
}
}
MouseArea {
anchors.fill: parent
onClicked: {
AppController.textToClipboard(plugin.otpSecret)
toaster.show(otpSecretPane, qsTr('Copied!'))
}
}
}
Label {
Layout.fillWidth: true
visible: !otpVerified && plugin.otpSecret
wrapMode: Text.Wrap
text: qsTr('Tap the QR code to open in your authenticator app, or scan it manually. Then authenticate below')
}
Label {
Layout.fillWidth: true
visible: !otpVerified && plugin.remoteKeyState == 'wallet_known'
wrapMode: Text.Wrap
text: qsTr('If you still have your OTP secret, then authenticate below')
}
TextField {
id: otp_auth
visible: !otpVerified && (plugin.otpSecret || plugin.remoteKeyState == 'wallet_known')
Layout.alignment: Qt.AlignHCenter
focus: true
inputMethodHints: Qt.ImhSensitiveData | Qt.ImhDigitsOnly
validator: IntValidator {bottom: 0; top: 999999;}
font.family: FixedFont
font.pixelSize: constants.fontSizeLarge
onTextChanged: {
if (text.length >= 6) {
plugin.checkOtp(plugin.shortId, otp_auth.text)
text = ''
}
}
}
Label {
Layout.fillWidth: true
visible: !otpVerified && plugin.remoteKeyState == 'wallet_known'
wrapMode: Text.Wrap
text: qsTr('Otherwise, you can request your OTP secret from the server, by pressing the button below')
}
Button {
Layout.alignment: Qt.AlignHCenter
visible: plugin.remoteKeyState == 'wallet_known' && !otpVerified
text: qsTr('Request OTP secret')
onClicked: plugin.resetOtpSecret()
}
Image {
Layout.alignment: Qt.AlignHCenter
source: '../../../gui/icons/confirmed.png'
visible: otpVerified
Layout.preferredWidth: constants.iconSizeXLarge
Layout.preferredHeight: constants.iconSizeXLarge
}
}
BusyIndicator {
anchors.centerIn: parent
visible: plugin ? plugin.busy : false
running: visible
}
Component.onCompleted: {
plugin = AppController.plugin('trustedcoin')
plugin.createKeystore()
otp_auth.forceActiveFocus()
}
Toaster {
id: toaster
}
Connections {
target: plugin
function onOtpError(message) {
console.log('OTP verify error')
errorBox.text = message
}
function onOtpSuccess() {
console.log('OTP verify success')
otpVerified = true
}
function onRemoteKeyError(message) {
errorBox.text = message
}
}
}