diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index ad7ecce2b..6ebc86421 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -231,6 +231,33 @@ const QSharedPointer Entry::passwordHealth() const return m_data.passwordHealth; } +int Entry::getPasswordAgeInDays() const +{ + QListIterator i(m_history); + i.toBack(); + Entry* compare = nullptr; + Entry* curr = nullptr; + + while (i.hasPrevious()) { + curr = i.previous(); + if (!compare) { + compare = curr; + continue; + } + if (*curr->attributes() != *compare->attributes()) { + if (curr->password() != compare->password()) { + // Found most recent password change; break out. + break; + } + } + } + if (!curr) { + // If no change in history, password is from creation time + return this->timeInfo().creationTime().daysTo(QDateTime::currentDateTime()); + } + return curr->timeInfo().lastModificationTime().daysTo(QDateTime::currentDateTime()); +} + bool Entry::excludeFromReports() const { return m_data.excludeFromReports diff --git a/src/core/Entry.h b/src/core/Entry.h index 7fc69c8fb..244dd63b4 100644 --- a/src/core/Entry.h +++ b/src/core/Entry.h @@ -116,6 +116,7 @@ public: QString path() const; const QSharedPointer passwordHealth(); const QSharedPointer passwordHealth() const; + int getPasswordAgeInDays() const; bool excludeFromReports() const; void setExcludeFromReports(bool state); diff --git a/src/core/PasswordHealth.cpp b/src/core/PasswordHealth.cpp index 3225affb3..16c602dbd 100644 --- a/src/core/PasswordHealth.cpp +++ b/src/core/PasswordHealth.cpp @@ -198,6 +198,15 @@ QSharedPointer HealthChecker::evaluate(const Entry* entry) const } } + // Fourth, reduce score by 5 for each year beyond one year old. + int age = entry->getPasswordAgeInDays(); + int ageInYears = age / 365; + if (ageInYears > 1) { + constexpr auto penalty = 5; + health->adjustScore(-penalty * ageInYears); + health->addScoreReason(QObject::tr("Password is %1 year(s) old", "", ageInYears).arg(ageInYears)); + } + // Return the result return health; }