qml: 2fa: make it possible to copy 2fa secret
What changed, and why it matters
This commit changes the Electrum mobile/QML wallet's two-factor authentication (2FA) setup screen so that users can tap the displayed 2FA secret to copy it to the clipboard. Previously the secret had to be written down manually. The change is a straightforward usability improvement and does not appear to be a security fix.
No security action required. If desired, the project could document that copying 2FA secrets to the clipboard may leave them briefly exposed to other apps, but this is a known UX/security trade-off and not a defect introduced by this commit.
Security signals we found
No security-relevant signals detected in the diff or commit message.
Change is described as a usability improvement ('very inconveniant' typo in message).
Clipboard access is user-initiated via onClicked, not automatic or hidden.
Evidence from the diff
In electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml, the TextHighlightPane showing plugin.otpSecret is wrapped in an Item with a MouseArea overlay. onClicked calls AppController.textToClipboard(plugin.otpSecret) and shows a ‘Copied!’ toast. A Toaster component is added to the page. This exposes the OTP secret to the system clipboard on user action, which is a UX trade-off rather than a vulnerability.
Changed components
electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qmlInspect captured patch +21 / −5
diff --git a/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml b/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
index 778b3dd..b99ab97 100644
--- a/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
+++ b/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
@@ -42,13 +42,25 @@ WizardComponent {
render: plugin.otpSecret
}
- TextHighlightPane {
+ Item {
Layout.alignment: Qt.AlignHCenter
visible: plugin.otpSecret
- Label {
- text: plugin.otpSecret
- font.family: FixedFont
- font.bold: true
+ 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!'))
+ }
}
}
@@ -118,6 +130,10 @@ WizardComponent {
otp_auth.forceActiveFocus()
}
+ Toaster {
+ id: toaster
+ }
+
Connections {
target: plugin
function onOtpError(message) {
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.