From bc57985e2c5d6ce499a22ded7ca6033de850f29d Mon Sep 17 00:00:00 2001 From: mattesony <49170923+mattesony@users.noreply.github.com> Date: Tue, 1 Nov 2022 19:08:46 -0700 Subject: [PATCH 1/7] Expire now option --- src/gui/entry/EditEntryWidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 9af9aa6014..ec9b894650 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -1678,6 +1678,7 @@ void EditEntryWidget::deleteAllHistoryEntries() QMenu* EditEntryWidget::createPresetsMenu() { auto* expirePresetsMenu = new QMenu(this); + expirePresetsMenu->addAction(tr("Now"))->setData(QVariant::fromValue(TimeDelta(0,0,0,0))); expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 12))->setData(QVariant::fromValue(TimeDelta::fromHours(12))); expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 24))->setData(QVariant::fromValue(TimeDelta::fromHours(24))); expirePresetsMenu->addSeparator(); From b60c02b600f9175135c15b440b998ad93b762212 Mon Sep 17 00:00:00 2001 From: mattesony <49170923+mattesony@users.noreply.github.com> Date: Tue, 1 Nov 2022 22:39:17 -0700 Subject: [PATCH 2/7] Added expire entry option --- share/translations/keepassxc_en.ts | 63 ++++++++++++++----- src/gui/DatabaseWidget.cpp | 25 ++++++++ src/gui/DatabaseWidget.h | 2 + src/gui/GuiTools.cpp | 14 +++++ src/gui/GuiTools.h | 1 + src/gui/MainWindow.cpp | 7 ++- src/gui/MainWindow.ui | 10 +++ src/gui/entry/EditEntryWidget.cpp | 2 +- .../ReportsWidgetBrowserStatistics.cpp | 29 +++++++++ .../reports/ReportsWidgetBrowserStatistics.h | 2 + src/gui/reports/ReportsWidgetHealthcheck.cpp | 23 ++++++- src/gui/reports/ReportsWidgetHealthcheck.h | 2 + src/gui/reports/ReportsWidgetHibp.cpp | 20 +++++- src/gui/reports/ReportsWidgetHibp.h | 2 + 14 files changed, 181 insertions(+), 21 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index bc9e17f226..e8ea3f0059 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -2919,6 +2919,10 @@ Would you like to correct it? + + Now + + Failed to decrypt SSH key, ensure password is correct. @@ -5950,6 +5954,14 @@ Expect some bugs and minor issues, this version is meant for testing purposes.Import Passkey + + &Expire Entry… + + + + Remote S&ync… + + Quit Application @@ -6054,6 +6066,10 @@ Expect some bugs and minor issues, this version is meant for testing purposes.Show Password Generator + + Remove Passkey From Entry + + Perform Auto-Type: {USERNAME} @@ -6199,25 +6215,17 @@ Expect some bugs and minor issues, this version is meant for testing purposes. - Remote S&ync… + Show Group Panel - Remove Passkey From Entry + Toggle Show Group Panel Setup Remote Sync… - - Show Group Panel - - - - Toggle Show Group Panel - - Password Generator @@ -9281,6 +9289,13 @@ This option is deprecated, use --set-key-file instead. Exclude from reports + + Expire Entry(s)… + + + + + Only show entries that have a URL @@ -9307,6 +9322,14 @@ This option is deprecated, use --set-key-file instead. ReportsWidgetHealthcheck + + Show expired entries + + + + (Expired) + + Hover over reason to show additional details. Double-click entries to edit. @@ -9370,18 +9393,17 @@ This option is deprecated, use --set-key-file instead. Exclude from reports - - Show expired entries - + + Expire Entry(s)… + + + + Show entries that have been excluded from reports - - (Expired) - - ReportsWidgetHibp @@ -9480,6 +9502,13 @@ This option is deprecated, use --set-key-file instead. Exclude from reports + + Expire Entry(s)… + + + + + ReportsWidgetPasskeys diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index b651b52850..ed9d5a8981 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -569,6 +569,22 @@ void DatabaseWidget::setupTotp() setupTotpDialog->open(); } +void DatabaseWidget::expireSelectedEntries() +{ + const QModelIndexList selected = m_entryView->selectionModel()->selectedRows(); + if (selected.isEmpty()) { + return; + } + + // Resolve entries from the selection model + QList selectedEntries; + for (const QModelIndex& index : selected) { + selectedEntries.append(m_entryView->entryFromIndex(index)); + } + + expireEntries(std::move(selectedEntries)); +} + void DatabaseWidget::deleteSelectedEntries() { const QModelIndexList selected = m_entryView->selectionModel()->selectedRows(); @@ -605,6 +621,15 @@ void DatabaseWidget::restoreSelectedEntries() } } +void DatabaseWidget::expireEntries(QList selectedEntries) +{ + if (selectedEntries.isEmpty()) { + return; + } + + GuiTools::expireEntries(this, selectedEntries); +} + void DatabaseWidget::deleteEntries(QList selectedEntries, bool confirm) { if (selectedEntries.isEmpty()) { diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 5ef8709259..7b6a267b81 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -180,8 +180,10 @@ public slots: void replaceDatabase(QSharedPointer db); void createEntry(); void cloneEntry(); + void expireSelectedEntries(); void deleteSelectedEntries(); void restoreSelectedEntries(); + void expireEntries(QList entries); void deleteEntries(QList entries, bool confirm = true); void focusOnEntries(bool editIfFocused = false); void focusOnGroups(bool editIfFocused = false); diff --git a/src/gui/GuiTools.cpp b/src/gui/GuiTools.cpp index b2dfa63f3a..1c6437b595 100644 --- a/src/gui/GuiTools.cpp +++ b/src/gui/GuiTools.cpp @@ -17,6 +17,7 @@ #include "GuiTools.h" +#include "core/Clock.h" #include "core/Config.h" #include "core/Group.h" #include "gui/MessageBox.h" @@ -81,6 +82,19 @@ namespace GuiTools return answer == MessageBox::Delete; } + size_t expireEntries(QWidget* parent, const QList& entries) + { + if (!parent || entries.isEmpty()) { + return 0; + } + + for (auto entry : asConst(entries)) { + entry->setExpiryTime(Clock::currentDateTimeUtc()); + entry->setExpires(true); + } + return entries.size(); + } + size_t deleteEntriesResolveReferences(QWidget* parent, const QList& entries, bool permanent) { if (!parent || entries.isEmpty()) { diff --git a/src/gui/GuiTools.h b/src/gui/GuiTools.h index c5e7108964..133f6a0370 100644 --- a/src/gui/GuiTools.h +++ b/src/gui/GuiTools.h @@ -27,6 +27,7 @@ namespace GuiTools { bool confirmDeleteEntries(QWidget* parent, const QList& entries, bool permanent); bool confirmDeletePluginData(QWidget* parent, const QList& entries); + size_t expireEntries(QWidget* parent, const QList& entries); size_t deleteEntriesResolveReferences(QWidget* parent, const QList& entries, bool permanent); } // namespace GuiTools #endif // KEEPASSXC_GUITOOLS_H diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 3191b45aa1..3a19f06683 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -144,6 +144,7 @@ MainWindow::MainWindow() m_entryContextMenu->addSeparator(); #endif m_entryContextMenu->addAction(m_ui->actionEntryEdit); + m_entryContextMenu->addAction(m_ui->actionEntryExpire); m_entryContextMenu->addAction(m_ui->actionEntryClone); m_entryContextMenu->addAction(m_ui->actionEntryDelete); m_entryContextMenu->addAction(m_ui->actionEntryNew); @@ -276,6 +277,7 @@ MainWindow::MainWindow() // Unfortunately, Qt::AA_DontShowShortcutsInContextMenus is broken, have to manually enable them m_ui->actionEntryNew->setShortcutVisibleInContextMenu(true); m_ui->actionEntryEdit->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryExpire->setShortcutVisibleInContextMenu(true); m_ui->actionEntryDelete->setShortcutVisibleInContextMenu(true); m_ui->actionEntryRestore->setShortcutVisibleInContextMenu(true); m_ui->actionEntryClone->setShortcutVisibleInContextMenu(true); @@ -372,6 +374,7 @@ MainWindow::MainWindow() m_ui->actionEntryNew->setIcon(icons()->icon("entry-new")); m_ui->actionEntryClone->setIcon(icons()->icon("entry-clone")); m_ui->actionEntryEdit->setIcon(icons()->icon("entry-edit")); + m_ui->actionEntryExpire->setIcon(icons()->icon("entry-expire")); m_ui->actionEntryDelete->setIcon(icons()->icon("entry-delete")); m_ui->actionEntryRestore->setIcon(icons()->icon("entry-restore")); m_ui->actionEntryAutoType->setIcon(icons()->icon("auto-type")); @@ -489,8 +492,9 @@ MainWindow::MainWindow() connect(m_ui->actionQuit, SIGNAL(triggered()), SLOT(appExit())); m_actionMultiplexer.connect(m_ui->actionEntryNew, SIGNAL(triggered()), SLOT(createEntry())); - m_actionMultiplexer.connect(m_ui->actionEntryClone, SIGNAL(triggered()), SLOT(cloneEntry())); m_actionMultiplexer.connect(m_ui->actionEntryEdit, SIGNAL(triggered()), SLOT(switchToEntryEdit())); + m_actionMultiplexer.connect(m_ui->actionEntryExpire, SIGNAL(triggered()), SLOT(expireSelectedEntries())); + m_actionMultiplexer.connect(m_ui->actionEntryClone, SIGNAL(triggered()), SLOT(cloneEntry())); m_actionMultiplexer.connect(m_ui->actionEntryDelete, SIGNAL(triggered()), SLOT(deleteSelectedEntries())); m_actionMultiplexer.connect(m_ui->actionEntryRestore, SIGNAL(triggered()), SLOT(restoreSelectedEntries())); @@ -912,6 +916,7 @@ void MainWindow::updateMenuActionState() m_ui->actionEntryNew->setEnabled(inDatabase && !inRecycleBin); m_ui->actionEntryClone->setEnabled(singleEntrySelected && !inRecycleBin); m_ui->actionEntryEdit->setEnabled(singleEntrySelected); + m_ui->actionEntryExpire->setEnabled(multiEntrySelected); m_ui->actionEntryDelete->setEnabled(multiEntrySelected); m_ui->actionEntryRestore->setVisible(multiEntrySelected && inRecycleBin); m_ui->actionEntryRestore->setEnabled(multiEntrySelected && inRecycleBin); diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui index 1110b64262..292ab3aa0b 100644 --- a/src/gui/MainWindow.ui +++ b/src/gui/MainWindow.ui @@ -321,6 +321,7 @@ + @@ -429,6 +430,7 @@ + @@ -544,6 +546,14 @@ Ctrl+E + + + false + + + &Expire Entry… + + &Delete Entry… diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index ec9b894650..2a843759db 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -1678,7 +1678,7 @@ void EditEntryWidget::deleteAllHistoryEntries() QMenu* EditEntryWidget::createPresetsMenu() { auto* expirePresetsMenu = new QMenu(this); - expirePresetsMenu->addAction(tr("Now"))->setData(QVariant::fromValue(TimeDelta(0,0,0,0))); + expirePresetsMenu->addAction(tr("Now"))->setData(QVariant::fromValue(TimeDelta(0, 0, 0, 0))); expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 12))->setData(QVariant::fromValue(TimeDelta::fromHours(12))); expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 24))->setData(QVariant::fromValue(TimeDelta::fromHours(24))); expirePresetsMenu->addSeparator(); diff --git a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp index 579840a24d..6d00ac769d 100644 --- a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp +++ b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp @@ -275,6 +275,11 @@ void ReportsWidgetBrowserStatistics::customMenuRequested(QPoint pos) }); } + // Create the "expire entry" menu item + const auto expEntry = new QAction(icons()->icon("entry-expire"), tr("Expire Entry(s)…", "", selected.size()), this); + menu->addAction(expEntry); + connect(expEntry, &QAction::triggered, this, &ReportsWidgetBrowserStatistics::expireSelectedEntries); + // Create the "delete entry" menu item const auto deleteEntry = new QAction(icons()->icon("entry-delete"), tr("Delete Entry(s)…", "", selected.size()), this); @@ -327,6 +332,30 @@ void ReportsWidgetBrowserStatistics::saveSettings() // Nothing to do - the tab is passive } +QList ReportsWidgetBrowserStatistics::getSelectedEntries() +{ + QList selectedEntries; + for (auto index : m_ui->browserStatisticsTableView->selectionModel()->selectedRows()) { + auto row = m_modelProxy->mapToSource(index).row(); + auto entry = m_rowToEntry[row].second; + if (entry) { + selectedEntries << entry; + } + } + return selectedEntries; +} + +void ReportsWidgetBrowserStatistics::expireSelectedEntries() +{ + QList selectedEntries = getSelectedEntries(); + if (selectedEntries.isEmpty()) { + return; + } + GuiTools::expireEntries(this, selectedEntries); + + calculateBrowserStatistics(); +} + void ReportsWidgetBrowserStatistics::deleteSelectedEntries() { const auto& selectedEntries = getSelectedEntries(); diff --git a/src/gui/reports/ReportsWidgetBrowserStatistics.h b/src/gui/reports/ReportsWidgetBrowserStatistics.h index 9de20086f9..9b1cc7d602 100644 --- a/src/gui/reports/ReportsWidgetBrowserStatistics.h +++ b/src/gui/reports/ReportsWidgetBrowserStatistics.h @@ -53,6 +53,8 @@ public slots: void calculateBrowserStatistics(); void emitEntryActivated(const QModelIndex& index); void customMenuRequested(QPoint); + QList getSelectedEntries(); + void expireSelectedEntries(); void deleteSelectedEntries(); void deletePluginDataFromSelectedEntries(); diff --git a/src/gui/reports/ReportsWidgetHealthcheck.cpp b/src/gui/reports/ReportsWidgetHealthcheck.cpp index a50fd1d7db..b7043934b8 100644 --- a/src/gui/reports/ReportsWidgetHealthcheck.cpp +++ b/src/gui/reports/ReportsWidgetHealthcheck.cpp @@ -323,6 +323,11 @@ void ReportsWidgetHealthcheck::customMenuRequested(QPoint pos) }); } + // Create the "Expire entry" menu item + const auto expEntry = new QAction(tr("Expire Entry(s)…", "", selected.size()), this); + menu->addAction(expEntry); + connect(expEntry, &QAction::triggered, this, &ReportsWidgetHealthcheck::expireSelectedEntries); + // Create the "delete entry" menu item const auto delEntry = new QAction(icons()->icon("entry-delete"), tr("Delete Entry(s)…", "", selected.size()), this); menu->addAction(delEntry); @@ -365,7 +370,7 @@ void ReportsWidgetHealthcheck::saveSettings() // nothing to do - the tab is passive } -void ReportsWidgetHealthcheck::deleteSelectedEntries() +QList ReportsWidgetHealthcheck::getSelectedEntries() { QList selectedEntries; for (auto index : m_ui->healthcheckTableView->selectionModel()->selectedRows()) { @@ -375,7 +380,23 @@ void ReportsWidgetHealthcheck::deleteSelectedEntries() selectedEntries << entry; } } + return selectedEntries; +} + +void ReportsWidgetHealthcheck::expireSelectedEntries() +{ + QList selectedEntries = getSelectedEntries(); + if (selectedEntries.isEmpty()) { + return; + } + GuiTools::expireEntries(this, selectedEntries); + + calculateHealth(); +} +void ReportsWidgetHealthcheck::deleteSelectedEntries() +{ + QList selectedEntries = getSelectedEntries(); bool permanent = !m_db->metadata()->recycleBinEnabled(); if (GuiTools::confirmDeleteEntries(this, selectedEntries, permanent)) { GuiTools::deleteEntriesResolveReferences(this, selectedEntries, permanent); diff --git a/src/gui/reports/ReportsWidgetHealthcheck.h b/src/gui/reports/ReportsWidgetHealthcheck.h index 21d121b00b..9a46b36b1f 100644 --- a/src/gui/reports/ReportsWidgetHealthcheck.h +++ b/src/gui/reports/ReportsWidgetHealthcheck.h @@ -53,6 +53,8 @@ public slots: void calculateHealth(); void emitEntryActivated(const QModelIndex& index); void customMenuRequested(QPoint); + QList getSelectedEntries(); + void expireSelectedEntries(); void deleteSelectedEntries(); private: diff --git a/src/gui/reports/ReportsWidgetHibp.cpp b/src/gui/reports/ReportsWidgetHibp.cpp index 201b1010f0..0f4dd1dd24 100644 --- a/src/gui/reports/ReportsWidgetHibp.cpp +++ b/src/gui/reports/ReportsWidgetHibp.cpp @@ -374,6 +374,11 @@ void ReportsWidgetHibp::customMenuRequested(QPoint pos) }); } + // Create the "Expire entry" menu item + const auto expEntry = new QAction(tr("Expire Entry(s)…", "", selected.size()), this); + menu->addAction(expEntry); + connect(expEntry, &QAction::triggered, this, &ReportsWidgetHibp::expireSelectedEntries); + // Create the "delete entry" menu item const auto delEntry = new QAction(icons()->icon("entry-delete"), tr("Delete Entry(s)…", "", selected.size()), this); menu->addAction(delEntry); @@ -411,7 +416,7 @@ void ReportsWidgetHibp::customMenuRequested(QPoint pos) menu->popup(m_ui->hibpTableView->viewport()->mapToGlobal(pos)); } -void ReportsWidgetHibp::deleteSelectedEntries() +QList ReportsWidgetHibp::getSelectedEntries() { QList selectedEntries; for (auto index : m_ui->hibpTableView->selectionModel()->selectedRows()) { @@ -421,7 +426,20 @@ void ReportsWidgetHibp::deleteSelectedEntries() selectedEntries << entry; } } + return selectedEntries; +} + +void ReportsWidgetHibp::expireSelectedEntries() +{ + QList selectedEntries = getSelectedEntries(); + GuiTools::expireEntries(this, selectedEntries); + makeHibpTable(); +} + +void ReportsWidgetHibp::deleteSelectedEntries() +{ + QList selectedEntries = getSelectedEntries(); bool permanent = !m_db->metadata()->recycleBinEnabled(); if (GuiTools::confirmDeleteEntries(this, selectedEntries, permanent)) { GuiTools::deleteEntriesResolveReferences(this, selectedEntries, permanent); diff --git a/src/gui/reports/ReportsWidgetHibp.h b/src/gui/reports/ReportsWidgetHibp.h index 29a2c4ff1f..8e0d5e47bc 100644 --- a/src/gui/reports/ReportsWidgetHibp.h +++ b/src/gui/reports/ReportsWidgetHibp.h @@ -58,6 +58,8 @@ public slots: void fetchFailed(const QString& error); void makeHibpTable(); void customMenuRequested(QPoint); + QList getSelectedEntries(); + void expireSelectedEntries(); void deleteSelectedEntries(); private: From f397cc27b414900bc860f4f8e92df36c59ce5f94 Mon Sep 17 00:00:00 2001 From: mattesony <49170923+mattesony@users.noreply.github.com> Date: Tue, 1 Nov 2022 23:23:29 -0700 Subject: [PATCH 3/7] Added icon for expire action --- COPYING | 3 +- .../scalable/actions/entry-expire.svg | 51 +++++++++++++++++++ share/icons/icons.qrc | 1 + src/gui/reports/ReportsWidgetHealthcheck.cpp | 2 +- src/gui/reports/ReportsWidgetHibp.cpp | 2 +- 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 share/icons/application/scalable/actions/entry-expire.svg diff --git a/COPYING b/COPYING index ed03b77f82..a5bbc01858 100644 --- a/COPYING +++ b/COPYING @@ -131,7 +131,8 @@ Copyright: none License: CC0 Comment: Taken from https://github.com/paomedia/small-n-flat -Files: share/icons/badges/2_Expired.svg +Files: share/icons/application/scalable/actions/entry-expire.svg + share/icons/badges/2_Expired.svg share/icons/database/C37_KPercentage.svg share/icons/database/C45_Cancel.svg share/icons/database/C46_Help.svg diff --git a/share/icons/application/scalable/actions/entry-expire.svg b/share/icons/application/scalable/actions/entry-expire.svg new file mode 100644 index 0000000000..0a3a1f1ec6 --- /dev/null +++ b/share/icons/application/scalable/actions/entry-expire.svg @@ -0,0 +1,51 @@ + + + + + + + + + diff --git a/share/icons/icons.qrc b/share/icons/icons.qrc index a5f86b28d1..e92c98a351 100644 --- a/share/icons/icons.qrc +++ b/share/icons/icons.qrc @@ -40,6 +40,7 @@ application/scalable/actions/edit-clear-locationbar-rtl.svg application/scalable/actions/entry-clone.svg application/scalable/actions/entry-delete.svg + application/scalable/actions/entry-expire.svg application/scalable/actions/entry-restore.svg application/scalable/actions/entry-edit.svg application/scalable/actions/entry-new.svg diff --git a/src/gui/reports/ReportsWidgetHealthcheck.cpp b/src/gui/reports/ReportsWidgetHealthcheck.cpp index b7043934b8..7baffe25e2 100644 --- a/src/gui/reports/ReportsWidgetHealthcheck.cpp +++ b/src/gui/reports/ReportsWidgetHealthcheck.cpp @@ -324,7 +324,7 @@ void ReportsWidgetHealthcheck::customMenuRequested(QPoint pos) } // Create the "Expire entry" menu item - const auto expEntry = new QAction(tr("Expire Entry(s)…", "", selected.size()), this); + const auto expEntry = new QAction(icons()->icon("entry-expire"), tr("Expire Entry(s)…", "", selected.size()), this); menu->addAction(expEntry); connect(expEntry, &QAction::triggered, this, &ReportsWidgetHealthcheck::expireSelectedEntries); diff --git a/src/gui/reports/ReportsWidgetHibp.cpp b/src/gui/reports/ReportsWidgetHibp.cpp index 0f4dd1dd24..9fa7e9b6c8 100644 --- a/src/gui/reports/ReportsWidgetHibp.cpp +++ b/src/gui/reports/ReportsWidgetHibp.cpp @@ -375,7 +375,7 @@ void ReportsWidgetHibp::customMenuRequested(QPoint pos) } // Create the "Expire entry" menu item - const auto expEntry = new QAction(tr("Expire Entry(s)…", "", selected.size()), this); + const auto expEntry = new QAction(icons()->icon("entry-expire"), tr("Expire Entry(s)…", "", selected.size()), this); menu->addAction(expEntry); connect(expEntry, &QAction::triggered, this, &ReportsWidgetHibp::expireSelectedEntries); From e4ed9bccbb7530aadb972de0e1e52e2bd96d38cc Mon Sep 17 00:00:00 2001 From: mattesony <49170923+mattesony@users.noreply.github.com> Date: Wed, 2 Nov 2022 14:39:58 -0700 Subject: [PATCH 4/7] Changed expire icon to timer-alert-outline --- COPYING | 4 +- .../scalable/actions/entry-expire.svg | 52 +------------------ 2 files changed, 3 insertions(+), 53 deletions(-) diff --git a/COPYING b/COPYING index a5bbc01858..4e85fc078d 100644 --- a/COPYING +++ b/COPYING @@ -131,8 +131,7 @@ Copyright: none License: CC0 Comment: Taken from https://github.com/paomedia/small-n-flat -Files: share/icons/application/scalable/actions/entry-expire.svg - share/icons/badges/2_Expired.svg +Files: share/icons/badges/2_Expired.svg share/icons/database/C37_KPercentage.svg share/icons/database/C45_Cancel.svg share/icons/database/C46_Help.svg @@ -179,6 +178,7 @@ Files: share/icons/application/scalable/actions/application-exit.svg share/icons/application/scalable/actions/entry-delete.svg share/icons/application/scalable/actions/entry-restore.svg share/icons/application/scalable/actions/entry-edit.svg + share/icons/application/scalable/actions/entry-expire.svg share/icons/application/scalable/actions/entry-new.svg share/icons/application/scalable/actions/favicon-download.svg share/icons/application/scalable/actions/fingerprint.svg diff --git a/share/icons/application/scalable/actions/entry-expire.svg b/share/icons/application/scalable/actions/entry-expire.svg index 0a3a1f1ec6..a0a9ad53bf 100644 --- a/share/icons/application/scalable/actions/entry-expire.svg +++ b/share/icons/application/scalable/actions/entry-expire.svg @@ -1,51 +1 @@ - - - - - - - - - + \ No newline at end of file From 7338b501e97871634263ab1837658d84cb408a52 Mon Sep 17 00:00:00 2001 From: mattesony <49170923+mattesony@users.noreply.github.com> Date: Wed, 2 Nov 2022 15:33:41 -0700 Subject: [PATCH 5/7] Revert "Expire now option" This reverts commit 30c0842ac939033dff68ca69ff2e14b7e98bb294. --- src/gui/entry/EditEntryWidget.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 2a843759db..9af9aa6014 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -1678,7 +1678,6 @@ void EditEntryWidget::deleteAllHistoryEntries() QMenu* EditEntryWidget::createPresetsMenu() { auto* expirePresetsMenu = new QMenu(this); - expirePresetsMenu->addAction(tr("Now"))->setData(QVariant::fromValue(TimeDelta(0, 0, 0, 0))); expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 12))->setData(QVariant::fromValue(TimeDelta::fromHours(12))); expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 24))->setData(QVariant::fromValue(TimeDelta::fromHours(24))); expirePresetsMenu->addSeparator(); From 5860e3ef58a89e77d3b4e7f1754360e162faf630 Mon Sep 17 00:00:00 2001 From: mattesony <49170923+mattesony@users.noreply.github.com> Date: Wed, 2 Nov 2022 15:43:20 -0700 Subject: [PATCH 6/7] Update translations after removing Now preset --- share/translations/keepassxc_en.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index e8ea3f0059..11612309d9 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -2919,10 +2919,6 @@ Would you like to correct it? - - Now - - Failed to decrypt SSH key, ensure password is correct. From 43915ec670e4fad9aa1253a69ab9c212fb16d5a5 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sat, 11 Jan 2025 23:42:14 -0500 Subject: [PATCH 7/7] Code cleanup --- share/translations/keepassxc_en.ts | 8 +++---- src/core/Entry.cpp | 6 +++++ src/core/Entry.h | 1 + src/gui/DatabaseWidget.cpp | 24 ++++--------------- src/gui/DatabaseWidget.h | 1 - src/gui/GuiTools.cpp | 14 ----------- src/gui/GuiTools.h | 1 - src/gui/MainWindow.ui | 3 +-- .../ReportsWidgetBrowserStatistics.cpp | 6 ++--- src/gui/reports/ReportsWidgetHealthcheck.cpp | 6 ++--- src/gui/reports/ReportsWidgetHibp.cpp | 5 ++-- 11 files changed, 24 insertions(+), 51 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 11612309d9..ed4effabc9 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -5950,10 +5950,6 @@ Expect some bugs and minor issues, this version is meant for testing purposes.Import Passkey - - &Expire Entry… - - Remote S&ync… @@ -6226,6 +6222,10 @@ Expect some bugs and minor issues, this version is meant for testing purposes.Password Generator + + E&xpire Entry… + + ManageDatabase diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index 9587e8d67e..1acf663818 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -460,6 +460,12 @@ bool Entry::willExpireInDays(int days) const return m_data.timeInfo.expires() && m_data.timeInfo.expiryTime() < Clock::currentDateTime().addDays(days); } +void Entry::expireNow() +{ + setExpiryTime(Clock::currentDateTimeUtc()); + setExpires(true); +} + bool Entry::isRecycled() const { const Database* db = database(); diff --git a/src/core/Entry.h b/src/core/Entry.h index 749a9fe542..3fb3fbcbbc 100644 --- a/src/core/Entry.h +++ b/src/core/Entry.h @@ -126,6 +126,7 @@ class Entry : public ModifiableObject bool hasTotp() const; bool isExpired() const; bool willExpireInDays(int days) const; + void expireNow(); bool isRecycled() const; bool isAttributeReference(const QString& key) const; bool isAttributeReferenceOf(const QString& key, const QUuid& uuid) const; diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index ed9d5a8981..2b4266c907 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -572,17 +572,12 @@ void DatabaseWidget::setupTotp() void DatabaseWidget::expireSelectedEntries() { const QModelIndexList selected = m_entryView->selectionModel()->selectedRows(); - if (selected.isEmpty()) { - return; - } - - // Resolve entries from the selection model - QList selectedEntries; - for (const QModelIndex& index : selected) { - selectedEntries.append(m_entryView->entryFromIndex(index)); + for (const auto& index : selected) { + auto entry = m_entryView->entryFromIndex(index); + if (entry) { + entry->expireNow(); + } } - - expireEntries(std::move(selectedEntries)); } void DatabaseWidget::deleteSelectedEntries() @@ -621,15 +616,6 @@ void DatabaseWidget::restoreSelectedEntries() } } -void DatabaseWidget::expireEntries(QList selectedEntries) -{ - if (selectedEntries.isEmpty()) { - return; - } - - GuiTools::expireEntries(this, selectedEntries); -} - void DatabaseWidget::deleteEntries(QList selectedEntries, bool confirm) { if (selectedEntries.isEmpty()) { diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 7b6a267b81..1e85dd312c 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -183,7 +183,6 @@ public slots: void expireSelectedEntries(); void deleteSelectedEntries(); void restoreSelectedEntries(); - void expireEntries(QList entries); void deleteEntries(QList entries, bool confirm = true); void focusOnEntries(bool editIfFocused = false); void focusOnGroups(bool editIfFocused = false); diff --git a/src/gui/GuiTools.cpp b/src/gui/GuiTools.cpp index 1c6437b595..b2dfa63f3a 100644 --- a/src/gui/GuiTools.cpp +++ b/src/gui/GuiTools.cpp @@ -17,7 +17,6 @@ #include "GuiTools.h" -#include "core/Clock.h" #include "core/Config.h" #include "core/Group.h" #include "gui/MessageBox.h" @@ -82,19 +81,6 @@ namespace GuiTools return answer == MessageBox::Delete; } - size_t expireEntries(QWidget* parent, const QList& entries) - { - if (!parent || entries.isEmpty()) { - return 0; - } - - for (auto entry : asConst(entries)) { - entry->setExpiryTime(Clock::currentDateTimeUtc()); - entry->setExpires(true); - } - return entries.size(); - } - size_t deleteEntriesResolveReferences(QWidget* parent, const QList& entries, bool permanent) { if (!parent || entries.isEmpty()) { diff --git a/src/gui/GuiTools.h b/src/gui/GuiTools.h index 133f6a0370..c5e7108964 100644 --- a/src/gui/GuiTools.h +++ b/src/gui/GuiTools.h @@ -27,7 +27,6 @@ namespace GuiTools { bool confirmDeleteEntries(QWidget* parent, const QList& entries, bool permanent); bool confirmDeletePluginData(QWidget* parent, const QList& entries); - size_t expireEntries(QWidget* parent, const QList& entries); size_t deleteEntriesResolveReferences(QWidget* parent, const QList& entries, bool permanent); } // namespace GuiTools #endif // KEEPASSXC_GUITOOLS_H diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui index 292ab3aa0b..c84727c3e8 100644 --- a/src/gui/MainWindow.ui +++ b/src/gui/MainWindow.ui @@ -430,7 +430,6 @@ - @@ -551,7 +550,7 @@ false - &Expire Entry… + E&xpire Entry… diff --git a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp index 6d00ac769d..63267d77fd 100644 --- a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp +++ b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp @@ -347,11 +347,9 @@ QList ReportsWidgetBrowserStatistics::getSelectedEntries() void ReportsWidgetBrowserStatistics::expireSelectedEntries() { - QList selectedEntries = getSelectedEntries(); - if (selectedEntries.isEmpty()) { - return; + for (auto entry : getSelectedEntries()) { + entry->expireNow(); } - GuiTools::expireEntries(this, selectedEntries); calculateBrowserStatistics(); } diff --git a/src/gui/reports/ReportsWidgetHealthcheck.cpp b/src/gui/reports/ReportsWidgetHealthcheck.cpp index 7baffe25e2..f6151dda43 100644 --- a/src/gui/reports/ReportsWidgetHealthcheck.cpp +++ b/src/gui/reports/ReportsWidgetHealthcheck.cpp @@ -385,11 +385,9 @@ QList ReportsWidgetHealthcheck::getSelectedEntries() void ReportsWidgetHealthcheck::expireSelectedEntries() { - QList selectedEntries = getSelectedEntries(); - if (selectedEntries.isEmpty()) { - return; + for (auto entry : getSelectedEntries()) { + entry->expireNow(); } - GuiTools::expireEntries(this, selectedEntries); calculateHealth(); } diff --git a/src/gui/reports/ReportsWidgetHibp.cpp b/src/gui/reports/ReportsWidgetHibp.cpp index 9fa7e9b6c8..a559208aaa 100644 --- a/src/gui/reports/ReportsWidgetHibp.cpp +++ b/src/gui/reports/ReportsWidgetHibp.cpp @@ -431,8 +431,9 @@ QList ReportsWidgetHibp::getSelectedEntries() void ReportsWidgetHibp::expireSelectedEntries() { - QList selectedEntries = getSelectedEntries(); - GuiTools::expireEntries(this, selectedEntries); + for (auto entry : getSelectedEntries()) { + entry->expireNow(); + } makeHibpTable(); }