1
0

Merge pull request #10426 from f321x/qml_preferences_section

qml: restructure preferences, security improvements
This commit is contained in:
ThomasV
2026-01-21 11:04:27 +01:00
committed by GitHub
4 changed files with 112 additions and 90 deletions

View File

@@ -346,4 +346,10 @@ Pane {
dialog.open()
}
}
Binding {
target: AppController
property: 'secureWindow'
value: Boolean(addressdetails.privkey)
}
}

View File

@@ -157,6 +157,93 @@ Pane {
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
Switch {
id: syncLabels
onCheckedChanged: {
if (activeFocus)
AppController.setPluginEnabled('labels', checked)
}
}
Label {
Layout.fillWidth: true
text: qsTr('Synchronize labels')
wrapMode: Text.Wrap
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
Switch {
id: psbtNostr
onCheckedChanged: {
if (activeFocus)
AppController.setPluginEnabled('psbt_nostr', checked)
}
}
Label {
Layout.fillWidth: true
text: qsTr('Nostr Cosigner')
wrapMode: Text.Wrap
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
enabled: AppController.isAndroid()
Switch {
id: setMaxBrightnessOnQrDisplay
onCheckedChanged: {
if (activeFocus)
Config.setMaxBrightnessOnQrDisplay = checked
}
}
Label {
Layout.fillWidth: true
text: qsTr('Increase brightness when displaying QR codes')
wrapMode: Text.Wrap
}
}
PrefsHeading {
Layout.columnSpan: 2
text: qsTr('Security')
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
property bool noWalletPassword: Daemon.currentWallet ? Daemon.currentWallet.verifyPassword('') : true
enabled: Daemon.currentWallet && !noWalletPassword
Switch {
id: paymentAuthentication
// showing the toggle as checked even if the wallet has no password would be misleading
checked: Config.paymentAuthentication && !(Daemon.currentWallet && parent.noWalletPassword)
onCheckedChanged: {
if (activeFocus) {
// will request authentication when checked = false
console.log('paymentAuthentication: ' + checked)
Config.paymentAuthentication = checked;
}
}
}
Label {
Layout.fillWidth: true
text: qsTr('Request authentication for payments')
wrapMode: Text.Wrap
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
@@ -214,79 +301,17 @@ Pane {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
property bool noWalletPassword: Daemon.currentWallet ? Daemon.currentWallet.verifyPassword('') : true
enabled: Daemon.currentWallet && !noWalletPassword
enabled: AppController.isAndroid()
Switch {
id: paymentAuthentication
// showing the toggle as checked even if the wallet has no password would be misleading
checked: Config.paymentAuthentication && !(Daemon.currentWallet && parent.noWalletPassword)
onCheckedChanged: {
if (activeFocus) {
// will request authentication when checked = false
console.log('paymentAuthentication: ' + checked)
Config.paymentAuthentication = checked;
}
}
}
Label {
Layout.fillWidth: true
text: qsTr('Payment authentication')
wrapMode: Text.Wrap
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
Switch {
id: syncLabels
id: disableScreenshots
onCheckedChanged: {
if (activeFocus)
AppController.setPluginEnabled('labels', checked)
Config.alwaysAllowScreenshots = !checked
}
}
Label {
Layout.fillWidth: true
text: qsTr('Synchronize labels')
wrapMode: Text.Wrap
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
Switch {
id: psbtNostr
onCheckedChanged: {
if (activeFocus)
AppController.setPluginEnabled('psbt_nostr', checked)
}
}
Label {
Layout.fillWidth: true
text: qsTr('Nostr Cosigner')
wrapMode: Text.Wrap
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
Switch {
id: setMaxBrightnessOnQrDisplay
onCheckedChanged: {
if (activeFocus)
Config.setMaxBrightnessOnQrDisplay = checked
}
}
Label {
Layout.fillWidth: true
text: qsTr('Set display to max brightness when displaying QR codes')
text: qsTr('Protect secrets from screenshots')
wrapMode: Text.Wrap
}
}
@@ -463,24 +488,6 @@ Pane {
wrapMode: Text.Wrap
}
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
spacing: 0
Switch {
id: alwaysAllowScreenshots
onCheckedChanged: {
if (activeFocus)
Config.alwaysAllowScreenshots = checked
}
}
Label {
Layout.fillWidth: true
text: qsTr('Always allow screenshots')
wrapMode: Text.Wrap
}
}
}
}
}
@@ -498,8 +505,8 @@ Pane {
freezeReusedAddressUtxos.checked = Config.freezeReusedAddressUtxos
useTrampolineRouting.checked = !Config.useGossip
enableDebugLogs.checked = Config.enableDebugLogs
alwaysAllowScreenshots.checked = Config.alwaysAllowScreenshots
setMaxBrightnessOnQrDisplay.checked = Config.setMaxBrightnessOnQrDisplay
disableScreenshots.checked = !Config.alwaysAllowScreenshots && AppController.isAndroid()
setMaxBrightnessOnQrDisplay.checked = Config.setMaxBrightnessOnQrDisplay && AppController.isAndroid()
useRecoverableChannels.checked = Config.useRecoverableChannels
syncLabels.checked = AppController.isPluginEnabled('labels')
psbtNostr.checked = AppController.isPluginEnabled('psbt_nostr')

View File

@@ -189,8 +189,8 @@ ElDialog {
enabled: _addressMine
icon.source: '../../icons/seal.png'
onClicked: {
var sig = Daemon.currentWallet.signMessage(addressField.text, plaintext.text)
signature.text = sig
Daemon.currentWallet.signMessage(addressField.text, plaintext.text)
// emits messageSigned(sig)
}
}
FlatButton {
@@ -207,7 +207,13 @@ ElDialog {
}
}
}
}
Connections {
target: Daemon.currentWallet
function onMessageSigned(sig) {
signature.text = sig
}
}
Component.onCompleted: {

View File

@@ -78,6 +78,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
otpFailed = pyqtSignal([str, str], arguments=['code', 'message'])
peersUpdated = pyqtSignal()
seedRetrieved = pyqtSignal()
messageSigned = pyqtSignal([str], arguments=['signature'])
_network_signal = pyqtSignal(str, object)
@@ -848,10 +849,12 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
def isAddressMine(self, addr):
return self.wallet.is_mine(addr)
@pyqtSlot(str, str, result=str)
@pyqtSlot(str, str)
@auth_protect(message=_("Sign message?"))
def signMessage(self, address, message):
sig = self.wallet.sign_message(address, message, self.password)
return base64.b64encode(sig).decode('ascii')
result = base64.b64encode(sig).decode('ascii')
self.messageSigned.emit(result)
def determine_max(self, *, mktx: Callable[[FeePolicy], PartialTransaction]) -> Tuple[Optional[int], Optional[str]]:
# TODO: merge with SendTab.spend_max() and move to backend wallet