Changes 2023-08-15

This commit is contained in:
varjolintu 2023-08-15 16:33:05 +03:00
parent 541aa82c0c
commit daff6a6a95
6 changed files with 85 additions and 39 deletions

View file

@ -137,6 +137,10 @@ kpxcEvent.initLoginPopup = async function(tab, logins) {
browserAction.show(tab, popupData);
};
kpxcEvent.isProtocolV2 = async function(tab) {
return keepass.protocolV2;
};
kpxcEvent.loadKeyRing = async function() {
const item = await browser.storage.local.get({ 'keyRing': {} }).catch((err) => {
logError('kpxcEvent.loadKeyRing error: ' + err);
@ -294,12 +298,15 @@ kpxcEvent.messageHandlers = {
'hide_troubleshooting_guide_alert': kpxcEvent.hideTroubleshootingGuideAlert,
'init_http_auth': kpxcEvent.initHttpAuth,
'is_connected': kpxcEvent.getIsKeePassXCAvailable,
'is_protocol_v2': kpxcEvent.isProtocolV2,
'load_keyring': kpxcEvent.loadKeyRing,
'load_settings': kpxcEvent.loadSettings,
'lock_database': kpxcEvent.lockDatabase,
'page_clear_auto_lock_requested': page.clearAutoLockRequested,
'page_clear_logins': kpxcEvent.pageClearLogins,
'page_clear_submitted': page.clearSubmittedCredentials,
'page_get_autosubmit_performed': page.getAutoSubmitPerformed,
'page_get_auto_lock_requested': page.getAutoLockRequested,
'page_get_login_id': page.getLoginId,
'page_get_manual_fill': page.getManualFill,
'page_get_redirect_count': kpxcEvent.pageGetRedirectCount,

View file

@ -34,6 +34,7 @@ const defaultSettings = {
const AUTO_SUBMIT_TIMEOUT = 5000;
var page = {};
page.autoLockRequested = false;
page.autoSubmitPerformed = false;
page.attributeMenuItemIds = [];
page.blockedTabs = [];
@ -212,6 +213,11 @@ page.retrieveCredentials = async function(tab, args = []) {
// TODO: Make keepass.js to handle protocol/protocolClient and legacyProtocol/legacyProcotolClient
const credentials = await keepass.getCredentials(tab, args);
page.tabs[tab.id].credentials = credentials;
if (credentials.autoLockRequested) {
page.autoLockRequested = true;
}
return credentials;
};
@ -267,6 +273,14 @@ page.setAutoSubmitPerformed = async function(tab) {
}
};
page.clearAutoLockRequested = async function() {
page.autoLockRequested = false;
};
page.getAutoLockRequested = async function() {
return page.autoLockRequested;
};
page.getLoginList = async function(tab) {
return page.tabs[tab.id] ? page.tabs[tab.id].loginList : [];
};

View file

@ -190,7 +190,7 @@ protocol.getCredentials = async function(tab, args = []) {
}
if (httpAuth) {
messageData.httpAuth = 'true';
messageData.httpAuth = true;
}
try {
@ -302,19 +302,21 @@ protocol.getDatabaseStatuses = async function(tab, args = []) {
}
};
// TODO: Finish this
protocol.getTotp = async function(tab, args = []) {
if (!keepass.isConnected) {
return [];
}
const [ uuid, oldTotp ] = args;
/*const [ uuids, oldTotp ] = args;
// KeePassXC 2.6.1 and older does not support retrieving
if (!keepass.compareVersion('2.6.1', keepass.currentKeePassXC, true)) {
return oldTotp;
}
}*/
const messageData = {
action: kpActions.GET_TOTP,
uuid: uuid,
uuids: args,
keys: protocol.getKeys(), // Added
hash: keepass.databaseHash // Added
};
@ -323,7 +325,7 @@ protocol.getTotp = async function(tab, args = []) {
const response = await protocolClient.sendMessage(tab, messageData);
if (response) {
keepass.updateLastUsed(keepass.databaseHash);
return response.totp;
return response.totpList;
}
return;
@ -444,7 +446,7 @@ protocol.updateCredentials = async function(tab, args = []) {
}
const [ entryId, username, password, url, group, groupUuid ] = args;
const [ dbid ] = keepass.getCryptoKey();
//const [ dbid ] = keepass.getCryptoKey();
const messageData = {
action: kpActions.CREATE_CREDENTIALS,

View file

@ -140,24 +140,42 @@ kpxcFill.fillTOTPFromUuid = async function(el, uuid) {
return;
}
let totpFound = false;
if (user.totp?.length > 0) {
// Retrieve a new TOTP value
const totp = await sendMessage('get_totp', [ user.uuid, user.totp ]);
if (!totp) {
kpxcUI.createNotification('warning', tr('credentialsNoTOTPFound'));
return;
}
const protocolV2 = await sendMessage('is_protocol_v2');
if (protocolV2) {
const totpList = await sendMessage('get_totp', [ user.uuid ]);
if (!totpList) {
kpxcUI.createNotification('warning', tr('credentialsNoTOTPFound'));
return;
}
kpxcFill.setTOTPValue(el, totp);
const result = totpList.find(t => t.uuid === uuid);
kpxcFill.setTOTPValue(el, result?.totp);
} else {
const totp = await sendMessage('get_totp', [ user.uuid, user.totp ]);
if (!totp) {
kpxcUI.createNotification('warning', tr('credentialsNoTOTPFound'));
return;
}
kpxcFill.setTOTPValue(el, totp);
}
return;
} else if (user.stringFields?.length > 0) {
const stringFields = user.stringFields;
for (const s of stringFields) {
const val = s['KPH: {TOTP}'];
if (val) {
kpxcFill.setTOTPValue(el, val);
totpFound = true;
}
}
}
if (!totpFound) {
kpxcUI.createNotification('warning', tr('credentialsNoTOTPFound'));
}
};
// Set normal or segmented TOTP value
@ -272,6 +290,12 @@ kpxcFill.fillInCredentials = async function(combination, predefinedUsername, uui
await sendMessage('page_set_manual_fill', ManualFill.NONE);
await kpxcFill.performAutoSubmit(combination, skipAutoSubmit);
// Auto-lock database when requested
if (await sendMessage('page_get_auto_lock_requested')) {
await sendMessage('page_clear_auto_lock_requested');
sendMessage('lock_database');
}
};
// Fills StringFields defined in Custom Fields

View file

@ -748,35 +748,34 @@ kpxc.updateDatabaseState = async function() {
kpxc.databaseState = res.databaseClosed ? DatabaseState.LOCKED : DatabaseState.UNLOCKED;
};
// Updates the TOTP Autocomplete Menu
// Updates the TOTP Autocomplete Menu. All TOTP's will be listed
// TODO: Check that the latest TOTP is actually updated with Protocol V1
kpxc.updateTOTPList = async function() {
let uuid = await sendMessage('page_get_login_id');
if (uuid === undefined || kpxc.credentials.length === 0) {
// Credential haven't been selected
logDebug('Error: No credentials selected for TOTP.');
return;
const hasTotp = function(cred) {
return cred.totp || (cred.stringFields && cred.stringFields.some(s => s['KPH: {TOTP}']));
};
// Filter credentials with TOTP set
const credentialList = kpxc.credentials.filter(c => hasTotp(c));
// Check for duplicate entries (TOTP might be in another database with identical username and title)
const duplicates = credentialList.filter(c =>
kpxc.credentials.some(l => l.login === c.login && l.name === c.name && l.uuid !== c.uuid)
);
// Use the UUID from the duplicate (if it contains the TOTP) for Autocomplete menu instead of the original
for (const e of kpxcUserAutocomplete.elements) {
const duplicate = duplicates.find(d => d.login === e.value);
if (duplicate) {
e.uuid = duplicate.uuid;
}
}
// Use the first credential available if not set
if (uuid === '') {
uuid = kpxc.credentials[0].uuid;
}
// Filter the User Autocomplete menu items to those which contains TOTP
kpxcTOTPAutocomplete.elements = kpxcUserAutocomplete.elements.filter(e => credentialList.find(u => u.uuid === e.uuid));
const credentials = kpxc.credentials.find(c => c.uuid === uuid);
if (credentials) {
const username = credentials.login;
const password = credentials.password;
// If no username is set, compare with a password
const credentialList = kpxc.credentials.filter(c => (c.totp || (c.stringFields && c.stringFields.some(s => s['KPH: {TOTP}'])))
&& (c.login === username || (!username && c.password === password)));
// Filter TOTP Autocomplete Menu with matching 2FA credentials
kpxcTOTPAutocomplete.elements = kpxcUserAutocomplete.elements.filter(e => credentialList.some(u => u.uuid === e.uuid));
return credentialList;
}
return [];
// Return filtered list of kpxc.credentials with TOTP set
return credentialList;
};

View file

@ -38,7 +38,7 @@ function statusResponse(status) {
}
// Only supported with Protocol V2
if (status.databaseAssociationStatuses) {
if (status.databaseAssociationStatuses && Object.keys(status.databaseAssociationStatuses).length > 0) {
// This can be also shown when isAnyAssociated is true?
if (status.databaseAssociationStatuses.associationNeeded) {
$('#not-configured').show();