From 08380827c218e3b3dc56ba5ce0ffb33a868712fa Mon Sep 17 00:00:00 2001 From: Bart Nagel Date: Sun, 27 Sep 2020 12:14:08 +0300 Subject: Allow filling KPH attributes from context menu Co-authored-by: varjolintu --- keepassxc-browser/background/event.js | 3 +- keepassxc-browser/background/init.js | 3 ++ keepassxc-browser/background/page.js | 61 ++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) (limited to 'keepassxc-browser/background') diff --git a/keepassxc-browser/background/event.js b/keepassxc-browser/background/event.js index 862f0d3..986935a 100755 --- a/keepassxc-browser/background/event.js +++ b/keepassxc-browser/background/event.js @@ -236,5 +236,6 @@ kpxcEvent.messageHandlers = { 'update_credentials': keepass.updateCredentials, 'username_field_detected': kpxcEvent.onUsernameFieldDetected, 'save_settings': kpxcEvent.onSaveSettings, - 'update_available_keepassxc': kpxcEvent.onUpdateAvailableKeePassXC + 'update_available_keepassxc': kpxcEvent.onUpdateAvailableKeePassXC, + 'update_context_menu': page.updateContextMenu }; diff --git a/keepassxc-browser/background/init.js b/keepassxc-browser/background/init.js index 3cea8ab..0e7840e 100644 --- a/keepassxc-browser/background/init.js +++ b/keepassxc-browser/background/init.js @@ -107,6 +107,7 @@ const contextMenuItems = [ { title: tr('contextMenuFillUsernameAndPassword'), action: 'fill_username_password' }, { title: tr('contextMenuFillPassword'), action: 'fill_password' }, { title: tr('contextMenuFillTOTP'), action: 'fill_totp' }, + { title: tr('contextMenuFillAttribute'), id: 'fill_attribute', visible: false }, { title: tr('contextMenuShowPasswordGenerator'), action: 'show_password_generator' }, { title: tr('contextMenuSaveCredentials'), action: 'remember_credentials' } ]; @@ -122,6 +123,8 @@ for (const item of contextMenuItems) { browser.contextMenus.create({ title: item.title, contexts: menuContexts, + visible: item.visible, + id: item.id, onclick: (info, tab) => { browser.tabs.sendMessage(tab.id, { action: item.action diff --git a/keepassxc-browser/background/page.js b/keepassxc-browser/background/page.js index 0d0df3c..7efac4d 100755 --- a/keepassxc-browser/background/page.js +++ b/keepassxc-browser/background/page.js @@ -24,6 +24,7 @@ const defaultSettings = { }; var page = {}; +page.attributeMenuItemIds = []; page.blockedTabs = []; page.currentRequest = {}; page.currentTabId = -1; @@ -170,7 +171,14 @@ page.initSitePreferences = async function() { await browser.storage.local.set({ 'settings': page.settings }); }; -page.switchTab = function(tab) { +page.switchTab = async function(tab) { + browser.contextMenus.update('fill_attribute', { visible: false }); + if (page.tabs[tab.id] + && page.tabs[tab.id].credentials.length > 0 + && page.tabs[tab.id].credentials.some(e => e.stringFields && e.stringFields.length > 0)) { + await page.updateContextMenu(tab, page.tabs[tab.id].credentials); + } + browserAction.showDefault(tab); browser.tabs.sendMessage(tab.id, { action: 'activated_tab' }).catch((e) => { console.log('Cannot send activated_tab message: ', e); @@ -203,6 +211,8 @@ page.clearLogins = function(tabId) { page.tabs[tabId].loginList = []; page.currentRequest = {}; page.passwordFilled = false; + + browser.contextMenus.update('fill_attribute', { visible: false }); }; // Clear all logins from all pages and update the content scripts @@ -234,6 +244,7 @@ page.createTabEntry = function(tabId) { }; page.clearSubmittedCredentials(); + browser.contextMenus.update('fill_attribute', { visible: false }); }; page.removePageInformationFromNotExistingTabs = async function() { @@ -312,3 +323,51 @@ page.setSubmitted = async function(tab, args = []) { const [ submitted, username, password, url, oldCredentials ] = args; page.setSubmittedCredentials(submitted, username, password, url, oldCredentials, tab.id); }; + +// Update context menu for attribute filling +page.updateContextMenu = async function(tab, credentials) { + // Remove any old attribute items + while (page.attributeMenuItemIds.length) { + browser.contextMenus.remove(page.attributeMenuItemIds.pop()); + } + + // Set parent item visibility + browser.contextMenus.update('fill_attribute', { visible: true }); + + // Add any new attribute items + for (const cred of credentials) { + if (!cred.stringFields) { + continue; + } + + for (const attribute of cred.stringFields) { + // Show username inside [] if there are KPH attributes inside multiple credentials + const attributeName = Object.keys(attribute)[0].slice(5); + const finalName = credentials.length > 1 + ? `[${cred.login}] ${attributeName}` + : attributeName; + + page.attributeMenuItemIds.push(createContextMenuItem({ + action: 'fill_attribute', + args: attribute, + parentId: 'fill_attribute', + title: finalName + })); + } + } +}; + +const createContextMenuItem = function({action, args, ...options}) { + return browser.contextMenus.create({ + contexts: menuContexts, + onclick: (info, tab) => { + browser.tabs.sendMessage(tab.id, { + action: action, + args: args + }).catch((err) => { + console.log(err); + }); + }, + ...options + }); +}; -- cgit v1.2.3