From e565f89d47b7eb29ede30d77347ba1563bb3ae24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20V=C3=A4nttinen?= Date: Mon, 12 Aug 2024 01:32:10 +0300 Subject: [PATCH] Add option to disable database lock when switching user on macOS (#9707) --- share/translations/keepassxc_en.ts | 4 ++++ src/core/Config.cpp | 1 + src/core/Config.h | 1 + src/gui/ApplicationSettingsWidget.cpp | 10 +++++++++- src/gui/ApplicationSettingsWidgetSecurity.ui | 8 ++++++++ src/gui/DatabaseTabWidget.cpp | 9 ++++++++- src/gui/DatabaseTabWidget.h | 1 + src/gui/osutils/macutils/AppKit.h | 6 +++--- src/gui/osutils/macutils/AppKitImpl.mm | 6 +++--- src/gui/osutils/macutils/MacUtils.cpp | 4 ++-- src/gui/osutils/macutils/MacUtils.h | 4 ++-- 11 files changed, 42 insertions(+), 12 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 4c0d486b1..9c9cc2917 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -596,6 +596,10 @@ Hide TOTP in the entry preview panel + + Lock databases when switching user + + AutoType diff --git a/src/core/Config.cpp b/src/core/Config.cpp index c03e720ce..ba6927f30 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -135,6 +135,7 @@ static const QHash configStrings = { {Config::Security_LockDatabaseIdleSeconds, {QS("Security/LockDatabaseIdleSeconds"), Roaming, 240}}, {Config::Security_LockDatabaseMinimize, {QS("Security/LockDatabaseMinimize"), Roaming, false}}, {Config::Security_LockDatabaseScreenLock, {QS("Security/LockDatabaseScreenLock"), Roaming, true}}, + {Config::Security_LockDatabaseOnUserSwitch, {QS("Security/LockDatabaseOnUserSwitch"), Roaming, true}}, {Config::Security_RelockAutoType, {QS("Security/RelockAutoType"), Roaming, false}}, {Config::Security_PasswordsHidden, {QS("Security/PasswordsHidden"), Roaming, true}}, {Config::Security_PasswordEmptyPlaceholder, {QS("Security/PasswordEmptyPlaceholder"), Roaming, false}}, diff --git a/src/core/Config.h b/src/core/Config.h index db3187caa..2d7f5d9f3 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -115,6 +115,7 @@ public: Security_LockDatabaseIdleSeconds, Security_LockDatabaseMinimize, Security_LockDatabaseScreenLock, + Security_LockDatabaseOnUserSwitch, Security_RelockAutoType, Security_PasswordsHidden, Security_PasswordEmptyPlaceholder, diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index 6414e6be1..04ccb9bdb 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -1,6 +1,6 @@ /* + * Copyright (C) 2023 KeePassXC Team * Copyright (C) 2012 Felix Geyer - * Copyright (C) 2017 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -301,6 +301,13 @@ void ApplicationSettingsWidget::loadSettings() && config()->get(Config::Security_LockDatabaseMinimize).toBool()); m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked( config()->get(Config::Security_LockDatabaseScreenLock).toBool()); +#if defined(Q_OS_MACOS) + m_secUi->lockDatabasesOnUserSwitchCheckBox->setVisible(true); +#else + m_secUi->lockDatabasesOnUserSwitchCheckBox->setVisible(false); +#endif + m_secUi->lockDatabasesOnUserSwitchCheckBox->setChecked( + config()->get(Config::Security_LockDatabaseOnUserSwitch).toBool()); m_secUi->fallbackToSearch->setChecked(config()->get(Config::Security_IconDownloadFallback).toBool()); m_secUi->passwordsHiddenCheckBox->setChecked(config()->get(Config::Security_PasswordsHidden).toBool()); @@ -421,6 +428,7 @@ 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_LockDatabaseOnUserSwitch, m_secUi->lockDatabasesOnUserSwitchCheckBox->isChecked()); config()->set(Config::Security_IconDownloadFallback, m_secUi->fallbackToSearch->isChecked()); config()->set(Config::Security_PasswordsHidden, m_secUi->passwordsHiddenCheckBox->isChecked()); diff --git a/src/gui/ApplicationSettingsWidgetSecurity.ui b/src/gui/ApplicationSettingsWidgetSecurity.ui index d2fbbfd56..84f1083ac 100644 --- a/src/gui/ApplicationSettingsWidgetSecurity.ui +++ b/src/gui/ApplicationSettingsWidgetSecurity.ui @@ -186,6 +186,13 @@ + + + + Lock databases when switching user + + + @@ -277,6 +284,7 @@ clearClipboardSpinBox lockDatabaseIdleCheckBox lockDatabaseIdleSpinBox + lockDatabasesOnUserSwitchCheckBox clearSearchCheckBox clearSearchSpinBox quickUnlockCheckBox diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index 805d4eabd..fafecf4db 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -63,7 +63,7 @@ DatabaseTabWidget::DatabaseTabWidget(QWidget* parent) // clang-format on #ifdef Q_OS_MACOS - connect(macUtils(), SIGNAL(lockDatabases()), SLOT(lockDatabases())); + connect(macUtils(), SIGNAL(userSwitched()), SLOT(lockDatabasesOnUserSwitch())); #endif m_lockDelayTimer.setSingleShot(true); @@ -693,6 +693,13 @@ void DatabaseTabWidget::lockDatabasesDelayed() } } +void DatabaseTabWidget::lockDatabasesOnUserSwitch() +{ + if (config()->get(Config::Security_LockDatabaseOnUserSwitch).toBool()) { + lockDatabases(); + } +} + /** * Unlock a database with an unlock popup dialog. * diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h index 59e555451..57b863106 100644 --- a/src/gui/DatabaseTabWidget.h +++ b/src/gui/DatabaseTabWidget.h @@ -74,6 +74,7 @@ public slots: bool lockDatabases(); void lockDatabasesDelayed(); + void lockDatabasesOnUserSwitch(); void closeDatabaseFromSender(); void unlockDatabaseInDialog(DatabaseWidget* dbWidget, DatabaseOpenDialog::Intent intent); void unlockDatabaseInDialog(DatabaseWidget* dbWidget, DatabaseOpenDialog::Intent intent, const QString& filePath); diff --git a/src/gui/osutils/macutils/AppKit.h b/src/gui/osutils/macutils/AppKit.h index 309c05b90..260b6c208 100644 --- a/src/gui/osutils/macutils/AppKit.h +++ b/src/gui/osutils/macutils/AppKit.h @@ -1,6 +1,6 @@ /* + * Copyright (C) 2023 KeePassXC Team * Copyright (C) 2016 Lennart Glauer - * Copyright (C) 2017 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,8 @@ #ifndef KEEPASSX_APPKIT_H #define KEEPASSX_APPKIT_H -#include #include +#include #include class QWindow; @@ -47,7 +47,7 @@ public: void setWindowSecurity(QWindow* window, bool state); signals: - void lockDatabases(); + void userSwitched(); void interfaceThemeChanged(); private: diff --git a/src/gui/osutils/macutils/AppKitImpl.mm b/src/gui/osutils/macutils/AppKitImpl.mm index 439cf18d4..f2692bd6e 100644 --- a/src/gui/osutils/macutils/AppKitImpl.mm +++ b/src/gui/osutils/macutils/AppKitImpl.mm @@ -32,7 +32,7 @@ selector:@selector(didDeactivateApplicationObserver:) name:NSWorkspaceDidDeactivateApplicationNotification object:nil]; - + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(userSwitchHandler:) name:NSWorkspaceSessionDidResignActiveNotification @@ -160,7 +160,7 @@ { if ([[notification name] isEqualToString:NSWorkspaceSessionDidResignActiveNotification] && m_appkit) { - emit m_appkit->lockDatabases(); + emit m_appkit->userSwitched(); } } @@ -188,7 +188,7 @@ // Request screen recording permission on macOS 10.15+ // This is necessary to get the current window title CGDisplayStreamRef stream = CGDisplayStreamCreate(CGMainDisplayID(), 1, 1, kCVPixelFormatType_32BGRA, nil, - ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, + ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) { Q_UNUSED(status); Q_UNUSED(displayTime); diff --git a/src/gui/osutils/macutils/MacUtils.cpp b/src/gui/osutils/macutils/MacUtils.cpp index 0f2cc6161..107cd3a29 100644 --- a/src/gui/osutils/macutils/MacUtils.cpp +++ b/src/gui/osutils/macutils/MacUtils.cpp @@ -1,6 +1,6 @@ /* + * Copyright (C) 2023 KeePassXC Team * Copyright (C) 2012 Felix Geyer - * Copyright (C) 2018 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ MacUtils::MacUtils(QObject* parent) : OSUtilsBase(parent) , m_appkit(new AppKit()) { - connect(m_appkit.data(), SIGNAL(lockDatabases()), SIGNAL(lockDatabases())); + connect(m_appkit.data(), SIGNAL(userSwitched()), SIGNAL(userSwitched())); connect(m_appkit.data(), SIGNAL(interfaceThemeChanged()), SIGNAL(interfaceThemeChanged())); connect(m_appkit.data(), &AppKit::interfaceThemeChanged, this, [this]() { // Emit with delay, since isStatusBarDark() still returns the old value diff --git a/src/gui/osutils/macutils/MacUtils.h b/src/gui/osutils/macutils/MacUtils.h index 1281aa072..16cda54e2 100644 --- a/src/gui/osutils/macutils/MacUtils.h +++ b/src/gui/osutils/macutils/MacUtils.h @@ -1,6 +1,6 @@ /* + * Copyright (C) 2023 KeePassXC Team * Copyright (C) 2012 Felix Geyer - * Copyright (C) 2017 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,7 +66,7 @@ public: bool setPreventScreenCapture(QWindow* window, bool prevent) const override; signals: - void lockDatabases(); + void userSwitched(); protected: explicit MacUtils(QObject* parent = nullptr);