From 448165613db5935caa504f3e936478589fcacaec 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 16cd879b9..113053acb 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -573,6 +573,10 @@ Font size selection + + Skip confirmation for main window Auto-Type actions + + ApplicationSettingsWidgetSecurity diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f1a78830d..04b724fb1 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 5678bbc6e..9385f9ef1 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -129,6 +129,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 8d53d6f0f..2fd0b6d7a 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -129,6 +129,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))); @@ -302,6 +304,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()) { @@ -445,6 +450,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()) { @@ -618,6 +625,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 7e43196b1..25450600c 100644 --- a/src/gui/ApplicationSettingsWidget.h +++ b/src/gui/ApplicationSettingsWidget.h @@ -63,6 +63,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 eb69f2615..71ea8c47f 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 a9f7f5a81..e84916960 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -877,12 +877,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()) {