mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-08-09 23:12:23 -04:00
Merge branch 'master' into develop
This commit is contained in:
commit
b2fd7f6d54
26 changed files with 238 additions and 121 deletions
|
@ -44,10 +44,11 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent)
|
|||
|
||||
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. %3")
|
||||
tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2 and %3. %4")
|
||||
.arg("<a href=\"https://addons.mozilla.org/firefox/addon/keepassxc-browser/\">Firefox</a>",
|
||||
"<a href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk\">"
|
||||
"Google Chrome / Chromium / Vivaldi / Brave</a>",
|
||||
"<a href=\"https://microsoftedge.microsoft.com/addons/detail/pdffhmdngciaglkoonimfcmckehcpafo\">Microsoft Edge</a>",
|
||||
snapInstructions));
|
||||
// clang-format on
|
||||
|
||||
|
@ -123,6 +124,7 @@ void BrowserOptionDialog::loadSettings()
|
|||
m_ui->chromeSupport->setChecked(settings->chromeSupport());
|
||||
m_ui->chromiumSupport->setChecked(settings->chromiumSupport());
|
||||
m_ui->firefoxSupport->setChecked(settings->firefoxSupport());
|
||||
m_ui->edgeSupport->setChecked(settings->edgeSupport());
|
||||
#ifndef Q_OS_WIN
|
||||
m_ui->braveSupport->setChecked(settings->braveSupport());
|
||||
m_ui->vivaldiSupport->setChecked(settings->vivaldiSupport());
|
||||
|
@ -132,6 +134,12 @@ void BrowserOptionDialog::loadSettings()
|
|||
m_ui->snapWarningLabel->setVisible(false);
|
||||
#endif
|
||||
|
||||
// TODO: Enable when Linux version is released
|
||||
#ifdef Q_OS_LINUX
|
||||
m_ui->edgeSupport->setChecked(false);
|
||||
m_ui->edgeSupport->setEnabled(false);
|
||||
#endif
|
||||
|
||||
#if defined(KEEPASSXC_DIST_APPIMAGE)
|
||||
m_ui->supportBrowserProxy->setChecked(true);
|
||||
m_ui->supportBrowserProxy->setEnabled(false);
|
||||
|
@ -194,6 +202,7 @@ void BrowserOptionDialog::saveSettings()
|
|||
settings->setChromeSupport(m_ui->chromeSupport->isChecked());
|
||||
settings->setChromiumSupport(m_ui->chromiumSupport->isChecked());
|
||||
settings->setFirefoxSupport(m_ui->firefoxSupport->isChecked());
|
||||
settings->setEdgeSupport(m_ui->edgeSupport->isChecked());
|
||||
#ifndef Q_OS_WIN
|
||||
settings->setBraveSupport(m_ui->braveSupport->isChecked());
|
||||
settings->setVivaldiSupport(m_ui->vivaldiSupport->isChecked());
|
||||
|
|
|
@ -167,6 +167,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QCheckBox" name="edgeSupport">
|
||||
<property name="text">
|
||||
<string>&Edge</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -935,6 +935,12 @@ int BrowserService::sortPriority(const Entry* entry,
|
|||
if (url.scheme().isEmpty()) {
|
||||
url.setScheme("https");
|
||||
}
|
||||
|
||||
// Add the empty path to the URL if it's missing
|
||||
if (url.path().isEmpty() && !url.hasFragment() && !url.hasQuery()) {
|
||||
url.setPath("/");
|
||||
}
|
||||
|
||||
const QString entryURL = url.toString(QUrl::StripTrailingSlash);
|
||||
const QString baseEntryURL =
|
||||
url.toString(QUrl::StripTrailingSlash | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment);
|
||||
|
@ -1046,7 +1052,12 @@ bool BrowserService::handleURL(const QString& entryUrl, const QString& url, cons
|
|||
return false;
|
||||
}
|
||||
|
||||
// Filter to match hostname in URL field
|
||||
// Match the base domain
|
||||
if (baseDomain(siteQUrl.host()) != baseDomain(entryQUrl.host())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Match the subdomains with the limited wildcard
|
||||
if (siteQUrl.host().endsWith(entryQUrl.host())) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -280,6 +280,17 @@ void BrowserSettings::setTorBrowserSupport(bool enabled)
|
|||
HostInstaller::SupportedBrowsers::TOR_BROWSER, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
}
|
||||
|
||||
bool BrowserSettings::edgeSupport()
|
||||
{
|
||||
return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::EDGE);
|
||||
}
|
||||
|
||||
void BrowserSettings::setEdgeSupport(bool enabled)
|
||||
{
|
||||
m_hostInstaller.installBrowser(
|
||||
HostInstaller::SupportedBrowsers::EDGE, enabled, supportBrowserProxy(), customProxyLocation());
|
||||
}
|
||||
|
||||
bool BrowserSettings::passwordUseNumbers()
|
||||
{
|
||||
return config()->get("generator/Numbers", PasswordGenerator::DefaultNumbers).toBool();
|
||||
|
|
|
@ -80,6 +80,8 @@ public:
|
|||
void setBraveSupport(bool enabled);
|
||||
bool torBrowserSupport();
|
||||
void setTorBrowserSupport(bool enabled);
|
||||
bool edgeSupport();
|
||||
void setEdgeSupport(bool enabled);
|
||||
|
||||
bool passwordUseNumbers();
|
||||
void setPasswordUseNumbers(bool useNumbers);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
HostInstaller::HostInstaller()
|
||||
: HOST_NAME("org.keepassxc.keepassxc_browser")
|
||||
, ALLOWED_EXTENSIONS(QStringList() << "keepassxc-browser@keepassxc.org")
|
||||
, ALLOWED_ORIGINS(QStringList() << "chrome-extension://iopaggbpplllidnfmcghoonnokmjoicf/"
|
||||
, ALLOWED_ORIGINS(QStringList() << "chrome-extension://pdffhmdngciaglkoonimfcmckehcpafo/"
|
||||
<< "chrome-extension://oboonakemofpalcgghocfoadofidjkkk/")
|
||||
#if defined(Q_OS_MACOS)
|
||||
, TARGET_DIR_CHROME("/Library/Application Support/Google/Chrome/NativeMessagingHosts")
|
||||
|
@ -40,6 +40,7 @@ HostInstaller::HostInstaller()
|
|||
, TARGET_DIR_VIVALDI("/Library/Application Support/Vivaldi/NativeMessagingHosts")
|
||||
, TARGET_DIR_TOR_BROWSER("/Library/Application Support/TorBrowser-Data/Browser/Mozilla/NativeMessagingHosts")
|
||||
, TARGET_DIR_BRAVE("/Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts")
|
||||
, TARGET_DIR_EDGE("/Library/Application Support/Microsoft Edge/NativeMessagingHosts")
|
||||
#elif defined(Q_OS_WIN)
|
||||
// clang-format off
|
||||
, TARGET_DIR_CHROME("HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
|
@ -49,6 +50,8 @@ HostInstaller::HostInstaller()
|
|||
, TARGET_DIR_VIVALDI(TARGET_DIR_CHROME)
|
||||
, TARGET_DIR_TOR_BROWSER(TARGET_DIR_FIREFOX)
|
||||
, TARGET_DIR_BRAVE(TARGET_DIR_CHROME)
|
||||
, TARGET_DIR_EDGE(
|
||||
"HKEY_CURRENT_USER\\Software\\Microsoft\\Edge\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
|
||||
#else
|
||||
, TARGET_DIR_CHROME("/.config/google-chrome/NativeMessagingHosts")
|
||||
, TARGET_DIR_CHROMIUM("/.config/chromium/NativeMessagingHosts")
|
||||
|
@ -56,6 +59,7 @@ HostInstaller::HostInstaller()
|
|||
, TARGET_DIR_VIVALDI("/.config/vivaldi/NativeMessagingHosts")
|
||||
, TARGET_DIR_TOR_BROWSER("/.tor-browser/app/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts")
|
||||
, TARGET_DIR_BRAVE("/.config/BraveSoftware/Brave-Browser/NativeMessagingHosts")
|
||||
, TARGET_DIR_EDGE("/.config/microsoftedge/NativeMessagingHosts")
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
@ -139,8 +143,7 @@ void HostInstaller::installBrowser(SupportedBrowsers browser,
|
|||
*/
|
||||
void HostInstaller::updateBinaryPaths(const bool& proxy, const QString& location)
|
||||
{
|
||||
// Where 6 is the number of entries in the SupportedBrowsers enum declared in HostInstaller.h
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
for (int i = 0; i <= SupportedBrowsers::EDGE; ++i) {
|
||||
if (checkIfInstalled(static_cast<SupportedBrowsers>(i))) {
|
||||
installBrowser(static_cast<SupportedBrowsers>(i), true, proxy, location);
|
||||
}
|
||||
|
@ -168,6 +171,8 @@ QString HostInstaller::getTargetPath(SupportedBrowsers browser) const
|
|||
return TARGET_DIR_TOR_BROWSER;
|
||||
case SupportedBrowsers::BRAVE:
|
||||
return TARGET_DIR_BRAVE;
|
||||
case SupportedBrowsers::EDGE:
|
||||
return TARGET_DIR_EDGE;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
|
@ -195,6 +200,8 @@ QString HostInstaller::getBrowserName(SupportedBrowsers browser) const
|
|||
return "tor-browser";
|
||||
case SupportedBrowsers::BRAVE:
|
||||
return "brave";
|
||||
case SupportedBrowsers::EDGE:
|
||||
return "edge";
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ public:
|
|||
FIREFOX = 2,
|
||||
VIVALDI = 3,
|
||||
TOR_BROWSER = 4,
|
||||
BRAVE = 5
|
||||
BRAVE = 5,
|
||||
EDGE = 6
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -68,6 +69,7 @@ private:
|
|||
const QString TARGET_DIR_VIVALDI;
|
||||
const QString TARGET_DIR_TOR_BROWSER;
|
||||
const QString TARGET_DIR_BRAVE;
|
||||
const QString TARGET_DIR_EDGE;
|
||||
};
|
||||
|
||||
#endif // HOSTINSTALLER_H
|
||||
|
|
|
@ -106,9 +106,9 @@ void NativeMessagingBase::readNativeMessages()
|
|||
quint32 length = 0;
|
||||
while (m_running.load() != 0 && !std::cin.eof()) {
|
||||
length = 0;
|
||||
std::cin.read(reinterpret_cast<char*>(&length), 4);
|
||||
std::cin.readsome(reinterpret_cast<char*>(&length), 4);
|
||||
readStdIn(length);
|
||||
QThread::msleep(1);
|
||||
QThread::msleep(100);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ namespace Tools
|
|||
|
||||
bool checkUrlValid(const QString& urlField)
|
||||
{
|
||||
if (urlField.isEmpty()) {
|
||||
if (urlField.isEmpty() || urlField.startsWith("cmd://", Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,20 +44,22 @@ Clipboard::Clipboard(QObject* parent)
|
|||
connect(qApp, SIGNAL(aboutToQuit()), SLOT(clearCopiedText()));
|
||||
}
|
||||
|
||||
void Clipboard::setText(const QString& text)
|
||||
void Clipboard::setText(const QString& text, bool clear)
|
||||
{
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
auto* clipboard = QApplication::clipboard();
|
||||
if (!clipboard) {
|
||||
qWarning("Unable to access the clipboard.");
|
||||
return;
|
||||
}
|
||||
|
||||
QMimeData* mime = new QMimeData;
|
||||
auto* mime = new QMimeData;
|
||||
#ifdef Q_OS_MACOS
|
||||
mime->setText(text);
|
||||
mime->setData("application/x-nspasteboard-concealed-type", text.toUtf8());
|
||||
clipboard->setMimeData(mime, QClipboard::Clipboard);
|
||||
#else
|
||||
const QString secretStr = "secret";
|
||||
QByteArray secretBa = secretStr.toUtf8();
|
||||
mime->setText(text);
|
||||
mime->setData("x-kde-passwordManagerHint", secretBa);
|
||||
mime->setData("x-kde-passwordManagerHint", QByteArrayLiteral("secret"));
|
||||
clipboard->setMimeData(mime, QClipboard::Clipboard);
|
||||
|
||||
if (clipboard->supportsSelection()) {
|
||||
|
@ -65,7 +67,7 @@ void Clipboard::setText(const QString& text)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (config()->get("security/clearclipboard").toBool()) {
|
||||
if (clear && config()->get("security/clearclipboard").toBool()) {
|
||||
int timeout = config()->get("security/clearclipboardtimeout").toInt();
|
||||
if (timeout > 0) {
|
||||
m_lastCopied = text;
|
||||
|
@ -84,19 +86,15 @@ void Clipboard::clearCopiedText()
|
|||
|
||||
void Clipboard::clearClipboard()
|
||||
{
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
|
||||
auto* clipboard = QApplication::clipboard();
|
||||
if (!clipboard) {
|
||||
qWarning("Unable to access the clipboard.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (clipboard->text(QClipboard::Clipboard) == m_lastCopied) {
|
||||
clipboard->clear(QClipboard::Clipboard);
|
||||
}
|
||||
|
||||
if (clipboard->supportsSelection() && (clipboard->text(QClipboard::Selection) == m_lastCopied)) {
|
||||
clipboard->clear(QClipboard::Selection);
|
||||
if (m_lastCopied == clipboard->text(QClipboard::Clipboard)
|
||||
|| m_lastCopied == clipboard->text(QClipboard::Selection)) {
|
||||
setText("", false);
|
||||
}
|
||||
|
||||
m_lastCopied.clear();
|
||||
|
|
|
@ -32,7 +32,7 @@ class Clipboard : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void setText(const QString& text);
|
||||
void setText(const QString& text, bool clear = true);
|
||||
|
||||
static Clipboard* instance();
|
||||
|
||||
|
|
|
@ -154,6 +154,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
|
|||
m_shareLabel->setVisible(false);
|
||||
#endif
|
||||
|
||||
m_previewView->setObjectName("previewWidget");
|
||||
m_previewView->hide();
|
||||
m_previewSplitter->addWidget(m_entryView);
|
||||
m_previewSplitter->addWidget(m_previewView);
|
||||
|
@ -552,6 +553,14 @@ void DatabaseWidget::deleteEntries(QList<Entry*> selectedEntries)
|
|||
}
|
||||
|
||||
refreshSearch();
|
||||
|
||||
m_entryView->setFirstEntryActive();
|
||||
auto* currentEntry = currentSelectedEntry();
|
||||
if (currentEntry) {
|
||||
m_previewView->setEntry(currentEntry);
|
||||
} else {
|
||||
m_previewView->setGroup(groupView()->currentGroup());
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseWidget::confirmDeleteEntries(QList<Entry*> entries, bool permanent)
|
||||
|
|
|
@ -145,10 +145,12 @@ void EntryPreviewWidget::setDatabaseMode(DatabaseWidget::Mode mode)
|
|||
}
|
||||
|
||||
if (mode == DatabaseWidget::Mode::ViewMode) {
|
||||
if (m_ui->stackedWidget->currentWidget() == m_ui->pageGroup) {
|
||||
if (m_currentGroup && m_ui->stackedWidget->currentWidget() == m_ui->pageGroup) {
|
||||
setGroup(m_currentGroup);
|
||||
} else {
|
||||
} else if (m_currentEntry) {
|
||||
setEntry(m_currentEntry);
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,8 +77,8 @@ private:
|
|||
|
||||
const QScopedPointer<Ui::EntryPreviewWidget> m_ui;
|
||||
bool m_locked;
|
||||
Entry* m_currentEntry;
|
||||
Group* m_currentGroup;
|
||||
QPointer<Entry> m_currentEntry;
|
||||
QPointer<Group> m_currentGroup;
|
||||
QTimer m_totpTimer;
|
||||
quint8 m_selectedTabEntry;
|
||||
quint8 m_selectedTabGroup;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue