Add credential sorting

This commit is contained in:
varjolintu 2021-03-24 16:42:12 +02:00
parent 07d59efebc
commit a4355c95c2
8 changed files with 110 additions and 21 deletions

View file

@ -683,6 +683,10 @@
"message": "Color theme",
"description": "Theme selection header text."
},
"optionsCredentialSortSelectionHeader": {
"message": "Sort matching credentials by",
"description": "Credential sort option header text."
},
"optionsThemeSelection": {
"message": "Select color theme",
"description": "Theme selection title text."
@ -903,6 +907,22 @@
"message": "Disable all features",
"description": "Site preferences option selection."
},
"optionsSortByTitle": {
"message": "Title",
"desription": "Sort matching credentials by title option selection."
},
"optionsSortByUsername": {
"message": "Username",
"desription": "Sort matching credentials by username option selection."
},
"optionsSortByGroupAndTitle": {
"message": "Group and title",
"desription": "Sort matching credentials by group and title option selection."
},
"optionsSortByGroupAndUsername": {
"message": "Group and username",
"desription": "Sort matching credentials by group and username option selection."
},
"optionsCustomFieldsNotFound": {
"message": "No saved custom login fields found.",
"description": "Shown when no saved custom credentials are saved."

View file

@ -10,6 +10,7 @@ const defaultSettings = {
autoSubmit: false,
checkUpdateKeePassXC: 3,
colorTheme: 'system',
credentialSorting: SORT_BY_GROUP_AND_TITLE,
defaultGroup: '',
defaultGroupAlwaysAsk: false,
redirectAllowance: 1,
@ -82,6 +83,10 @@ page.initSettings = async function() {
page.settings.colorTheme = defaultSettings.colorTheme;
}
if (!('credentialSorting' in page.settings)) {
page.settings.credentialSorting = defaultSettings.credentialSorting;
}
if (!('defaultGroup' in page.settings)) {
page.settings.defaultGroup = defaultSettings.defaultGroup;
}

View file

@ -1,10 +1,17 @@
'use strict';
// Site Preferences ignore options
const IGNORE_NOTHING = 'ignoreNothing';
const IGNORE_NORMAL = 'ignoreNormal';
const IGNORE_AUTOSUBMIT = 'ignoreAutoSubmit';
const IGNORE_FULL = 'ignoreFull';
// Credential sorting options
const SORT_BY_TITLE = 'sortByTitle';
const SORT_BY_USERNAME = 'sortByUsername';
const SORT_BY_GROUP_AND_TITLE = 'sortByGroupAndTitle';
const SORT_BY_GROUP_AND_USERNAME = 'sortByGroupAndUsername';
const schemeSegment = '(\\*|http|https|ws|wss|file|ftp)';
const hostSegment = '(\\*|(?:\\*\\.)?(?:[^/*]+))?';
const pathSegment = '(.*)';

View file

@ -1329,25 +1329,46 @@ kpxc.initCredentialFields = async function() {
}
};
// Intializes the login popup list for choosing credentials
// Intializes the login lists for popup and Autocomplete Menu
kpxc.initLoginPopup = function() {
if (kpxc.credentials.length === 0) {
return;
}
const getLoginText = function(credential, withGroup) {
const name = credential.name.length < MAX_AUTOCOMPLETE_NAME_LEN
// Returns a login item with additional information for sorting
const getLoginItem = function(credential, withGroup, loginId) {
const title = credential.name.length < MAX_AUTOCOMPLETE_NAME_LEN
? credential.name
: credential.name.substr(0, MAX_AUTOCOMPLETE_NAME_LEN) + '…';
const group = (withGroup && credential.group) ? `[${credential.group}] ` : '';
const visibleLogin = (credential.login.length > 0) ? credential.login : tr('credentialsNoUsername');
const text = `${group}${name} (${visibleLogin})`;
let text = `${group}${title} (${visibleLogin})`;
if (credential.expired && credential.expired === 'true') {
return `${text} [${tr('credentialExpired')}]`;
text = `${text} [${tr('credentialExpired')}]`;
}
return text;
return {
title: title,
group: group,
visibleLogin: visibleLogin,
login: credential.login,
loginId: loginId,
uuid: credential.uuid,
text: text
};
};
// Sorting with or without group name included
const sortLoginItemBy = function(a, b, name, withGroup = false) {
const firstGroup = a.group.toLowerCase();
const secondGroup = b.group.toLowerCase();
const first = a[name].toLowerCase();
const second = b[name].toLowerCase();
return withGroup
? firstGroup.localeCompare(secondGroup) || first.localeCompare(second)
: first.localeCompare(second);
};
const getUniqueGroupCount = function(creds) {
@ -1356,25 +1377,43 @@ kpxc.initLoginPopup = function() {
return uniqueGroups.size;
};
// Add usernames + descriptions to autocomplete-list and popup-list
const usernames = [];
kpxcUserAutocomplete.clear();
const showGroupNameInAutocomplete = kpxc.settings.showGroupNameInAutocomplete && (getUniqueGroupCount(kpxc.credentials) > 1);
// Initialize login items
const loginItems = [];
for (let i = 0; i < kpxc.credentials.length; i++) {
const loginText = getLoginText(kpxc.credentials[i], showGroupNameInAutocomplete);
usernames.push({ text: loginText, uuid: kpxc.credentials[i].uuid });
const loginItem = getLoginItem(kpxc.credentials[i], showGroupNameInAutocomplete, i);
loginItems.push(loginItem);
}
// Sort login items
if (kpxc.settings.credentialSorting === SORT_BY_TITLE) {
loginItems.sort((a, b) => sortLoginItemBy(a, b, 'title'));
} else if (kpxc.settings.credentialSorting === SORT_BY_USERNAME) {
loginItems.sort((a, b) => sortLoginItemBy(a, b, 'visibleLogin'));
} else if (kpxc.settings.credentialSorting === SORT_BY_GROUP_AND_TITLE) {
loginItems.sort((a, b) => sortLoginItemBy(a, b, 'title', true));
} else if (kpxc.settings.credentialSorting === SORT_BY_GROUP_AND_USERNAME) {
loginItems.sort((a, b) => sortLoginItemBy(a, b, 'visibleLogin', true));
}
const popupLoginItems = [];
kpxcUserAutocomplete.clear();
// Initialize Popup Login and Autocomplete Menu items
for (const l of loginItems) {
popupLoginItems.push({ text: l.text, uuid: l.uuid });
kpxcUserAutocomplete.elements.push({
label: loginText,
value: kpxc.credentials[i].login,
uuid: kpxc.credentials[i].uuid,
loginId: i
label: l.text,
value: l.login,
uuid: l.uuid,
loginId: l.loginId
});
}
// Generate popup-list of usernames + descriptions
sendMessage('popup_login', usernames);
// Activate Popup Login list of usernames + descriptions
sendMessage('popup_login', popupLoginItems);
};
kpxc.passwordFilled = async function() {

View file

@ -1,8 +1,8 @@
{
"manifest_version": 2,
"name": "KeePassXC-Browser",
"version": "1.7.6",
"version_name": "1.7.6",
"version": "1.7.7",
"version_name": "1.7.7",
"description": "__MSG_extensionDescription__",
"author": "KeePassXC Team",
"icons": {

View file

@ -140,6 +140,18 @@
</div>
</div>
<div class="form-group">
<div class="form-check">
<label for="credentialSorting" data-i18n="optionsCredentialSortSelectionHeader"></label>
<select class="form-control form-control-sm col-md-2" id="credentialSorting" data-i18n="[title]optionsCredentialSortSelection">
<option value="sortByTitle" data-i18n="optionsSortByTitle"></option>
<option value="sortByUsername" data-i18n="optionsSortByUsername"></option>
<option value="sortByGroupAndTitle" data-i18n="optionsSortByGroupAndTitle"></option>
<option value="sortByGroupAndUsername" data-i18n="optionsSortByGroupAndUsername"></option>
</select>
</div>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="autoSubmit" id="autoSubmit" value="true" />

View file

@ -73,12 +73,17 @@ options.initGeneralSettings = function() {
$('#tab-general-settings select#colorTheme').val(options.settings['colorTheme']);
}
$('#tab-general-settings select:first').change(async function() {
$('#tab-general-settings select#colorTheme').change(async function() {
options.settings['colorTheme'] = $(this).val();
await options.saveSettings();
location.reload();
});
$('#tab-general-settings select#credentialSorting').change(async function() {
options.settings['credentialSorting'] = $(this).val();
await options.saveSettings();
});
$('#tab-general-settings input[type=checkbox]').each(function() {
$(this).attr('checked', options.settings[$(this).attr('name')]);
if ($(this).attr('name') === 'defaultGroupAlwaysAsk' && $(this).attr('checked')) {
@ -115,6 +120,7 @@ options.initGeneralSettings = function() {
}
});
$('#tab-general-settings select#credentialSorting').val(options.settings['credentialSorting']);
$('#tab-general-settings input#defaultGroup').val(options.settings['defaultGroup']);
$('#tab-general-settings input[type=radio]').each(function() {

View file

@ -1,6 +1,6 @@
{
"name": "KeePassXC-Browser",
"version": "1.7.6",
"version": "1.7.7",
"description": "KeePassXC-Browser",
"main": "build.js",
"devDependencies": {