mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Merge pull request #2443 from brainplot/code-cleanup
Code cleanup and performance improvements - Part 2
This commit is contained in:
commit
c66f293f1e
@ -672,7 +672,7 @@ bool AutoType::checkSyntax(const QString& string)
|
||||
QString shortcutKeys = "[\\^\\%~\\+@]";
|
||||
// a normal string not in parentheses
|
||||
QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*";
|
||||
|
||||
// clang-format off
|
||||
QRegularExpression autoTypeSyntax(
|
||||
"^(?:" + shortcutKeys + "|" + fixedStrings + "|\\{(?:" + normalCommands + "|" + specialLiterals + "|"
|
||||
+ functionKeys
|
||||
@ -688,6 +688,7 @@ bool AutoType::checkSyntax(const QString& string)
|
||||
+ customAttributes
|
||||
+ "\\})*$",
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
// clang-format on
|
||||
QRegularExpressionMatch match = autoTypeSyntax.match(string);
|
||||
return match.hasMatch();
|
||||
}
|
||||
@ -755,8 +756,9 @@ bool AutoType::verifyAutoTypeSyntax(const QString& sequence)
|
||||
}
|
||||
} else if (AutoType::checkHighRepetition(sequence)) {
|
||||
QMessageBox::StandardButton reply;
|
||||
reply =
|
||||
QMessageBox::question(nullptr, tr("Auto-Type"), tr("This Auto-Type command contains arguments which are "
|
||||
reply = QMessageBox::question(nullptr,
|
||||
tr("Auto-Type"),
|
||||
tr("This Auto-Type command contains arguments which are "
|
||||
"repeated very often. Do you really want to proceed?"));
|
||||
|
||||
if (reply == QMessageBox::No) {
|
||||
|
@ -67,10 +67,13 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
|
||||
QLabel* descriptionLabel = new QLabel(tr("Select entry to Auto-Type:"), this);
|
||||
layout->addWidget(descriptionLabel);
|
||||
|
||||
// clang-format off
|
||||
connect(m_view, SIGNAL(activated(QModelIndex)), SLOT(emitMatchActivated(QModelIndex)));
|
||||
connect(m_view, SIGNAL(clicked(QModelIndex)), SLOT(emitMatchActivated(QModelIndex)));
|
||||
connect(m_view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(matchRemoved()));
|
||||
connect(m_view, SIGNAL(rejected()), SLOT(reject()));
|
||||
// clang-format on
|
||||
|
||||
layout->addWidget(m_view);
|
||||
|
||||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, Qt::Horizontal, this);
|
||||
|
@ -211,8 +211,7 @@ int AutoTypePlatformX11::platformEventFilter(void* event)
|
||||
xcb_key_press_event_t* keyPressEvent = static_cast<xcb_key_press_event_t*>(event);
|
||||
if (keyPressEvent->detail == m_currentGlobalKeycode
|
||||
&& (keyPressEvent->state & m_modifierMask) == m_currentGlobalNativeModifiers
|
||||
&& (!QApplication::activeWindow() || QApplication::activeWindow()->isMinimized())
|
||||
&& m_loaded) {
|
||||
&& (!QApplication::activeWindow() || QApplication::activeWindow()->isMinimized()) && m_loaded) {
|
||||
if (type == XCB_KEY_PRESS) {
|
||||
emit globalShortcutTriggered();
|
||||
}
|
||||
|
@ -17,9 +17,10 @@
|
||||
*/
|
||||
|
||||
#include "BrowserAccessControlDialog.h"
|
||||
#include "core/Entry.h"
|
||||
#include "ui_BrowserAccessControlDialog.h"
|
||||
|
||||
#include "core/Entry.h"
|
||||
|
||||
BrowserAccessControlDialog::BrowserAccessControlDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::BrowserAccessControlDialog())
|
||||
|
@ -167,7 +167,8 @@ QJsonObject BrowserAction::handleAssociate(const QJsonObject& json, const QStrin
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (key.compare(m_clientPublicKey, Qt::CaseSensitive) == 0) {
|
||||
// Check for identification key. If it's not found, ensure backwards compatibility and use the current public key
|
||||
// Check for identification key. If it's not found, ensure backwards compatibility and use the current public
|
||||
// key
|
||||
const QString idKey = decrypted.value("idKey").toString();
|
||||
const QString id = m_browserService.storeKey((idKey.isEmpty() ? key : idKey));
|
||||
if (id.isEmpty()) {
|
||||
|
@ -19,11 +19,12 @@
|
||||
#ifndef BROWSERENTRYSAVEDIALOG_H
|
||||
#define BROWSERENTRYSAVEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
#include <QListWidgetItem>
|
||||
#include "gui/DatabaseTabWidget.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidgetItem>
|
||||
#include <QScopedPointer>
|
||||
|
||||
class Entry;
|
||||
|
||||
namespace Ui
|
||||
|
@ -18,10 +18,11 @@
|
||||
*/
|
||||
|
||||
#include "BrowserOptionDialog.h"
|
||||
#include "ui_BrowserOptionDialog.h"
|
||||
|
||||
#include "BrowserSettings.h"
|
||||
#include "config-keepassx.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "ui_BrowserOptionDialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
@ -32,18 +33,24 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent)
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->extensionLabel->setOpenExternalLinks(true);
|
||||
m_ui->extensionLabel->setText(tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2.").arg(
|
||||
"<a href=\"https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/\">Firefox</a>",
|
||||
"<a href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk\">Google Chrome / Chromium / Vivaldi</a>"));
|
||||
m_ui->extensionLabel->setText(
|
||||
tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2.")
|
||||
.arg("<a href=\"https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/\">Firefox</a>",
|
||||
"<a "
|
||||
"href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/"
|
||||
"oboonakemofpalcgghocfoadofidjkkk\">Google Chrome / Chromium / Vivaldi</a>"));
|
||||
|
||||
m_ui->scriptWarningWidget->setVisible(false);
|
||||
m_ui->scriptWarningWidget->setAutoHideTimeout(-1);
|
||||
m_ui->scriptWarningWidget->showMessage(tr("<b>Warning</b>, the keepassxc-proxy application was not found!"
|
||||
m_ui->scriptWarningWidget->showMessage(
|
||||
tr("<b>Warning</b>, the keepassxc-proxy application was not found!"
|
||||
"<br />Please check the KeePassXC installation directory or confirm the custom path in advanced options."
|
||||
"<br />Browser integration WILL NOT WORK without the proxy application."
|
||||
"<br />Expected Path: "), MessageWidget::Warning);
|
||||
"<br />Expected Path: "),
|
||||
MessageWidget::Warning);
|
||||
|
||||
m_ui->warningWidget->showMessage(tr("<b>Warning:</b> The following options can be dangerous!"), MessageWidget::Warning);
|
||||
m_ui->warningWidget->showMessage(tr("<b>Warning:</b> The following options can be dangerous!"),
|
||||
MessageWidget::Warning);
|
||||
m_ui->warningWidget->setCloseButtonVisible(false);
|
||||
m_ui->warningWidget->setAutoHideTimeout(-1);
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
#ifndef BROWSEROPTIONDIALOG_H
|
||||
#define BROWSEROPTIONDIALOG_H
|
||||
|
||||
#include <QScopedPointer>
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
|
@ -17,16 +17,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QInputDialog>
|
||||
#include <QProgressDialog>
|
||||
#include <QJsonArray>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
#include <QUuid>
|
||||
|
||||
#include "BrowserService.h"
|
||||
#include "BrowserAccessControlDialog.h"
|
||||
#include "BrowserEntryConfig.h"
|
||||
#include "BrowserEntrySaveDialog.h"
|
||||
#include "BrowserService.h"
|
||||
#include "BrowserSettings.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/EntrySearcher.h"
|
||||
@ -54,7 +54,8 @@ BrowserService::BrowserService(DatabaseTabWidget* parent)
|
||||
// Don't connect the signals when used from DatabaseSettingsWidgetBrowser (parent is nullptr)
|
||||
if (m_dbTabWidget) {
|
||||
connect(m_dbTabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), this, SLOT(databaseLocked(DatabaseWidget*)));
|
||||
connect(m_dbTabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), this, SLOT(databaseUnlocked(DatabaseWidget*)));
|
||||
connect(
|
||||
m_dbTabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), this, SLOT(databaseUnlocked(DatabaseWidget*)));
|
||||
connect(m_dbTabWidget,
|
||||
SIGNAL(activateDatabaseChanged(DatabaseWidget*)),
|
||||
this,
|
||||
@ -355,7 +356,8 @@ void BrowserService::updateEntry(const QString& id,
|
||||
return;
|
||||
}
|
||||
|
||||
if (username.compare(login, Qt::CaseSensitive) != 0 || entry->password().compare(password, Qt::CaseSensitive) != 0) {
|
||||
if (username.compare(login, Qt::CaseSensitive) != 0
|
||||
|| entry->password().compare(password, Qt::CaseSensitive) != 0) {
|
||||
int dialogResult = QMessageBox::No;
|
||||
if (!browserSettings()->alwaysAllowUpdate()) {
|
||||
QMessageBox msgBox;
|
||||
@ -394,8 +396,9 @@ QList<Entry*> BrowserService::searchEntries(QSharedPointer<Database> db, const Q
|
||||
QUrl qUrl(url);
|
||||
|
||||
// Ignore entry if port or scheme defined in the URL doesn't match
|
||||
if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port()) ||
|
||||
(browserSettings()->matchUrlScheme() && !entryScheme.isEmpty() && entryScheme.compare(qUrl.scheme()) != 0)) {
|
||||
if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port())
|
||||
|| (browserSettings()->matchUrlScheme() && !entryScheme.isEmpty()
|
||||
&& entryScheme.compare(qUrl.scheme()) != 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -420,7 +423,8 @@ QList<Entry*> BrowserService::searchEntries(const QString& url, const StringPair
|
||||
if (const auto& db = dbWidget->database()) {
|
||||
// Check if database is connected with KeePassXC-Browser
|
||||
for (const StringPair& keyPair : keyList) {
|
||||
QString key = db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + keyPair.first);
|
||||
QString key =
|
||||
db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + keyPair.first);
|
||||
if (!key.isEmpty() && keyPair.second == key) {
|
||||
databases << db;
|
||||
}
|
||||
@ -484,16 +488,22 @@ void BrowserService::convertAttributesToCustomData(QSharedPointer<Database> curr
|
||||
progress.reset();
|
||||
|
||||
if (counter > 0) {
|
||||
QMessageBox::information(nullptr, tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
QMessageBox::information(nullptr,
|
||||
tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
tr("Successfully converted attributes from %1 entry(s).\n"
|
||||
"Moved %2 keys to custom data.", "").arg(counter).arg(keyCounter),
|
||||
"Moved %2 keys to custom data.",
|
||||
"")
|
||||
.arg(counter)
|
||||
.arg(keyCounter),
|
||||
QMessageBox::Ok);
|
||||
} else if (counter == 0 && keyCounter > 0) {
|
||||
QMessageBox::information(nullptr, tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
QMessageBox::information(nullptr,
|
||||
tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
tr("Successfully moved %n keys to custom data.", "", keyCounter),
|
||||
QMessageBox::Ok);
|
||||
} else {
|
||||
QMessageBox::information(nullptr, tr("KeePassXC: No entry with KeePassHTTP attributes found!"),
|
||||
QMessageBox::information(nullptr,
|
||||
tr("KeePassXC: No entry with KeePassHTTP attributes found!"),
|
||||
tr("The active database does not contain an entry with KeePassHTTP attributes."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
@ -539,9 +549,14 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin
|
||||
// Sort same priority entries by Title or UserName
|
||||
auto entries = priorities.values(i);
|
||||
std::sort(entries.begin(), entries.end(), [&field](Entry* left, Entry* right) {
|
||||
return (QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) < 0) ||
|
||||
((QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) == 0) &&
|
||||
(QString::localeAwareCompare(left->attributes()->value("UserName"), right->attributes()->value("UserName")) < 0));
|
||||
return (QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field))
|
||||
< 0)
|
||||
|| ((QString::localeAwareCompare(left->attributes()->value(field),
|
||||
right->attributes()->value(field))
|
||||
== 0)
|
||||
&& (QString::localeAwareCompare(left->attributes()->value("UserName"),
|
||||
right->attributes()->value("UserName"))
|
||||
< 0));
|
||||
});
|
||||
results << entries;
|
||||
if (browserSettings()->bestMatchOnly() && !pwEntries.isEmpty()) {
|
||||
@ -843,7 +858,8 @@ int BrowserService::moveKeysToCustomData(Entry* entry, QSharedPointer<Database>
|
||||
|
||||
// Add key to database custom data
|
||||
if (db && !db->metadata()->customData()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey)) {
|
||||
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey, entry->attributes()->value(key));
|
||||
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey,
|
||||
entry->attributes()->value(key));
|
||||
++keyCounter;
|
||||
}
|
||||
}
|
||||
@ -879,7 +895,6 @@ bool BrowserService::checkLegacySettings()
|
||||
"Do you want to upgrade the settings to the latest standard?\n"
|
||||
"This is necessary to maintain compatibility with the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
return dialogResult == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,10 @@ HostInstaller::HostInstaller()
|
||||
, TARGET_DIR_VIVALDI("/.config/vivaldi/NativeMessagingHosts")
|
||||
, TARGET_DIR_TOR_BROWSER("/.tor-browser/app/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts")
|
||||
#elif defined(Q_OS_WIN)
|
||||
// clang-format off
|
||||
, TARGET_DIR_CHROME("HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
, TARGET_DIR_CHROMIUM("HKEY_CURRENT_USER\\Software\\Chromium\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
// clang-format on
|
||||
, TARGET_DIR_FIREFOX("HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
, TARGET_DIR_VIVALDI(TARGET_DIR_CHROME)
|
||||
, TARGET_DIR_TOR_BROWSER(TARGET_DIR_FIREFOX)
|
||||
|
@ -138,7 +138,8 @@ QString NativeMessagingBase::getLocalServerPath() const
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
// Use XDG_RUNTIME_DIR instead of /tmp if it's available
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
||||
return path.isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::TempLocation) + serverPath : path + serverPath;
|
||||
return path.isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::TempLocation) + serverPath
|
||||
: path + serverPath;
|
||||
#else // Q_OS_MACOS, Q_OS_WIN and others
|
||||
return QStandardPaths::writableLocation(QStandardPaths::TempLocation) + serverPath;
|
||||
#endif
|
||||
|
@ -33,8 +33,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
static const int NATIVE_MSG_MAX_LENGTH = 1024 * 1024;
|
||||
|
@ -65,8 +65,8 @@ void NativeMessagingHost::run()
|
||||
|
||||
// Update KeePassXC/keepassxc-proxy binary paths to Native Messaging scripts
|
||||
if (browserSettings()->updateBinaryPath()) {
|
||||
browserSettings()->updateBinaryPaths(browserSettings()->useCustomProxy() ? browserSettings()->customProxyLocation()
|
||||
: "");
|
||||
browserSettings()->updateBinaryPaths(
|
||||
browserSettings()->useCustomProxy() ? browserSettings()->customProxyLocation() : "");
|
||||
}
|
||||
|
||||
m_running.store(true);
|
||||
|
@ -51,7 +51,8 @@ int Add::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption username(QStringList() << "u" << "username",
|
||||
QCommandLineOption username(QStringList() << "u"
|
||||
<< "username",
|
||||
QObject::tr("Username for the entry."),
|
||||
QObject::tr("username"));
|
||||
parser.addOption(username);
|
||||
@ -59,15 +60,18 @@ int Add::execute(const QStringList& arguments)
|
||||
QCommandLineOption url(QStringList() << "url", QObject::tr("URL for the entry."), QObject::tr("URL"));
|
||||
parser.addOption(url);
|
||||
|
||||
QCommandLineOption prompt(QStringList() << "p" << "password-prompt",
|
||||
QCommandLineOption prompt(QStringList() << "p"
|
||||
<< "password-prompt",
|
||||
QObject::tr("Prompt for the entry's password."));
|
||||
parser.addOption(prompt);
|
||||
|
||||
QCommandLineOption generate(QStringList() << "g" << "generate",
|
||||
QCommandLineOption generate(QStringList() << "g"
|
||||
<< "generate",
|
||||
QObject::tr("Generate a password for the entry."));
|
||||
parser.addOption(generate);
|
||||
|
||||
QCommandLineOption length(QStringList() << "l" << "password-length",
|
||||
QCommandLineOption length(QStringList() << "l"
|
||||
<< "password-length",
|
||||
QObject::tr("Length for the generated password."),
|
||||
QObject::tr("length"));
|
||||
parser.addOption(length);
|
||||
|
@ -50,12 +50,13 @@ int Clip::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption totp(QStringList() << "t" << "totp",
|
||||
QCommandLineOption totp(QStringList() << "t"
|
||||
<< "totp",
|
||||
QObject::tr("Copy the current TOTP to the clipboard."));
|
||||
parser.addOption(totp);
|
||||
parser.addPositionalArgument("entry", QObject::tr("Path of the entry to clip.", "clip = copy to clipboard"));
|
||||
parser.addPositionalArgument("timeout",
|
||||
QObject::tr("Timeout in seconds before clearing the clipboard."), "[timeout]");
|
||||
parser.addPositionalArgument(
|
||||
"timeout", QObject::tr("Timeout in seconds before clearing the clipboard."), "[timeout]");
|
||||
parser.addHelpOption();
|
||||
parser.process(arguments);
|
||||
|
||||
|
@ -43,11 +43,13 @@ int Diceware::execute(const QStringList& arguments)
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(description);
|
||||
QCommandLineOption words(QStringList() << "W" << "words",
|
||||
QCommandLineOption words(QStringList() << "W"
|
||||
<< "words",
|
||||
QObject::tr("Word count for the diceware passphrase."),
|
||||
QObject::tr("count", "CLI parameter"));
|
||||
parser.addOption(words);
|
||||
QCommandLineOption wordlistFile(QStringList() << "w" << "word-list",
|
||||
QCommandLineOption wordlistFile(QStringList() << "w"
|
||||
<< "word-list",
|
||||
QObject::tr("Wordlist for the diceware generator.\n[Default: EFF English]"),
|
||||
QObject::tr("path"));
|
||||
parser.addOption(wordlistFile);
|
||||
|
@ -51,7 +51,8 @@ int Edit::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption username(QStringList() << "u" << "username",
|
||||
QCommandLineOption username(QStringList() << "u"
|
||||
<< "username",
|
||||
QObject::tr("Username for the entry."),
|
||||
QObject::tr("username"));
|
||||
parser.addOption(username);
|
||||
@ -59,20 +60,24 @@ int Edit::execute(const QStringList& arguments)
|
||||
QCommandLineOption url(QStringList() << "url", QObject::tr("URL for the entry."), QObject::tr("URL"));
|
||||
parser.addOption(url);
|
||||
|
||||
QCommandLineOption title(QStringList() << "t" << "title",
|
||||
QCommandLineOption title(QStringList() << "t"
|
||||
<< "title",
|
||||
QObject::tr("Title for the entry."),
|
||||
QObject::tr("title"));
|
||||
parser.addOption(title);
|
||||
|
||||
QCommandLineOption prompt(QStringList() << "p" << "password-prompt",
|
||||
QCommandLineOption prompt(QStringList() << "p"
|
||||
<< "password-prompt",
|
||||
QObject::tr("Prompt for the entry's password."));
|
||||
parser.addOption(prompt);
|
||||
|
||||
QCommandLineOption generate(QStringList() << "g" << "generate",
|
||||
QCommandLineOption generate(QStringList() << "g"
|
||||
<< "generate",
|
||||
QObject::tr("Generate a password for the entry."));
|
||||
parser.addOption(generate);
|
||||
|
||||
QCommandLineOption length(QStringList() << "l" << "password-length",
|
||||
QCommandLineOption length(QStringList() << "l"
|
||||
<< "password-length",
|
||||
QObject::tr("Length for the generated password."),
|
||||
QObject::tr("length"));
|
||||
parser.addOption(length);
|
||||
@ -111,8 +116,7 @@ int Edit::execute(const QStringList& arguments)
|
||||
}
|
||||
|
||||
if (parser.value("username").isEmpty() && parser.value("url").isEmpty() && parser.value("title").isEmpty()
|
||||
&& !parser.isSet(prompt)
|
||||
&& !parser.isSet(generate)) {
|
||||
&& !parser.isSet(prompt) && !parser.isSet(generate)) {
|
||||
err << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -51,9 +51,11 @@ static void estimate(const char* pwd, bool advanced)
|
||||
int len = static_cast<int>(strlen(pwd));
|
||||
if (!advanced) {
|
||||
e = ZxcvbnMatch(pwd, nullptr, nullptr);
|
||||
// clang-format off
|
||||
out << QObject::tr("Length %1").arg(len, 0) << '\t'
|
||||
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
|
||||
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << endl;
|
||||
// clang-format on
|
||||
} else {
|
||||
int ChkLen = 0;
|
||||
ZxcMatch_t *info, *p;
|
||||
@ -63,10 +65,12 @@ static void estimate(const char* pwd, bool advanced)
|
||||
m += p->Entrpy;
|
||||
}
|
||||
m = e - m;
|
||||
// clang-format off
|
||||
out << QObject::tr("Length %1").arg(len) << '\t'
|
||||
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
|
||||
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << "\n "
|
||||
<< QObject::tr("Multi-word extra bits %1").arg(m, 0, 'f', 1) << endl;
|
||||
// clang-format on
|
||||
p = info;
|
||||
ChkLen = 0;
|
||||
while (p) {
|
||||
@ -132,9 +136,10 @@ static void estimate(const char* pwd, bool advanced)
|
||||
break;
|
||||
}
|
||||
ChkLen += p->Length;
|
||||
|
||||
// clang-format off
|
||||
out << QObject::tr("Length %1").arg(p->Length) << '\t'
|
||||
<< QObject::tr("Entropy %1 (%2)").arg(p->Entrpy, 6, 'f', 3).arg(p->Entrpy * 0.301029996, 0, 'f', 2) << '\t';
|
||||
// clang-format on
|
||||
for (n = 0; n < p->Length; ++n, ++pwd) {
|
||||
out << *pwd;
|
||||
}
|
||||
@ -143,7 +148,8 @@ static void estimate(const char* pwd, bool advanced)
|
||||
}
|
||||
ZxcvbnFreeInfo(info);
|
||||
if (ChkLen != len) {
|
||||
out << QObject::tr("*** Password length (%1) != sum of length of parts (%2) ***").arg(len).arg(ChkLen) << endl;
|
||||
out << QObject::tr("*** Password length (%1) != sum of length of parts (%2) ***").arg(len).arg(ChkLen)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -156,7 +162,8 @@ int Estimate::execute(const QStringList& arguments)
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(description);
|
||||
parser.addPositionalArgument("password", QObject::tr("Password for which to estimate the entropy."), "[password]");
|
||||
QCommandLineOption advancedOption(QStringList() << "a" << "advanced",
|
||||
QCommandLineOption advancedOption(QStringList() << "a"
|
||||
<< "advanced",
|
||||
QObject::tr("Perform advanced analysis on the password."));
|
||||
parser.addOption(advancedOption);
|
||||
parser.addHelpOption();
|
||||
|
@ -84,7 +84,8 @@ int Extract::execute(const QStringList& arguments)
|
||||
if (fileKey->type() != FileKey::Hashed) {
|
||||
err << QObject::tr("WARNING: You are using a legacy key file format which may become\n"
|
||||
"unsupported in the future.\n\n"
|
||||
"Please consider generating a new key file.") << endl;
|
||||
"Please consider generating a new key file.")
|
||||
<< endl;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
|
@ -43,26 +43,33 @@ int Generate::execute(const QStringList& arguments)
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(description);
|
||||
QCommandLineOption len(QStringList() << "L" << "length",
|
||||
QCommandLineOption len(QStringList() << "L"
|
||||
<< "length",
|
||||
QObject::tr("Length of the generated password"),
|
||||
QObject::tr("length"));
|
||||
parser.addOption(len);
|
||||
QCommandLineOption lower(QStringList() << "l" << "lower",
|
||||
QCommandLineOption lower(QStringList() << "l"
|
||||
<< "lower",
|
||||
QObject::tr("Use lowercase characters"));
|
||||
parser.addOption(lower);
|
||||
QCommandLineOption upper(QStringList() << "u" << "upper",
|
||||
QCommandLineOption upper(QStringList() << "u"
|
||||
<< "upper",
|
||||
QObject::tr("Use uppercase characters"));
|
||||
parser.addOption(upper);
|
||||
QCommandLineOption numeric(QStringList() << "n" << "numeric",
|
||||
QCommandLineOption numeric(QStringList() << "n"
|
||||
<< "numeric",
|
||||
QObject::tr("Use numbers."));
|
||||
parser.addOption(numeric);
|
||||
QCommandLineOption special(QStringList() << "s" << "special",
|
||||
QCommandLineOption special(QStringList() << "s"
|
||||
<< "special",
|
||||
QObject::tr("Use special characters"));
|
||||
parser.addOption(special);
|
||||
QCommandLineOption extended(QStringList() << "e" << "extended",
|
||||
QCommandLineOption extended(QStringList() << "e"
|
||||
<< "extended",
|
||||
QObject::tr("Use extended ASCII"));
|
||||
parser.addOption(extended);
|
||||
QCommandLineOption exclude(QStringList() << "x" << "exclude",
|
||||
QCommandLineOption exclude(QStringList() << "x"
|
||||
<< "exclude",
|
||||
QObject::tr("Exclude character set"),
|
||||
QObject::tr("chars"));
|
||||
parser.addOption(exclude);
|
||||
|
@ -49,7 +49,8 @@ int List::execute(const QStringList& arguments)
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption recursiveOption(QStringList() << "R" << "recursive",
|
||||
QCommandLineOption recursiveOption(QStringList() << "R"
|
||||
<< "recursive",
|
||||
QObject::tr("Recursively list the elements of the group."));
|
||||
parser.addOption(recursiveOption);
|
||||
parser.addHelpOption();
|
||||
|
@ -47,12 +47,14 @@ int Merge::execute(const QStringList& arguments)
|
||||
parser.addPositionalArgument("database2", QObject::tr("Path of the database to merge from."));
|
||||
parser.addOption(Command::QuietOption);
|
||||
|
||||
QCommandLineOption samePasswordOption(QStringList() << "s" << "same-credentials",
|
||||
QCommandLineOption samePasswordOption(QStringList() << "s"
|
||||
<< "same-credentials",
|
||||
QObject::tr("Use the same credentials for both database files."));
|
||||
parser.addOption(samePasswordOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
|
||||
QCommandLineOption keyFileFromOption(QStringList() << "f" << "key-file-from",
|
||||
QCommandLineOption keyFileFromOption(QStringList() << "f"
|
||||
<< "key-file-from",
|
||||
QObject::tr("Key file of the database to merge from."),
|
||||
QObject::tr("path"));
|
||||
parser.addOption(keyFileFromOption);
|
||||
|
@ -48,11 +48,13 @@ int Show::execute(const QStringList& arguments)
|
||||
parser.addPositionalArgument("database", QObject::tr("Path of the database."));
|
||||
parser.addOption(Command::QuietOption);
|
||||
parser.addOption(Command::KeyFileOption);
|
||||
QCommandLineOption totp(QStringList() << "t" << "totp",
|
||||
QCommandLineOption totp(QStringList() << "t"
|
||||
<< "totp",
|
||||
QObject::tr("Show the entry's current TOTP."));
|
||||
parser.addOption(totp);
|
||||
QCommandLineOption attributes(
|
||||
QStringList() << "a" << "attributes",
|
||||
QStringList() << "a"
|
||||
<< "attributes",
|
||||
QObject::tr(
|
||||
"Names of the attributes to show. "
|
||||
"This option can be specified more than once, with each attribute shown one-per-line in the given order. "
|
||||
|
@ -67,7 +67,6 @@ void setStdinEcho(bool enable = true)
|
||||
}
|
||||
|
||||
SetConsoleMode(hIn, mode);
|
||||
|
||||
#else
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t);
|
||||
|
@ -18,8 +18,8 @@
|
||||
#ifndef KEEPASSXC_UTILS_H
|
||||
#define KEEPASSXC_UTILS_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include "cli/TextStream.h"
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
@ -36,6 +36,6 @@ namespace Test
|
||||
{
|
||||
void setNextPassword(const QString& password);
|
||||
}
|
||||
};
|
||||
}; // namespace Utils
|
||||
|
||||
#endif // KEEPASSXC_UTILS_H
|
||||
|
@ -15,7 +15,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef KEEPASSXC_BOOTSTRAP_H
|
||||
#define KEEPASSXC_BOOTSTRAP_H
|
||||
|
||||
@ -28,7 +27,6 @@ void restoreMainWindowState(MainWindow& mainWindow);
|
||||
void disableCoreDumps();
|
||||
bool createWindowsDACL();
|
||||
void setupSearchPaths();
|
||||
};
|
||||
|
||||
}; // namespace Bootstrap
|
||||
|
||||
#endif // KEEPASSXC_BOOTSTRAP_H
|
||||
|
@ -403,11 +403,12 @@ QString CsvParser::getStatus() const
|
||||
|
||||
int CsvParser::getCsvCols() const
|
||||
{
|
||||
if ((m_table.size() > 0) && (m_table.at(0).size() > 0))
|
||||
if (!m_table.isEmpty() && !m_table.at(0).isEmpty()) {
|
||||
return m_table.at(0).size();
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int CsvParser::getCsvRows() const
|
||||
{
|
||||
|
@ -727,7 +727,8 @@ QSharedPointer<Database> Database::unlockFromStdin(const QString& databaseFilena
|
||||
if (fileKey->type() != FileKey::Hashed) {
|
||||
err << QObject::tr("WARNING: You are using a legacy key file format which may become\n"
|
||||
"unsupported in the future.\n\n"
|
||||
"Please consider generating a new key file.") << endl;
|
||||
"Please consider generating a new key file.")
|
||||
<< endl;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
|
@ -657,12 +657,14 @@ Entry* Entry::clone(CloneFlags flags) const
|
||||
if (flags & CloneUserAsRef) {
|
||||
// Build the username reference
|
||||
QString username = "{REF:U@I:" + uuidToHex() + "}";
|
||||
entry->m_attributes->set(EntryAttributes::UserNameKey, username.toUpper(), m_attributes->isProtected(EntryAttributes::UserNameKey));
|
||||
entry->m_attributes->set(
|
||||
EntryAttributes::UserNameKey, username.toUpper(), m_attributes->isProtected(EntryAttributes::UserNameKey));
|
||||
}
|
||||
|
||||
if (flags & ClonePassAsRef) {
|
||||
QString password = "{REF:P@I:" + uuidToHex() + "}";
|
||||
entry->m_attributes->set(EntryAttributes::PasswordKey, password.toUpper(), m_attributes->isProtected(EntryAttributes::PasswordKey));
|
||||
entry->m_attributes->set(
|
||||
EntryAttributes::PasswordKey, password.toUpper(), m_attributes->isProtected(EntryAttributes::PasswordKey));
|
||||
}
|
||||
|
||||
entry->m_autoTypeAssociations->copyDataFrom(m_autoTypeAssociations);
|
||||
@ -1065,7 +1067,8 @@ QString Entry::resolveUrl(const QString& url) const
|
||||
|
||||
// Validate the URL
|
||||
QUrl tempUrl = QUrl(newUrl);
|
||||
if (tempUrl.isValid() && (tempUrl.scheme() == "http" || tempUrl.scheme() == "https" || tempUrl.scheme() == "file")) {
|
||||
if (tempUrl.isValid()
|
||||
&& (tempUrl.scheme() == "http" || tempUrl.scheme() == "https" || tempUrl.scheme() == "file")) {
|
||||
return tempUrl.url();
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,8 @@
|
||||
|
||||
class Database;
|
||||
class Group;
|
||||
namespace Totp {
|
||||
namespace Totp
|
||||
{
|
||||
struct Settings;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@ const QString EntryAttributes::UserNameKey = "UserName";
|
||||
const QString EntryAttributes::PasswordKey = "Password";
|
||||
const QString EntryAttributes::URLKey = "URL";
|
||||
const QString EntryAttributes::NotesKey = "Notes";
|
||||
const QStringList EntryAttributes::DefaultAttributes(QStringList() << TitleKey << UserNameKey << PasswordKey << URLKey
|
||||
<< NotesKey);
|
||||
const QStringList EntryAttributes::DefaultAttributes(QStringList()
|
||||
<< TitleKey << UserNameKey << PasswordKey << URLKey << NotesKey);
|
||||
|
||||
const QString EntryAttributes::WantedFieldGroupName = "WantedField";
|
||||
const QString EntryAttributes::SearchInGroupName = "SearchIn";
|
||||
|
@ -630,10 +630,12 @@ Entry* Group::findEntryByPathRecursive(const QString& entryPath, const QString&
|
||||
// Return the first entry that matches the full path OR if there is no leading
|
||||
// slash, return the first entry title that matches
|
||||
for (Entry* entry : entries()) {
|
||||
// clang-format off
|
||||
if (entryPath == (basePath + entry->title())
|
||||
|| (!entryPath.startsWith("/") && entry->title() == entryPath)) {
|
||||
return entry;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
for (Group* group : children()) {
|
||||
@ -654,9 +656,11 @@ Group* Group::findGroupByPath(const QString& groupPath)
|
||||
if (groupPath.isEmpty()) {
|
||||
normalizedGroupPath = QString("/"); // root group
|
||||
} else {
|
||||
// clang-format off
|
||||
normalizedGroupPath = (groupPath.startsWith("/") ? "" : "/")
|
||||
+ groupPath
|
||||
+ (groupPath.endsWith("/") ? "" : "/");
|
||||
// clang-format on
|
||||
}
|
||||
return findGroupByPathRecursive(normalizedGroupPath, "/");
|
||||
}
|
||||
@ -894,6 +898,7 @@ void Group::connectDatabaseSignalsRecursive(Database* db)
|
||||
}
|
||||
|
||||
if (db) {
|
||||
// clang-format off
|
||||
connect(this, SIGNAL(groupDataChanged(Group*)), db, SIGNAL(groupDataChanged(Group*)));
|
||||
connect(this, SIGNAL(groupAboutToRemove(Group*)), db, SIGNAL(groupAboutToRemove(Group*)));
|
||||
connect(this, SIGNAL(groupRemoved()), db, SIGNAL(groupRemoved()));
|
||||
@ -902,6 +907,7 @@ void Group::connectDatabaseSignalsRecursive(Database* db)
|
||||
connect(this, SIGNAL(aboutToMove(Group*,Group*,int)), db, SIGNAL(groupAboutToMove(Group*,Group*,int)));
|
||||
connect(this, SIGNAL(groupMoved()), db, SIGNAL(groupMoved()));
|
||||
connect(this, SIGNAL(groupModified()), db, SLOT(markAsModified()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
m_db = db;
|
||||
@ -983,7 +989,7 @@ QStringList Group::locate(const QString& locateTerm, const QString& currentPath)
|
||||
|
||||
for (const Entry* entry : asConst(m_entries)) {
|
||||
QString entryPath = currentPath + entry->title();
|
||||
if (entryPath.toLower().contains(locateTerm.toLower())) {
|
||||
if (entryPath.contains(locateTerm, Qt::CaseInsensitive)) {
|
||||
response << entryPath;
|
||||
}
|
||||
}
|
||||
|
@ -55,12 +55,13 @@ void InactivityTimer::deactivate()
|
||||
bool InactivityTimer::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
const QEvent::Type type = event->type();
|
||||
|
||||
// clang-format off
|
||||
if ((type >= QEvent::MouseButtonPress && type <= QEvent::KeyRelease)
|
||||
|| (type >= QEvent::HoverEnter && type <= QEvent::HoverMove)
|
||||
|| (type == QEvent::Wheel)) {
|
||||
m_timer->start();
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
@ -93,7 +93,8 @@ Merger::ChangeList Merger::mergeGroup(const MergeContext& context)
|
||||
moveEntry(targetEntry, context.m_targetGroup);
|
||||
} else {
|
||||
// Entry is already present in the database. Update it.
|
||||
const bool locationChanged = targetEntry->timeInfo().locationChanged() < sourceEntry->timeInfo().locationChanged();
|
||||
const bool locationChanged =
|
||||
targetEntry->timeInfo().locationChanged() < sourceEntry->timeInfo().locationChanged();
|
||||
if (locationChanged && targetEntry->group() != context.m_targetGroup) {
|
||||
changes << tr("Relocating %1 [%2]").arg(sourceEntry->title(), sourceEntry->uuidToHex());
|
||||
moveEntry(targetEntry, context.m_targetGroup);
|
||||
@ -136,7 +137,8 @@ Merger::ChangeList Merger::mergeGroup(const MergeContext& context)
|
||||
return changes;
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveGroupConflict(const MergeContext& context, const Group* sourceChildGroup, Group* targetChildGroup)
|
||||
Merger::ChangeList
|
||||
Merger::resolveGroupConflict(const MergeContext& context, const Group* sourceChildGroup, Group* targetChildGroup)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
ChangeList changes;
|
||||
@ -261,10 +263,13 @@ void Merger::eraseGroup(Group* group)
|
||||
database->setDeletedObjects(deletions);
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
// if one entry is newer, create a clone and add it to the group
|
||||
if (comparison < 0) {
|
||||
Entry* clonedEntry = sourceEntry->clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
|
||||
@ -280,11 +285,14 @@ Merger::ChangeList Merger::resolveEntryConflict_Duplicate(const MergeContext& co
|
||||
return changes;
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
if (comparison < 0) {
|
||||
// we need to make our older entry "newer" than the new entry - therefore
|
||||
// we just create a new history entry without any changes - this preserves
|
||||
@ -300,11 +308,14 @@ Merger::ChangeList Merger::resolveEntryConflict_KeepLocal(const MergeContext& co
|
||||
return changes;
|
||||
}
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
if (comparison > 0) {
|
||||
// we need to make our older entry "newer" than the new entry - therefore
|
||||
// we just create a new history entry without any changes - this preserves
|
||||
@ -322,13 +333,17 @@ Merger::ChangeList Merger::resolveEntryConflict_KeepRemote(const MergeContext& c
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict_MergeHistories(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry, Group::MergeMode mergeMethod)
|
||||
Merger::ChangeList Merger::resolveEntryConflict_MergeHistories(const MergeContext& context,
|
||||
const Entry* sourceEntry,
|
||||
Entry* targetEntry,
|
||||
Group::MergeMode mergeMethod)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
|
||||
ChangeList changes;
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(), sourceEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(targetEntry->timeInfo().lastModificationTime(),
|
||||
sourceEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
if (comparison < 0) {
|
||||
Group* currentGroup = targetEntry->group();
|
||||
Entry* clonedEntry = sourceEntry->clone(Entry::CloneIncludeHistory);
|
||||
@ -347,14 +362,15 @@ Merger::ChangeList Merger::resolveEntryConflict_MergeHistories(const MergeContex
|
||||
qPrintable(targetEntry->group()->name()));
|
||||
const bool changed = mergeHistory(sourceEntry, targetEntry, mergeMethod);
|
||||
if (changed) {
|
||||
changes << tr("Synchronizing from older source %1 [%2]").arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
changes
|
||||
<< tr("Synchronizing from older source %1 [%2]").arg(targetEntry->title(), targetEntry->uuidToHex());
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
Merger::ChangeList Merger::resolveEntryConflict(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
Merger::ChangeList
|
||||
Merger::resolveEntryConflict(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry)
|
||||
{
|
||||
ChangeList changes;
|
||||
// We need to cut off the milliseconds since the persistent format only supports times down to seconds
|
||||
@ -395,15 +411,19 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
Q_UNUSED(mergeMethod);
|
||||
const auto targetHistoryItems = targetEntry->historyItems();
|
||||
const auto sourceHistoryItems = sourceEntry->historyItems();
|
||||
const int comparison = compare(sourceEntry->timeInfo().lastModificationTime(), targetEntry->timeInfo().lastModificationTime(), CompareItemIgnoreMilliseconds);
|
||||
const int comparison = compare(sourceEntry->timeInfo().lastModificationTime(),
|
||||
targetEntry->timeInfo().lastModificationTime(),
|
||||
CompareItemIgnoreMilliseconds);
|
||||
const bool preferLocal = mergeMethod == Group::KeepLocal || comparison < 0;
|
||||
const bool preferRemote = mergeMethod == Group::KeepRemote || comparison > 0;
|
||||
|
||||
QMap<QDateTime, Entry*> merged;
|
||||
for (Entry* historyItem : targetHistoryItems) {
|
||||
const QDateTime modificationTime = Clock::serialized(historyItem->timeInfo().lastModificationTime());
|
||||
if (merged.contains(modificationTime) && !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning("Inconsistent history entry of %s[%s] at %s contains conflicting changes - conflict resolution may lose data!",
|
||||
if (merged.contains(modificationTime)
|
||||
&& !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning("Inconsistent history entry of %s[%s] at %s contains conflicting changes - conflict resolution "
|
||||
"may lose data!",
|
||||
qPrintable(sourceEntry->title()),
|
||||
qPrintable(sourceEntry->uuidToHex()),
|
||||
qPrintable(modificationTime.toString("yyyy-MM-dd HH-mm-ss-zzz")));
|
||||
@ -413,8 +433,10 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
for (Entry* historyItem : sourceHistoryItems) {
|
||||
// Items with same modification-time changes will be regarded as same (like KeePass2)
|
||||
const QDateTime modificationTime = Clock::serialized(historyItem->timeInfo().lastModificationTime());
|
||||
if (merged.contains(modificationTime) && !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning("History entry of %s[%s] at %s contains conflicting changes - conflict resolution may lose data!",
|
||||
if (merged.contains(modificationTime)
|
||||
&& !merged[modificationTime]->equals(historyItem, CompareItemIgnoreMilliseconds)) {
|
||||
::qWarning(
|
||||
"History entry of %s[%s] at %s contains conflicting changes - conflict resolution may lose data!",
|
||||
qPrintable(sourceEntry->title()),
|
||||
qPrintable(sourceEntry->uuidToHex()),
|
||||
qPrintable(modificationTime.toString("yyyy-MM-dd HH-mm-ss-zzz")));
|
||||
@ -430,7 +452,9 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
|
||||
const QDateTime targetModificationTime = Clock::serialized(targetEntry->timeInfo().lastModificationTime());
|
||||
const QDateTime sourceModificationTime = Clock::serialized(sourceEntry->timeInfo().lastModificationTime());
|
||||
if (targetModificationTime == sourceModificationTime && !targetEntry->equals(sourceEntry, CompareItemIgnoreMilliseconds | CompareItemIgnoreHistory | CompareItemIgnoreLocation)) {
|
||||
if (targetModificationTime == sourceModificationTime
|
||||
&& !targetEntry->equals(sourceEntry,
|
||||
CompareItemIgnoreMilliseconds | CompareItemIgnoreHistory | CompareItemIgnoreLocation)) {
|
||||
::qWarning("Entry of %s[%s] contains conflicting changes - conflict resolution may lose data!",
|
||||
qPrintable(sourceEntry->title()),
|
||||
qPrintable(sourceEntry->uuidToHex()));
|
||||
@ -480,7 +504,7 @@ bool Merger::mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::M
|
||||
bool updateTimeInfo = targetEntry->canUpdateTimeinfo();
|
||||
targetEntry->setUpdateTimeinfo(false);
|
||||
targetEntry->removeHistoryItems(targetHistoryItems);
|
||||
for (Entry* historyItem : merged.values()) {
|
||||
for (Entry* historyItem : merged) {
|
||||
Q_ASSERT(!historyItem->parent());
|
||||
targetEntry->addHistoryItem(historyItem);
|
||||
}
|
||||
|
@ -55,14 +55,22 @@ private:
|
||||
bool mergeHistory(const Entry* sourceEntry, Entry* targetEntry, Group::MergeMode mergeMethod);
|
||||
void moveEntry(Entry* entry, Group* targetGroup);
|
||||
void moveGroup(Group* group, Group* targetGroup);
|
||||
void eraseEntry(Entry* entry); // remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
void eraseGroup(Group* group); // remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
// remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
void eraseEntry(Entry* entry);
|
||||
// remove an entry without a trace in the deletedObjects - needed for elemination cloned entries
|
||||
void eraseGroup(Group* group);
|
||||
ChangeList resolveEntryConflict(const MergeContext& context, const Entry* existingEntry, Entry* otherEntry);
|
||||
ChangeList resolveGroupConflict(const MergeContext& context, const Group* existingGroup, Group* otherGroup);
|
||||
Merger::ChangeList resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_MergeHistories(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry, Group::MergeMode mergeMethod);
|
||||
Merger::ChangeList
|
||||
resolveEntryConflict_Duplicate(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList
|
||||
resolveEntryConflict_KeepLocal(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList
|
||||
resolveEntryConflict_KeepRemote(const MergeContext& context, const Entry* sourceEntry, Entry* targetEntry);
|
||||
Merger::ChangeList resolveEntryConflict_MergeHistories(const MergeContext& context,
|
||||
const Entry* sourceEntry,
|
||||
Entry* targetEntry,
|
||||
Group::MergeMode mergeMethod);
|
||||
|
||||
private:
|
||||
MergeContext m_context;
|
||||
|
@ -9,6 +9,7 @@ class OSEventFilter : public QAbstractNativeEventFilter
|
||||
public:
|
||||
OSEventFilter();
|
||||
bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(OSEventFilter)
|
||||
};
|
||||
|
@ -124,7 +124,6 @@ bool PasswordGenerator::isValid() const
|
||||
}
|
||||
|
||||
return !passwordGroups().isEmpty();
|
||||
|
||||
}
|
||||
|
||||
QVector<PasswordGroup> PasswordGenerator::passwordGroups() const
|
||||
|
@ -22,14 +22,12 @@
|
||||
#include "core/Translator.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QElapsedTimer>
|
||||
#include <QIODevice>
|
||||
#include <QImageReader>
|
||||
#include <QLocale>
|
||||
#include <QStringList>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <QStringList>
|
||||
#include <cctype>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@ -105,8 +103,7 @@ bool readAllFromDevice(QIODevice* device, QByteArray& data)
|
||||
if (readResult > 0) {
|
||||
readBytes += readResult;
|
||||
}
|
||||
}
|
||||
while (readResult > 0);
|
||||
} while (readResult > 0);
|
||||
|
||||
if (readResult == -1) {
|
||||
return false;
|
||||
@ -196,8 +193,7 @@ void wait(int ms)
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, timeLeft);
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
while (!timer.hasExpired(ms));
|
||||
} while (!timer.hasExpired(ms));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ bool isHex(const QByteArray& ba);
|
||||
bool isBase64(const QByteArray& ba);
|
||||
void sleep(int ms);
|
||||
void wait(int ms);
|
||||
QRegularExpression convertToRegex(const QString& string, bool useWildcards = false, bool exactMatch = false,
|
||||
bool caseSensitive = false);
|
||||
QRegularExpression convertToRegex(const QString& string, bool useWildcards = false,
|
||||
bool exactMatch = false, bool caseSensitive = false);
|
||||
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
|
||||
|
@ -144,7 +144,8 @@ bool Crypto::testSha512()
|
||||
QByteArray sha512Test =
|
||||
CryptoHash::hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", CryptoHash::Sha512);
|
||||
|
||||
if (sha512Test != QByteArray::fromHex("204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b"
|
||||
if (sha512Test
|
||||
!= QByteArray::fromHex("204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b"
|
||||
"07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445")) {
|
||||
raiseError("SHA-512 mismatch.");
|
||||
return false;
|
||||
|
@ -18,8 +18,8 @@
|
||||
#ifndef KEEPASSX_KDF_H
|
||||
#define KEEPASSX_KDF_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <QUuid>
|
||||
#include <QVariant>
|
||||
|
||||
#define KDF_DEFAULT_SEED_SIZE 32
|
||||
#define KDF_DEFAULT_ROUNDS 1000000ull
|
||||
|
@ -42,8 +42,7 @@ bool Kdbx3Reader::readDatabaseImpl(QIODevice* device,
|
||||
|
||||
// check if all required headers were present
|
||||
if (m_masterSeed.isEmpty() || m_encryptionIV.isEmpty() || m_streamStartBytes.isEmpty()
|
||||
|| m_protectedStreamKey.isEmpty()
|
||||
|| db->cipher().isNull()) {
|
||||
|| m_protectedStreamKey.isEmpty() || db->cipher().isNull()) {
|
||||
raiseError(tr("missing database headers"));
|
||||
return false;
|
||||
}
|
||||
|
@ -66,9 +66,10 @@ bool Kdbx3Writer::writeDatabase(QIODevice* device, Database* db)
|
||||
writeMagicNumbers(&header, KeePass2::SIGNATURE_1, KeePass2::SIGNATURE_2, KeePass2::FILE_VERSION_3_1);
|
||||
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::CipherID, db->cipher().toRfc4122()));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes<qint32>(db->compressionAlgorithm(),
|
||||
KeePass2::BYTEORDER)));
|
||||
CHECK_RETURN_FALSE(
|
||||
writeHeaderField<quint16>(&header,
|
||||
KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes<qint32>(db->compressionAlgorithm(), KeePass2::BYTEORDER)));
|
||||
auto kdf = db->kdf();
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::MasterSeed, masterSeed));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint16>(&header, KeePass2::HeaderFieldID::TransformSeed, kdf->seed()));
|
||||
|
@ -50,7 +50,6 @@ bool Kdbx4Writer::writeDatabase(QIODevice* device, Database* db)
|
||||
QByteArray masterSeed = randomGen()->randomArray(32);
|
||||
QByteArray encryptionIV = randomGen()->randomArray(ivSize);
|
||||
QByteArray protectedStreamKey = randomGen()->randomArray(64);
|
||||
QByteArray startBytes;
|
||||
QByteArray endOfHeader = "\r\n\r\n";
|
||||
|
||||
if (!db->setKey(db->key(), false, true)) {
|
||||
@ -73,10 +72,12 @@ bool Kdbx4Writer::writeDatabase(QIODevice* device, Database* db)
|
||||
|
||||
writeMagicNumbers(&header, KeePass2::SIGNATURE_1, KeePass2::SIGNATURE_2, KeePass2::FILE_VERSION_4);
|
||||
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::CipherID, db->cipher().toRfc4122()));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes(static_cast<int>(db->compressionAlgorithm()),
|
||||
KeePass2::BYTEORDER)));
|
||||
CHECK_RETURN_FALSE(
|
||||
writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::CipherID, db->cipher().toRfc4122()));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(
|
||||
&header,
|
||||
KeePass2::HeaderFieldID::CompressionFlags,
|
||||
Endian::sizedIntToBytes(static_cast<int>(db->compressionAlgorithm()), KeePass2::BYTEORDER)));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::MasterSeed, masterSeed));
|
||||
CHECK_RETURN_FALSE(writeHeaderField<quint32>(&header, KeePass2::HeaderFieldID::EncryptionIV, encryptionIV));
|
||||
|
||||
|
@ -731,7 +731,7 @@ Entry* KdbxXmlReader::parseEntry(bool history)
|
||||
}
|
||||
if (m_xml.name() == "Binary") {
|
||||
QPair<QString, QString> ref = parseEntryBinary(entry);
|
||||
if (!ref.first.isNull() && !ref.second.isNull()) {
|
||||
if (!ref.first.isEmpty() && !ref.second.isEmpty()) {
|
||||
binaryRefs.append(ref);
|
||||
}
|
||||
continue;
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "core/Database.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "core/TimeInfo.h"
|
||||
#include "core/Database.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QPair>
|
||||
|
@ -356,12 +356,14 @@ void KdbxXmlWriter::writeEntry(const Entry* entry)
|
||||
for (const QString& key : attributesKeyList) {
|
||||
m_xml.writeStartElement("String");
|
||||
|
||||
// clang-format off
|
||||
bool protect =
|
||||
(((key == "Title") && m_meta->protectTitle()) || ((key == "UserName") && m_meta->protectUsername())
|
||||
|| ((key == "Password") && m_meta->protectPassword())
|
||||
|| ((key == "URL") && m_meta->protectUrl())
|
||||
|| ((key == "Notes") && m_meta->protectNotes())
|
||||
|| entry->attributes()->isProtected(key));
|
||||
// clang-format on
|
||||
|
||||
writeString("Key", key);
|
||||
|
||||
|
@ -35,6 +35,6 @@ namespace KeePass1
|
||||
Rijndael = 2,
|
||||
Twofish = 8
|
||||
};
|
||||
}
|
||||
} // namespace KeePass1
|
||||
|
||||
#endif // KEEPASSX_KEEPASS1_H
|
||||
|
@ -50,14 +50,12 @@ const QString KeePass2::KDFPARAM_ARGON2_ASSOCDATA("A");
|
||||
const QList<QPair<QUuid, QString>> KeePass2::CIPHERS{
|
||||
qMakePair(KeePass2::CIPHER_AES256, QObject::tr("AES: 256-bit")),
|
||||
qMakePair(KeePass2::CIPHER_TWOFISH, QObject::tr("Twofish: 256-bit")),
|
||||
qMakePair(KeePass2::CIPHER_CHACHA20, QObject::tr("ChaCha20: 256-bit"))
|
||||
};
|
||||
qMakePair(KeePass2::CIPHER_CHACHA20, QObject::tr("ChaCha20: 256-bit"))};
|
||||
|
||||
const QList<QPair<QUuid, QString>> KeePass2::KDFS{
|
||||
qMakePair(KeePass2::KDF_ARGON2, QObject::tr("Argon2 (KDBX 4 – recommended)")),
|
||||
qMakePair(KeePass2::KDF_AES_KDBX4, QObject::tr("AES-KDF (KDBX 4)")),
|
||||
qMakePair(KeePass2::KDF_AES_KDBX3, QObject::tr("AES-KDF (KDBX 3.1)"))
|
||||
};
|
||||
qMakePair(KeePass2::KDF_AES_KDBX3, QObject::tr("AES-KDF (KDBX 3.1)"))};
|
||||
|
||||
QByteArray KeePass2::hmacKey(const QByteArray& masterSeed, const QByteArray& transformedMasterKey)
|
||||
{
|
||||
|
@ -21,9 +21,9 @@
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QSharedPointer>
|
||||
#include <QUuid>
|
||||
#include <QVariantMap>
|
||||
#include <QtGlobal>
|
||||
#include <QUuid>
|
||||
|
||||
#include "crypto/SymmetricCipher.h"
|
||||
#include "crypto/kdf/Kdf.h"
|
||||
|
@ -64,10 +64,9 @@ AboutDialog::AboutDialog(QWidget* parent)
|
||||
debugInfo.append(tr("Distribution: %1").arg(KEEPASSXC_DIST_TYPE).append("\n"));
|
||||
#endif
|
||||
|
||||
debugInfo.append("\n").append(QString("%1\n- Qt %2\n- %3\n\n")
|
||||
.arg(tr("Libraries:"),
|
||||
QString::fromLocal8Bit(qVersion()),
|
||||
Crypto::backendVersion()));
|
||||
debugInfo.append("\n").append(
|
||||
QString("%1\n- Qt %2\n- %3\n\n")
|
||||
.arg(tr("Libraries:"), QString::fromLocal8Bit(qVersion()), Crypto::backendVersion()));
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
debugInfo.append(tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4")
|
||||
|
@ -25,7 +25,7 @@ namespace Ui
|
||||
{
|
||||
class ApplicationSettingsWidgetGeneral;
|
||||
class ApplicationSettingsWidgetSecurity;
|
||||
}
|
||||
} // namespace Ui
|
||||
|
||||
class ISettingsPage
|
||||
{
|
||||
|
@ -38,8 +38,9 @@ CategoryListWidget::CategoryListWidget(QWidget* parent)
|
||||
connect(m_ui->scrollUp, SIGNAL(clicked()), SLOT(scrollCategoriesUp()));
|
||||
connect(m_ui->scrollDown, SIGNAL(clicked()), SLOT(scrollCategoriesDown()));
|
||||
connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(updateCategoryScrollButtons()));
|
||||
connect(
|
||||
m_ui->categoryList->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), SLOT(updateCategoryScrollButtons()));
|
||||
// clang-format off
|
||||
connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), SLOT(updateCategoryScrollButtons()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
CategoryListWidget::~CategoryListWidget()
|
||||
|
@ -105,9 +105,11 @@ void DatabaseOpenWidget::showEvent(QShowEvent* event)
|
||||
#ifdef WITH_XC_YUBIKEY
|
||||
// showEvent() may be called twice, so make sure we are only polling once
|
||||
if (!m_yubiKeyBeingPolled) {
|
||||
// clang-format off
|
||||
connect(YubiKey::instance(), SIGNAL(detected(int,bool)), SLOT(yubikeyDetected(int,bool)), Qt::QueuedConnection);
|
||||
connect(YubiKey::instance(), SIGNAL(detectComplete()), SLOT(yubikeyDetectComplete()), Qt::QueuedConnection);
|
||||
connect(YubiKey::instance(), SIGNAL(notFound()), SLOT(noYubikeyFound()), Qt::QueuedConnection);
|
||||
// clang-format on
|
||||
|
||||
pollYubikey();
|
||||
m_yubiKeyBeingPolled = true;
|
||||
@ -172,7 +174,7 @@ QSharedPointer<Database> DatabaseOpenWidget::database()
|
||||
|
||||
void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
|
||||
{
|
||||
if (!pw.isNull()) {
|
||||
if (!pw.isEmpty()) {
|
||||
m_ui->editPassword->setText(pw);
|
||||
}
|
||||
if (!keyFile.isEmpty()) {
|
||||
|
@ -94,10 +94,12 @@ QSharedPointer<Database> DatabaseTabWidget::execNewDatabaseWizard()
|
||||
Q_ASSERT(db->key());
|
||||
Q_ASSERT(db->kdf());
|
||||
if (!db->key() || !db->kdf()) {
|
||||
MessageBox::critical(this, tr("Database creation error"),
|
||||
MessageBox::critical(this,
|
||||
tr("Database creation error"),
|
||||
tr("The created database has no key or KDF, refusing to save it.\n"
|
||||
"This is definitely a bug, please report it to the developers."),
|
||||
QMessageBox::Ok, QMessageBox::Ok);
|
||||
QMessageBox::Ok,
|
||||
QMessageBox::Ok);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -216,7 +218,7 @@ void DatabaseTabWidget::mergeDatabase()
|
||||
auto dbWidget = currentDatabaseWidget();
|
||||
if (dbWidget && !dbWidget->isLocked()) {
|
||||
QString filter = QString("%1 (*.kdbx);;%2 (*)").arg(tr("KeePass 2 Database"), tr("All files"));
|
||||
const QString fileName = fileDialog()->getOpenFileName(this, tr("Merge database"), "", filter);
|
||||
const QString fileName = fileDialog()->getOpenFileName(this, tr("Merge database"), QString(), filter);
|
||||
if (!fileName.isEmpty()) {
|
||||
mergeDatabase(fileName);
|
||||
}
|
||||
|
@ -50,8 +50,8 @@
|
||||
#include "gui/EntryPreviewWidget.h"
|
||||
#include "gui/KeePass1OpenWidget.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/TotpSetupDialog.h"
|
||||
#include "gui/TotpDialog.h"
|
||||
#include "gui/TotpSetupDialog.h"
|
||||
#include "gui/TotpExportSettingsDialog.h"
|
||||
#include "gui/entry/EditEntryWidget.h"
|
||||
#include "gui/entry/EntryView.h"
|
||||
@ -155,6 +155,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
|
||||
addChildWidget(m_csvImportWizard);
|
||||
addChildWidget(m_keepass1OpenWidget);
|
||||
|
||||
// clang-format off
|
||||
connect(m_mainSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(mainSplitterSizesChanged()));
|
||||
connect(m_previewSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(previewSplitterSizesChanged()));
|
||||
connect(this, SIGNAL(currentModeChanged(DatabaseWidget::Mode)), m_previewView, SLOT(setDatabaseMode(DatabaseWidget::Mode)));
|
||||
@ -177,6 +178,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
|
||||
connect(&m_fileWatchTimer, SIGNAL(timeout()), this, SLOT(reloadDatabaseFile()));
|
||||
connect(&m_fileWatchUnblockTimer, SIGNAL(timeout()), this, SLOT(unblockAutoReload()));
|
||||
connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged()));
|
||||
// clang-format on
|
||||
|
||||
connectDatabaseSignals();
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "EditWidget.h"
|
||||
#include "ui_EditWidget.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
#include <QtNetwork>
|
||||
#include <QNetworkAccessManager>
|
||||
#endif
|
||||
|
||||
IconStruct::IconStruct()
|
||||
@ -44,6 +45,7 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
, m_ui(new Ui::EditWidgetIcons())
|
||||
, m_db(nullptr)
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
, m_netMgr(new QNetworkAccessManager(this))
|
||||
, m_reply(nullptr)
|
||||
#endif
|
||||
, m_defaultIconModel(new DefaultIconModel(this))
|
||||
@ -54,6 +56,7 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
m_ui->defaultIconsView->setModel(m_defaultIconModel);
|
||||
m_ui->customIconsView->setModel(m_customIconModel);
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->defaultIconsView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateRadioButtonDefaultIcons()));
|
||||
connect(m_ui->customIconsView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateRadioButtonCustomIcons()));
|
||||
connect(m_ui->defaultIconsRadio, SIGNAL(toggled(bool)), this, SLOT(updateWidgetsDefaultIcons(bool)));
|
||||
@ -64,14 +67,11 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
|
||||
connect(m_ui->defaultIconsRadio, SIGNAL(toggled(bool)), this, SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->defaultIconsRadio, SIGNAL(toggled(bool)), this, SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->defaultIconsView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this,
|
||||
SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->customIconsView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this,
|
||||
SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->defaultIconsView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SIGNAL(widgetUpdated()));
|
||||
connect(m_ui->customIconsView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SIGNAL(widgetUpdated()));
|
||||
// clang-format on
|
||||
|
||||
m_ui->faviconButton->setVisible(false);
|
||||
m_ui->addButton->setEnabled(true);
|
||||
@ -156,7 +156,8 @@ void EditWidgetIcons::setUrl(const QString& url)
|
||||
}
|
||||
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
// Try to get the 2nd level domain of the host part of a QUrl. For example,
|
||||
// "foo.bar.example.com" would become "example.com", and "foo.bar.example.co.uk"
|
||||
// would become "example.co.uk".
|
||||
@ -173,7 +174,7 @@ namespace {
|
||||
{
|
||||
QUrl url;
|
||||
if (var.canConvert<QUrl>())
|
||||
url = var.value<QUrl>();
|
||||
url = var.toUrl();
|
||||
return url;
|
||||
}
|
||||
|
||||
@ -183,7 +184,7 @@ namespace {
|
||||
QUrl url = convertVariantToUrl(var);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
void EditWidgetIcons::downloadFavicon()
|
||||
@ -264,8 +265,9 @@ void EditWidgetIcons::fetchFinished()
|
||||
return;
|
||||
} else {
|
||||
if (!fallbackEnabled) {
|
||||
emit messageEditEntry(tr("Unable to fetch favicon.") + "\n" +
|
||||
tr("Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security"),
|
||||
emit messageEditEntry(
|
||||
tr("Unable to fetch favicon.") + "\n"
|
||||
+ tr("Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security"),
|
||||
MessageWidget::Error);
|
||||
} else {
|
||||
emit messageEditEntry(tr("Unable to fetch favicon."), MessageWidget::Error);
|
||||
@ -294,7 +296,7 @@ void EditWidgetIcons::startFetchFavicon(const QUrl& url)
|
||||
|
||||
QNetworkRequest request(url);
|
||||
|
||||
m_reply = m_netMgr.get(request);
|
||||
m_reply = m_netMgr->get(request);
|
||||
connect(m_reply, &QNetworkReply::finished, this, &EditWidgetIcons::fetchFinished);
|
||||
connect(m_reply, &QIODevice::readyRead, this, &EditWidgetIcons::fetchReadyRead);
|
||||
#else
|
||||
@ -339,8 +341,9 @@ void EditWidgetIcons::addCustomIconFromFile()
|
||||
if (!errornames.empty()) {
|
||||
// Show the first 8 icons that failed to load
|
||||
errornames = errornames.mid(0, 8);
|
||||
emit messageEditEntry(msg + "\n" + tr("The following icon(s) failed:", "", errornames.size()) +
|
||||
"\n" + errornames.join("\n"), MessageWidget::Error);
|
||||
emit messageEditEntry(msg + "\n" + tr("The following icon(s) failed:", "", errornames.size()) + "\n"
|
||||
+ errornames.join("\n"),
|
||||
MessageWidget::Error);
|
||||
} else if (numloaded > 0) {
|
||||
emit messageEditEntry(msg, MessageWidget::Positive);
|
||||
} else {
|
||||
|
@ -21,9 +21,8 @@
|
||||
|
||||
#include <QSet>
|
||||
#include <QUrl>
|
||||
#include <QWidget>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QUuid>
|
||||
#include <QWidget>
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "core/Global.h"
|
||||
@ -33,6 +32,7 @@ class Database;
|
||||
class DefaultIconModel;
|
||||
class CustomIconModel;
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
#endif
|
||||
|
||||
@ -95,7 +95,7 @@ private:
|
||||
QUrl m_fetchUrl;
|
||||
QList<QUrl> m_urlsToTry;
|
||||
QByteArray m_bytesReceived;
|
||||
QNetworkAccessManager m_netMgr;
|
||||
QNetworkAccessManager* m_netMgr;
|
||||
QNetworkReply* m_reply;
|
||||
int m_redirects;
|
||||
#endif
|
||||
|
@ -16,11 +16,11 @@
|
||||
*/
|
||||
|
||||
#include "EditWidgetProperties.h"
|
||||
|
||||
#include <QUuid>
|
||||
#include "ui_EditWidgetProperties.h"
|
||||
|
||||
#include "MessageBox.h"
|
||||
#include "ui_EditWidgetProperties.h"
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
EditWidgetProperties::EditWidgetProperties(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
@ -32,9 +32,11 @@ EditWidgetProperties::EditWidgetProperties(QWidget* parent)
|
||||
m_ui->removeCustomDataButton->setEnabled(false);
|
||||
m_ui->customDataTable->setModel(m_customDataModel);
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->customDataTable->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
SLOT(toggleRemoveButton(QItemSelection)));
|
||||
// clang-format on
|
||||
connect(m_ui->removeCustomDataButton, SIGNAL(clicked()), SLOT(removeSelectedPluginData()));
|
||||
}
|
||||
|
||||
@ -66,7 +68,8 @@ const CustomData* EditWidgetProperties::customData() const
|
||||
|
||||
void EditWidgetProperties::removeSelectedPluginData()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Delete plugin data?"),
|
||||
tr("Do you really want to delete the selected plugin data?\n"
|
||||
"This may cause the affected plugins to malfunction."),
|
||||
@ -97,8 +100,8 @@ void EditWidgetProperties::updateModel()
|
||||
m_customDataModel->setHorizontalHeaderLabels({tr("Key"), tr("Value")});
|
||||
|
||||
for (const QString& key : m_customData->keys()) {
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>() << new QStandardItem(key)
|
||||
<< new QStandardItem(m_customData->value(key)));
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>()
|
||||
<< new QStandardItem(key) << new QStandardItem(m_customData->value(key)));
|
||||
}
|
||||
|
||||
m_ui->removeCustomDataButton->setEnabled(false);
|
||||
|
@ -220,7 +220,7 @@ void EntryPreviewWidget::updateEntryAttributesTab()
|
||||
m_ui->entryAttributesEdit->clear();
|
||||
const EntryAttributes* attributes = m_currentEntry->attributes();
|
||||
const QStringList customAttributes = attributes->customKeys();
|
||||
const bool haveAttributes = customAttributes.size() > 0;
|
||||
const bool haveAttributes = !customAttributes.isEmpty();
|
||||
setTabEnabled(m_ui->entryTabWidget, m_ui->entryAttributesTab, haveAttributes);
|
||||
if (haveAttributes) {
|
||||
QString attributesText;
|
||||
|
@ -287,7 +287,6 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
|
||||
|
||||
// Tint close icon
|
||||
auto closeButtonPixmap = d->closeButtonPixmap;
|
||||
QPixmap mask(closeButtonPixmap);
|
||||
QPainter painter;
|
||||
painter.begin(&closeButtonPixmap);
|
||||
painter.setRenderHints(QPainter::HighQualityAntialiasing);
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "KeePass1OpenWidget.h"
|
||||
#include "ui_DatabaseOpenWidget.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
@ -24,7 +25,6 @@
|
||||
#include "core/Metadata.h"
|
||||
#include "format/KeePass1Reader.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "ui_DatabaseOpenWidget.h"
|
||||
|
||||
KeePass1OpenWidget::KeePass1OpenWidget(QWidget* parent)
|
||||
: DatabaseOpenWidget(parent)
|
||||
|
@ -20,10 +20,10 @@
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QDesktopServices>
|
||||
#include <QMimeData>
|
||||
#include <QShortcut>
|
||||
#include <QTimer>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include "config-keepassx.h"
|
||||
|
||||
@ -56,8 +56,8 @@
|
||||
#include <QtDBus/QtDBus>
|
||||
#endif
|
||||
|
||||
#include "gui/PasswordGeneratorWidget.h"
|
||||
#include "gui/ApplicationSettingsWidget.h"
|
||||
#include "gui/PasswordGeneratorWidget.h"
|
||||
|
||||
#include "touchid/TouchID.h"
|
||||
|
||||
@ -67,7 +67,8 @@ class BrowserPlugin : public ISettingsPage
|
||||
public:
|
||||
BrowserPlugin(DatabaseTabWidget* tabWidget)
|
||||
{
|
||||
m_nativeMessagingHost = QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled()));
|
||||
m_nativeMessagingHost =
|
||||
QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled()));
|
||||
}
|
||||
|
||||
~BrowserPlugin()
|
||||
@ -346,11 +347,13 @@ MainWindow::MainWindow()
|
||||
#ifdef Q_OS_MACOS
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->tabWidget,
|
||||
SIGNAL(messageGlobal(QString,MessageWidget::MessageType)),
|
||||
this,
|
||||
SLOT(displayGlobalMessage(QString,MessageWidget::MessageType)));
|
||||
// clang-format on
|
||||
|
||||
connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage()));
|
||||
|
||||
m_screenLockListener = new ScreenLockListener(this);
|
||||
@ -368,13 +371,15 @@ MainWindow::MainWindow()
|
||||
tr("WARNING: You are using an unstable build of KeePassXC!\n"
|
||||
"There is a high risk of corruption, maintain a backup of your databases.\n"
|
||||
"This version is not meant for production use."),
|
||||
MessageWidget::Warning, -1);
|
||||
MessageWidget::Warning,
|
||||
-1);
|
||||
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) && QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
|
||||
if (!config()->get("QtErrorMessageShown", false).toBool()) {
|
||||
m_ui->globalMessageWidget->showMessage(
|
||||
tr("WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard!\n"
|
||||
"We recommend you use the AppImage available on our downloads page."),
|
||||
MessageWidget::Warning, -1);
|
||||
MessageWidget::Warning,
|
||||
-1);
|
||||
config()->set("QtErrorMessageShown", true);
|
||||
}
|
||||
#endif
|
||||
|
@ -71,7 +71,8 @@ void PasswordEdit::setShowPassword(bool show)
|
||||
emit showPasswordChanged(show);
|
||||
}
|
||||
|
||||
bool PasswordEdit::isPasswordVisible() const {
|
||||
bool PasswordEdit::isPasswordVisible() const
|
||||
{
|
||||
return isEnabled();
|
||||
}
|
||||
|
||||
|
@ -338,10 +338,8 @@ void PasswordGeneratorWidget::selectSimpleMode()
|
||||
m_ui->checkBoxLower->setChecked(m_ui->checkBoxLowerAdv->isChecked());
|
||||
m_ui->checkBoxNumbers->setChecked(m_ui->checkBoxNumbersAdv->isChecked());
|
||||
m_ui->checkBoxSpecialChars->setChecked(m_ui->checkBoxBraces->isChecked() | m_ui->checkBoxPunctuation->isChecked()
|
||||
| m_ui->checkBoxQuotes->isChecked()
|
||||
| m_ui->checkBoxMath->isChecked()
|
||||
| m_ui->checkBoxDashes->isChecked()
|
||||
| m_ui->checkBoxLogograms->isChecked());
|
||||
| m_ui->checkBoxQuotes->isChecked() | m_ui->checkBoxMath->isChecked()
|
||||
| m_ui->checkBoxDashes->isChecked() | m_ui->checkBoxLogograms->isChecked());
|
||||
m_ui->checkBoxExtASCII->setChecked(m_ui->checkBoxExtASCIIAdv->isChecked());
|
||||
m_ui->simpleBar->show();
|
||||
}
|
||||
|
@ -17,9 +17,10 @@
|
||||
*/
|
||||
|
||||
#include "TotpSetupDialog.h"
|
||||
#include "totp/totp.h"
|
||||
#include "ui_TotpSetupDialog.h"
|
||||
|
||||
#include "totp/totp.h"
|
||||
|
||||
TotpSetupDialog::TotpSetupDialog(QWidget* parent, Entry* entry)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::TotpSetupDialog())
|
||||
|
@ -89,7 +89,9 @@ CsvImportWidget::CsvImportWidget(QWidget* parent)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [=] { comboChanged(combo, i); });
|
||||
#else
|
||||
connect(combo, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=]{ comboChanged(combo, i); });
|
||||
connect(combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=] {
|
||||
comboChanged(combo, i);
|
||||
});
|
||||
#endif
|
||||
|
||||
// layout labels and combo fields in column-first order
|
||||
|
@ -42,7 +42,6 @@ void CsvImportWizard::load(const QString& filename, Database* database)
|
||||
m_parse->load(filename, database);
|
||||
}
|
||||
|
||||
|
||||
void CsvImportWizard::parseFinished(bool accepted)
|
||||
{
|
||||
emit importFinished(accepted);
|
||||
|
@ -18,16 +18,17 @@
|
||||
|
||||
#include "DatabaseSettingsDialog.h"
|
||||
#include "ui_DatabaseSettingsDialog.h"
|
||||
#include "DatabaseSettingsWidgetGeneral.h"
|
||||
|
||||
#include "DatabaseSettingsWidgetEncryption.h"
|
||||
#include "DatabaseSettingsWidgetGeneral.h"
|
||||
#include "DatabaseSettingsWidgetMasterKey.h"
|
||||
#ifdef WITH_XC_BROWSER
|
||||
#include "DatabaseSettingsWidgetBrowser.h"
|
||||
#endif
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "touchid/TouchID.h"
|
||||
|
||||
DatabaseSettingsDialog::DatabaseSettingsDialog(QWidget* parent)
|
||||
@ -62,7 +63,8 @@ DatabaseSettingsDialog::DatabaseSettingsDialog(QWidget* parent)
|
||||
connect(m_ui->advancedSettingsToggle, SIGNAL(toggled(bool)), SLOT(toggleAdvancedMode(bool)));
|
||||
|
||||
#ifdef WITH_XC_BROWSER
|
||||
m_ui->categoryList->addCategory(tr("Browser Integration"), FilePath::instance()->icon("apps", "internet-web-browser"));
|
||||
m_ui->categoryList->addCategory(tr("Browser Integration"),
|
||||
FilePath::instance()->icon("apps", "internet-web-browser"));
|
||||
m_ui->stackedWidget->addWidget(m_browserWidget);
|
||||
#endif
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
#ifndef KEEPASSX_DATABASESETTINGSWIDGET_H
|
||||
#define KEEPASSX_DATABASESETTINGSWIDGET_H
|
||||
|
||||
#include "gui/DialogyWidget.h"
|
||||
#include "config-keepassx.h"
|
||||
#include "gui/DialogyWidget.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include "DatabaseSettingsWidget.h"
|
||||
#include "core/Database.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
DatabaseSettingsWidget::DatabaseSettingsWidget(QWidget* parent)
|
||||
: SettingsWidget(parent)
|
||||
|
@ -17,18 +17,21 @@
|
||||
*/
|
||||
|
||||
#include "DatabaseSettingsWidgetBrowser.h"
|
||||
#include "ui_DatabaseSettingsWidgetBrowser.h"
|
||||
|
||||
#include <QProgressDialog>
|
||||
|
||||
#include "browser/BrowserSettings.h"
|
||||
#include "core/Clock.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/Entry.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "browser/BrowserSettings.h"
|
||||
#include "ui_DatabaseSettingsWidgetBrowser.h"
|
||||
|
||||
DatabaseSettingsWidgetBrowser::DatabaseSettingsWidgetBrowser(QWidget* parent)
|
||||
: DatabaseSettingsWidget(parent), m_ui(new Ui::DatabaseSettingsWidgetBrowser())
|
||||
: DatabaseSettingsWidget(parent)
|
||||
, m_ui(new Ui::DatabaseSettingsWidgetBrowser())
|
||||
, m_customData(new CustomData(this))
|
||||
, m_customDataModel(new QStandardItemModel(this))
|
||||
, m_browserService(nullptr)
|
||||
@ -38,8 +41,13 @@ DatabaseSettingsWidgetBrowser::DatabaseSettingsWidgetBrowser(QWidget* parent)
|
||||
m_ui->customDataTable->setModel(m_customDataModel);
|
||||
|
||||
settingsWarning();
|
||||
connect(m_ui->customDataTable->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->customDataTable->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
SLOT(toggleRemoveButton(QItemSelection)));
|
||||
// clang-format on
|
||||
|
||||
connect(m_ui->removeCustomDataButton, SIGNAL(clicked()), SLOT(removeSelectedKey()));
|
||||
connect(m_ui->convertToCustomData, SIGNAL(clicked()), this, SLOT(convertAttributesToCustomData()));
|
||||
connect(m_ui->convertToCustomData, SIGNAL(clicked()), this, SLOT(updateSharedKeyList()));
|
||||
@ -83,11 +91,13 @@ bool DatabaseSettingsWidgetBrowser::save()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::removeSelectedKey()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Delete the selected key?"),
|
||||
tr("Do you really want to delete the selected key?\n"
|
||||
"This may prevent connection to the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -116,8 +126,7 @@ void DatabaseSettingsWidgetBrowser::updateModel()
|
||||
if (key.startsWith(BrowserService::ASSOCIATE_KEY_PREFIX)) {
|
||||
QString strippedKey = key;
|
||||
strippedKey.remove(BrowserService::ASSOCIATE_KEY_PREFIX);
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>()
|
||||
<< new QStandardItem(strippedKey)
|
||||
m_customDataModel->appendRow(QList<QStandardItem*>() << new QStandardItem(strippedKey)
|
||||
<< new QStandardItem(customData()->value(key)));
|
||||
}
|
||||
}
|
||||
@ -132,7 +141,8 @@ void DatabaseSettingsWidgetBrowser::settingsWarning()
|
||||
m_ui->removeSharedEncryptionKeys->setEnabled(false);
|
||||
m_ui->removeStoredPermissions->setEnabled(false);
|
||||
m_ui->customDataTable->setEnabled(false);
|
||||
m_ui->warningWidget->showMessage(tr("Enable Browser Integration to access these settings."), MessageWidget::Warning);
|
||||
m_ui->warningWidget->showMessage(tr("Enable Browser Integration to access these settings."),
|
||||
MessageWidget::Warning);
|
||||
m_ui->warningWidget->setCloseButtonVisible(false);
|
||||
m_ui->warningWidget->setAutoHideTimeout(-1);
|
||||
} else {
|
||||
@ -146,11 +156,13 @@ void DatabaseSettingsWidgetBrowser::settingsWarning()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::removeSharedEncryptionKeys()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Disconnect all browsers"),
|
||||
tr("Do you really want to disconnect all browsers?\n"
|
||||
"This may prevent connection to the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -182,11 +194,13 @@ void DatabaseSettingsWidgetBrowser::removeSharedEncryptionKeys()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::removeStoredPermissions()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(this,
|
||||
tr("Forget all site-specific settings on entries"),
|
||||
tr("Do you really want forget all site-specific settings on every entry?\n"
|
||||
"Permissions to access entries will be revoked."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -226,11 +240,14 @@ void DatabaseSettingsWidgetBrowser::removeStoredPermissions()
|
||||
|
||||
void DatabaseSettingsWidgetBrowser::convertAttributesToCustomData()
|
||||
{
|
||||
if (QMessageBox::Yes != MessageBox::question(this,
|
||||
if (QMessageBox::Yes
|
||||
!= MessageBox::question(
|
||||
this,
|
||||
tr("Move KeePassHTTP attributes to custom data"),
|
||||
tr("Do you really want to move all legacy browser integration data to the latest standard?\n"
|
||||
"This is necessary to maintain compatibility with the browser plugin."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -242,4 +259,3 @@ void DatabaseSettingsWidgetBrowser::updateSharedKeyList()
|
||||
{
|
||||
updateModel();
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,14 @@
|
||||
|
||||
#include "DatabaseSettingsWidget.h"
|
||||
|
||||
#include "browser/BrowserService.h"
|
||||
#include "core/CustomData.h"
|
||||
#include "gui/DatabaseTabWidget.h"
|
||||
|
||||
#include <QItemSelection>
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
#include <QStandardItemModel>
|
||||
#include <QItemSelection>
|
||||
#include "core/CustomData.h"
|
||||
#include "gui/DatabaseTabWidget.h"
|
||||
#include "browser/BrowserService.h"
|
||||
|
||||
class Database;
|
||||
namespace Ui
|
||||
@ -45,7 +46,10 @@ public:
|
||||
~DatabaseSettingsWidgetBrowser() override;
|
||||
|
||||
CustomData* customData() const;
|
||||
inline bool hasAdvancedMode() const override { return false; }
|
||||
inline bool hasAdvancedMode() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void initialize() override;
|
||||
|
@ -17,13 +17,14 @@
|
||||
|
||||
#include "DatabaseSettingsWidgetEncryption.h"
|
||||
#include "ui_DatabaseSettingsWidgetEncryption.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "core/Global.h"
|
||||
|
||||
#include "core/AsyncTask.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "crypto/kdf/Argon2Kdf.h"
|
||||
#include "format/KeePass2.h"
|
||||
#include "gui/MessageBox.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPushButton>
|
||||
|
@ -38,7 +38,10 @@ public:
|
||||
Q_DISABLE_COPY(DatabaseSettingsWidgetEncryption);
|
||||
~DatabaseSettingsWidgetEncryption() override;
|
||||
|
||||
inline bool hasAdvancedMode() const override { return true; }
|
||||
inline bool hasAdvancedMode() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void setAdvancedMode(bool advanced) override;
|
||||
|
||||
public slots:
|
||||
@ -64,7 +67,11 @@ private slots:
|
||||
void markDirty();
|
||||
|
||||
private:
|
||||
enum FormatSelection { KDBX4, KDBX3 };
|
||||
enum FormatSelection
|
||||
{
|
||||
KDBX4,
|
||||
KDBX3
|
||||
};
|
||||
static const char* CD_DECRYPTION_TIME_PREFERENCE_KEY;
|
||||
|
||||
bool m_isDirty = false;
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "DatabaseSettingsWidgetGeneral.h"
|
||||
#include "ui_DatabaseSettingsWidgetGeneral.h"
|
||||
|
||||
#include "core/Clock.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/Entry.h"
|
||||
@ -24,7 +25,8 @@
|
||||
#include "core/Metadata.h"
|
||||
|
||||
DatabaseSettingsWidgetGeneral::DatabaseSettingsWidgetGeneral(QWidget* parent)
|
||||
: DatabaseSettingsWidget(parent), m_ui(new Ui::DatabaseSettingsWidgetGeneral())
|
||||
: DatabaseSettingsWidget(parent)
|
||||
, m_ui(new Ui::DatabaseSettingsWidgetGeneral())
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
|
@ -38,7 +38,10 @@ public:
|
||||
Q_DISABLE_COPY(DatabaseSettingsWidgetGeneral);
|
||||
~DatabaseSettingsWidgetGeneral() override;
|
||||
|
||||
inline bool hasAdvancedMode() const override { return false; }
|
||||
inline bool hasAdvancedMode() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void initialize() override;
|
||||
|
@ -16,18 +16,19 @@
|
||||
*/
|
||||
|
||||
#include "DatabaseSettingsWidgetMasterKey.h"
|
||||
#include "core/Database.h"
|
||||
#include "keys/PasswordKey.h"
|
||||
#include "keys/FileKey.h"
|
||||
#include "keys/YkChallengeResponseKey.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/masterkey/PasswordEditWidget.h"
|
||||
#include "gui/masterkey/KeyFileEditWidget.h"
|
||||
#include "gui/masterkey/YubiKeyEditWidget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QSpacerItem>
|
||||
#include "core/Database.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/masterkey/KeyFileEditWidget.h"
|
||||
#include "gui/masterkey/PasswordEditWidget.h"
|
||||
#include "gui/masterkey/YubiKeyEditWidget.h"
|
||||
#include "keys/FileKey.h"
|
||||
#include "keys/PasswordKey.h"
|
||||
#include "keys/YkChallengeResponseKey.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QSpacerItem>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
DatabaseSettingsWidgetMasterKey::DatabaseSettingsWidgetMasterKey(QWidget* parent)
|
||||
: DatabaseSettingsWidget(parent)
|
||||
@ -168,18 +169,22 @@ bool DatabaseSettingsWidgetMasterKey::save()
|
||||
#endif
|
||||
|
||||
if (newKey->keys().isEmpty() && newKey->challengeResponseKeys().isEmpty()) {
|
||||
MessageBox::critical(this, tr("No encryption key added"),
|
||||
MessageBox::critical(this,
|
||||
tr("No encryption key added"),
|
||||
tr("You must add at least one encryption key to secure your database!"),
|
||||
QMessageBox::Ok, QMessageBox::Ok);
|
||||
QMessageBox::Ok,
|
||||
QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_passwordEditWidget->visiblePage() == KeyComponentWidget::AddNew) {
|
||||
auto answer = MessageBox::warning(this, tr("No password set"),
|
||||
auto answer = MessageBox::warning(this,
|
||||
tr("No password set"),
|
||||
tr("WARNING! You have not set a password. Using a database without "
|
||||
"a password is strongly discouraged!\n\n"
|
||||
"Are you sure you want to continue without a password?"),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel);
|
||||
if (answer != QMessageBox::Yes) {
|
||||
return false;
|
||||
}
|
||||
@ -210,7 +215,8 @@ void DatabaseSettingsWidgetMasterKey::setAdditionalKeyOptionsVisible(bool show)
|
||||
}
|
||||
|
||||
bool DatabaseSettingsWidgetMasterKey::addToCompositeKey(KeyComponentWidget* widget,
|
||||
QSharedPointer<CompositeKey>& newKey, QSharedPointer<Key>& oldKey)
|
||||
QSharedPointer<CompositeKey>& newKey,
|
||||
QSharedPointer<Key>& oldKey)
|
||||
{
|
||||
if (widget->visiblePage() == KeyComponentWidget::Edit) {
|
||||
QString error = tr("Unknown error");
|
||||
@ -226,7 +232,8 @@ bool DatabaseSettingsWidgetMasterKey::addToCompositeKey(KeyComponentWidget* widg
|
||||
}
|
||||
|
||||
bool DatabaseSettingsWidgetMasterKey::addToCompositeKey(KeyComponentWidget* widget,
|
||||
QSharedPointer<CompositeKey>& newKey, QSharedPointer<ChallengeResponseKey>& oldKey)
|
||||
QSharedPointer<CompositeKey>& newKey,
|
||||
QSharedPointer<ChallengeResponseKey>& oldKey)
|
||||
{
|
||||
if (widget->visiblePage() == KeyComponentWidget::Edit) {
|
||||
QString error = tr("Unknown error");
|
||||
|
@ -18,8 +18,9 @@
|
||||
#ifndef KEEPASSXC_DATABASESETTINGSPAGECHANGEMASTERKEY_H
|
||||
#define KEEPASSXC_DATABASESETTINGSPAGECHANGEMASTERKEY_H
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "DatabaseSettingsWidget.h"
|
||||
#include "config-keepassx.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
class Database;
|
||||
@ -43,7 +44,10 @@ public:
|
||||
|
||||
void load(QSharedPointer<Database> db) override;
|
||||
|
||||
inline bool hasAdvancedMode() const override { return false; }
|
||||
inline bool hasAdvancedMode() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void initialize() override;
|
||||
@ -58,9 +62,12 @@ private slots:
|
||||
private:
|
||||
void setAdditionalKeyOptionsVisible(bool show);
|
||||
|
||||
// clang-format off
|
||||
bool addToCompositeKey(KeyComponentWidget* widget,
|
||||
QSharedPointer<CompositeKey>& newKey,
|
||||
QSharedPointer<Key>& oldKey);
|
||||
// clang-format on
|
||||
|
||||
bool addToCompositeKey(KeyComponentWidget* widget,
|
||||
QSharedPointer<CompositeKey>& newKey,
|
||||
QSharedPointer<ChallengeResponseKey>& oldKey);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "DatabaseSettingsWidgetMetaDataSimple.h"
|
||||
#include "ui_DatabaseSettingsWidgetMetaDataSimple.h"
|
||||
|
||||
#include "core/Database.h"
|
||||
#include "core/Metadata.h"
|
||||
|
||||
|
@ -38,7 +38,10 @@ public:
|
||||
Q_DISABLE_COPY(DatabaseSettingWidgetMetaData);
|
||||
~DatabaseSettingWidgetMetaData() override;
|
||||
|
||||
inline bool hasAdvancedMode() const override { return false; }
|
||||
inline bool hasAdvancedMode() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void initialize() override;
|
||||
|
@ -101,7 +101,6 @@ QVariant AutoTypeMatchModel::data(const QModelIndex& index, int role) const
|
||||
AutoTypeMatch match = matchFromIndex(index);
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
QString result;
|
||||
switch (index.column()) {
|
||||
case ParentGroup:
|
||||
if (match.entry->group()) {
|
||||
|
@ -18,11 +18,11 @@
|
||||
|
||||
#include "AutoTypeMatchView.h"
|
||||
|
||||
#include "gui/SortFilterHideProxyModel.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "gui/SortFilterHideProxyModel.h"
|
||||
|
||||
AutoTypeMatchView::AutoTypeMatchView(QWidget* parent)
|
||||
: QTreeView(parent)
|
||||
, m_model(new AutoTypeMatchModel(this))
|
||||
@ -43,8 +43,10 @@ AutoTypeMatchView::AutoTypeMatchView(QWidget* parent)
|
||||
header()->setDefaultSectionSize(150);
|
||||
|
||||
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(emitMatchActivated(QModelIndex)));
|
||||
// clang-format off
|
||||
connect(
|
||||
selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SIGNAL(matchSelectionChanged()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void AutoTypeMatchView::keyPressEvent(QKeyEvent* event)
|
||||
|
@ -102,9 +102,12 @@ EditEntryWidget::EditEntryWidget(QWidget* parent)
|
||||
connect(this, SIGNAL(accepted()), SLOT(acceptEntry()));
|
||||
connect(this, SIGNAL(rejected()), SLOT(cancel()));
|
||||
connect(this, SIGNAL(apply()), SLOT(commitEntry()));
|
||||
// clang-format off
|
||||
connect(m_iconsWidget,
|
||||
SIGNAL(messageEditEntry(QString,MessageWidget::MessageType)),
|
||||
SLOT(showMessage(QString,MessageWidget::MessageType)));
|
||||
// clang-format on
|
||||
|
||||
connect(m_iconsWidget, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage()));
|
||||
|
||||
m_mainUi->passwordGenerator->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
@ -166,6 +169,8 @@ void EditEntryWidget::setupAdvanced()
|
||||
|
||||
m_attributesModel->setEntryAttributes(m_entryAttributes);
|
||||
m_advancedUi->attributesView->setModel(m_attributesModel);
|
||||
|
||||
// clang-format off
|
||||
connect(m_advancedUi->addAttributeButton, SIGNAL(clicked()), SLOT(insertAttribute()));
|
||||
connect(m_advancedUi->editAttributeButton, SIGNAL(clicked()), SLOT(editCurrentAttribute()));
|
||||
connect(m_advancedUi->removeAttributeButton, SIGNAL(clicked()), SLOT(removeCurrentAttribute()));
|
||||
@ -176,6 +181,7 @@ void EditEntryWidget::setupAdvanced()
|
||||
SLOT(updateCurrentAttribute()));
|
||||
connect(m_advancedUi->fgColorButton, SIGNAL(clicked()), SLOT(pickColor()));
|
||||
connect(m_advancedUi->bgColorButton, SIGNAL(clicked()), SLOT(pickColor()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void EditEntryWidget::setupIcon()
|
||||
@ -193,26 +199,27 @@ void EditEntryWidget::setupAutoType()
|
||||
m_autoTypeAssocModel->setAutoTypeAssociations(m_autoTypeAssoc);
|
||||
m_autoTypeUi->assocView->setModel(m_autoTypeAssocModel);
|
||||
m_autoTypeUi->assocView->setColumnHidden(1, true);
|
||||
|
||||
// clang-format off
|
||||
connect(m_autoTypeUi->enableButton, SIGNAL(toggled(bool)), SLOT(updateAutoTypeEnabled()));
|
||||
connect(
|
||||
m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)), m_autoTypeUi->sequenceEdit, SLOT(setEnabled(bool)));
|
||||
connect(m_autoTypeUi->customWindowSequenceButton,
|
||||
SIGNAL(toggled(bool)),
|
||||
m_autoTypeUi->windowSequenceEdit,
|
||||
SLOT(setEnabled(bool)));
|
||||
connect(m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)),
|
||||
m_autoTypeUi->sequenceEdit, SLOT(setEnabled(bool)));
|
||||
connect(m_autoTypeUi->customWindowSequenceButton, SIGNAL(toggled(bool)),
|
||||
m_autoTypeUi->windowSequenceEdit, SLOT(setEnabled(bool)));
|
||||
connect(m_autoTypeUi->assocAddButton, SIGNAL(clicked()), SLOT(insertAutoTypeAssoc()));
|
||||
connect(m_autoTypeUi->assocRemoveButton, SIGNAL(clicked()), SLOT(removeAutoTypeAssoc()));
|
||||
connect(m_autoTypeUi->assocView->selectionModel(),
|
||||
SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
|
||||
SLOT(updateAutoTypeEnabled()));
|
||||
connect(m_autoTypeAssocModel, SIGNAL(modelReset()), SLOT(updateAutoTypeEnabled()));
|
||||
connect(m_autoTypeUi->assocView->selectionModel(),
|
||||
SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
|
||||
SLOT(loadCurrentAssoc(QModelIndex)));
|
||||
connect(m_autoTypeAssocModel, SIGNAL(modelReset()), SLOT(updateAutoTypeEnabled()));
|
||||
connect(m_autoTypeAssocModel, SIGNAL(modelReset()), SLOT(clearCurrentAssoc()));
|
||||
connect(m_autoTypeUi->windowTitleCombo, SIGNAL(editTextChanged(QString)), SLOT(applyCurrentAssoc()));
|
||||
connect(m_autoTypeUi->customWindowSequenceButton, SIGNAL(toggled(bool)), SLOT(applyCurrentAssoc()));
|
||||
connect(m_autoTypeUi->windowSequenceEdit, SIGNAL(textChanged(QString)), SLOT(applyCurrentAssoc()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void EditEntryWidget::setupProperties()
|
||||
@ -234,14 +241,17 @@ void EditEntryWidget::setupHistory()
|
||||
m_historyUi->historyView->setModel(m_sortModel);
|
||||
m_historyUi->historyView->setRootIsDecorated(false);
|
||||
|
||||
// clang-format off
|
||||
connect(m_historyUi->historyView, SIGNAL(activated(QModelIndex)), SLOT(histEntryActivated(QModelIndex)));
|
||||
connect(m_historyUi->historyView->selectionModel(),
|
||||
SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||
SLOT(updateHistoryButtons(QModelIndex,QModelIndex)));
|
||||
|
||||
connect(m_historyUi->showButton, SIGNAL(clicked()), SLOT(showHistoryEntry()));
|
||||
connect(m_historyUi->restoreButton, SIGNAL(clicked()), SLOT(restoreHistoryEntry()));
|
||||
connect(m_historyUi->deleteButton, SIGNAL(clicked()), SLOT(deleteHistoryEntry()));
|
||||
connect(m_historyUi->deleteAllButton, SIGNAL(clicked()), SLOT(deleteAllHistoryEntries()));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void EditEntryWidget::setupEntryUpdate()
|
||||
@ -253,7 +263,7 @@ void EditEntryWidget::setupEntryUpdate()
|
||||
connect(m_mainUi->passwordRepeatEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges()));
|
||||
#ifdef WITH_XC_NETWORKING
|
||||
connect(m_mainUi->urlEdit, SIGNAL(textChanged(const QString&)), this, SLOT(updateFaviconButtonEnable(const QString&)));
|
||||
connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString&)), this, SLOT(updateFaviconButtonEnable(QString&)));
|
||||
#endif
|
||||
connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_mainUi->notesEnabled, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
@ -288,13 +298,12 @@ void EditEntryWidget::setupEntryUpdate()
|
||||
connect(m_sshAgentUi->attachmentRadioButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->externalFileRadioButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->attachmentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
connect(
|
||||
m_sshAgentUi->attachmentComboBox, SIGNAL(editTextChanged(QString)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->attachmentComboBox, SIGNAL(editTextChanged(QString)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->externalFileEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->addKeyToAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->removeKeyFromAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
connect(
|
||||
m_sshAgentUi->requireUserConfirmationCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->requireUserConfirmationCheckBox, SIGNAL(stateChanged(int)),
|
||||
this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->lifetimeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
connect(m_sshAgentUi->lifetimeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setUnsavedChanges()));
|
||||
}
|
||||
@ -427,11 +436,8 @@ void EditEntryWidget::updateSSHAgentKeyInfo()
|
||||
}
|
||||
|
||||
if (!key.fingerprint().isEmpty()) {
|
||||
m_sshAgentUi->fingerprintTextLabel->setText(
|
||||
key.fingerprint(QCryptographicHash::Md5) +
|
||||
"\n" +
|
||||
key.fingerprint(QCryptographicHash::Sha256)
|
||||
);
|
||||
m_sshAgentUi->fingerprintTextLabel->setText(key.fingerprint(QCryptographicHash::Md5) + "\n"
|
||||
+ key.fingerprint(QCryptographicHash::Sha256));
|
||||
} else {
|
||||
m_sshAgentUi->fingerprintTextLabel->setText(tr("(encrypted)"));
|
||||
}
|
||||
@ -463,7 +469,6 @@ void EditEntryWidget::updateSSHAgentKeyInfo()
|
||||
void EditEntryWidget::saveSSHAgentConfig()
|
||||
{
|
||||
KeeAgentSettings settings;
|
||||
QString privateKeyPath = m_sshAgentUi->attachmentComboBox->currentText();
|
||||
|
||||
settings.setAddAtDatabaseOpen(m_sshAgentUi->addKeyToAgentCheckBox->isChecked());
|
||||
settings.setRemoveAtDatabaseClose(m_sshAgentUi->removeKeyFromAgentCheckBox->isChecked());
|
||||
@ -614,11 +619,8 @@ void EditEntryWidget::decryptPrivateKey()
|
||||
m_sshAgentUi->commentTextLabel->setText(tr("n/a"));
|
||||
}
|
||||
|
||||
m_sshAgentUi->fingerprintTextLabel->setText(
|
||||
key.fingerprint(QCryptographicHash::Md5) +
|
||||
"\n" +
|
||||
key.fingerprint(QCryptographicHash::Sha256)
|
||||
);
|
||||
m_sshAgentUi->fingerprintTextLabel->setText(key.fingerprint(QCryptographicHash::Md5) + "\n"
|
||||
+ key.fingerprint(QCryptographicHash::Sha256));
|
||||
m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey());
|
||||
m_sshAgentUi->copyToClipboardButton->setEnabled(true);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#ifndef KEEPASSX_EDITENTRYWIDGET_H
|
||||
#define KEEPASSX_EDITENTRYWIDGET_H
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QModelIndex>
|
||||
#include <QScopedPointer>
|
||||
#include <QButtonGroup>
|
||||
@ -52,7 +53,7 @@ namespace Ui
|
||||
class EditEntryWidgetMain;
|
||||
class EditEntryWidgetHistory;
|
||||
class EditWidget;
|
||||
}
|
||||
} // namespace Ui
|
||||
|
||||
class EditEntryWidget : public EditWidget
|
||||
{
|
||||
|
@ -43,9 +43,12 @@ EntryAttachmentsWidget::EntryAttachmentsWidget(QWidget* parent)
|
||||
|
||||
connect(this, SIGNAL(readOnlyChanged(bool)), SLOT(updateButtonsEnabled()));
|
||||
connect(m_attachmentsModel, SIGNAL(modelReset()), SLOT(updateButtonsEnabled()));
|
||||
|
||||
// clang-format off
|
||||
connect(m_ui->attachmentsView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
SLOT(updateButtonsEnabled()));
|
||||
// clang-format on
|
||||
|
||||
connect(m_ui->attachmentsView, SIGNAL(doubleClicked(QModelIndex)), SLOT(openAttachment(QModelIndex)));
|
||||
connect(m_ui->saveAttachmentButton, SIGNAL(clicked()), SLOT(saveSelectedAttachments()));
|
||||
|
@ -46,9 +46,15 @@ void EntryAttributesModel::setEntryAttributes(EntryAttributes* entryAttributes)
|
||||
connect(m_entryAttributes, SIGNAL(added(QString)), SLOT(attributeAdd()));
|
||||
connect(m_entryAttributes, SIGNAL(aboutToBeRemoved(QString)), SLOT(attributeAboutToRemove(QString)));
|
||||
connect(m_entryAttributes, SIGNAL(removed(QString)), SLOT(attributeRemove()));
|
||||
// clang-format off
|
||||
connect(
|
||||
m_entryAttributes, SIGNAL(aboutToRename(QString,QString)), SLOT(attributeAboutToRename(QString,QString)));
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
connect(m_entryAttributes, SIGNAL(renamed(QString,QString)), SLOT(attributeRename(QString,QString)));
|
||||
// clang-format on
|
||||
|
||||
connect(m_entryAttributes, SIGNAL(aboutToBeReset()), SLOT(aboutToReset()));
|
||||
connect(m_entryAttributes, SIGNAL(reset()), SLOT(reset()));
|
||||
}
|
||||
|
@ -49,10 +49,12 @@ EntryView::EntryView(QWidget* parent)
|
||||
// QAbstractItemView::startDrag() uses this property as the default drag action
|
||||
setDefaultDropAction(Qt::MoveAction);
|
||||
|
||||
// clang-format off
|
||||
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
|
||||
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(emitEntrySelectionChanged()));
|
||||
connect(m_model, SIGNAL(usernamesHiddenChanged()), SIGNAL(viewStateChanged()));
|
||||
connect(m_model, SIGNAL(passwordsHiddenChanged()), SIGNAL(viewStateChanged()));
|
||||
// clang-format on
|
||||
|
||||
m_headerMenu = new QMenu(this);
|
||||
m_headerMenu->setTitle(tr("Customize View"));
|
||||
@ -93,10 +95,21 @@ EntryView::EntryView(QWidget* parent)
|
||||
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
connect(header(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(showHeaderMenu(QPoint)));
|
||||
// clang-format off
|
||||
connect(header(), SIGNAL(sectionCountChanged(int,int)), SIGNAL(viewStateChanged()));
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
connect(header(), SIGNAL(sectionMoved(int,int,int)), SIGNAL(viewStateChanged()));
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
connect(header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(viewStateChanged()));
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), SIGNAL(viewStateChanged()));
|
||||
// clang-format on
|
||||
|
||||
resetFixedColumns();
|
||||
|
||||
|
@ -47,9 +47,12 @@ EditGroupWidget::EditGroupWidget(QWidget* parent)
|
||||
connect(this, SIGNAL(accepted()), SLOT(save()));
|
||||
connect(this, SIGNAL(rejected()), SLOT(cancel()));
|
||||
|
||||
// clang-format off
|
||||
connect(m_editGroupWidgetIcons,
|
||||
SIGNAL(messageEditEntry(QString,MessageWidget::MessageType)),
|
||||
SLOT(showMessage(QString,MessageWidget::MessageType)));
|
||||
// clang-format on
|
||||
|
||||
connect(m_editGroupWidgetIcons, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage()));
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace Ui
|
||||
{
|
||||
class EditGroupWidgetMain;
|
||||
class EditWidget;
|
||||
}
|
||||
} // namespace Ui
|
||||
|
||||
class EditGroupWidget : public EditWidget
|
||||
{
|
||||
|
@ -39,6 +39,7 @@ void GroupModel::changeDatabase(Database* newDb)
|
||||
|
||||
m_db = newDb;
|
||||
|
||||
// clang-format off
|
||||
connect(m_db, SIGNAL(groupDataChanged(Group*)), SLOT(groupDataChanged(Group*)));
|
||||
connect(m_db, SIGNAL(groupAboutToAdd(Group*,int)), SLOT(groupAboutToAdd(Group*,int)));
|
||||
connect(m_db, SIGNAL(groupAdded()), SLOT(groupAdded()));
|
||||
@ -46,6 +47,7 @@ void GroupModel::changeDatabase(Database* newDb)
|
||||
connect(m_db, SIGNAL(groupRemoved()), SLOT(groupRemoved()));
|
||||
connect(m_db, SIGNAL(groupAboutToMove(Group*,Group*,int)), SLOT(groupAboutToMove(Group*,Group*,int)));
|
||||
connect(m_db, SIGNAL(groupMoved()), SLOT(groupMoved()));
|
||||
// clang-format on
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
@ -34,11 +34,13 @@ GroupView::GroupView(Database* db, QWidget* parent)
|
||||
setHeaderHidden(true);
|
||||
setUniformRowHeights(true);
|
||||
|
||||
// clang-format off
|
||||
connect(this, SIGNAL(expanded(QModelIndex)), SLOT(expandedChanged(QModelIndex)));
|
||||
connect(this, SIGNAL(collapsed(QModelIndex)), SLOT(expandedChanged(QModelIndex)));
|
||||
connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(syncExpandedState(QModelIndex,int,int)));
|
||||
connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
|
||||
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), SLOT(emitGroupChanged()));
|
||||
// clang-format on
|
||||
|
||||
modelReset();
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "KeyComponentWidget.h"
|
||||
#include "ui_KeyComponentWidget.h"
|
||||
|
||||
#include <QStackedWidget>
|
||||
#include <QTimer>
|
||||
|
||||
@ -124,7 +125,8 @@ void KeyComponentWidget::updateComponentName(const QString& name)
|
||||
m_ui->addButton->setText(tr("Add %1", "Add a key component").arg(name));
|
||||
m_ui->changeButton->setText(tr("Change %1", "Change a key component").arg(name));
|
||||
m_ui->removeButton->setText(tr("Remove %1", "Remove a key component").arg(name));
|
||||
m_ui->changeOrRemoveLabel->setText(tr("%1 set, click to change or remove", "Change or remove a key component").arg(name));
|
||||
m_ui->changeOrRemoveLabel->setText(
|
||||
tr("%1 set, click to change or remove", "Change or remove a key component").arg(name));
|
||||
}
|
||||
|
||||
void KeyComponentWidget::updateComponentDescription(const QString& description)
|
||||
|
@ -18,8 +18,8 @@
|
||||
#ifndef KEEPASSXC_KEYCOMPONENTWIDGET_H
|
||||
#define KEEPASSXC_KEYCOMPONENTWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QScopedPointer>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -31,12 +31,14 @@ class QStackedWidget;
|
||||
class KeyComponentWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
// clang-format off
|
||||
Q_PROPERTY(QString componentName READ m_componentName READ componentName
|
||||
WRITE setComponentName NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString componentDescription READ m_componentDescription READ componentDescription
|
||||
WRITE setComponentDescription NOTIFY descriptionChanged)
|
||||
Q_PROPERTY(bool componentAdded READ m_isComponentAdded READ componentAdded
|
||||
WRITE setComponentAdded NOTIFY componentAddChanged)
|
||||
// clang-format on
|
||||
|
||||
public:
|
||||
enum Page
|
||||
|
@ -17,8 +17,9 @@
|
||||
|
||||
#include "KeyFileEditWidget.h"
|
||||
#include "ui_KeyFileEditWidget.h"
|
||||
#include "gui/MainWindow.h"
|
||||
|
||||
#include "gui/FileDialog.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "keys/CompositeKey.h"
|
||||
#include "keys/FileKey.h"
|
||||
@ -100,8 +101,10 @@ void KeyFileEditWidget::createKeyFile()
|
||||
QString errorMsg;
|
||||
bool created = FileKey::create(fileName, &errorMsg);
|
||||
if (!created) {
|
||||
MessageBox::critical(getMainWindow(), tr("Error creating key file"),
|
||||
tr("Unable to create key file: %1").arg(errorMsg), QMessageBox::Button::Ok);
|
||||
MessageBox::critical(getMainWindow(),
|
||||
tr("Error creating key file"),
|
||||
tr("Unable to create key file: %1").arg(errorMsg),
|
||||
QMessageBox::Button::Ok);
|
||||
} else {
|
||||
m_compUi->keyFileCombo->setEditText(fileName);
|
||||
}
|
||||
|
@ -17,10 +17,11 @@
|
||||
|
||||
#include "PasswordEditWidget.h"
|
||||
#include "ui_PasswordEditWidget.h"
|
||||
|
||||
#include "core/FilePath.h"
|
||||
#include "gui/PasswordGeneratorWidget.h"
|
||||
#include "keys/PasswordKey.h"
|
||||
#include "keys/CompositeKey.h"
|
||||
#include "keys/PasswordKey.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@ -67,7 +68,10 @@ QWidget* PasswordEditWidget::componentEditWidget()
|
||||
m_compUi->passwordGeneratorButton->setIcon(filePath()->icon("actions", "password-generator", false));
|
||||
m_compUi->repeatPasswordEdit->enableVerifyMode(m_compUi->enterPasswordEdit);
|
||||
|
||||
connect(m_compUi->togglePasswordButton, SIGNAL(toggled(bool)), m_compUi->enterPasswordEdit, SLOT(setShowPassword(bool)));
|
||||
connect(m_compUi->togglePasswordButton,
|
||||
SIGNAL(toggled(bool)),
|
||||
m_compUi->enterPasswordEdit,
|
||||
SLOT(setShowPassword(bool)));
|
||||
connect(m_compUi->passwordGeneratorButton, SIGNAL(clicked(bool)), SLOT(showPasswordGenerator()));
|
||||
|
||||
return m_compEditWidget;
|
||||
|
@ -17,11 +17,12 @@
|
||||
|
||||
#include "YubiKeyEditWidget.h"
|
||||
#include "ui_YubiKeyEditWidget.h"
|
||||
#include "gui/MessageBox.h"
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "keys/CompositeKey.h"
|
||||
#include "keys/YkChallengeResponseKey.h"
|
||||
#include "config-keepassx.h"
|
||||
|
||||
#include <QtConcurrent>
|
||||
|
||||
@ -30,7 +31,8 @@ YubiKeyEditWidget::YubiKeyEditWidget(QWidget* parent)
|
||||
, m_compUi(new Ui::YubiKeyEditWidget())
|
||||
{
|
||||
setComponentName(tr("YubiKey Challenge-Response"));
|
||||
setComponentDescription(tr("<p>If you own a <a href=\"https://www.yubico.com/\">YubiKey</a>, you can use it "
|
||||
setComponentDescription(
|
||||
tr("<p>If you own a <a href=\"https://www.yubico.com/\">YubiKey</a>, you can use it "
|
||||
"for additional security.</p><p>The YubiKey requires one of its slots to be programmed as "
|
||||
"<a href=\"https://www.yubico.com/products/services-software/personalization-tools/challenge-response/\">"
|
||||
"HMAC-SHA1 Challenge-Response</a>.</p>"));
|
||||
@ -75,7 +77,10 @@ QWidget* YubiKeyEditWidget::componentEditWidget()
|
||||
#ifdef WITH_XC_YUBIKEY
|
||||
connect(m_compUi->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollYubikey()));
|
||||
|
||||
// clang-format off
|
||||
connect(YubiKey::instance(), SIGNAL(detected(int,bool)), SLOT(yubikeyDetected(int,bool)), Qt::QueuedConnection);
|
||||
// clang-format on
|
||||
|
||||
connect(YubiKey::instance(), SIGNAL(notFound()), SLOT(noYubikeyFound()), Qt::QueuedConnection);
|
||||
|
||||
pollYubikey();
|
||||
|
@ -16,14 +16,14 @@
|
||||
*/
|
||||
|
||||
#include "NewDatabaseWizard.h"
|
||||
#include "NewDatabaseWizardPageMetaData.h"
|
||||
#include "NewDatabaseWizardPageEncryption.h"
|
||||
#include "NewDatabaseWizardPageMasterKey.h"
|
||||
#include "NewDatabaseWizardPageMetaData.h"
|
||||
|
||||
#include "core/Global.h"
|
||||
#include "core/Database.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
#include "format/KeePass2.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
@ -35,9 +35,11 @@ NewDatabaseWizard::NewDatabaseWizard(QWidget* parent)
|
||||
setWizardStyle(QWizard::MacStyle);
|
||||
setOption(QWizard::WizardOption::HaveHelpButton, false);
|
||||
|
||||
// clang-format off
|
||||
m_pages << new NewDatabaseWizardPageMetaData()
|
||||
<< new NewDatabaseWizardPageEncryption()
|
||||
<< new NewDatabaseWizardPageMasterKey();
|
||||
// clang-format on
|
||||
|
||||
for (const auto& page : asConst(m_pages)) {
|
||||
addPage(page);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "NewDatabaseWizardPage.h"
|
||||
#include "ui_NewDatabaseWizardPage.h"
|
||||
|
||||
#include "core/Database.h"
|
||||
#include "gui/dbsettings/DatabaseSettingsWidget.h"
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user