Skip to content

Commit

Permalink
Add Pin Quick Unlock option
Browse files Browse the repository at this point in the history
* Introduce QuickUnlockManager to fall back to pin unlock if OS native options are not available.
  • Loading branch information
droidmonkey committed Dec 9, 2024
1 parent 0ee002d commit 8e4cba3
Show file tree
Hide file tree
Showing 16 changed files with 533 additions and 222 deletions.
120 changes: 76 additions & 44 deletions share/translations/keepassxc_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,10 +586,6 @@
<source>Convenience</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enable database quick unlock (Touch ID / Windows Hello)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lock databases when session is locked or lid is closed</source>
<translation type="unfinished"></translation>
Expand Down Expand Up @@ -634,6 +630,18 @@
<source>Hide notes in the entry preview panel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Quick unlock can only be remembered when using Touch ID or Windows Hello</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enable database quick unlock by default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remember quick unlock after database is closed (Touch ID / Windows Hello only)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AutoType</name>
Expand Down Expand Up @@ -1527,10 +1535,6 @@ Backup database located at %2</source>
<source>Unlock Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unlock</source>
<translation type="unfinished"></translation>
Expand Down Expand Up @@ -1664,6 +1668,18 @@ Are you sure you want to continue with this file?.</source>
<source>&lt;a href=&quot;#&quot; style=&quot;text-decoration: underline&quot;&gt;I have a key file&lt;/a&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enable Quick Unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Close Database</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DatabaseSettingWidgetMetaData</name>
Expand Down Expand Up @@ -8852,46 +8868,10 @@ This option is deprecated, use --set-key-file instead.</source>
<source>Passkeys</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>AES initialization failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>AES encrypt failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to store in Linux Keyring</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Polkit returned an error: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Could not locate key in keyring</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Could not read key in keyring</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>AES decrypt failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No Polkit authentication agent was available</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Polkit authorization failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No Quick Unlock provider is available</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to init KeePassXC crypto.</source>
<translation type="unfinished"></translation>
Expand Down Expand Up @@ -9073,6 +9053,58 @@ This option is deprecated, use --set-key-file instead.</source>
<source>Passkey</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Quick Unlock Pin Entry</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter a %1 to %2 digit pin to use for quick unlock:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Pin setup was canceled. Quick unlock has not been enabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to get credentials for quick unlock.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter quick unlock pin (%1 of %2 attempts):</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Pin entry was canceled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Maximum pin attempts have been reached.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to store key in Linux Keyring. Quick unlock has not been enabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Could not locate key in Linux Keyring.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Could not read key in Linux Keyring.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No Polkit authentication agent was available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Polkit authorization failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Windows Hello setup was canceled or failed. Quick unlock has not been enabled.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtIOCompressor</name>
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ set(gui_SOURCES
gui/wizard/NewDatabaseWizardPageEncryption.cpp
gui/wizard/NewDatabaseWizardPageDatabaseKey.cpp
quickunlock/QuickUnlockInterface.cpp
quickunlock/PinUnlock.cpp
../share/icons/icons.qrc
../share/wizard/wizard.qrc)

Expand Down
1 change: 1 addition & 0 deletions src/core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class Config : public QObject
Security_EnableCopyOnDoubleClick,
Security_QuickUnlock,
Security_QuickUnlockRemember,
Security_DatabasePasswordMinimumQuality,

Browser_Enabled,
Browser_ShowNotification,
Expand Down
23 changes: 6 additions & 17 deletions src/gui/ApplicationSettingsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,6 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
m_secUi->lockDatabaseMinimizeCheckBox->setEnabled(!state);
});

connect(m_secUi->quickUnlockCheckBox, &QCheckBox::toggled, this, [this](bool state) {
m_secUi->quickUnlockRememberCheckBox->setEnabled(state);
});

