mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Redirect allowance
This commit is contained in:
parent
b01ab1e835
commit
5ea08adac8
10 changed files with 139 additions and 69 deletions
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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 (!('autoRetrieveCredentials' in page.settings)) {
|
||||
page.settings.autoRetrieveCredentials = defaultSettings.autoRetrieveCredentials;
|
||||
}
|
||||
if (!('showNotifications' in page.settings)) {
|
||||
page.settings.showNotifications = defaultSettings.showNotifications;
|
||||
}
|
||||
if (!('showLoginNotifications' in page.settings)) {
|
||||
page.settings.showLoginNotifications = defaultSettings.showLoginNotifications;
|
||||
}
|
||||
if (!('showLoginFormIcon' in page.settings)) {
|
||||
page.settings.showLoginFormIcon = defaultSettings.showLoginFormIcon;
|
||||
}
|
||||
if (!('showOTPIcon' in page.settings)) {
|
||||
page.settings.showOTPIcon = defaultSettings.showOTPIcon;
|
||||
}
|
||||
if (!('saveDomainOnly' in page.settings)) {
|
||||
page.settings.saveDomainOnly = defaultSettings.saveDomainOnly;
|
||||
}
|
||||
if (!('saveDomainOnlyNewCreds' in page.settings)) {
|
||||
page.settings.saveDomainOnlyNewCreds = defaultSettings.saveDomainOnlyNewCreds;
|
||||
}
|
||||
|
||||
if (!('autoReconnect' in page.settings)) {
|
||||
page.settings.autoReconnect = defaultSettings.autoReconnect;
|
||||
}
|
||||
|
||||
if (!('autoRetrieveCredentials' in page.settings)) {
|
||||
page.settings.autoRetrieveCredentials = defaultSettings.autoRetrieveCredentials;
|
||||
}
|
||||
|
||||
if (!('autoSubmit' in page.settings)) {
|
||||
page.settings.autoSubmit = defaultSettings.autoSubmit;
|
||||
}
|
||||
|
||||
if (!('checkUpdateKeePassXC' in page.settings)) {
|
||||
page.settings.checkUpdateKeePassXC = defaultSettings.checkUpdateKeePassXC;
|
||||
}
|
||||
|
||||
if (!('colorTheme' in page.settings)) {
|
||||
page.settings.colorTheme = defaultSettings.colorTheme;
|
||||
}
|
||||
|
||||
if (!('defaultGroup' in page.settings)) {
|
||||
page.settings.defaultGroup = defaultSettings.defaultGroup;
|
||||
}
|
||||
|
||||
if (!('defaultGroupAlwaysAsk' in page.settings)) {
|
||||
page.settings.defaultGroupAlwaysAsk = defaultSettings.defaultGroupAlwaysAsk;
|
||||
}
|
||||
if (!('colorTheme' in page.settings)) {
|
||||
page.settings.colorTheme = defaultSettings.colorTheme;
|
||||
|
||||
if (!('saveDomainOnly' in page.settings)) {
|
||||
page.settings.saveDomainOnly = defaultSettings.saveDomainOnly;
|
||||
}
|
||||
|
||||
if (!('showLoginFormIcon' in page.settings)) {
|
||||
page.settings.showLoginFormIcon = defaultSettings.showLoginFormIcon;
|
||||
}
|
||||
|
||||
if (!('showLoginNotifications' in page.settings)) {
|
||||
page.settings.showLoginNotifications = defaultSettings.showLoginNotifications;
|
||||
}
|
||||
|
||||
if (!('showNotifications' in page.settings)) {
|
||||
page.settings.showNotifications = defaultSettings.showNotifications;
|
||||
}
|
||||
|
||||
if (!('showOTPIcon' in page.settings)) {
|
||||
page.settings.showOTPIcon = defaultSettings.showOTPIcon;
|
||||
}
|
||||
|
||||
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 });
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ const initColorTheme = function(elem) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// Enables dragging
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
if (kpxcPasswordDialog.selected === kpxcPasswordDialog.titleBar) {
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@
|
|||
"notifications",
|
||||
"storage",
|
||||
"tabs",
|
||||
"webNavigation",
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"https://*/*",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,14 +149,14 @@
|
|||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoSubmit" value="false" /><span data-i18n="optionsCheckboxAutoSubmit"></span>
|
||||
</label>
|
||||
<span class="help-block" data-i18n="optionsAutoSubmitHelpText"></span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoSubmit" value="false" /><span data-i18n="optionsCheckboxAutoSubmit"></span>
|
||||
</label>
|
||||
<span class="help-block" data-i18n="optionsAutoSubmitHelpText"></span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
|
|
@ -164,6 +164,7 @@
|
|||
</label>
|
||||
<span class="help-block" data-i18n="optionsShowNotificationsHelpText"></span>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="showLoginNotifications" value="true" /><span data-i18n="optionsCheckboxShowLoginNotifications"></span>
|
||||
|
|
@ -175,6 +176,11 @@
|
|||
</label>
|
||||
<span class="help-block" data-i18n="optionsSaveDomainOnlyHelpText"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label id="redirectAllowanceLabel" for="redirectAllowance" data-i18n="optionsRedirectAllowance" i18n-placeholder="1"></label>
|
||||
<input type="range" name="redirectAllowance" min="1" max="11" step="1" value="1" />
|
||||
<span class="help-block" data-i18n="optionsRedirectAllowanceHelpText"></span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue