mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-12-04 15:39:34 +01:00
Compare commits
8 Commits
fix/cli-sh
...
feature/up
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc92ec1814 | ||
|
|
c8f3018c4c | ||
|
|
a174ec4ee7 | ||
|
|
c669765256 | ||
|
|
626f592c98 | ||
|
|
9eae0b318e | ||
|
|
bcc81b069b | ||
|
|
fa785e1745 |
@@ -23,6 +23,7 @@
|
||||
#include "core/Group.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "core/PasswordHealth.h"
|
||||
#include "core/TimeDelta.h"
|
||||
#include "core/Tools.h"
|
||||
#include "totp/totp.h"
|
||||
|
||||
@@ -727,6 +728,20 @@ void Entry::setExpiryTime(const QDateTime& dateTime)
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::setExtendsExpirationOnPwdChange(const bool& value)
|
||||
{
|
||||
if (m_customData->value("ExpirationExtension").toInt() != value) {
|
||||
m_customData->set("ExpirationExtension", QString::number(value));
|
||||
emit entryModified();
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::setExpirationExtension(const QString& quantity, const QString& magnitude)
|
||||
{
|
||||
m_customData->set("ExpirationExtensionQuantity", quantity);
|
||||
m_customData->set("ExpirationExtensionMagnitude", magnitude);
|
||||
}
|
||||
|
||||
QList<Entry*> Entry::historyItems()
|
||||
{
|
||||
return m_history;
|
||||
|
||||
@@ -151,6 +151,8 @@ public:
|
||||
void setDefaultAttribute(const QString& attribute, const QString& value);
|
||||
void setExpires(const bool& value);
|
||||
void setExpiryTime(const QDateTime& dateTime);
|
||||
void setExtendsExpirationOnPwdChange(const bool& value);
|
||||
void setExpirationExtension(const QString& quantity, const QString& magnitude);
|
||||
void setTotp(QSharedPointer<Totp::Settings> settings);
|
||||
|
||||
QList<Entry*> historyItems();
|
||||
|
||||
@@ -53,6 +53,16 @@ TimeDelta::TimeDelta(int days, int months, int years)
|
||||
{
|
||||
}
|
||||
|
||||
TimeDelta TimeDelta::operator*(unsigned int n)
|
||||
{
|
||||
return TimeDelta(n * m_days, n * m_months, n * m_years);
|
||||
}
|
||||
|
||||
bool TimeDelta::operator==(const TimeDelta& tD) const
|
||||
{
|
||||
return m_days == tD.getDays() && m_years == tD.getYears() && m_months == tD.getMonths();
|
||||
}
|
||||
|
||||
int TimeDelta::getDays() const
|
||||
{
|
||||
return m_days;
|
||||
|
||||
@@ -34,6 +34,8 @@ public:
|
||||
|
||||
TimeDelta();
|
||||
TimeDelta(int days, int months, int years);
|
||||
TimeDelta operator*(unsigned n);
|
||||
bool operator==(const TimeDelta& tD) const;
|
||||
|
||||
int getDays() const;
|
||||
int getMonths() const;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QStringListModel>
|
||||
#include <QTemporaryFile>
|
||||
#include <tuple>
|
||||
|
||||
#include "autotype/AutoType.h"
|
||||
#include "core/Clock.h"
|
||||
@@ -66,9 +67,24 @@
|
||||
#include "gui/entry/EntryAttributesModel.h"
|
||||
#include "gui/entry/EntryHistoryModel.h"
|
||||
|
||||
QString timeDelta2Text(const TimeDelta& tD)
|
||||
{
|
||||
if (tD.getDays()) {
|
||||
return "day(s)";
|
||||
}
|
||||
return tD.getMonths() ? "month(s)" : "year(s)";
|
||||
};
|
||||
|
||||
qint64 timeDeltaToDays(const TimeDelta& delta)
|
||||
{
|
||||
QDateTime now = Clock::currentDateTime();
|
||||
return now.daysTo(now + delta);
|
||||
}
|
||||
|
||||
EditEntryWidget::EditEntryWidget(QWidget* parent)
|
||||
: EditWidget(parent)
|
||||
, m_entry(nullptr)
|
||||
, m_extensionOnPwUpdate(std::make_tuple(0, TimeDelta(1, 0, 0)))
|
||||
, m_mainUi(new Ui::EditEntryWidgetMain())
|
||||
, m_advancedUi(new Ui::EditEntryWidgetAdvanced())
|
||||
, m_autoTypeUi(new Ui::EditEntryWidgetAutoType())
|
||||
@@ -168,7 +184,7 @@ void EditEntryWidget::setupMain()
|
||||
m_mainUi->urlEdit->enableVerifyMode();
|
||||
#endif
|
||||
connect(m_mainUi->expireCheck, &QCheckBox::toggled, [&](bool enabled) {
|
||||
m_mainUi->expireDatePicker->setEnabled(enabled);
|
||||
m_mainUi->expirationBox->setEnabled(enabled);
|
||||
if (enabled) {
|
||||
m_mainUi->expireDatePicker->setDateTime(Clock::currentDateTime());
|
||||
}
|
||||
@@ -178,6 +194,42 @@ void EditEntryWidget::setupMain()
|
||||
|
||||
m_mainUi->expirePresets->setMenu(createPresetsMenu());
|
||||
connect(m_mainUi->expirePresets->menu(), SIGNAL(triggered(QAction*)), this, SLOT(useExpiryPreset(QAction*)));
|
||||
m_mainUi->extendByMagnitude->setMenu(createExtendByMenu());
|
||||
connect(m_mainUi->extendByMagnitude->menu(), &QMenu::triggered, this, [&](QAction* action) {
|
||||
std::get<1>(m_extensionOnPwUpdate) = action->data().value<TimeDelta>();
|
||||
m_mainUi->extendByMagnitude->setText(action->text());
|
||||
m_mainUi->randomizeByQuantity->setMaximum(
|
||||
timeDeltaToDays(std::get<1>(m_extensionOnPwUpdate) * std::get<0>(m_extensionOnPwUpdate)));
|
||||
setModified(true);
|
||||
});
|
||||
connect(m_mainUi->extendByQuantity, QOverload<int>::of(&QSpinBox::valueChanged), this, [&](int n) {
|
||||
std::get<0>(m_extensionOnPwUpdate) = static_cast<unsigned>(n);
|
||||
m_mainUi->randomizeByQuantity->setMaximum(
|
||||
timeDeltaToDays(std::get<1>(m_extensionOnPwUpdate) * std::get<0>(m_extensionOnPwUpdate)));
|
||||
});
|
||||
connect(m_mainUi->autoExtendExpire, &QCheckBox::toggled, [&](bool enabled) {
|
||||
m_mainUi->extendByQuantity->setEnabled(enabled);
|
||||
m_mainUi->extendByMagnitude->setEnabled(enabled);
|
||||
m_mainUi->randomizeExtensionDeadline->setEnabled(enabled);
|
||||
});
|
||||
connect(m_mainUi->randomizeExtensionDeadline, &QCheckBox::toggled, [&](bool enabled) {
|
||||
m_mainUi->randomizeByQuantity->setEnabled(enabled);
|
||||
});
|
||||
connect(m_mainUi->randomizeByQuantity, QOverload<int>::of(&QSpinBox::valueChanged), this, [&](int n) {
|
||||
m_daysRandomizeExtension = static_cast<qint64>(n);
|
||||
});
|
||||
connect(m_mainUi->passwordEdit, &QLineEdit::textChanged, this, [&]() {
|
||||
if (m_mainUi->autoExtendExpire->isEnabled()) {
|
||||
TimeDelta delta = std::get<1>(m_extensionOnPwUpdate) * std::get<0>(m_extensionOnPwUpdate);
|
||||
QDateTime now = Clock::currentDateTime();
|
||||
QDateTime expiryDateTime = now + delta;
|
||||
if (m_mainUi->randomizeExtensionDeadline->isChecked()) {
|
||||
expiryDateTime =
|
||||
expiryDateTime.addDays(-QRandomGenerator::global()->bounded(0, m_daysRandomizeExtension + 1));
|
||||
}
|
||||
m_mainUi->expireDatePicker->setDateTime(expiryDateTime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EditEntryWidget::setupAdvanced()
|
||||
@@ -435,7 +487,9 @@ void EditEntryWidget::setupEntryUpdate()
|
||||
#endif
|
||||
connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), this, SLOT(setModified()));
|
||||
connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(setModified()));
|
||||
connect(m_mainUi->autoExtendExpire, SIGNAL(stateChanged(int)), this, SLOT(setModified()));
|
||||
connect(m_mainUi->notesEdit, SIGNAL(textChanged()), this, SLOT(setModified()));
|
||||
connect(m_mainUi->extendByQuantity, SIGNAL(valueChanged(int)), this, SLOT(setModified()));
|
||||
|
||||
// Advanced tab
|
||||
connect(m_advancedUi->attributesEdit, SIGNAL(textChanged()), this, SLOT(setModified()));
|
||||
@@ -840,6 +894,7 @@ void EditEntryWidget::setForms(Entry* entry, bool restore)
|
||||
m_mainUi->passwordEdit->setReadOnly(m_history);
|
||||
m_mainUi->expireCheck->setEnabled(!m_history);
|
||||
m_mainUi->expireDatePicker->setReadOnly(m_history);
|
||||
m_mainUi->autoExtendExpire->setEnabled(!m_history);
|
||||
m_mainUi->notesEnabled->setChecked(!config()->get(Config::Security_HideNotes).toBool());
|
||||
m_mainUi->notesEdit->setReadOnly(m_history);
|
||||
m_mainUi->notesEdit->setVisible(!config()->get(Config::Security_HideNotes).toBool());
|
||||
@@ -882,6 +937,14 @@ void EditEntryWidget::setForms(Entry* entry, bool restore)
|
||||
m_mainUi->expireCheck->setChecked(entry->timeInfo().expires());
|
||||
m_mainUi->expireDatePicker->setDateTime(entry->timeInfo().expiryTime().toLocalTime());
|
||||
m_mainUi->expirePresets->setEnabled(!m_history);
|
||||
m_mainUi->autoExtendExpire->setChecked(entry->timeInfo().expires());
|
||||
m_mainUi->autoExtendExpire->setChecked(entry->customData()->value("ExpirationExtension").toInt());
|
||||
m_mainUi->extendByQuantity->setEnabled(m_mainUi->autoExtendExpire->isChecked());
|
||||
m_mainUi->extendByQuantity->setValue(entry->customData()->value("ExpirationExtensionQuantity").toInt());
|
||||
m_mainUi->extendByMagnitude->setEnabled(m_mainUi->autoExtendExpire->isChecked());
|
||||
m_mainUi->extendByMagnitude->setText(entry->customData()->value("ExpirationExtensionMagnitude"));
|
||||
m_mainUi->randomizeByQuantity->setMaximum(
|
||||
timeDeltaToDays(std::get<1>(m_extensionOnPwUpdate) * std::get<0>(m_extensionOnPwUpdate)));
|
||||
|
||||
QList<QString> commonUsernames = m_db->commonUsernames();
|
||||
m_usernameCompleterModel->setStringList(commonUsernames);
|
||||
@@ -1122,7 +1185,9 @@ void EditEntryWidget::updateEntryData(Entry* entry) const
|
||||
entry->setPassword(m_mainUi->passwordEdit->text());
|
||||
entry->setExpires(m_mainUi->expireCheck->isChecked());
|
||||
entry->setExpiryTime(m_mainUi->expireDatePicker->dateTime().toUTC());
|
||||
|
||||
entry->setExtendsExpirationOnPwdChange(m_mainUi->autoExtendExpire->isChecked());
|
||||
entry->setExpirationExtension(QString::number(std::get<0>(m_extensionOnPwUpdate)),
|
||||
timeDelta2Text(std::get<1>(m_extensionOnPwUpdate)));
|
||||
entry->setNotes(m_mainUi->notesEdit->toPlainText());
|
||||
|
||||
if (entry->excludeFromReports() != m_advancedUi->excludeReportsCheckBox->isChecked()) {
|
||||
@@ -1526,6 +1591,18 @@ QMenu* EditEntryWidget::createPresetsMenu()
|
||||
return expirePresetsMenu;
|
||||
}
|
||||
|
||||
QMenu* EditEntryWidget::createExtendByMenu()
|
||||
{
|
||||
auto* expirePresetsMenu = new QMenu(this);
|
||||
auto tD = TimeDelta::fromDays(1);
|
||||
expirePresetsMenu->addAction(timeDelta2Text(tD))->setData(QVariant::fromValue(tD));
|
||||
tD = TimeDelta::fromMonths(1);
|
||||
expirePresetsMenu->addAction(timeDelta2Text(tD))->setData(QVariant::fromValue(tD));
|
||||
tD = TimeDelta::fromYears(1);
|
||||
expirePresetsMenu->addAction(timeDelta2Text(tD))->setData(QVariant::fromValue(tD));
|
||||
return expirePresetsMenu;
|
||||
}
|
||||
|
||||
void EditEntryWidget::setupColorButton(bool foreground, const QColor& color)
|
||||
{
|
||||
QWidget* button = m_advancedUi->fgColorButton;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "core/TimeDelta.h"
|
||||
#include "gui/EditWidget.h"
|
||||
|
||||
class AutoTypeAssociations;
|
||||
@@ -152,6 +153,7 @@ private:
|
||||
bool passwordsEqual();
|
||||
void setForms(Entry* entry, bool restore = false);
|
||||
QMenu* createPresetsMenu();
|
||||
QMenu* createExtendByMenu();
|
||||
void updateEntryData(Entry* entry) const;
|
||||
#ifdef WITH_XC_SSHAGENT
|
||||
bool getOpenSSHKey(OpenSSHKey& key, bool decrypt = false);
|
||||
@@ -162,6 +164,9 @@ private:
|
||||
QPointer<Entry> m_entry;
|
||||
QSharedPointer<Database> m_db;
|
||||
|
||||
std::tuple<unsigned, TimeDelta> m_extensionOnPwUpdate;
|
||||
qint64 m_daysRandomizeExtension;
|
||||
|
||||
bool m_create;
|
||||
bool m_history;
|
||||
#ifdef WITH_XC_SSHAGENT
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<property name="verticalSpacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="notesEdit">
|
||||
@@ -99,7 +99,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="7" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notesEnabled">
|
||||
@@ -129,45 +129,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QDateTimeEdit" name="expireDatePicker">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Expiration field</string>
|
||||
</property>
|
||||
<property name="calendarPopup">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="expirePresets">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Expiration Presets</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Expiration presets</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Presets</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="passwordLabel">
|
||||
<property name="text">
|
||||
@@ -252,25 +213,177 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="expireCheck">
|
||||
<property name="toolTip">
|
||||
<string>Toggle expiration</string>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="expireCheck">
|
||||
<property name="toolTip">
|
||||
<string>Toggle expiration</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Toggle expiration</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Expires:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<property name="accessibleName">
|
||||
<string>Toggle expiration</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Configure an expiration date</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QGroupBox" name="expirationBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Expiration settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_expiration">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_expiration">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QDateTimeEdit" name="expireDatePicker">
|
||||
<property name="accessibleName">
|
||||
<string>Expiration field</string>
|
||||
</property>
|
||||
<property name="calendarPopup">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="expirePresets">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Expiration Presets</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Expiration presets</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Presets</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalautoUpdate">
|
||||
<property name="spacing">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="autoExtendExpire">
|
||||
<property name="toolTip">
|
||||
<string>Toggle auto updating expiration</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Toggle auto updating expiration date</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Extend when password is changed, by:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="extendByQuantity">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="FixedWidth">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="extendByMagnitude">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Expiration extension Presets</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Expiration extension presets</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Time period</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalRandomize">
|
||||
<property name="spacing">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="randomizeExtensionDeadline">
|
||||
<property name="toolTip">
|
||||
<string>Toggle randomizing expiration date</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Toggle randomizing expiration date</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Randomize the extension deadline within </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="randomizeByQuantity">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="FixedWidth">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel">
|
||||
<property name="visible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> days from the deadline</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@@ -301,6 +414,6 @@
|
||||
<tabstop>notesEnabled</tabstop>
|
||||
<tabstop>notesEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<resources />
|
||||
<connections />
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user