Refactor compare version functions (#2375)

Refactor compare version functions
This commit is contained in:
Sami Vänttinen 2024-11-01 14:58:22 +02:00 committed by GitHub
parent 82fef19699
commit 392fe2e670
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 74 additions and 50 deletions

View file

@ -102,6 +102,7 @@
"CHECK_UPDATE_ONE_WEEK": "readonly",
"CHECK_UPDATE_THREE_DAYS": "readonly",
"cloneInto": "readonly",
"compareVersion": "readonly",
"createResult": "readonly",
"createStylesheet": "readonly",
"DatabaseState": "readonly",

View file

@ -206,8 +206,8 @@ kpxcEvent.pageClearLogins = async function(tab, alreadyCalled) {
}
};
kpxcEvent.compareVersion = async function(tab, args = []) {
return keepass.compareVersion(args[0], args[1]);
kpxcEvent.compareMultipleVersions = async function(tab, args = []) {
return keepass.compareMultipleVersions(args[0], args[1]);
};
kpxcEvent.getIsKeePassXCAvailable = async function() {
@ -241,7 +241,7 @@ kpxcEvent.messageHandlers = {
'banner_set_position': page.setBannerPosition,
'check_database_hash': keepass.checkDatabaseHash,
'check_update_keepassxc': kpxcEvent.onCheckUpdateKeePassXC,
'compare_version': kpxcEvent.compareVersion,
'compare_versions': kpxcEvent.compareMultipleVersions,
'create_new_group': keepass.createNewGroup,
'enable_automatic_reconnect': keepass.enableAutomaticReconnect,
'disable_automatic_reconnect': keepass.disableAutomaticReconnect,

View file

@ -172,7 +172,7 @@ keepass.generatePassword = async function(tab) {
return '';
}
if (!keepass.compareVersion(keepass.requiredKeePassXC, keepass.currentKeePassXC)) {
if (!compareVersion(keepass.requiredKeePassXC, keepass.currentKeePassXC)) {
return '';
}
@ -230,7 +230,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 = keepass.compareVersion('2.3.4', keepass.currentKeePassXC) ? idKey : key;
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.associated.value = true;
keepass.associated.hash = response.hash || 0;
@ -544,7 +544,7 @@ keepass.createNewGroup = async function(tab, args = []) {
keepass.getTotp = async function(tab, args = []) {
const [ uuid, oldTotp ] = args;
if (!keepass.compareVersion('2.6.1', keepass.currentKeePassXC, true)) {
if (!compareVersion('2.6.1', keepass.currentKeePassXC, true)) {
return oldTotp;
}
@ -786,7 +786,7 @@ keepass.enableAutomaticReconnect = async function() {
if (!page.settings.autoReconnect
|| (navigator.platform.toLowerCase().includes('win')
&& keepass.currentKeePassXC
&& !keepass.compareVersion('2.3.4', keepass.currentKeePassXC))) {
&& !compareVersion('2.3.4', keepass.currentKeePassXC))) {
return;
}
@ -869,7 +869,7 @@ keepass.keePassXCUpdateAvailable = async function() {
await keepass.checkForNewKeePassXCVersion();
}
return keepass.compareVersion(keepass.currentKeePassXC, keepass.latestKeePassXC.version, false);
return compareVersion(keepass.currentKeePassXC, keepass.latestKeePassXC.version, false);
}
return false;
@ -945,25 +945,18 @@ keepass.updateDatabaseHashToContent = async function() {
}
};
keepass.compareVersion = function(minimum, current, canBeEqual = true) {
if (!minimum || !current) {
return false;
// Expects an array of versions to compare
keepass.compareMultipleVersions = function(versions, current, canBeEqual = true) {
if (!Array.isArray(versions)) {
return {};
}
// Handle beta/snapshot builds as stable version
const snapshot = '-snapshot';
const beta = '-beta';
if (current.endsWith(snapshot)) {
current = current.slice(0, -snapshot.length);
const result = {};
for (const version of versions) {
result[version] = compareVersion(version, current, canBeEqual);
}
if (current.endsWith(beta)) {
current = current.slice(0, -beta.length);
}
const min = minimum.split('.', 3).map(s => s.padStart(4, '0')).join('.');
const cur = current.split('.', 3).map(s => s.padStart(4, '0')).join('.');
return (canBeEqual ? (min <= cur) : (min < cur));
return result;
};
const removeDuplicateEntries = function(arr) {

View file

@ -61,6 +61,27 @@ const ManualFill = {
BOTH: 2
};
const compareVersion = function(minimum, current, canBeEqual = true) {
if (!minimum || !current || minimum?.indexOf('.') === -1 || current?.indexOf('.') === -1) {
return false;
}
// Handle beta/snapshot builds as stable version
const snapshot = '-snapshot';
const beta = '-beta';
if (current.endsWith(snapshot)) {
current = current.slice(0, -snapshot.length);
}
if (current.endsWith(beta)) {
current = current.slice(0, -beta.length);
}
const min = minimum.split('.', 3).map(s => s.padStart(4, '0')).join('.');
const cur = current.split('.', 3).map(s => s.padStart(4, '0')).join('.');
return (canBeEqual ? (min <= cur) : (min < cur));
};
// Checks if element's nodeName matches
const matchesWithNodeName = function(elem, name) {
// Don't allow undefined element or 'name'
@ -164,6 +185,7 @@ const getCurrentTab = async function() {
// Exports for tests
if (typeof module === 'object') {
module.exports = {
compareVersion,
matchesWithNodeName,
siteMatch,
slashNeededForUrl,

View file

@ -150,9 +150,9 @@ const isPasswordGeneratorSupported = async function() {
});
const result = await browser.runtime.sendMessage({
action: 'compare_version',
args: [ '2.7.0', response.current ]
action: 'compare_versions',
args: [ [ '2.7.0' ], response.current ]
});
return result;
return result['2.7.0'] || false;
};

View file

@ -324,48 +324,40 @@ options.showKeePassXCVersions = async function(response) {
$('#tab-about span.kpxcVersion').textContent = response.current;
$('#tab-general-settings button.checkUpdateKeePassXC').disabled = false;
// Hide/disable certain options with older KeePassXC versions than 2.6.0
const version260Result = await browser.runtime.sendMessage({
action: 'compare_version',
args: [ '2.6.0', response.current ]
const versionResults = await browser.runtime.sendMessage({
action: 'compare_versions',
args: [
[
'2.6.0',
'2.7.0',
'2.7.7',
'2.7.10'
],
response.current
],
});
if (version260Result) {
// Hide/disable certain options with older KeePassXC versions than 2.6.0
if (versionResults['2.6.0']) {
$('#tab-general-settings #versionRequiredAlert').hide();
} else {
$('#tab-general-settings #showGroupNameInAutocomplete').disabled = true;
}
// Hide certain options with older KeePassXC versions than 2.7.0
const version270Result = await browser.runtime.sendMessage({
action: 'compare_version',
args: [ '2.7.0', response.current ]
});
if (!version270Result) {
if (!versionResults['2.7.0']) {
$('#tab-general-settings #downloadFaviconAfterSaveFormGroup').hide();
}
// Hide certain options with older KeePassXC versions than 2.7.7
const version277Result = await browser.runtime.sendMessage({
action: 'compare_version',
args: [ '2.7.7', response.current ]
});
if (!version277Result) {
if (!versionResults['2.7.7']) {
$('#tab-general-settings #passkeysOptionsCard').hide();
}
const version2710Result = await browser.runtime.sendMessage({
action: 'compare_version',
args: [ '2.7.10', response.current ]
});
// Hide passkeys default group option with KeePassXC version < 2.7.10
if (!version2710Result) {
if (!versionResults['2.7.10']) {
$('#tab-general-settings #passkeysDefaultGroup').hide();
}
};
options.getPartiallyHiddenKey = function(key) {

View file

@ -1,11 +1,27 @@
import { test, expect } from '@playwright/test';
import {
compareVersion,
matchesWithNodeName,
siteMatch,
slashNeededForUrl,
trimURL
} from '../keepassxc-browser/common/global.js';
test('Test compareVersion()', async ({ page }) => {
// compareVersion(minimum, current)
expect(compareVersion('2.7.0', '2.7.0')).toBe(true);
expect(compareVersion('2.7.1', '2.7.0')).toBe(false);
expect(compareVersion('2.8.0', '2.7.0')).toBe(false);
expect(compareVersion('2.7.9', '2.7.9-snapshot')).toBe(true);
expect(compareVersion('2.7.9', '2.7.9-beta')).toBe(true);
expect(compareVersion('2.7.9-snapshot', '2.7.9')).toBe(false); // Snapshot cannot be the minimum version
expect(compareVersion('2.7.9-beta', '2.7.9')).toBe(false); // Beta cannot be the minimum version
expect(compareVersion('faulty', '2.7.0')).toBe(false);
expect(compareVersion('2.7.0', 'faulty')).toBe(false);
expect(compareVersion('2.7.0.0.0.0.0', '2.7.0.0.0.0.0')).toBe(true);
expect(compareVersion('2.7.0.0', '2.7.0.1')).toBe(true);
});
test('Test matchesWithNodeName()', async ({ page }) => {
const elem1 = { nodeName: 'INPUT' };
const elem2 = { nodeName: 'input' };