From bfbc0e5ec6ee77f44411dbe3f63c80405cb1c182 Mon Sep 17 00:00:00 2001 From: Toni Spets Date: Sat, 19 Feb 2022 22:40:59 +0200 Subject: [PATCH] Auto-Type: Allow retyping with automatic relock If relock after performing Auto-Type is enabled it will wait until specified timeout before doing so. Retype time is now configurable and is decreased from the old hardcoded 30 seconds down to 15 seconds to keep the default a bit more secure while still allowing the user to set it higher for their liking. To restore old behavior the user can set retype time to 0 which will make the database relock instantly. Auto-Type relock setting relocated to Auto-Type tab to group it better with the other Auto-Type settings. --- share/translations/keepassxc_en.ts | 16 +- src/autotype/AutoType.cpp | 17 ++- src/autotype/AutoType.h | 4 +- src/core/Config.cpp | 1 + src/core/Config.h | 1 + src/gui/ApplicationSettingsWidget.cpp | 6 +- src/gui/ApplicationSettingsWidgetGeneral.ui | 148 +++++++++++-------- src/gui/ApplicationSettingsWidgetSecurity.ui | 8 - src/gui/DatabaseTabWidget.cpp | 2 +- 9 files changed, 120 insertions(+), 83 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 7991c5c5..71649a3e 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -476,6 +476,18 @@ will expire within + + s + + + + Re-lock previously locked database after performing Auto-Type + Re-lock previously locked database after performing Auto-Type + + + Remember last typed entry for: + + ApplicationSettingsWidgetSecurity @@ -520,10 +532,6 @@ Lock databases after minimizing the window Lock databases after minimizing the window - - Re-lock previously locked database after performing Auto-Type - Re-lock previously locked database after performing Auto-Type - Hide passwords in the entry preview panel Hide passwords in the entry preview panel diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index daed6a1e..60389600 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -111,7 +111,6 @@ namespace {"f14", Qt::Key_F14}, {"f15", Qt::Key_F15}, {"f16", Qt::Key_F16}}; - static constexpr int rememberLastEntrySecs = 30; } // namespace AutoType* AutoType::m_instance = nullptr; @@ -124,8 +123,15 @@ AutoType::AutoType(QObject* parent, bool test) , m_windowState(WindowState::Normal) , m_windowForGlobal(0) , m_lastMatch(nullptr, QString()) - , m_lastMatchTime(0) + , m_lastMatchRetypeTimer(nullptr) { + // configure timer to reset last match + m_lastMatchRetypeTimer.setSingleShot(true); + connect(&m_lastMatchRetypeTimer, &QTimer::timeout, this, [this] { + m_lastMatch = {nullptr, QString()}; + emit autotypeRetypeTimeout(); + }); + // prevent crash when the plugin has unresolved symbols m_pluginLoader->setLoadHints(QLibrary::ResolveAllSymbolsHint); @@ -426,11 +432,6 @@ void AutoType::performGlobalAutoType(const QList>& dbLi return; } - // Invalidate last match if it's old enough - if (m_lastMatch.first && (Clock::currentSecondsSinceEpoch() - m_lastMatchTime) > rememberLastEntrySecs) { - m_lastMatch = {nullptr, QString()}; - } - QList matchList; bool hideExpired = config()->get(Config::AutoTypeHideExpiredEntry).toBool(); @@ -468,7 +469,7 @@ void AutoType::performGlobalAutoType(const QList>& dbLi connect(getMainWindow(), &MainWindow::databaseLocked, selectDialog, &AutoTypeSelectDialog::reject); connect(selectDialog, &AutoTypeSelectDialog::matchActivated, this, [this](const AutoTypeMatch& match) { m_lastMatch = match; - m_lastMatchTime = Clock::currentSecondsSinceEpoch(); + m_lastMatchRetypeTimer.start(config()->get(Config::GlobalAutoTypeRetypeTime).toInt() * 1000); executeAutoTypeActions(match.first, nullptr, match.second, m_windowForGlobal); resetAutoTypeState(); }); diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index dd7e9258..1e09adaf 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -21,6 +21,7 @@ #include #include +#include #include #include "AutoTypeMatch.h" @@ -61,6 +62,7 @@ signals: void globalAutoTypeTriggered(const QString& search); void autotypePerformed(); void autotypeRejected(); + void autotypeRetypeTimeout(); private slots: void startGlobalAutoType(const QString& search); @@ -98,7 +100,7 @@ private: WindowState m_windowState; WId m_windowForGlobal; AutoTypeMatch m_lastMatch; - qint64 m_lastMatchTime; + QTimer m_lastMatchRetypeTimer; Q_DISABLE_COPY(AutoType) }; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 66803d0d..af897364 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -78,6 +78,7 @@ static const QHash configStrings = { {Config::AutoTypeHideExpiredEntry,{QS("AutoTypeHideExpiredEntry"), Roaming, false}}, {Config::GlobalAutoTypeKey,{QS("GlobalAutoTypeKey"), Roaming, 0}}, {Config::GlobalAutoTypeModifiers,{QS("GlobalAutoTypeModifiers"), Roaming, 0}}, + {Config::GlobalAutoTypeRetypeTime,{QS("GlobalAutoTypeRetypeTime"), Roaming, 15}}, {Config::FaviconDownloadTimeout,{QS("FaviconDownloadTimeout"), Roaming, 10}}, {Config::UpdateCheckMessageShown,{QS("UpdateCheckMessageShown"), Roaming, false}}, {Config::UseTouchID,{QS("UseTouchID"), Roaming, false}}, diff --git a/src/core/Config.h b/src/core/Config.h index df003924..5ab14b5b 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -60,6 +60,7 @@ public: AutoTypeHideExpiredEntry, GlobalAutoTypeKey, GlobalAutoTypeModifiers, + GlobalAutoTypeRetypeTime, FaviconDownloadTimeout, UpdateCheckMessageShown, UseTouchID, diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index 61a3cc0f..7620c9ba 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -260,6 +260,7 @@ void ApplicationSettingsWidget::loadSettings() showExpiredEntriesOnDatabaseUnlockToggled(m_generalUi->showExpiredEntriesOnDatabaseUnlockCheckBox->isChecked()); m_generalUi->autoTypeAskCheckBox->setChecked(config()->get(Config::Security_AutoTypeAsk).toBool()); + m_generalUi->autoTypeRelockDatabaseCheckBox->setChecked(config()->get(Config::Security_RelockAutoType).toBool()); if (autoType()->isAvailable()) { m_globalAutoTypeKey = static_cast(config()->get(Config::GlobalAutoTypeKey).toInt()); @@ -268,6 +269,7 @@ void ApplicationSettingsWidget::loadSettings() if (m_globalAutoTypeKey > 0 && m_globalAutoTypeModifiers > 0) { m_generalUi->autoTypeShortcutWidget->setShortcut(m_globalAutoTypeKey, m_globalAutoTypeModifiers); } + m_generalUi->autoTypeRetypeTimeSpinBox->setValue(config()->get(Config::GlobalAutoTypeRetypeTime).toInt()); m_generalUi->autoTypeShortcutWidget->setAttribute(Qt::WA_MacShowFocusRect, true); m_generalUi->autoTypeDelaySpinBox->setValue(config()->get(Config::AutoTypeDelay).toInt()); m_generalUi->autoTypeStartDelaySpinBox->setValue(config()->get(Config::AutoTypeStartDelay).toInt()); @@ -297,7 +299,6 @@ void ApplicationSettingsWidget::loadSettings() m_secUi->lockDatabaseMinimizeCheckBox->setChecked(config()->get(Config::Security_LockDatabaseMinimize).toBool()); m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked( config()->get(Config::Security_LockDatabaseScreenLock).toBool()); - m_secUi->relockDatabaseAutoTypeCheckBox->setChecked(config()->get(Config::Security_RelockAutoType).toBool()); m_secUi->fallbackToSearch->setChecked(config()->get(Config::Security_IconDownloadFallback).toBool()); m_secUi->passwordsHiddenCheckBox->setChecked(config()->get(Config::Security_PasswordsHidden).toBool()); @@ -392,11 +393,13 @@ void ApplicationSettingsWidget::saveSettings() m_generalUi->showExpiredEntriesOnDatabaseUnlockOffsetSpinBox->value()); config()->set(Config::Security_AutoTypeAsk, m_generalUi->autoTypeAskCheckBox->isChecked()); + config()->set(Config::Security_RelockAutoType, m_generalUi->autoTypeRelockDatabaseCheckBox->isChecked()); if (autoType()->isAvailable()) { config()->set(Config::GlobalAutoTypeKey, m_generalUi->autoTypeShortcutWidget->key()); config()->set(Config::GlobalAutoTypeModifiers, static_cast(m_generalUi->autoTypeShortcutWidget->modifiers())); + config()->set(Config::GlobalAutoTypeRetypeTime, m_generalUi->autoTypeRetypeTimeSpinBox->value()); config()->set(Config::AutoTypeDelay, m_generalUi->autoTypeDelaySpinBox->value()); config()->set(Config::AutoTypeStartDelay, m_generalUi->autoTypeStartDelaySpinBox->value()); } @@ -410,7 +413,6 @@ void ApplicationSettingsWidget::saveSettings() config()->set(Config::Security_LockDatabaseIdleSeconds, m_secUi->lockDatabaseIdleSpinBox->value()); config()->set(Config::Security_LockDatabaseMinimize, m_secUi->lockDatabaseMinimizeCheckBox->isChecked()); config()->set(Config::Security_LockDatabaseScreenLock, m_secUi->lockDatabaseOnScreenLockCheckBox->isChecked()); - config()->set(Config::Security_RelockAutoType, m_secUi->relockDatabaseAutoTypeCheckBox->isChecked()); config()->set(Config::Security_IconDownloadFallback, m_secUi->fallbackToSearch->isChecked()); config()->set(Config::Security_PasswordsHidden, m_secUi->passwordsHiddenCheckBox->isChecked()); diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index f0404b21..4450b6f5 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -266,12 +266,15 @@ On database unlock, show entries that - - will expire within + + are expired days + + will expire within + 0 @@ -281,9 +284,6 @@ 0 - - are expired - @@ -1020,6 +1020,13 @@ + + + + Re-lock previously locked database after performing Auto-Type + + + @@ -1045,57 +1052,32 @@ 8 - + - Auto-Type typing delay: + Auto-Type start delay: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - autoTypeDelaySpinBox + autoTypeStartDelaySpinBox - - - - - 0 - 0 - + + + + Global Auto-Type shortcut: - - Global auto-type shortcut + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + autoTypeShortcutWidget - - - - 0 - 0 - - - - Auto-type character typing delay milliseconds - - - ms - - - - - - 1000 - - - 25 - - - - @@ -1126,29 +1108,16 @@ - - + + - Global Auto-Type shortcut: + Auto-Type typing delay: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - autoTypeShortcutWidget - - - - - - - Auto-Type start delay: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - autoTypeStartDelaySpinBox + autoTypeDelaySpinBox @@ -1165,6 +1134,67 @@ + + + + + 0 + 0 + + + + Global auto-type shortcut + + + + + + + + 0 + 0 + + + + Auto-type character typing delay milliseconds + + + ms + + + + + + 1000 + + + 25 + + + + + + + Remember last typed entry for: + + + + + + + s + + + 0 + + + 60 + + + 15 + + + diff --git a/src/gui/ApplicationSettingsWidgetSecurity.ui b/src/gui/ApplicationSettingsWidgetSecurity.ui index deab7a6a..bf4b984e 100644 --- a/src/gui/ApplicationSettingsWidgetSecurity.ui +++ b/src/gui/ApplicationSettingsWidgetSecurity.ui @@ -215,13 +215,6 @@ - - - - Re-lock previously locked database after performing Auto-Type - - - @@ -320,7 +313,6 @@ lockDatabaseOnScreenLockCheckBox touchIDResetOnScreenLockCheckBox lockDatabaseMinimizeCheckBox - relockDatabaseAutoTypeCheckBox passwordsRepeatVisibleCheckBox passwordsHiddenCheckBox passwordShowDotsCheckBox diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index 02affe6f..e75467ab 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -52,7 +52,7 @@ DatabaseTabWidget::DatabaseTabWidget(QWidget* parent) connect(this, SIGNAL(activeDatabaseChanged(DatabaseWidget*)), m_dbWidgetStateSync, SLOT(setActive(DatabaseWidget*))); connect(autoType(), SIGNAL(globalAutoTypeTriggered(const QString&)), SLOT(performGlobalAutoType(const QString&))); - connect(autoType(), SIGNAL(autotypePerformed()), SLOT(relockPendingDatabase())); + connect(autoType(), SIGNAL(autotypeRetypeTimeout()), SLOT(relockPendingDatabase())); connect(autoType(), SIGNAL(autotypeRejected()), SLOT(relockPendingDatabase())); connect(m_databaseOpenDialog.data(), &DatabaseOpenDialog::dialogFinished, this, &DatabaseTabWidget::handleDatabaseUnlockDialogFinished);