Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ option(KPXC_MINIMAL "Build KeePassXC with the minimal feature set required for b
option(KPXC_FEATURE_BROWSER "Browser integration and passkeys support" ON)
option(KPXC_FEATURE_SSHAGENT "SSH Agent integration" ON)
option(KPXC_FEATURE_FDOSECRETS "freedesktop.org Secret Service integration; replace system keyring" ON)
option(KPXC_FEATURE_URLOVERRIDE "Global URL scheme override support" ON)

if(KPXC_MINIMAL)
# Disable advanced features in minimal mode
set(KPXC_FEATURE_BROWSER OFF)
set(KPXC_FEATURE_SSHAGENT OFF)
set(KPXC_FEATURE_FDOSECRETS OFF)
set(KPXC_FEATURE_URLOVERRIDE OFF)
endif()

# Minor Feature Flags
Expand All @@ -82,6 +84,7 @@ endif()
# Define feature summaries
add_feature_info("Browser" KPXC_FEATURE_BROWSER "Browser integration and passkeys support")
add_feature_info("SSH Agent" KPXC_FEATURE_SSHAGENT "SSH Agent integration")
add_feature_info("URL Override" KPXC_FEATURE_URLOVERRIDE "Global URL scheme override support")
if(UNIX AND NOT APPLE)
add_feature_info("Secret Service" KPXC_FEATURE_FDOSECRETS "Replace system keyring with freedesktop.org Secret Service integration")
endif()
Expand Down
1 change: 1 addition & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ KeePassXC comes with a variety of build options that can turn on/off features. E
-DKPXC_FEATURE_BROWSER=[ON|OFF] Browser integration and passkeys support (default: ON)
-DKPXC_FEATURE_SSHAGENT=[ON|OFF] SSH Agent integration (default: ON)
-DKPXC_FEATURE_FDOSECRETS=[ON|OFF] (Linux Only) freedesktop.org Secret Service integration; replace system keyring (default:ON)
-DKPXC_FEATURE_URLOVERRIDE=[ON|OFF] Global URL scheme override support (default: ON)

-DKPXC_FEATURE_NETWORK=[ON|OFF] Include code that reaches out to external networks (e.g. downloading icons) (default: ON)
-DKPXC_FEATURE_UPDATES=[ON|OFF] Include automatic update checks; disable for managed distributions (requires networking) (default: ON)
Expand Down
8 changes: 7 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ if(KPXC_FEATURE_FDOSECRETS)
set(fdosecrets_LIB fdosecrets)
endif()

add_subdirectory(urloverride)
if(KPXC_FEATURE_URLOVERRIDE)
set(urloverride_LIB urloverride)
endif()

configure_file(config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepassx.h)
configure_file(git-info.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/git-info.h)

Expand Down Expand Up @@ -374,7 +379,8 @@ target_link_libraries(keepassxc_gui
${browser_LIB}
${fdosecrets_LIB}
${keeshare_LIB}
${sshagent_LIB})
${sshagent_LIB}
${urloverride_LIB})

if(APPLE)
target_link_libraries(keepassxc_gui "-framework Foundation -framework AppKit -framework Carbon -framework Security -framework LocalAuthentication -framework ScreenCaptureKit")
Expand Down
1 change: 1 addition & 0 deletions src/config-keepassx.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#cmakedefine KPXC_FEATURE_BROWSER
#cmakedefine KPXC_FEATURE_SSHAGENT
#cmakedefine KPXC_FEATURE_FDOSECRETS
#cmakedefine KPXC_FEATURE_URLOVERRIDE

/* Minor Features */
#cmakedefine KPXC_FEATURE_NETWORK
Expand Down
4 changes: 3 additions & 1 deletion src/core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,9 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {

// Messages
{Config::Messages_NoLegacyKeyFileWarning, {QS("Messages/NoLegacyKeyFileWarning"), Roaming, false}},
{Config::Messages_HidePreReleaseWarning, {QS("Messages/HidePreReleaseWarning"), Local, {}}}};
{Config::Messages_HidePreReleaseWarning, {QS("Messages/HidePreReleaseWarning"), Local, {}}},

{Config::UrlOverride_Rules, {QS("UrlOverride/Rules"), Roaming, {}}}};

// clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ class Config : public QObject
Messages_NoLegacyKeyFileWarning,
Messages_HidePreReleaseWarning,

UrlOverride_Rules,

// Special internal value
Deleted
};
Expand Down
22 changes: 19 additions & 3 deletions src/gui/DatabaseWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
#include "remote/RemoteHandler.h"
#include "remote/RemoteSettings.h"

#ifdef KPXC_FEATURE_URLOVERRIDE
#include "urloverride/UrlOverride.h"
#endif

#ifdef KPXC_FEATURE_NETWORK
#include "gui/IconDownloaderDialog.h"
#endif
Expand Down Expand Up @@ -1001,14 +1005,22 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
return;
}

QString cmdString = entry->resolveMultiplePlaceholders(entry->url());
QString rawTemplate = entry->url();
#ifdef KPXC_FEATURE_URLOVERRIDE
const auto overrideCommand = UrlOverride::findCommand(rawTemplate);
if (!overrideCommand.isEmpty()) {
rawTemplate = overrideCommand;
}
#endif
QString cmdString = entry->resolveMultiplePlaceholders(rawTemplate);

if (cmdString.startsWith("cmd://")) {
// check if decision to execute command was stored
bool launch = (entry->attributes()->value(EntryAttributes::RememberCmdExecAttr) == "1");

// otherwise ask user
if (!launch && cmdString.length() > 6) {
QString cmdTruncated = entry->resolveMultiplePlaceholders(entry->maskPasswordPlaceholders(entry->url()));
QString cmdTruncated = entry->resolveMultiplePlaceholders(entry->maskPasswordPlaceholders(rawTemplate));
cmdTruncated = cmdTruncated.mid(6);
if (cmdTruncated.length() > 400) {
cmdTruncated = cmdTruncated.left(400) + " […]";
Expand Down Expand Up @@ -1043,7 +1055,11 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
QStringList cmdList = QProcess::splitCommand(cmd);
if (!cmdList.isEmpty()) {
const QString program = cmdList.takeFirst();
#ifdef KPXC_FEATURE_URLOVERRIDE
UrlOverride::executeCommand(program, cmdList);
#else
QProcess::startDetached(program, cmdList);
#endif
}

if (config()->get(Config::MinimizeOnOpenUrl).toBool()) {
Expand All @@ -1053,7 +1069,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
} else if (cmdString.startsWith("kdbx://")) {
openDatabaseFromEntry(entry, false);
} else {
QUrl url = QUrl::fromUserInput(entry->resolveMultiplePlaceholders(entry->url()));
QUrl url = QUrl::fromUserInput(cmdString);
if (!url.isEmpty()) {
#ifdef KEEPASSXC_DIST_APPIMAGE
QProcess::execute("xdg-open", {url.toString(QUrl::FullyEncoded)});
Expand Down
7 changes: 7 additions & 0 deletions src/gui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
#include "browser/BrowserService.h"
#endif

#ifdef KPXC_FEATURE_URLOVERRIDE
#include "urloverride/UrlOverrideSettingsPage.h"
#endif

#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && !defined(QT_NO_DBUS)
#include "mainwindowadaptor.h"
#endif
Expand Down Expand Up @@ -203,6 +207,9 @@ MainWindow::MainWindow()
initActionCollection();

m_ui->settingsWidget->addSettingsPage(new ShortcutSettingsPage());
#ifdef KPXC_FEATURE_URLOVERRIDE
m_ui->settingsWidget->addSettingsPage(new UrlOverrideSettingsPage());
#endif

#ifdef KPXC_FEATURE_BROWSER
connect(
Expand Down
26 changes: 26 additions & 0 deletions src/urloverride/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (C) 2026 KeePassXC Team <team@keepassxc.org>
#
# 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
# the Free Software Foundation, either version 2 or (at your option)
# version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

if(KPXC_FEATURE_URLOVERRIDE)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})

set(urloverride_SOURCES
UrlOverride.cpp
UrlOverrideSettingsPage.cpp
)

add_library(urloverride STATIC ${urloverride_SOURCES})
target_link_libraries(urloverride Qt6::Core Qt6::Widgets)
endif()
Loading