// Set Auto-Type shortcut when changed
connect(
m_generalUi->autoTypeShortcutWidget, &ShortcutWidget::shortcutChanged, this, [this](auto key, auto modifiers) {
Expand Down Expand Up @@ -346,17 +342,12 @@ void ApplicationSettingsWidget::loadSettings()
m_secUi->hideTotpCheckBox->setChecked(config()->get(Config::Security_HideTotpPreviewPanel).toBool());
m_secUi->hideNotesCheckBox->setChecked(config()->get(Config::Security_HideNotes).toBool());

m_secUi->quickUnlockCheckBox->setEnabled(getQuickUnlock()->isAvailable());
m_secUi->quickUnlockCheckBox->setChecked(config()->get(Config::Security_QuickUnlock).toBool());
m_secUi->quickUnlockCheckBox->setToolTip(
m_secUi->quickUnlockCheckBox->isEnabled() ? QString() : tr("Quick unlock is not available on your device."));

m_secUi->quickUnlockRememberCheckBox->setEnabled(getQuickUnlock()->isAvailable()
&& getQuickUnlock()->canRemember());
m_secUi->quickUnlockRememberCheckBox->setChecked(config()->get(Config::Security_QuickUnlockRemember).toBool());
m_secUi->quickUnlockRememberCheckBox->setToolTip(m_secUi->quickUnlockRememberCheckBox->isEnabled()
? QString()
: tr("Quick unlock cannot be remembered on your device."));
#ifdef Q_OS_LINUX
// Remembering quick unlock is not supported on Linux
m_secUi->quickUnlockRememberCheckBox->setVisible(false);
#endif

for (const ExtraPage& page : asConst(m_extraPages)) {
page.loadSettings();
Expand Down Expand Up @@ -471,10 +462,8 @@ void ApplicationSettingsWidget::saveSettings()
config()->set(Config::Security_HideTotpPreviewPanel, m_secUi->hideTotpCheckBox->isChecked());
config()->set(Config::Security_HideNotes, m_secUi->hideNotesCheckBox->isChecked());

if (m_secUi->quickUnlockCheckBox->isEnabled()) {
config()->set(Config::Security_QuickUnlock, m_secUi->quickUnlockCheckBox->isChecked());
config()->set(Config::Security_QuickUnlockRemember, m_secUi->quickUnlockRememberCheckBox->isChecked());
}
config()->set(Config::Security_QuickUnlock, m_secUi->quickUnlockCheckBox->isChecked());
config()->set(Config::Security_QuickUnlockRemember, m_secUi->quickUnlockRememberCheckBox->isChecked());

// Security: clear storage if related settings are disabled
if (!config()->get(Config::RememberLastDatabases).toBool()) {
Expand Down
42 changes: 11 additions & 31 deletions src/gui/ApplicationSettingsWidgetSecurity.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>364</width>
<height>505</height>
<width>437</width>
<height>529</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
Expand Down Expand Up @@ -168,39 +168,19 @@
<item>
<widget class="QCheckBox" name="quickUnlockCheckBox">
<property name="text">
<string>Enable database quick unlock (Touch ID / Windows Hello / Polkit)</string>
<string>Enable database quick unlock by default</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="quickUnlockRememberCheckBox">
<property name="text">
<string>Remember quick unlock after database is closed</string>
</property>
</widget>
</item>
</layout>
<widget class="QCheckBox" name="quickUnlockRememberCheckBox">
<property name="toolTip">
<string>Quick unlock can only be remembered when using Touch ID or Windows Hello</string>
</property>
<property name="text">
<string>Remember quick unlock after database is closed (Touch ID / Windows Hello only)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="lockDatabaseOnScreenLockCheckBox">
Expand Down
5 changes: 2 additions & 3 deletions src/gui/DatabaseOpenDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,8 @@ void DatabaseOpenDialog::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
QTimer::singleShot(100, this, [this] {
if (m_view->isOnQuickUnlockScreen() && !m_view->unlockingDatabase()) {
m_view->triggerQuickUnlock();
}
// Automatically trigger quick unlock if it's available
m_view->triggerQuickUnlock();
});
}

Expand Down
Loading

0 comments on commit 8e4cba3

Please sign in to comment.