Add support for features list (#2848)

This commit is contained in:
Sami Vänttinen 2026-02-05 11:02:31 +02:00 committed by GitHub
parent 58beb79927
commit 497bdd4b8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 60 additions and 45 deletions

View file

@ -1058,6 +1058,10 @@
"message": "Requires KeePassXC version: $1",
"description": "KeePassXC version requirement text."
},
"optionsMinimumKeePassXCVersionRequired": {
"message": "The extension requires KeePassXC version: $1. Earlier versions can cause unwanted behavior.",
"description": "KeePassXC minimum version requirement text."
},
"optionsDefault": {
"message": "Default: $1",
"description": "Default setting text."

View file

@ -400,7 +400,7 @@ function onDisconnected() {
page.clearAllLogins();
keepass.updatePopup('cross');
keepass.updateDatabaseHashToContent();
logError(`Failed to connect: ${(browser.runtime.lastError === null ? 'Unknown error' : browser.runtime.lastError.message)}`);
logError(`Failed to connect: ${(browser.runtime.lastError === null ? 'Unknown error' : browser.runtime.lastError?.message)}`);
}
keepassClient.onNativeMessage = function(response) {

View file

@ -245,6 +245,10 @@ kpxcEvent.isFirefox = async function(tab) {
return page.isFirefox;
};
kpxcEvent.getFeaturesList = async function (tab) {
return keepass.featuresList;
};
// All methods named in this object have to be declared BEFORE this!
kpxcEvent.messageHandlers = {
'add_credentials': keepass.addCredentials,
@ -253,7 +257,6 @@ kpxcEvent.messageHandlers = {
'banner_set_position': page.setBannerPosition,
'check_database_hash': keepass.checkDatabaseHash,
'check_update_keepassxc': kpxcEvent.onCheckUpdateKeePassXC,
'compare_versions': kpxcEvent.compareMultipleVersions,
'create_new_group': keepass.createNewGroup,
'enable_automatic_reconnect': keepass.enableAutomaticReconnect,
'disable_automatic_reconnect': keepass.disableAutomaticReconnect,
@ -265,6 +268,7 @@ kpxcEvent.messageHandlers = {
'get_database_hash': keepass.getDatabaseHash,
'get_database_groups': keepass.getDatabaseGroups,
'get_error_message': keepass.getErrorMessage,
'get_features_list': kpxcEvent.getFeaturesList,
'get_keepassxc_versions': kpxcEvent.onGetKeePassXCVersions,
'get_login_list': page.getLoginList,
'get_status': kpxcEvent.onGetStatus,

View file

@ -2,6 +2,14 @@
const keepass = {};
keepass.associated = { 'value': false, 'hash': null };
keepass.featuresList = {
downloadFaviconAfterSave: false,
newTotp: false,
passwordGenerator: false,
passkeys: false,
passkeysDefaultGroup: false,
requiredKeePassXCVersionFound: false,
};
keepass.keyPair = { publicKey: null, secretKey: null };
keepass.serverPublicKey = '';
keepass.clientID = '';
@ -10,7 +18,7 @@ keepass.isDatabaseClosed = true;
keepass.isKeePassXCAvailable = false;
keepass.isEncryptionKeyUnrecognized = false;
keepass.currentKeePassXC = '';
keepass.requiredKeePassXC = '2.3.1';
keepass.requiredKeePassXC = '2.6.0';
keepass.latestVersionUrl = 'https://api.github.com/repos/keepassxreboot/keepassxc/releases/latest';
keepass.cacheTimeout = 30 * 1000; // Milliseconds
keepass.databaseHash = '';
@ -172,7 +180,7 @@ keepass.generatePassword = async function(tab) {
return '';
}
if (!compareVersion(keepass.requiredKeePassXC, keepass.currentKeePassXC)) {
if (!keepass.featuresList.passwordGenerator) {
return '';
}
@ -229,9 +237,7 @@ keepass.associate = async function(tab) {
const response = await keepassClient.sendMessage(kpAction, tab, messageData, nonce, false, true);
if (response) {
// Use public key as identification key with older KeePassXC releases
const savedKey = compareVersion('2.3.4', keepass.currentKeePassXC) ? idKey : key;
keepass.setCryptoKey(response.id, savedKey); // Save the new identification public key as id key for the database
keepass.setCryptoKey(response.id, idKey);
keepass.associated.value = true;
keepass.associated.hash = response.hash || 0;
@ -412,6 +418,7 @@ keepass.changePublicKeys = async function(tab, enableTimeout = false, connection
try {
const response = await keepassClient.sendNativeMessage(request, enableTimeout, connectionTimeout);
keepass.setcurrentKeePassXCVersion(response.version);
keepass.updateFeaturesList(response.version);
if (!keepassClient.verifyKeyResponse(response, key, incrementedNonce)) {
if (tab && page.tabs[tab.id]) {
@ -544,7 +551,7 @@ keepass.createNewGroup = async function(tab, args = []) {
keepass.getTotp = async function(tab, args = []) {
const [ uuid, oldTotp ] = args;
if (!compareVersion('2.6.1', keepass.currentKeePassXC, true)) {
if (!keepass.featuresList.newTotpSupported) {
return oldTotp;
}
@ -783,13 +790,9 @@ keepass.getCryptoKeys = function() {
keepass.enableAutomaticReconnect = async function() {
// Disable for Windows if KeePassXC is older than 2.3.4
if (!page.settings.autoReconnect
|| (navigator.platform.toLowerCase().includes('win')
&& keepass.currentKeePassXC
&& !compareVersion('2.3.4', keepass.currentKeePassXC))) {
if (!page.settings.autoReconnect) {
return;
}
if (keepass.reconnectLoop === null) {
keepass.reconnectLoop = setInterval(async () => {
if (!keepass.isKeePassXCAvailable) {
@ -945,6 +948,25 @@ keepass.updateDatabaseHashToContent = async function() {
}
};
keepass.updateFeaturesList = function (currentVersion) {
const versionResults = keepass.compareMultipleVersions([
keepass.requiredKeePassXC,
'2.6.1',
'2.7.0',
'2.7.7',
'2.7.10'
], currentVersion);
keepass.featuresList = {
downloadFaviconAfterSave: versionResults['2.7.0'],
newTotp: versionResults['2.6.1'],
passwordGenerator: versionResults['2.7.0'],
passkeys: versionResults['2.7.7'],
passkeysDefaultGroup: versionResults['2.7.10'],
requiredKeePassXCVersionFound: versionResults[keepass.requiredKeePassXC],
};
};
// Expects an array of versions to compare
keepass.compareMultipleVersions = function(versions, current, canBeEqual = true) {
if (!Array.isArray(versions)) {

View file

@ -157,13 +157,7 @@ kpxcPasswordGenerator.fill = function(elem, password) {
const isPasswordGeneratorSupported = async function() {
const response = await browser.runtime.sendMessage({
action: 'get_keepassxc_versions'
action: 'get_features_list'
});
const result = await browser.runtime.sendMessage({
action: 'compare_versions',
args: [ [ '2.7.0' ], response.current ]
});
return result['2.7.0'] || false;
return response?.passwordGenerator;
};

View file

@ -81,6 +81,12 @@
</div>
<div class="card-body">
<!-- Version warning -->
<div class="alert alert-warning mt-3 col-lg-9" role="alert" id="minimumVersionAlert" style="display: none;">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
<span data-i18n="optionsMinimumKeePassXCVersionRequired" data-i18n-placeholder="2.6.0"></span>
</div>
<!-- Color theme -->
<div class="form-group col-sm-3 pb-2">
<label for="colorTheme" class="form-label" data-i18n="optionsThemeSelectionHeader"></label>

View file

@ -366,38 +366,23 @@ options.showKeePassXCVersions = async function(response) {
$('#tab-about span.kpxcVersion').textContent = response.current;
$('#tab-general-settings button.checkUpdateKeePassXC').disabled = false;
const versionResults = await browser.runtime.sendMessage({
action: 'compare_versions',
args: [
[
'2.6.0',
'2.7.0',
'2.7.7',
'2.7.10'
],
response.current
],
});
// Hide/disable certain options with older KeePassXC versions than 2.6.0
if (versionResults['2.6.0']) {
const featureList = await browser.runtime.sendMessage({ action: 'get_features_list' });
if (featureList?.requiredKeePassXCVersionFound) {
$('#tab-general-settings #versionRequiredAlert').hide();
} else {
$('#tab-general-settings #showGroupNameInAutocomplete').disabled = true;
$('#tab-general-settings #minimumVersionAlert').show();
}
// Hide certain options with older KeePassXC versions than 2.7.0
if (!versionResults['2.7.0']) {
if (!featureList?.downloadFaviconAfterSave) {
$('#tab-general-settings #downloadFaviconAfterSaveFormGroup').hide();
}
// Hide certain options with older KeePassXC versions than 2.7.7
if (!versionResults['2.7.7']) {
if (!featureList?.passkeys) {
$('#tab-general-settings #passkeysOptionsCard').hide();
}
// Hide passkeys default group option with KeePassXC version < 2.7.10
if (!versionResults['2.7.10']) {
if (!featureList?.passkeysDefaultGroup) {
$('#tab-general-settings #passkeysDefaultGroup').hide();
}
};
@ -726,7 +711,7 @@ options.initSitePreferences = function() {
// Page URL
row.children[0].children[0].children[0].value = url;
row.children[0].children[0]?.addEventListener('dblclick', (e) =>
row.children[0].children[0]?.addEventListener('dblclick', (e) =>
enterEditMode(e, row, inputField, editButton, cancelButton, saveButton)
);
@ -891,7 +876,7 @@ const getBrowserId = function(userAgent) {
return `${query.name} ${getVersion(userAgent, query.findStr)}`;
}
}
return 'Other/Unknown';
};
@ -919,7 +904,7 @@ const updateDropdownPosition = function(e, dropdown) {
if (!rect) {
return;
}
const zoom = getComputedStyle(document.body).zoom || 1;
const scrollTop = document.defaultView.scrollY / zoom;
const scrollLeft = document.defaultView?.scrollX / zoom;