From 5ea08adac8a93ae3a9f8ddb823984b29cdcbe53e Mon Sep 17 00:00:00 2001 From: varjolintu Date: Thu, 6 Feb 2020 20:42:32 +0200 Subject: Redirect allowance --- keepassxc-browser/_locales/en/messages.json | 8 +++ keepassxc-browser/background/event.js | 5 ++ keepassxc-browser/background/init.js | 16 +++++ keepassxc-browser/background/page.js | 91 +++++++++++++++----------- keepassxc-browser/content/keepassxc-browser.js | 14 +++- keepassxc-browser/content/ui.js | 1 - keepassxc-browser/manifest.json | 1 + keepassxc-browser/options/options.css | 22 +++---- keepassxc-browser/options/options.html | 22 ++++--- keepassxc-browser/options/options.js | 16 +++++ 10 files changed, 133 insertions(+), 63 deletions(-) diff --git a/keepassxc-browser/_locales/en/messages.json b/keepassxc-browser/_locales/en/messages.json index 8b72f7f..1b55928 100644 --- a/keepassxc-browser/_locales/en/messages.json +++ b/keepassxc-browser/_locales/en/messages.json @@ -619,6 +619,14 @@ "message": "Show a banner on the page when new credentials can be saved to the database.", "description": "Show login notifications checkbox text." }, + "optionsRedirectAllowance": { + "message": "Number of allowed redirects: $1", + "description": "Redirect allowance range input text." + }, + "optionsRedirectAllowanceHelpText": { + "message": "How many redirects are allowed until the banner disappears. Default value is 1. Maximum is infinite.", + "description": "Redirect allowance help text." + }, "optionsCheckboxAutoFillAndSend": { "message": "Automatically fill in HTTP Basic Auth dialogs and submit them.", "description": "Auto fill HTTP Basic Auth dialogs and send them checkbox text." diff --git a/keepassxc-browser/background/event.js b/keepassxc-browser/background/event.js index aa7cb83..393aa33 100755 --- a/keepassxc-browser/background/event.js +++ b/keepassxc-browser/background/event.js @@ -241,6 +241,10 @@ kpxcEvent.getColorTheme = async function(tab) { return page.settings.colorTheme; }; +kpxcEvent.pageGetRedirectCount = async function() { + return page.redirectCount; +}; + // All methods named in this object have to be declared BEFORE this! kpxcEvent.messageHandlers = { 'add_credentials': keepass.addCredentials, @@ -266,6 +270,7 @@ kpxcEvent.messageHandlers = { 'page_clear_logins': kpxcEvent.pageClearLogins, 'page_clear_submitted': kpxcEvent.pageClearSubmitted, 'page_get_login_id': kpxcEvent.pageGetLoginId, + 'page_get_redirect_count': kpxcEvent.pageGetRedirectCount, 'page_get_submitted': kpxcEvent.pageGetSubmitted, 'page_set_login_id': kpxcEvent.pageSetLoginId, 'page_set_submitted': kpxcEvent.pageSetSubmitted, diff --git a/keepassxc-browser/background/init.js b/keepassxc-browser/background/init.js index 14202f6..fec0ccb 100644 --- a/keepassxc-browser/background/init.js +++ b/keepassxc-browser/background/init.js @@ -71,6 +71,7 @@ browser.tabs.onActivated.addListener(async function(activeInfo) { * Update browserAction on every update of the page * @param {integer} tabId * @param {object} changeInfo + * @param {object} tab */ browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { // If the tab URL has changed (e.g. logged in) clear credentials @@ -86,6 +87,21 @@ browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { } }); +/** + * Detects page redirects and increases the count. Count is reset after a normal navigation event. + * Form submit is counted as one. + * @param {object} details + */ +browser.webNavigation.onCommitted.addListener((details) => { + if ((details.transitionQualifiers.length > 0 && details.transitionQualifiers[0] === 'client_redirect') || + details.transitionType === 'form_submit') { + page.redirectCount += 1; + return; + } + + page.redirectCount = 0; +}); + browser.runtime.onMessage.addListener(kpxcEvent.onMessage); const contextMenuItems = [ diff --git a/keepassxc-browser/background/page.js b/keepassxc-browser/background/page.js index 6a22327..c87ca68 100755 --- a/keepassxc-browser/background/page.js +++ b/keepassxc-browser/background/page.js @@ -1,23 +1,23 @@ 'use strict'; const defaultSettings = { - checkUpdateKeePassXC: 3, autoCompleteUsernames: true, autoFillAndSend: false, - usePasswordGeneratorIcons: false, autoFillSingleEntry: false, - autoSubmit: false, - autoRetrieveCredentials: true, - showNotifications: true, - showLoginNotifications: true, - showLoginFormIcon: true, - showOTPIcon: true, - saveDomainOnly: true, - saveDomainOnlyNewCreds: false, autoReconnect: false, + autoRetrieveCredentials: true, + autoSubmit: false, + checkUpdateKeePassXC: 3, + colorTheme: 'system', defaultGroup: '', defaultGroupAlwaysAsk: false, - colorTheme: 'system' + redirectAllowance: 1, + saveDomainOnly: true, + showLoginFormIcon: true, + showLoginNotifications: true, + showNotifications: true, + showOTPIcon: true, + usePasswordGeneratorIcons: false }; var page = {}; @@ -25,6 +25,7 @@ page.blockedTabs = []; page.currentTabId = -1; page.loginId = -1; page.passwordFilled = false; +page.redirectCount = 0; page.submitted = false; page.submittedCredentials = {}; page.tabs = []; @@ -35,56 +36,72 @@ page.initSettings = async function() { const item = await browser.storage.local.get({ 'settings': {} }); page.settings = item.settings; - if (!('checkUpdateKeePassXC' in page.settings)) { - page.settings.checkUpdateKeePassXC = defaultSettings.checkUpdateKeePassXC; - } if (!('autoCompleteUsernames' in page.settings)) { page.settings.autoCompleteUsernames = defaultSettings.autoCompleteUsernames; } + if (!('autoFillAndSend' in page.settings)) { page.settings.autoFillAndSend = defaultSettings.autoFillAndSend; } - if (!('usePasswordGeneratorIcons' in page.settings)) { - page.settings.usePasswordGeneratorIcons = defaultSettings.usePasswordGeneratorIcons; - } + if (!('autoFillSingleEntry' in page.settings)) { page.settings.autoFillSingleEntry = defaultSettings.autoFillSingleEntry; } - if (!('autoSubmit' in page.settings)) { - page.settings.autoSubmit = defaultSettings.autoSubmit; + + if (!('autoReconnect' in page.settings)) { + page.settings.autoReconnect = defaultSettings.autoReconnect; } + if (!('autoRetrieveCredentials' in page.settings)) { page.settings.autoRetrieveCredentials = defaultSettings.autoRetrieveCredentials; } - if (!('showNotifications' in page.settings)) { - page.settings.showNotifications = defaultSettings.showNotifications; + + if (!('autoSubmit' in page.settings)) { + page.settings.autoSubmit = defaultSettings.autoSubmit; } - if (!('showLoginNotifications' in page.settings)) { - page.settings.showLoginNotifications = defaultSettings.showLoginNotifications; + + if (!('checkUpdateKeePassXC' in page.settings)) { + page.settings.checkUpdateKeePassXC = defaultSettings.checkUpdateKeePassXC; } - if (!('showLoginFormIcon' in page.settings)) { - page.settings.showLoginFormIcon = defaultSettings.showLoginFormIcon; + + if (!('colorTheme' in page.settings)) { + page.settings.colorTheme = defaultSettings.colorTheme; } - if (!('showOTPIcon' in page.settings)) { - page.settings.showOTPIcon = defaultSettings.showOTPIcon; + + if (!('defaultGroup' in page.settings)) { + page.settings.defaultGroup = defaultSettings.defaultGroup; } + + if (!('defaultGroupAlwaysAsk' in page.settings)) { + page.settings.defaultGroupAlwaysAsk = defaultSettings.defaultGroupAlwaysAsk; + } + if (!('saveDomainOnly' in page.settings)) { page.settings.saveDomainOnly = defaultSettings.saveDomainOnly; } - if (!('saveDomainOnlyNewCreds' in page.settings)) { - page.settings.saveDomainOnlyNewCreds = defaultSettings.saveDomainOnlyNewCreds; + + if (!('showLoginFormIcon' in page.settings)) { + page.settings.showLoginFormIcon = defaultSettings.showLoginFormIcon; } - if (!('autoReconnect' in page.settings)) { - page.settings.autoReconnect = defaultSettings.autoReconnect; + + if (!('showLoginNotifications' in page.settings)) { + page.settings.showLoginNotifications = defaultSettings.showLoginNotifications; } - if (!('defaultGroup' in page.settings)) { - page.settings.defaultGroup = defaultSettings.defaultGroup; + + if (!('showNotifications' in page.settings)) { + page.settings.showNotifications = defaultSettings.showNotifications; } - if (!('defaultGroupAlwaysAsk' in page.settings)) { - page.settings.defaultGroupAlwaysAsk = defaultSettings.defaultGroupAlwaysAsk; + + if (!('showOTPIcon' in page.settings)) { + page.settings.showOTPIcon = defaultSettings.showOTPIcon; } - if (!('colorTheme' in page.settings)) { - page.settings.colorTheme = defaultSettings.colorTheme; + + if (!('usePasswordGeneratorIcons' in page.settings)) { + page.settings.usePasswordGeneratorIcons = defaultSettings.usePasswordGeneratorIcons; + } + + if (!('redirectAllowance' in page.settings)) { + page.settings.redirectAllowance = defaultSettings.redirectAllowance; } await browser.storage.local.set({ 'settings': page.settings }); diff --git a/keepassxc-browser/content/keepassxc-browser.js b/keepassxc-browser/content/keepassxc-browser.js index 89161ff..1ebe201 100755 --- a/keepassxc-browser/content/keepassxc-browser.js +++ b/keepassxc-browser/content/keepassxc-browser.js @@ -303,6 +303,7 @@ kpxcFields.isVisible = function(field) { kpxcFields.getAllFields = function() { const fields = []; const inputs = kpxcObserverHelper.getInputs(document); + for (const i of inputs) { if (kpxcFields.isVisible(i) && !kpxcFields.isSearchField(i)) { kpxcFields.setUniqueId(i); @@ -794,6 +795,7 @@ observer.observe(document, { attributeFilter: [ 'style', 'class' ] }); + const kpxc = {}; kpxc.settings = {}; kpxc.u = null; @@ -816,15 +818,21 @@ const initcb = async function() { action: 'page_get_submitted' }); + const redirectCount = await browser.runtime.sendMessage({ + action: 'page_get_redirect_count' + }); + if (creds && creds.submitted) { // If username field is not set, wait for credentials in kpxc.retrieveCredentialsCallback. if (!creds.username) { return; } - await browser.runtime.sendMessage({ - action: 'page_clear_submitted' - }); + if (redirectCount >= kpxc.settings.redirectAllowance) { + await browser.runtime.sendMessage({ + action: 'page_clear_submitted' + }); + } kpxc.rememberCredentials(creds.username, creds.password, creds.url, creds.oldCredentials); } diff --git a/keepassxc-browser/content/ui.js b/keepassxc-browser/content/ui.js index bbae3d5..29e7235 100644 --- a/keepassxc-browser/content/ui.js +++ b/keepassxc-browser/content/ui.js @@ -165,7 +165,6 @@ const initColorTheme = function(elem) { } }; - // Enables dragging document.addEventListener('mousemove', function(e) { if (kpxcPasswordDialog.selected === kpxcPasswordDialog.titleBar) { diff --git a/keepassxc-browser/manifest.json b/keepassxc-browser/manifest.json index 70c290d..33103ab 100755 --- a/keepassxc-browser/manifest.json +++ b/keepassxc-browser/manifest.json @@ -120,6 +120,7 @@ "notifications", "storage", "tabs", + "webNavigation", "webRequest", "webRequestBlocking", "https://*/*", diff --git a/keepassxc-browser/options/options.css b/keepassxc-browser/options/options.css index ccfab65..79bab72 100644 --- a/keepassxc-browser/options/options.css +++ b/keepassxc-browser/options/options.css @@ -16,12 +16,15 @@ input:invalid { border: 2px solid red; } +input[type=range] { + width: 20%; +} + /* Custom container */ .container { margin: 0 auto; max-width: 1000px; } - .container > hr { margin: 30px 0; } @@ -36,67 +39,54 @@ input:invalid { float: none; width: 100%; } - .navbar-default .navbar-brand { color: #ffffff; } - .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { color: #ffffff; } - .navbar-default .navbar-text { color: #ffffff; } - .navbar-default .navbar-nav > li > a { color: #ffffff; text-align: center; } - .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { color: #ffffff; background-color: #5f9f40; } - .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { color: #ffffff; background-color: #3a8233; } - .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { color: #ffffff; background-color: #3a8233; } - .navbar-default .navbar-toggle { border-color: #3a8233; } - .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { background-color: #3a8233; } - .navbar-default .navbar-toggle .icon-bar { background-color: #ffffff; } - .navbar-default .navbar-collapse, .navbar-default .navbar-form { border-color: #ffffff; } - .navbar-default .navbar-link { color: #ffffff; } - .navbar-default .navbar-link:hover { color: #ffffff; } @@ -147,6 +137,10 @@ h2+hr { width: 50%; } +#redirectAllowanceLabel { + font-weight: normal; +} + tr.clone { display: none; } diff --git a/keepassxc-browser/options/options.html b/keepassxc-browser/options/options.html index 2755e90..2b5e2a4 100644 --- a/keepassxc-browser/options/options.html +++ b/keepassxc-browser/options/options.html @@ -149,14 +149,14 @@


-

- - -
-

-
+
+ + +
+

+

+
+
+ + + +


diff --git a/keepassxc-browser/options/options.js b/keepassxc-browser/options/options.js index 8c6490d..e51a2d1 100644 --- a/keepassxc-browser/options/options.js +++ b/keepassxc-browser/options/options.js @@ -98,6 +98,10 @@ options.initGeneralSettings = function() { } }); + $('#tab-general-settings input[type=range]').val(options.settings['redirectAllowance']); + $('#redirectAllowanceLabel').text(tr('optionsRedirectAllowance', + options.settings['redirectAllowance'] === 11 ? 'Infinite' : String(options.settings['redirectAllowance']))); + $('#tab-general-settings input[type=checkbox]').change(function() { const name = $(this).attr('name'); options.settings[name] = $(this).is(':checked'); @@ -134,6 +138,18 @@ options.initGeneralSettings = function() { options.saveSettings(); }); + // Change label text dynamically with the range input + $('#tab-general-settings input[type=range]').on('propertychange input', function(e) { + const currentValue = e.target.valueAsNumber === 11 ? 'Infinite' : e.target.value; + $('#redirectAllowanceLabel').text(tr('optionsRedirectAllowance', currentValue)); + }); + + // Only save the setting when mouse is released from the range input + $('#tab-general-settings input[type=range').change(function(e) { + options.settings['redirectAllowance'] = e.target.valueAsNumber; + options.saveSettings(); + }); + browser.runtime.sendMessage({ action: 'get_keepassxc_versions' }).then(options.showKeePassXCVersions); -- cgit v1.2.3