From 44cfc20e2b400c3be6642da9d49873d91c01e4a8 Mon Sep 17 00:00:00 2001 From: Juzu-O Date: Sun, 10 Aug 2025 05:36:51 +0300 Subject: [PATCH] Add more granular Auto-Type confirmation settings (#12370) This new setting gives users more control and safety: * When Auto-Type is invoked globally (e.g., via a system-wide hotkey), the confirmation popup will always appear, letting the user confirm which credentials will be auto-typed. * When Auto-Type is invoked from within KeePassXC's main window, the confirmation step can be skipped, since the user already can visually confirm which entry is being auto-typed. This balances usability and security, reducing friction for intended actions while providing an extra safeguard for potentially ambiguous global Auto-Type triggers. --------- Co-authored-by: Jonathan White --- share/translations/keepassxc_en.ts | 4 +++ src/core/Config.cpp | 1 + src/core/Config.h | 1 + src/gui/ApplicationSettingsWidget.cpp | 12 +++++++ src/gui/ApplicationSettingsWidget.h | 1 + src/gui/ApplicationSettingsWidgetGeneral.ui | 36 +++++++++++++++++++++ src/gui/DatabaseWidget.cpp | 18 +++++++---- 7 files changed, 67 insertions(+), 6 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 49f998167..e0007af7c 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -565,6 +565,10 @@ Font size selection + + Skip confirmation for main window Auto-Type actions + + recent files diff --git a/src/core/Config.cpp b/src/core/Config.cpp index c9b3b926e..51b325658 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -147,6 +147,7 @@ static const QHash configStrings = { {Config::Security_HidePasswordPreviewPanel, {QS("Security/HidePasswordPreviewPanel"), Roaming, true}}, {Config::Security_HideTotpPreviewPanel, {QS("Security/HideTotpPreviewPanel"), Roaming, false}}, {Config::Security_AutoTypeAsk, {QS("Security/AutotypeAsk"), Roaming, true}}, + {Config::Security_AutoTypeSkipMainWindowConfirmation, {QS("Security/AutoTypeSkipMainWindowConfirmation"), Roaming, false}}, {Config::Security_IconDownloadFallback, {QS("Security/IconDownloadFallback"), Roaming, false}}, {Config::Security_NoConfirmMoveEntryToRecycleBin,{QS("Security/NoConfirmMoveEntryToRecycleBin"), Roaming, true}}, {Config::Security_EnableCopyOnDoubleClick,{QS("Security/EnableCopyOnDoubleClick"), Roaming, false}}, diff --git a/src/core/Config.h b/src/core/Config.h index 54420c63c..62071b380 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -128,6 +128,7 @@ public: Security_HidePasswordPreviewPanel, Security_HideTotpPreviewPanel, Security_AutoTypeAsk, + Security_AutoTypeSkipMainWindowConfirmation, Security_IconDownloadFallback, Security_NoConfirmMoveEntryToRecycleBin, Security_EnableCopyOnDoubleClick, diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index ab233a239..ebdcc78d1 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -133,6 +133,8 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent) connect(m_generalUi->backupFilePathPicker, SIGNAL(pressed()), SLOT(selectBackupDirectory())); connect(m_generalUi->showExpiredEntriesOnDatabaseUnlockCheckBox, SIGNAL(toggled(bool)), SLOT(showExpiredEntriesOnDatabaseUnlockToggled(bool))); + connect(m_generalUi->autoTypeAskCheckBox, SIGNAL(toggled(bool)), + SLOT(autoTypeAskToggled(bool))); connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)), m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool))); @@ -292,6 +294,9 @@ void ApplicationSettingsWidget::loadSettings() showExpiredEntriesOnDatabaseUnlockToggled(m_generalUi->showExpiredEntriesOnDatabaseUnlockCheckBox->isChecked()); m_generalUi->autoTypeAskCheckBox->setChecked(config()->get(Config::Security_AutoTypeAsk).toBool()); + m_generalUi->autoTypeSkipMainWindowConfirmationCheckBox->setChecked( + config()->get(Config::Security_AutoTypeSkipMainWindowConfirmation).toBool()); + autoTypeAskToggled(m_generalUi->autoTypeAskCheckBox->isChecked()); m_generalUi->autoTypeRelockDatabaseCheckBox->setChecked(config()->get(Config::Security_RelockAutoType).toBool()); if (autoType()->isAvailable()) { @@ -442,6 +447,8 @@ void ApplicationSettingsWidget::saveSettings() m_generalUi->showExpiredEntriesOnDatabaseUnlockOffsetSpinBox->value()); config()->set(Config::Security_AutoTypeAsk, m_generalUi->autoTypeAskCheckBox->isChecked()); + config()->set(Config::Security_AutoTypeSkipMainWindowConfirmation, + m_generalUi->autoTypeSkipMainWindowConfirmationCheckBox->isChecked()); config()->set(Config::Security_RelockAutoType, m_generalUi->autoTypeRelockDatabaseCheckBox->isChecked()); if (autoType()->isAvailable()) { @@ -615,6 +622,11 @@ void ApplicationSettingsWidget::showExpiredEntriesOnDatabaseUnlockToggled(bool c m_generalUi->showExpiredEntriesOnDatabaseUnlockOffsetSpinBox->setEnabled(checked); } +void ApplicationSettingsWidget::autoTypeAskToggled(bool checked) +{ + m_generalUi->autoTypeSkipMainWindowConfirmationCheckBox->setEnabled(checked); +} + void ApplicationSettingsWidget::selectBackupDirectory() { auto backupDirectory = diff --git a/src/gui/ApplicationSettingsWidget.h b/src/gui/ApplicationSettingsWidget.h index 645edaaeb..096df0c53 100644 --- a/src/gui/ApplicationSettingsWidget.h +++ b/src/gui/ApplicationSettingsWidget.h @@ -65,6 +65,7 @@ private slots: void rememberDatabasesToggled(bool checked); void checkUpdatesToggled(bool checked); void showExpiredEntriesOnDatabaseUnlockToggled(bool checked); + void autoTypeAskToggled(bool checked); void selectBackupDirectory(); private: diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index 9e61e4615..56b2d124a 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -1157,6 +1157,42 @@ + + + + 0 + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + false + + + Skip confirmation for main window Auto-Type actions + + + false + + + + + diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index f0009a870..cc6757da8 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -872,12 +872,18 @@ void DatabaseWidget::performAutoType(const QString& sequence) { auto currentEntry = currentSelectedEntry(); if (currentEntry) { - // TODO: Include name of previously active window in confirmation question - if (config()->get(Config::Security_AutoTypeAsk).toBool() - && MessageBox::question( - this, tr("Confirm Auto-Type"), tr("Perform Auto-Type into the previously active window?")) - != MessageBox::Yes) { - return; + // Check if we need to ask for confirmation + bool shouldAsk = config()->get(Config::Security_AutoTypeAsk).toBool(); + bool skipMainWindowConfirmation = config()->get(Config::Security_AutoTypeSkipMainWindowConfirmation).toBool(); + + // Show confirmation if Security_AutoTypeAsk is true AND Security_AutoTypeSkipMainWindowConfirmation is false + if (shouldAsk && !skipMainWindowConfirmation) { + // TODO: Include name of previously active window in confirmation question + if (MessageBox::question( + this, tr("Confirm Auto-Type"), tr("Perform Auto-Type into the previously active window?")) + != MessageBox::Yes) { + return; + } } if (sequence.isEmpty()) {