diff --git a/src/browser/BrowserSettings.cpp b/src/browser/BrowserSettings.cpp index 5d6514cae..18477e599 100644 --- a/src/browser/BrowserSettings.cpp +++ b/src/browser/BrowserSettings.cpp @@ -187,6 +187,18 @@ QString BrowserSettings::proxyLocation() return m_nativeMessageInstaller.getProxyPath(); } +#ifdef QT_DEBUG +QString BrowserSettings::customExtensionId() +{ + return config()->get(Config::Browser_CustomExtensionId).toString(); +} + +void BrowserSettings::setCustomExtensionId(const QString& id) +{ + config()->set(Config::Browser_CustomExtensionId, id); +} +#endif + bool BrowserSettings::updateBinaryPath() { return config()->get(Config::Browser_UpdateBinaryPath).toBool(); diff --git a/src/browser/BrowserSettings.h b/src/browser/BrowserSettings.h index 3f5cceea7..e3bfe6ab4 100644 --- a/src/browser/BrowserSettings.h +++ b/src/browser/BrowserSettings.h @@ -64,6 +64,10 @@ public: QString customProxyLocation(); void setCustomProxyLocation(const QString& location); QString proxyLocation(); +#ifdef QT_DEBUG + QString customExtensionId(); + void setCustomExtensionId(const QString& id); +#endif bool updateBinaryPath(); void setUpdateBinaryPath(bool enabled); bool allowExpiredCredentials(); diff --git a/src/browser/BrowserSettingsWidget.cpp b/src/browser/BrowserSettingsWidget.cpp index 15b20b19a..7eaf87c2d 100644 --- a/src/browser/BrowserSettingsWidget.cpp +++ b/src/browser/BrowserSettingsWidget.cpp @@ -80,6 +80,11 @@ BrowserSettingsWidget::BrowserSettingsWidget(QWidget* parent) m_ui->firefoxSupport->setText("Firefox and Tor Browser"); #endif m_ui->browserGlobalWarningWidget->setVisible(false); + +#ifndef QT_DEBUG + m_ui->customExtensionId->setVisible(false); + m_ui->customExtensionLabel->setVisible(false); +#endif } BrowserSettingsWidget::~BrowserSettingsWidget() @@ -152,6 +157,10 @@ void BrowserSettingsWidget::loadSettings() m_ui->browserGlobalWarningWidget->setAutoHideTimeout(-1); #endif +#ifdef QT_DEBUG + m_ui->customExtensionId->setText(settings->customExtensionId()); +#endif + validateCustomProxyLocation(); } @@ -190,6 +199,10 @@ void BrowserSettingsWidget::saveSettings() settings->setSupportKphFields(m_ui->supportKphFields->isChecked()); settings->setNoMigrationPrompt(m_ui->noMigrationPrompt->isChecked()); +#ifdef QT_DEBUG + settings->setCustomExtensionId(m_ui->customExtensionId->text()); +#endif + settings->setBrowserSupport(BrowserShared::CHROME, m_ui->chromeSupport->isChecked()); settings->setBrowserSupport(BrowserShared::CHROMIUM, m_ui->chromiumSupport->isChecked()); settings->setBrowserSupport(BrowserShared::FIREFOX, m_ui->firefoxSupport->isChecked()); diff --git a/src/browser/BrowserSettingsWidget.ui b/src/browser/BrowserSettingsWidget.ui index b3458fdcd..467aa6167 100644 --- a/src/browser/BrowserSettingsWidget.ui +++ b/src/browser/BrowserSettingsWidget.ui @@ -378,6 +378,33 @@ + + + + 20 + + + + + Custom extension ID: + + + + + + + Custom extension ID + + + 999 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + diff --git a/src/browser/NativeMessageInstaller.cpp b/src/browser/NativeMessageInstaller.cpp index d3b3daf32..d9c6428bb 100644 --- a/src/browser/NativeMessageInstaller.cpp +++ b/src/browser/NativeMessageInstaller.cpp @@ -276,6 +276,12 @@ QJsonObject NativeMessageInstaller::constructFile(SupportedBrowsers browser) for (const QString& origin : ALLOWED_ORIGINS) { arr.append(origin); } +#ifdef QT_DEBUG + auto customId = browserSettings()->customExtensionId(); + if (!customId.isEmpty()) { + arr.append(QString("chrome-extension://%1/").arg(customId)); + } +#endif script["allowed_origins"] = arr; } diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 7a60e05b3..b027fa2d5 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -153,6 +153,9 @@ static const QHash configStrings = { {Config::Browser_SearchInAllDatabases, {QS("Browser/SearchInAllDatabases"), Roaming, false}}, {Config::Browser_SupportKphFields, {QS("Browser/SupportKphFields"), Roaming, true}}, {Config::Browser_NoMigrationPrompt, {QS("Browser/NoMigrationPrompt"), Roaming, false}}, +#ifdef QT_DEBUG + {Config::Browser_CustomExtensionId, {QS("Browser/CustomExtensionId"), Local, {}}}, +#endif // SSHAgent {Config::SSHAgent_Enabled, {QS("SSHAgent/Enabled"), Roaming, false}}, diff --git a/src/core/Config.h b/src/core/Config.h index 0141edce3..1beff9a92 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -134,6 +134,9 @@ public: Browser_SearchInAllDatabases, Browser_SupportKphFields, Browser_NoMigrationPrompt, +#ifdef QT_DEBUG + Browser_CustomExtensionId, +#endif SSHAgent_Enabled, SSHAgent_UseOpenSSH, diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp index a37f1f742..63659c22b 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp +++ b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp @@ -45,6 +45,8 @@ DatabaseSettingsWidgetBrowser::DatabaseSettingsWidgetBrowser(QWidget* parent) connect(m_ui->customDataTable->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(toggleRemoveButton(QItemSelection))); + connect(m_ui->customDataTable, SIGNAL(doubleClicked(QModelIndex)), SLOT(editIndex(QModelIndex))); + connect(m_customDataModel, SIGNAL(itemChanged(QStandardItem*)), SLOT(editFinished(QStandardItem*))); // clang-format on connect(m_ui->removeCustomDataButton, SIGNAL(clicked()), SLOT(removeSelectedKey())); @@ -127,9 +129,11 @@ void DatabaseSettingsWidgetBrowser::updateModel() QString strippedKey = key; strippedKey.remove(BrowserService::ASSOCIATE_KEY_PREFIX); auto created = customData()->value(QString("%1_%2").arg(CustomData::Created, strippedKey)); + auto createdItem = new QStandardItem(created); + createdItem->setEditable(false); m_customDataModel->appendRow(QList() << new QStandardItem(strippedKey) - << new QStandardItem(customData()->value(key)) << new QStandardItem(created)); + << new QStandardItem(customData()->value(key)) << createdItem); } } @@ -272,6 +276,52 @@ void DatabaseSettingsWidgetBrowser::refreshDatabaseID() m_db->rootGroup()->setUuid(QUuid::createUuid()); } +void DatabaseSettingsWidgetBrowser::editIndex(const QModelIndex& index) +{ + Q_ASSERT(index.isValid()); + if (!index.isValid()) { + return; + } + + m_valueInEdit = index.data().toString(); + m_ui->customDataTable->edit(index); +} + +void DatabaseSettingsWidgetBrowser::editFinished(QStandardItem* item) +{ + const QItemSelectionModel* itemSelectionModel = m_ui->customDataTable->selectionModel(); + + if (itemSelectionModel) { + auto indexList = itemSelectionModel->selectedRows(item->column()); + if (indexList.length() > 0) { + QString newValue = item->index().data().toString(); + + // The key is edited + if (item->column() == 0) { + // Get the old key/value pair, remove it and replace it + m_valueInEdit.insert(0, BrowserService::ASSOCIATE_KEY_PREFIX); + auto tempValue = customData()->value(m_valueInEdit); + newValue.insert(0, BrowserService::ASSOCIATE_KEY_PREFIX); + + m_db->metadata()->customData()->remove(m_valueInEdit); + m_db->metadata()->customData()->set(newValue, tempValue); + } else { + // Replace just the value + for (const QString& key : m_db->metadata()->customData()->keys()) { + if (key.startsWith(BrowserService::ASSOCIATE_KEY_PREFIX)) { + if (m_valueInEdit == m_db->metadata()->customData()->value(key)) { + m_db->metadata()->customData()->set(key, newValue); + break; + } + } + } + } + + updateModel(); + } + } +} + // Updates the shared key list after the list is cleared void DatabaseSettingsWidgetBrowser::updateSharedKeyList() { diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.h b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.h index 51abf7f39..369c8640f 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.h +++ b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.h @@ -64,6 +64,8 @@ private slots: void removeStoredPermissions(); void convertAttributesToCustomData(); void refreshDatabaseID(); + void editIndex(const QModelIndex& index); + void editFinished(QStandardItem* item); private: void updateModel(); @@ -77,6 +79,7 @@ protected: private: QPointer m_customData; QPointer m_customDataModel; + QString m_valueInEdit; }; #endif // KEEPASSXC_DATABASESETTINGSWIDGETBROWSER_H