Add support for Thunderbird

This commit is contained in:
varjolintu 2023-08-07 09:18:10 +03:00
parent 5fb26d666a
commit 7797bff184
No known key found for this signature in database
GPG Key ID: F6D95B66E258AD31
5 changed files with 57 additions and 18 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org> * Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -42,8 +42,9 @@ BrowserSettingsWidget::BrowserSettingsWidget(QWidget* parent)
m_ui->extensionLabel->setOpenExternalLinks(true); m_ui->extensionLabel->setOpenExternalLinks(true);
m_ui->extensionLabel->setText( m_ui->extensionLabel->setText(
tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2 and %3. %4") tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2 and %3 and %4. %5")
.arg("<a href=\"https://addons.mozilla.org/firefox/addon/keepassxc-browser/\">Firefox</a>", .arg("<a href=\"https://addons.mozilla.org/firefox/addon/keepassxc-browser/\">Firefox</a>",
"<a href=\"https://addons.thunderbird.net/thunderbird/addon/keepassxc-mail/\">Thunderbird</a>",
"<a href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk\">" "<a href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk\">"
"Google Chrome / Chromium / Vivaldi / Brave</a>", "Google Chrome / Chromium / Vivaldi / Brave</a>",
"<a href=\"https://microsoftedge.microsoft.com/addons/detail/pdffhmdngciaglkoonimfcmckehcpafo\">Microsoft Edge</a>", "<a href=\"https://microsoftedge.microsoft.com/addons/detail/pdffhmdngciaglkoonimfcmckehcpafo\">Microsoft Edge</a>",
@ -133,6 +134,7 @@ void BrowserSettingsWidget::loadSettings()
m_ui->chromiumSupport->setChecked(settings->browserSupport(BrowserShared::CHROMIUM)); m_ui->chromiumSupport->setChecked(settings->browserSupport(BrowserShared::CHROMIUM));
m_ui->firefoxSupport->setChecked(settings->browserSupport(BrowserShared::FIREFOX)); m_ui->firefoxSupport->setChecked(settings->browserSupport(BrowserShared::FIREFOX));
m_ui->edgeSupport->setChecked(settings->browserSupport(BrowserShared::EDGE)); m_ui->edgeSupport->setChecked(settings->browserSupport(BrowserShared::EDGE));
m_ui->thunderBirdSupport->setChecked(settings->browserSupport(BrowserShared::THUNDERBIRD));
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
m_ui->braveSupport->setChecked(settings->browserSupport(BrowserShared::BRAVE)); m_ui->braveSupport->setChecked(settings->browserSupport(BrowserShared::BRAVE));
m_ui->vivaldiSupport->setChecked(settings->browserSupport(BrowserShared::VIVALDI)); m_ui->vivaldiSupport->setChecked(settings->browserSupport(BrowserShared::VIVALDI));
@ -261,6 +263,7 @@ void BrowserSettingsWidget::saveSettings()
settings->setBrowserSupport(BrowserShared::CHROMIUM, m_ui->chromiumSupport->isChecked()); settings->setBrowserSupport(BrowserShared::CHROMIUM, m_ui->chromiumSupport->isChecked());
settings->setBrowserSupport(BrowserShared::FIREFOX, m_ui->firefoxSupport->isChecked()); settings->setBrowserSupport(BrowserShared::FIREFOX, m_ui->firefoxSupport->isChecked());
settings->setBrowserSupport(BrowserShared::EDGE, m_ui->edgeSupport->isChecked()); settings->setBrowserSupport(BrowserShared::EDGE, m_ui->edgeSupport->isChecked());
settings->setBrowserSupport(BrowserShared::THUNDERBIRD, m_ui->thunderBirdSupport->isChecked());
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
settings->setBrowserSupport(BrowserShared::BRAVE, m_ui->braveSupport->isChecked()); settings->setBrowserSupport(BrowserShared::BRAVE, m_ui->braveSupport->isChecked());
settings->setBrowserSupport(BrowserShared::VIVALDI, m_ui->vivaldiSupport->isChecked()); settings->setBrowserSupport(BrowserShared::VIVALDI, m_ui->vivaldiSupport->isChecked());

View File

@ -134,6 +134,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="3">
<widget class="QCheckBox" name="thunderBirdSupport">
<property name="text">
<string>Thunderbird</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="chromeSupport"> <widget class="QCheckBox" name="chromeSupport">
<property name="text"> <property name="text">

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org> * Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -33,6 +33,7 @@ namespace BrowserShared
TOR_BROWSER, TOR_BROWSER,
BRAVE, BRAVE,
EDGE, EDGE,
THUNDERBIRD,
CUSTOM, CUSTOM,
MAX_SUPPORTED MAX_SUPPORTED
}; };

View File

@ -1,6 +1,5 @@
/* /*
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com> * Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -37,7 +36,9 @@ using namespace BrowserShared;
namespace namespace
{ {
const QString HOST_NAME = QStringLiteral("org.keepassxc.keepassxc_browser"); const QString HOST_NAME = QStringLiteral("org.keepassxc.keepassxc_browser");
const QStringList ALLOWED_EXTENSIONS = QStringList() << QStringLiteral("keepassxc-browser@keepassxc.org"); const QString FIREFOX_EXTENSION = QStringLiteral("keepassxc-browser@keepassxc.org");
const QString THUNDERBIRD_HOST_NAME = QStringLiteral("org.keepassxc.keepassxc_mail");
const QString THUNDERBIRD_EXTENSION = QStringLiteral("keepassxc-mail@kkapsner.de");
const QStringList ALLOWED_ORIGINS = QStringList() const QStringList ALLOWED_ORIGINS = QStringList()
<< QStringLiteral("chrome-extension://pdffhmdngciaglkoonimfcmckehcpafo/") << QStringLiteral("chrome-extension://pdffhmdngciaglkoonimfcmckehcpafo/")
<< QStringLiteral("chrome-extension://oboonakemofpalcgghocfoadofidjkkk/"); << QStringLiteral("chrome-extension://oboonakemofpalcgghocfoadofidjkkk/");
@ -45,6 +46,7 @@ namespace
const QString TARGET_DIR_CHROME = QStringLiteral("/Library/Application Support/Google/Chrome/NativeMessagingHosts"); const QString TARGET_DIR_CHROME = QStringLiteral("/Library/Application Support/Google/Chrome/NativeMessagingHosts");
const QString TARGET_DIR_CHROMIUM = QStringLiteral("/Library/Application Support/Chromium/NativeMessagingHosts"); const QString TARGET_DIR_CHROMIUM = QStringLiteral("/Library/Application Support/Chromium/NativeMessagingHosts");
const QString TARGET_DIR_FIREFOX = QStringLiteral("/Library/Application Support/Mozilla/NativeMessagingHosts"); const QString TARGET_DIR_FIREFOX = QStringLiteral("/Library/Application Support/Mozilla/NativeMessagingHosts");
const QString TARGET_DIR_THUNDERBIRD = QStringLiteral("/Library/Mozilla/NativeMessagingHosts");
const QString TARGET_DIR_VIVALDI = QStringLiteral("/Library/Application Support/Vivaldi/NativeMessagingHosts"); const QString TARGET_DIR_VIVALDI = QStringLiteral("/Library/Application Support/Vivaldi/NativeMessagingHosts");
const QString TARGET_DIR_TOR_BROWSER = const QString TARGET_DIR_TOR_BROWSER =
QStringLiteral("/Library/Application Support/TorBrowser-Data/Browser/Mozilla/NativeMessagingHosts"); QStringLiteral("/Library/Application Support/TorBrowser-Data/Browser/Mozilla/NativeMessagingHosts");
@ -63,6 +65,8 @@ namespace
const QString TARGET_DIR_BRAVE = TARGET_DIR_CHROME; const QString TARGET_DIR_BRAVE = TARGET_DIR_CHROME;
const QString TARGET_DIR_EDGE = QStringLiteral( const QString TARGET_DIR_EDGE = QStringLiteral(
"HKEY_CURRENT_USER\\Software\\Microsoft\\Edge\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser"); "HKEY_CURRENT_USER\\Software\\Microsoft\\Edge\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser");
const QString TARGET_DIR_THUNDERBIRD =
QStringLiteral("HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\org.keepassxc.keepassxc_mail");
#else #else
const QString TARGET_DIR_CHROME = QStringLiteral("/google-chrome/NativeMessagingHosts"); const QString TARGET_DIR_CHROME = QStringLiteral("/google-chrome/NativeMessagingHosts");
const QString TARGET_DIR_CHROMIUM = QStringLiteral("/chromium/NativeMessagingHosts"); const QString TARGET_DIR_CHROMIUM = QStringLiteral("/chromium/NativeMessagingHosts");
@ -72,6 +76,7 @@ namespace
"/torbrowser/tbb/x86_64/tor-browser_en-US/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts"); "/torbrowser/tbb/x86_64/tor-browser_en-US/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts");
const QString TARGET_DIR_BRAVE = QStringLiteral("/BraveSoftware/Brave-Browser/NativeMessagingHosts"); const QString TARGET_DIR_BRAVE = QStringLiteral("/BraveSoftware/Brave-Browser/NativeMessagingHosts");
const QString TARGET_DIR_EDGE = QStringLiteral("/microsoft-edge/NativeMessagingHosts"); const QString TARGET_DIR_EDGE = QStringLiteral("/microsoft-edge/NativeMessagingHosts");
const QString TARGET_DIR_THUNDERBIRD = QStringLiteral("/.mozilla/native-messaging-hosts");
#endif #endif
} // namespace } // namespace
@ -160,6 +165,8 @@ QString NativeMessageInstaller::getTargetPath(SupportedBrowsers browser) const
return TARGET_DIR_BRAVE; return TARGET_DIR_BRAVE;
case SupportedBrowsers::EDGE: case SupportedBrowsers::EDGE:
return TARGET_DIR_EDGE; return TARGET_DIR_EDGE;
case SupportedBrowsers::THUNDERBIRD:
return TARGET_DIR_THUNDERBIRD;
case SupportedBrowsers::CUSTOM: case SupportedBrowsers::CUSTOM:
return browserSettings()->customBrowserLocation(); return browserSettings()->customBrowserLocation();
default: default:
@ -191,6 +198,8 @@ QString NativeMessageInstaller::getBrowserName(SupportedBrowsers browser) const
return QStringLiteral("brave"); return QStringLiteral("brave");
case SupportedBrowsers::EDGE: case SupportedBrowsers::EDGE:
return QStringLiteral("edge"); return QStringLiteral("edge");
case SupportedBrowsers::THUNDERBIRD:
return QStringLiteral("thunderbird");
case SupportedBrowsers::CUSTOM: case SupportedBrowsers::CUSTOM:
return QStringLiteral("custom"); return QStringLiteral("custom");
default: default:
@ -214,7 +223,7 @@ QString NativeMessageInstaller::getNativeMessagePath(SupportedBrowsers browser)
} else { } else {
basePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); basePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
} }
return QStringLiteral("%1/%2_%3.json").arg(basePath, HOST_NAME, getBrowserName(browser)); return QStringLiteral("%1/%2_%3.json").arg(basePath, getHostName(browser), getBrowserName(browser));
#elif defined(KEEPASSXC_DIST_FLATPAK) #elif defined(KEEPASSXC_DIST_FLATPAK)
// Flatpak sandboxes do not have access to the XDG_DATA_HOME and XDG_CONFIG_HOME variables // Flatpak sandboxes do not have access to the XDG_DATA_HOME and XDG_CONFIG_HOME variables
// defined in the host, so we must hardcode them here. // defined in the host, so we must hardcode them here.
@ -237,10 +246,10 @@ QString NativeMessageInstaller::getNativeMessagePath(SupportedBrowsers browser)
basePath = QDir::homePath(); basePath = QDir::homePath();
#endif #endif
if (browser == SupportedBrowsers::CUSTOM) { if (browser == SupportedBrowsers::CUSTOM) {
return QString("%1/%2.json").arg(getTargetPath(browser), HOST_NAME); return QString("%1/%2.json").arg(getTargetPath(browser), getHostName(browser));
} }
return QStringLiteral("%1%2/%3.json").arg(basePath, getTargetPath(browser), HOST_NAME); return QStringLiteral("%1%2/%3.json").arg(basePath, getTargetPath(browser), getHostName(browser));
} }
#ifdef KEEPASSXC_DIST_FLATPAK #ifdef KEEPASSXC_DIST_FLATPAK
@ -305,6 +314,17 @@ QString NativeMessageInstaller::getInstalledProxyPath() const
return QDir::toNativeSeparators(path); return QDir::toNativeSeparators(path);
} }
/**
* Returns name of the extension. Thunderbird differs from the default.
*
* @param browser Selected browser
* @return QString Name of the extension
*/
QString NativeMessageInstaller::getHostName(BrowserShared::SupportedBrowsers browser) const
{
return browser == SupportedBrowsers::THUNDERBIRD ? THUNDERBIRD_HOST_NAME : HOST_NAME;
}
/** /**
* Constructs the JSON script file used with native messaging * Constructs the JSON script file used with native messaging
* *
@ -315,18 +335,14 @@ QString NativeMessageInstaller::getInstalledProxyPath() const
QJsonObject NativeMessageInstaller::constructFile(SupportedBrowsers browser) QJsonObject NativeMessageInstaller::constructFile(SupportedBrowsers browser)
{ {
QJsonObject script; QJsonObject script;
script["name"] = HOST_NAME; script["name"] = getHostName(browser);
script["description"] = QStringLiteral("KeePassXC integration with native messaging support"); script["description"] = QStringLiteral("KeePassXC integration with native messaging support");
script["path"] = getProxyPath(); script["path"] = getProxyPath();
script["type"] = QStringLiteral("stdio"); script["type"] = QStringLiteral("stdio");
QJsonArray arr; QJsonArray arr;
if (browser == SupportedBrowsers::FIREFOX || browser == SupportedBrowsers::TOR_BROWSER if (isFirefoxBrowser(browser)) {
|| (browser == SupportedBrowsers::CUSTOM arr.append(browser == SupportedBrowsers::THUNDERBIRD ? THUNDERBIRD_EXTENSION : FIREFOX_EXTENSION);
&& browserSettings()->customBrowserType() == SupportedBrowsers::FIREFOX)) {
for (const QString& extension : ALLOWED_EXTENSIONS) {
arr.append(extension);
}
script["allowed_extensions"] = arr; script["allowed_extensions"] = arr;
} else { } else {
for (const QString& origin : ALLOWED_ORIGINS) { for (const QString& origin : ALLOWED_ORIGINS) {
@ -373,3 +389,11 @@ bool NativeMessageInstaller::createNativeMessageFile(SupportedBrowsers browser)
} }
return true; return true;
} }
bool NativeMessageInstaller::isFirefoxBrowser(BrowserShared::SupportedBrowsers browser) const
{
return browser == SupportedBrowsers::FIREFOX || browser == SupportedBrowsers::TOR_BROWSER
|| browser == SupportedBrowsers::THUNDERBIRD
|| (browser == SupportedBrowsers::CUSTOM
&& browserSettings()->customBrowserType() == SupportedBrowsers::FIREFOX);
}

View File

@ -1,6 +1,5 @@
/* /*
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com> * Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -40,8 +39,10 @@ private:
QString getTargetPath(BrowserShared::SupportedBrowsers browser) const; QString getTargetPath(BrowserShared::SupportedBrowsers browser) const;
QString getBrowserName(BrowserShared::SupportedBrowsers browser) const; QString getBrowserName(BrowserShared::SupportedBrowsers browser) const;
QString getNativeMessagePath(BrowserShared::SupportedBrowsers browser) const; QString getNativeMessagePath(BrowserShared::SupportedBrowsers browser) const;
QString getHostName(BrowserShared::SupportedBrowsers browser) const;
QJsonObject constructFile(BrowserShared::SupportedBrowsers browser); QJsonObject constructFile(BrowserShared::SupportedBrowsers browser);
bool createNativeMessageFile(BrowserShared::SupportedBrowsers browser); bool createNativeMessageFile(BrowserShared::SupportedBrowsers browser);
bool isFirefoxBrowser(BrowserShared::SupportedBrowsers browser) const;
Q_DISABLE_COPY(NativeMessageInstaller); Q_DISABLE_COPY(NativeMessageInstaller);
}; };