mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Merge branch 'develop'
This commit is contained in:
commit
f74e42f9c3
29 changed files with 4076 additions and 3923 deletions
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
.idea
|
||||
|
||||
*.swp
|
||||
*~
|
||||
*.tmp
|
||||
|
||||
*.zip
|
||||
*.crx
|
||||
.bz
|
||||
.bz2
|
||||
.xz
|
||||
39
CHANGELOG
Normal file → Executable file
39
CHANGELOG
Normal file → Executable file
|
|
@ -1,3 +1,42 @@
|
|||
1.0.0 (27-02-2018)
|
||||
=========================
|
||||
- First stable release
|
||||
|
||||
0.5.2 (02-02-2018)
|
||||
=========================
|
||||
- Choose own credential fields saves the full URL instead of host
|
||||
- HTTP Auth no longer gets stuck when there are no credentials available
|
||||
- Added option to show notifications (enabled by default)
|
||||
- Added notifications for HTTP Auth and saving new credentialsList (new permission needed)
|
||||
|
||||
0.5.1 (23-01-2018)
|
||||
=========================
|
||||
- Fixed unnecessary credential retrieving when input fields are not available
|
||||
|
||||
0.5.0 (22-01-2018)
|
||||
=========================
|
||||
- Fixed an error when filling only a password
|
||||
- Credential retrieval is allowed when only one input field is visible (TOTP)
|
||||
- Asynchronous receiveCredentialsIfNecessary()
|
||||
- Send triggerUnlock with request that need to popup KeePassXC to front
|
||||
- Added verifyDatabaseResponse to get_databasehash
|
||||
- Renamed keepassxc-browser to KeePassXC-Browser
|
||||
- Removed duplicate retrieve_credentials requests
|
||||
- Fixed identation
|
||||
- Added support for credential filling through user interaction when database is closed
|
||||
|
||||
0.4.8 (06-01-2018)
|
||||
=========================
|
||||
- Changed native messaging host name to org.keepassxc.keepassxc_browser
|
||||
- Exclude XSD files from content scripts
|
||||
- Switched default keyboard shortcuts to Alt+Shift+U and Alt+Shift+P
|
||||
|
||||
0.4.5 (28-12-2017)
|
||||
=========================
|
||||
- Added support for aria-hidden attribute when checking input field visibility
|
||||
- Fixed a bug in redetecting credentials
|
||||
- Small CSS fixes
|
||||
|
||||
0.4.4 (17-12-2017)
|
||||
=========================
|
||||
- Added support for OTP codes via context menu
|
||||
|
|
|
|||
74
README.md
74
README.md
|
|
@ -1,81 +1,25 @@
|
|||
# keepassxc-browser
|
||||
# KeePassXC-Browser
|
||||
Browser extension for [KeePassXC](https://keepassxc.org/) with Native Messaging.
|
||||
|
||||
This is a heavily forked version of [pfn](https://github.com/pfn)'s [chromeIPass](https://github.com/pfn/passifox).
|
||||
Some changes merged also from [smorks'](https://github.com/smorks/keepasshttp-connector) KeePassHttp-Connector fork.
|
||||
For testing purposes, please use only the following unofficial KeePassXC [release's](https://github.com/varjolintu/keepassxc/releases).
|
||||
Based on [pfn](https://github.com/pfn)'s [chromeIPass](https://github.com/pfn/passifox).
|
||||
Some changes merged also from [smorks'](https://github.com/smorks/keepasshttp-connector) KeePassHttp-Connector.
|
||||
|
||||
Get the extension for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) or [Chrome/Chromium](https://chrome.google.com/webstore/detail/keepassxc-browser/iopaggbpplllidnfmcghoonnokmjoicf).
|
||||
Get the extension for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) or [Chrome/Chromium](https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk).
|
||||
|
||||
Please see this [wiki page](https://github.com/varjolintu/keepassxc-browser/wiki/Connecting-the-database-with-keepassxc-browser) for instructions how to configure this KeePassXC fork in order to connect the database correctly.
|
||||
Please see this [document](https://keepassxc.org/docs/keepassxc-browser-migration/) for instructions how to configure KeePassXC in order to connect the database correctly.
|
||||
|
||||
## How it works
|
||||
There are two methods which you can use keepassxc-browser to connect to KeePassXC:
|
||||
There are two methods which you can use KeePassXC-Browser to connect to KeePassXC:
|
||||
|
||||
1. keepassxc-browser communicated with KeePassXC through keepassxc-proxy. The proxy handles listening stdin/stdout
|
||||
1. KeePassXC-Browser communicates with KeePassXC through keepassxc-proxy. The proxy handles listening to STDIN/STDOUT
|
||||
and transfers these messages through Unix domain sockets / named pipes to KeePassXC. This means KeePassXC can be used and started normally without inteference from
|
||||
Native Messaging API. keepassxc-browser starts only the proxy application and there's no risk of shutting down KeePassXC or losing any unsaved changes. You don't need to install keepassxc-proxy separately. It is included in the latest KeePassXC fork. Alternatively you can use
|
||||
Native Messaging API. KeePassXC-Browser starts only the proxy application and there's no risk of shutting down KeePassXC or losing any unsaved changes. You don't need to install keepassxc-proxy separately. It is included in the latest KeePassXC fork. Alternatively you can use
|
||||
[keepassxc-proxy-rust](https://github.com/varjolintu/keepassxc-proxy-rust) as a proxy if you prefer a non-Qt solution. There's also Python and C++ versions available at
|
||||
[keepassxc-proxy](https://github.com/varjolintu/keepassxc-proxy).
|
||||
|
||||
2. keepassxc-browser communicates directly with KeePassXC via stdin/stdout. Using native messaging directly is a more secure as it ensures the traffic between KeePassXC and keepassxc-browser is direct. This method launches KeePassXC every time you start the browser and closes when you exit.
|
||||
2. KeePassXC-Browser communicates directly with KeePassXC via stdin/stdout. Using native messaging directly is a more secure as it ensures the traffic between KeePassXC and KeePassXC-Browser is direct. This method launches KeePassXC every time you start the browser and closes when you exit.
|
||||
This can cause unsaved changes not to be saved. If you use this method it's important to enable `Automatically save after every change` from KeePassXC's preferences. Because this option is not preferred as default it's good to test this feature with your OS and ensure KeePassXC asks to confirm any unsaved changes before exit.
|
||||
|
||||
## Improvements
|
||||
The following improvements and features have been made after the fork. At this point some features are only available with the KeePassXC fork:
|
||||
- Real-time detection of database status (locked/unlocked)
|
||||
- Credentials on a page are cleared or received automatically again if database is locked or changed to another
|
||||
- It is possible to lock the active database from the popup (using the red lock icon)
|
||||
- Input forms are detected even if the login div has been hidden or is created after the page was loaded
|
||||
- It is possible to use the active database from multiple browsers at the same time with keepassxc-proxy option
|
||||
- Deprecated JavaScript functions are removed and everything is asynchronous
|
||||
- Updated Bootstrap to version 3.3.7 and jQuery to version 3.2.1
|
||||
- New buttons, icons and settings page graphics
|
||||
- Redesigned password generator dialog
|
||||
- Password generator supports diceware passphrases and extended ASCII characters
|
||||
- Autocomplete works also when only password fields are visible
|
||||
- Supports TOTP with custom KHP placeholders (`KPH: {TOPT}`)
|
||||
|
||||
## Protocol
|
||||
|
||||
The details about the messaging protocol used with the browser extension and KeePassXC can be found [here](keepassxc-protocol.md).
|
||||
|
||||
## Licenses
|
||||
|
||||
```
|
||||
keepassxc-browser Copyright (C) 2017 Sami Vänttinen
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
```
|
||||
|
||||
```
|
||||
PassIFox & ChromeIPass Copyright © 2010-2017 Perry Nguyen
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
```
|
||||
|
||||
## Donations
|
||||
|
||||
Feel free to support this project:
|
||||
- Donate via [PayPal](https://paypal.me/varjolintu)
|
||||
- Donate via Bitcoin: 1LHbD69CcmpLW5hjUXs2MGJhw3GxwqLdw3
|
||||
|
||||
Also consider donating to [KeePassXC](https://flattr.com/submit/auto?fid=x7yqz0&url=https%3A%2F%2Fkeepassxc.org) and [KeePassHttp-Connector](https://github.com/smorks/keepasshttp-connector) teams. They are doing great job.
|
||||
|
|
|
|||
378
keepassxc-browser/background/browserAction.js
Normal file → Executable file
378
keepassxc-browser/background/browserAction.js
Normal file → Executable file
|
|
@ -5,261 +5,267 @@ const BLINK_TIMEOUT_REDIRECT_THRESHOLD_TIME_DEFAULT = -1;
|
|||
const BLINK_TIMEOUT_REDIRECT_COUNT_DEFAULT = 1;
|
||||
|
||||
browserAction.show = function(callback, tab) {
|
||||
let data = {};
|
||||
if (!page.tabs[tab.id] || page.tabs[tab.id].stack.length == 0) {
|
||||
browserAction.showDefault(callback, tab);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
data = page.tabs[tab.id].stack[page.tabs[tab.id].stack.length - 1];
|
||||
}
|
||||
let data = {};
|
||||
if (!page.tabs[tab.id] || page.tabs[tab.id].stack.length == 0) {
|
||||
browserAction.showDefault(callback, tab);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
data = page.tabs[tab.id].stack[page.tabs[tab.id].stack.length - 1];
|
||||
}
|
||||
|
||||
browser.browserAction.setIcon({
|
||||
tabId: tab.id,
|
||||
path: '/icons/19x19/' + browserAction.generateIconName(data.iconType, data.icon)
|
||||
});
|
||||
browser.browserAction.setIcon({
|
||||
tabId: tab.id,
|
||||
path: '/icons/19x19/' + browserAction.generateIconName(data.iconType, data.icon)
|
||||
});
|
||||
|
||||
if (data.popup) {
|
||||
browser.browserAction.setPopup({
|
||||
tabId: tab.id,
|
||||
popup: 'popups/' + data.popup
|
||||
});
|
||||
}
|
||||
if (data.popup) {
|
||||
browser.browserAction.setPopup({
|
||||
tabId: tab.id,
|
||||
popup: 'popups/' + data.popup
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
browserAction.update = function(interval) {
|
||||
if (!page.tabs[page.currentTabId] || page.tabs[page.currentTabId].stack.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (!page.tabs[page.currentTabId] || page.tabs[page.currentTabId].stack.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = page.tabs[page.currentTabId].stack[page.tabs[page.currentTabId].stack.length - 1];
|
||||
let data = page.tabs[page.currentTabId].stack[page.tabs[page.currentTabId].stack.length - 1];
|
||||
|
||||
if (typeof data.visibleForMilliSeconds !== 'undefined') {
|
||||
if (data.visibleForMilliSeconds <= 0) {
|
||||
browserAction.stackPop(page.currentTabId);
|
||||
browserAction.show(null, {'id': page.currentTabId});
|
||||
page.clearCredentials(page.currentTabId);
|
||||
if (data.visibleForMilliSeconds <= 0) {
|
||||
browserAction.stackPop(page.currentTabId);
|
||||
browserAction.show(null, {'id': page.currentTabId});
|
||||
page.clearCredentials(page.currentTabId);
|
||||
return;
|
||||
}
|
||||
data.visibleForMilliSeconds -= interval;
|
||||
}
|
||||
}
|
||||
data.visibleForMilliSeconds -= interval;
|
||||
}
|
||||
|
||||
if (data.intervalIcon) {
|
||||
data.intervalIcon.counter += 1;
|
||||
if (data.intervalIcon.counter < data.intervalIcon.max) {
|
||||
return;
|
||||
}
|
||||
if (data.intervalIcon) {
|
||||
data.intervalIcon.counter += 1;
|
||||
if (data.intervalIcon.counter < data.intervalIcon.max) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.intervalIcon.counter = 0;
|
||||
data.intervalIcon.index += 1;
|
||||
data.intervalIcon.counter = 0;
|
||||
data.intervalIcon.index += 1;
|
||||
|
||||
if (data.intervalIcon.index > data.intervalIcon.icons.length - 1) {
|
||||
data.intervalIcon.index = 0;
|
||||
}
|
||||
if (data.intervalIcon.index > data.intervalIcon.icons.length - 1) {
|
||||
data.intervalIcon.index = 0;
|
||||
}
|
||||
|
||||
browser.browserAction.setIcon({
|
||||
tabId: page.currentTabId,
|
||||
path: '/icons/19x19/' + browserAction.generateIconName(null, data.intervalIcon.icons[data.intervalIcon.index])
|
||||
});
|
||||
}
|
||||
browser.browserAction.setIcon({
|
||||
tabId: page.currentTabId,
|
||||
path: '/icons/19x19/' + browserAction.generateIconName(null, data.intervalIcon.icons[data.intervalIcon.index])
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
browserAction.showDefault = function(callback, tab) {
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'normal',
|
||||
popup: 'popup.html'
|
||||
};
|
||||
keepass.isConfigured().then((response) => {
|
||||
if (!response || keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable || page.tabs[tab.id].errorMessage) {
|
||||
stackData.iconType = 'cross';
|
||||
}
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'normal',
|
||||
popup: 'popup.html'
|
||||
};
|
||||
keepass.isConfigured().then((response) => {
|
||||
if (!response || keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable || page.tabs[tab.id].errorMessage) {
|
||||
stackData.iconType = 'cross';
|
||||
}
|
||||
|
||||
if (page.tabs[tab.id].loginList.length > 0) {
|
||||
stackData.iconType = 'questionmark';
|
||||
stackData.popup = 'popup_login.html';
|
||||
}
|
||||
if (page.tabs[tab.id].loginList.length > 0) {
|
||||
stackData.iconType = 'questionmark';
|
||||
stackData.popup = 'popup_login.html';
|
||||
}
|
||||
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
browserAction.show(null, tab);
|
||||
});
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
browserAction.show(null, tab);
|
||||
});
|
||||
};
|
||||
|
||||
browserAction.stackAdd = function(callback, tab, icon, popup, level, push, visibleForMilliSeconds, visibleForPageUpdates, redirectOffset, dontShow) {
|
||||
const id = tab.id || page.currentTabId;
|
||||
const id = tab.id || page.currentTabId;
|
||||
|
||||
if (!level) {
|
||||
level = 1;
|
||||
}
|
||||
if (!level) {
|
||||
level = 1;
|
||||
}
|
||||
|
||||
let stackData = {
|
||||
level: level,
|
||||
icon: icon
|
||||
};
|
||||
let stackData = {
|
||||
level: level,
|
||||
icon: icon
|
||||
};
|
||||
|
||||
if (popup) {
|
||||
stackData.popup = popup;
|
||||
}
|
||||
if (popup) {
|
||||
stackData.popup = popup;
|
||||
}
|
||||
|
||||
if (visibleForMilliSeconds) {
|
||||
stackData.visibleForMilliSeconds = visibleForMilliSeconds;
|
||||
}
|
||||
if (visibleForMilliSeconds) {
|
||||
stackData.visibleForMilliSeconds = visibleForMilliSeconds;
|
||||
}
|
||||
|
||||
if (visibleForPageUpdates) {
|
||||
stackData.visibleForPageUpdates = visibleForPageUpdates;
|
||||
}
|
||||
if (visibleForPageUpdates) {
|
||||
stackData.visibleForPageUpdates = visibleForPageUpdates;
|
||||
}
|
||||
|
||||
if (redirectOffset) {
|
||||
stackData.redirectOffset = redirectOffset;
|
||||
}
|
||||
if (redirectOffset) {
|
||||
stackData.redirectOffset = redirectOffset;
|
||||
}
|
||||
|
||||
if (push) {
|
||||
browserAction.stackPush(stackData, id);
|
||||
}
|
||||
else {
|
||||
browserAction.stackUnshift(stackData, id);
|
||||
}
|
||||
if (push) {
|
||||
browserAction.stackPush(stackData, id);
|
||||
}
|
||||
else {
|
||||
browserAction.stackUnshift(stackData, id);
|
||||
}
|
||||
|
||||
if (!dontShow) {
|
||||
browserAction.show(null, {'id': id});
|
||||
}
|
||||
if (!dontShow) {
|
||||
browserAction.show(null, {'id': id});
|
||||
}
|
||||
};
|
||||
|
||||
browserAction.removeLevelFromStack = function(callback, tab, level, type, dontShow) {
|
||||
if (!page.tabs[tab.id]) {
|
||||
return;
|
||||
}
|
||||
if (!page.tabs[tab.id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
type = '<=';
|
||||
}
|
||||
if (!type) {
|
||||
type = '<=';
|
||||
}
|
||||
|
||||
let newStack = [];
|
||||
for (const i of page.tabs[tab.id].stack) {
|
||||
if (
|
||||
(type == '<' && i.level >= level) ||
|
||||
(type == '<=' && i.level > level) ||
|
||||
(type == '=' && i.level != level) ||
|
||||
(type == '==' && i.level != level) ||
|
||||
(type == '!=' && i.level == level) ||
|
||||
(type == '>' && i.level <= level) ||
|
||||
(type == '>=' && i.level < level)
|
||||
) {
|
||||
newStack.push(i);
|
||||
}
|
||||
}
|
||||
let newStack = [];
|
||||
for (const i of page.tabs[tab.id].stack) {
|
||||
if (
|
||||
(type == '<' && i.level >= level) ||
|
||||
(type == '<=' && i.level > level) ||
|
||||
(type == '=' && i.level != level) ||
|
||||
(type == '==' && i.level != level) ||
|
||||
(type == '!=' && i.level == level) ||
|
||||
(type == '>' && i.level <= level) ||
|
||||
(type == '>=' && i.level < level)
|
||||
) {
|
||||
newStack.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
page.tabs[tab.id].stack = newStack;
|
||||
page.tabs[tab.id].stack = newStack;
|
||||
|
||||
if (!dontShow) {
|
||||
browserAction.show(callback, tab);
|
||||
}
|
||||
if (!dontShow) {
|
||||
browserAction.show(callback, tab);
|
||||
}
|
||||
};
|
||||
|
||||
browserAction.stackPop = function(tabId) {
|
||||
const id = tabId || page.currentTabId;
|
||||
page.tabs[id].stack.pop();
|
||||
const id = tabId || page.currentTabId;
|
||||
page.tabs[id].stack.pop();
|
||||
};
|
||||
|
||||
browserAction.stackPush = function(data, tabId) {
|
||||
const id = tabId || page.currentTabId;
|
||||
browserAction.removeLevelFromStack(null, {'id': id}, data.level, '<=', true);
|
||||
page.tabs[id].stack.push(data);
|
||||
const id = tabId || page.currentTabId;
|
||||
browserAction.removeLevelFromStack(null, {'id': id}, data.level, '<=', true);
|
||||
page.tabs[id].stack.push(data);
|
||||
};
|
||||
|
||||
browserAction.stackUnshift = function(data, tabId) {
|
||||
const id = tabId || page.currentTabId;
|
||||
browserAction.removeLevelFromStack(null, {'id': id}, data.level, '<=', true);
|
||||
page.tabs[id].stack.unshift(data);
|
||||
const id = tabId || page.currentTabId;
|
||||
browserAction.removeLevelFromStack(null, {'id': id}, data.level, '<=', true);
|
||||
page.tabs[id].stack.unshift(data);
|
||||
};
|
||||
|
||||
|
||||
browserAction.removeRememberPopup = function(callback, tab, removeImmediately) {
|
||||
if (!page.tabs[tab.id]) {
|
||||
return;
|
||||
}
|
||||
if (!page.tabs[tab.id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( page.tabs[tab.id].stack.length == 0) {
|
||||
if( page.tabs[tab.id].stack.length == 0) {
|
||||
page.clearCredentials(tab.id);
|
||||
return;
|
||||
}
|
||||
const data = page.tabs[tab.id].stack[page.tabs[tab.id].stack.length - 1];
|
||||
return;
|
||||
}
|
||||
const data = page.tabs[tab.id].stack[page.tabs[tab.id].stack.length - 1];
|
||||
|
||||
if (removeImmediately || !isNaN(data.visibleForPageUpdates)) {
|
||||
const currentMS = Date.now();
|
||||
if (removeImmediately || (data.visibleForPageUpdates <= 0 && data.redirectOffset > 0)) {
|
||||
browserAction.stackPop(tab.id);
|
||||
browserAction.show(null, {"id": tab.id});
|
||||
page.clearCredentials(tab.id);
|
||||
return;
|
||||
}
|
||||
else if (!isNaN(data.visibleForPageUpdates) && data.redirectOffset > 0 && currentMS >= data.redirectOffset) {
|
||||
data.visibleForPageUpdates = data.visibleForPageUpdates - 1;
|
||||
}
|
||||
const currentMS = Date.now();
|
||||
if (removeImmediately || (data.visibleForPageUpdates <= 0 && data.redirectOffset > 0)) {
|
||||
browserAction.stackPop(tab.id);
|
||||
browserAction.show(null, {"id": tab.id});
|
||||
page.clearCredentials(tab.id);
|
||||
return;
|
||||
}
|
||||
else if (!isNaN(data.visibleForPageUpdates) && data.redirectOffset > 0 && currentMS >= data.redirectOffset) {
|
||||
data.visibleForPageUpdates = data.visibleForPageUpdates - 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
browserAction.setRememberPopup = function(tabId, username, password, url, usernameExists, credentialsList) {
|
||||
const settings = typeof(localStorage.settings) === 'undefined' ? {} : JSON.parse(localStorage.settings);
|
||||
const id = tabId || page.currentTabId;
|
||||
let timeoutMinMillis = Number(getValueOrDefault(settings, 'blinkMinTimeout', BLINK_TIMEOUT_REDIRECT_THRESHOLD_TIME_DEFAULT, 0));
|
||||
browser.storage.local.get({'settings': {}}).then(function(item) {
|
||||
const settings = item.settings;
|
||||
const id = tabId || page.currentTabId;
|
||||
let timeoutMinMillis = Number(getValueOrDefault(settings, 'blinkMinTimeout', BLINK_TIMEOUT_REDIRECT_THRESHOLD_TIME_DEFAULT, 0));
|
||||
|
||||
if (timeoutMinMillis > 0) {
|
||||
timeoutMinMillis += Date.now();
|
||||
}
|
||||
if (timeoutMinMillis > 0) {
|
||||
timeoutMinMillis += Date.now();
|
||||
}
|
||||
|
||||
const blinkTimeout = getValueOrDefault(settings, 'blinkTimeout', BLINK_TIMEOUT_DEFAULT, 0);
|
||||
const pageUpdateAllowance = getValueOrDefault(settings, 'allowedRedirect', BLINK_TIMEOUT_REDIRECT_COUNT_DEFAULT, 0);
|
||||
const blinkTimeout = getValueOrDefault(settings, 'blinkTimeout', BLINK_TIMEOUT_DEFAULT, 0);
|
||||
const pageUpdateAllowance = getValueOrDefault(settings, 'allowedRedirect', BLINK_TIMEOUT_REDIRECT_COUNT_DEFAULT, 0);
|
||||
|
||||
const stackData = {
|
||||
visibleForMilliSeconds: blinkTimeout,
|
||||
visibleForPageUpdates: pageUpdateAllowance,
|
||||
redirectOffset: timeoutMinMillis,
|
||||
level: 10,
|
||||
intervalIcon: {
|
||||
index: 0,
|
||||
counter: 0,
|
||||
max: 2,
|
||||
icons: ['icon_remember_red_background_19x19.png', 'icon_remember_red_lock_19x19.png']
|
||||
},
|
||||
icon: 'icon_remember_red_background_19x19.png',
|
||||
popup: 'popup_remember.html'
|
||||
};
|
||||
const stackData = {
|
||||
visibleForMilliSeconds: blinkTimeout,
|
||||
visibleForPageUpdates: pageUpdateAllowance,
|
||||
redirectOffset: timeoutMinMillis,
|
||||
level: 10,
|
||||
intervalIcon: {
|
||||
index: 0,
|
||||
counter: 0,
|
||||
max: 2,
|
||||
icons: ['icon_remember_red_background_19x19.png', 'icon_remember_red_lock_19x19.png']
|
||||
},
|
||||
icon: 'icon_remember_red_background_19x19.png',
|
||||
popup: 'popup_remember.html'
|
||||
};
|
||||
|
||||
browserAction.stackPush(stackData, id);
|
||||
browserAction.stackPush(stackData, id);
|
||||
|
||||
page.tabs[id].credentials = {
|
||||
username: username,
|
||||
password: password,
|
||||
url: url,
|
||||
usernameExists: usernameExists,
|
||||
list: credentialsList
|
||||
};
|
||||
page.tabs[id].credentials = {
|
||||
username: username,
|
||||
password: password,
|
||||
url: url,
|
||||
usernameExists: usernameExists,
|
||||
list: credentialsList
|
||||
};
|
||||
|
||||
browserAction.show(null, {'id': id});
|
||||
browserAction.show(null, {'id': id});
|
||||
|
||||
if (page.settings.showNotifications) {
|
||||
showNotification('Create or modify the credentials by clicking on the extension icon.');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function getValueOrDefault(settings, key, defaultVal, min) {
|
||||
try {
|
||||
let val = settings[key];
|
||||
if (isNaN(val) || val < min) {
|
||||
val = defaultVal;
|
||||
}
|
||||
return val;
|
||||
} catch(e) {
|
||||
return defaultVal;
|
||||
}
|
||||
try {
|
||||
let val = settings[key];
|
||||
if (isNaN(val) || val < min) {
|
||||
val = defaultVal;
|
||||
}
|
||||
return val;
|
||||
} catch(e) {
|
||||
return defaultVal;
|
||||
}
|
||||
}
|
||||
|
||||
browserAction.generateIconName = function(iconType, icon) {
|
||||
if (icon) {
|
||||
return icon;
|
||||
}
|
||||
if (icon) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
let name = 'icon_';
|
||||
name += (keepass.keePassXCUpdateAvailable()) ? 'new_' : '';
|
||||
name += (!iconType || iconType === 'normal') ? 'normal' : iconType;
|
||||
name += '_19x19.png';
|
||||
let name = 'icon_';
|
||||
name += (keepass.keePassXCUpdateAvailable()) ? 'new_' : '';
|
||||
name += (!iconType || iconType === 'normal') ? 'normal' : iconType;
|
||||
name += '_19x19.png';
|
||||
|
||||
return name;
|
||||
return name;
|
||||
};
|
||||
|
|
|
|||
404
keepassxc-browser/background/event.js
Normal file → Executable file
404
keepassxc-browser/background/event.js
Normal file → Executable file
|
|
@ -1,21 +1,21 @@
|
|||
const kpxcEvent = {};
|
||||
|
||||
kpxcEvent.onMessage = function(request, sender, callback) {
|
||||
if (request.action in kpxcEvent.messageHandlers) {
|
||||
//console.log('onMessage(' + request.action + ') for #' + sender.tab.id);
|
||||
if (!sender.hasOwnProperty('tab') || sender.tab.id < 1) {
|
||||
sender.tab = {};
|
||||
sender.tab.id = page.currentTabId;
|
||||
}
|
||||
if (request.action in kpxcEvent.messageHandlers) {
|
||||
//console.log('onMessage(' + request.action + ') for #' + sender.tab.id);
|
||||
if (!sender.hasOwnProperty('tab') || sender.tab.id < 1) {
|
||||
sender.tab = {};
|
||||
sender.tab.id = page.currentTabId;
|
||||
}
|
||||
|
||||
kpxcEvent.invoke(kpxcEvent.messageHandlers[request.action], callback, sender.tab.id, request.args);
|
||||
kpxcEvent.invoke(kpxcEvent.messageHandlers[request.action], callback, sender.tab.id, request.args);
|
||||
|
||||
// onMessage closes channel for callback automatically
|
||||
// if this method does not return true
|
||||
if (callback) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// onMessage closes channel for callback automatically
|
||||
// if this method does not return true
|
||||
if (callback !== undefined) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -30,272 +30,274 @@ kpxcEvent.onMessage = function(request, sender, callback) {
|
|||
* @returns null (asynchronous)
|
||||
*/
|
||||
kpxcEvent.invoke = function(handler, callback, senderTabId, args, secondTime) {
|
||||
if (senderTabId < 1) {
|
||||
return;
|
||||
}
|
||||
if (senderTabId < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!page.tabs[senderTabId]) {
|
||||
page.createTabEntry(senderTabId);
|
||||
}
|
||||
if (!page.tabs[senderTabId]) {
|
||||
page.createTabEntry(senderTabId);
|
||||
}
|
||||
|
||||
// remove information from no longer existing tabs
|
||||
page.removePageInformationFromNotExistingTabs();
|
||||
// remove information from no longer existing tabs
|
||||
page.removePageInformationFromNotExistingTabs();
|
||||
|
||||
browser.tabs.get(senderTabId).then((tab) => {
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
browser.tabs.get(senderTabId).then((tab) => {
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tab.url) {
|
||||
// Issue 6877: tab URL is not set directly after you opened a window
|
||||
// using window.open()
|
||||
if (!secondTime) {
|
||||
window.setTimeout(function() {
|
||||
kpxcEvent.invoke(handler, callback, senderTabId, args, true);
|
||||
}, 250);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!tab.url) {
|
||||
// Issue 6877: tab URL is not set directly after you opened a window
|
||||
// using window.open()
|
||||
if (!secondTime) {
|
||||
window.setTimeout(function() {
|
||||
kpxcEvent.invoke(handler, callback, senderTabId, args, true);
|
||||
}, 250);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!page.tabs[tab.id]) {
|
||||
page.createTabEntry(tab.id);
|
||||
}
|
||||
if (!page.tabs[tab.id]) {
|
||||
page.createTabEntry(tab.id);
|
||||
}
|
||||
|
||||
args = args || [];
|
||||
args = args || [];
|
||||
|
||||
args.unshift(tab);
|
||||
args.unshift(callback);
|
||||
args.unshift(tab);
|
||||
args.unshift(callback);
|
||||
|
||||
if (handler) {
|
||||
handler.apply(this, args);
|
||||
}
|
||||
else {
|
||||
console.log('undefined handler for tab ' + tab.id);
|
||||
}
|
||||
}).catch((e) => {console.log(e);});
|
||||
if (handler) {
|
||||
handler.apply(this, args);
|
||||
}
|
||||
else {
|
||||
console.log('undefined handler for tab ' + tab.id);
|
||||
}
|
||||
}).catch((e) => {console.log(e);});
|
||||
};
|
||||
|
||||
kpxcEvent.onShowAlert = function(callback, tab, message) {
|
||||
if (page.settings.supressAlerts) { console.log(message); }
|
||||
else { alert(message); }
|
||||
if (page.settings.supressAlerts) { console.log(message); }
|
||||
else { alert(message); }
|
||||
};
|
||||
|
||||
kpxcEvent.showStatus = function(configured, tab, callback) {
|
||||
let keyId = null;
|
||||
if (configured) {
|
||||
keyId = keepass.keyRing[keepass.databaseHash].id;
|
||||
}
|
||||
let keyId = null;
|
||||
if (configured) {
|
||||
keyId = keepass.keyRing[keepass.databaseHash].id;
|
||||
}
|
||||
|
||||
browserAction.showDefault(null, tab);
|
||||
const errorMessage = page.tabs[tab.id].errorMessage;
|
||||
callback({
|
||||
identifier: keyId,
|
||||
configured: configured,
|
||||
databaseClosed: keepass.isDatabaseClosed,
|
||||
keePassXCAvailable: keepass.isKeePassXCAvailable,
|
||||
encryptionKeyUnrecognized: keepass.isEncryptionKeyUnrecognized,
|
||||
associated: keepass.isAssociated(),
|
||||
error: errorMessage ? errorMessage : null
|
||||
});
|
||||
browserAction.showDefault(null, tab);
|
||||
const errorMessage = page.tabs[tab.id].errorMessage;
|
||||
callback({
|
||||
identifier: keyId,
|
||||
configured: configured,
|
||||
databaseClosed: keepass.isDatabaseClosed,
|
||||
keePassXCAvailable: keepass.isKeePassXCAvailable,
|
||||
encryptionKeyUnrecognized: keepass.isEncryptionKeyUnrecognized,
|
||||
associated: keepass.isAssociated(),
|
||||
error: errorMessage ? errorMessage : null
|
||||
});
|
||||
};
|
||||
|
||||
kpxcEvent.onLoadSettings = function(callback, tab) {
|
||||
page.initSettings().then((settings) => {
|
||||
callback(settings);
|
||||
}, (err) => {
|
||||
console.log('error loading settings: ' + err);
|
||||
});
|
||||
page.initSettings().then((settings) => {
|
||||
callback(settings);
|
||||
}, (err) => {
|
||||
console.log('error loading settings: ' + err);
|
||||
});
|
||||
};
|
||||
|
||||
kpxcEvent.onLoadKeyRing = function(callback, tab) {
|
||||
browser.storage.local.get({'keyRing': {}}).then(function(item) {
|
||||
keepass.keyRing = item.keyRing;
|
||||
if (keepass.isAssociated() && !keepass.keyRing[keepass.associated.hash]) {
|
||||
keepass.associated = {
|
||||
"value": false,
|
||||
"hash": null
|
||||
};
|
||||
}
|
||||
callback(item.keyRing);
|
||||
}, (err) => {
|
||||
console.log('error loading keyRing: ' + err);
|
||||
});
|
||||
browser.storage.local.get({'keyRing': {}}).then(function(item) {
|
||||
keepass.keyRing = item.keyRing;
|
||||
if (keepass.isAssociated() && !keepass.keyRing[keepass.associated.hash]) {
|
||||
keepass.associated = {
|
||||
"value": false,
|
||||
"hash": null
|
||||
};
|
||||
}
|
||||
callback(item.keyRing);
|
||||
}, (err) => {
|
||||
console.log('error loading keyRing: ' + err);
|
||||
});
|
||||
};
|
||||
|
||||
kpxcEvent.onSaveSettings = function(callback, tab, settings) {
|
||||
browser.storage.local.set({'settings': settings}).then(function() {
|
||||
kpxcEvent.onLoadSettings(callback, tab);
|
||||
});
|
||||
browser.storage.local.set({'settings': settings}).then(function() {
|
||||
kpxcEvent.onLoadSettings(callback, tab);
|
||||
});
|
||||
};
|
||||
|
||||
kpxcEvent.onGetStatus = function(callback, tab, internalPoll = false) {
|
||||
// When internalPoll is true the event is triggered from content script in intervals -> don't poll KeePassXC
|
||||
if (!internalPoll) {
|
||||
keepass.testAssociation((response) => {
|
||||
if (!response) {
|
||||
kpxcEvent.showStatus(false, tab, callback);
|
||||
return;
|
||||
}
|
||||
kpxcEvent.onGetStatus = function(callback, tab, internalPoll = false, triggerUnlock = false) {
|
||||
// When internalPoll is true the event is triggered from content script in intervals -> don't poll KeePassXC
|
||||
if (!internalPoll) {
|
||||
keepass.testAssociation((response) => {
|
||||
if (!response) {
|
||||
kpxcEvent.showStatus(false, tab, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
keepass.isConfigured().then((configured) => {
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
});
|
||||
}, tab, true);
|
||||
} else {
|
||||
keepass.isConfigured().then((configured) => {
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
});
|
||||
}
|
||||
keepass.isConfigured().then((configured) => {
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
});
|
||||
}, tab, true, triggerUnlock);
|
||||
} else {
|
||||
keepass.isConfigured().then((configured) => {
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
kpxcEvent.onReconnect = function(callback, tab) {
|
||||
keepass.connectToNative();
|
||||
keepass.connectToNative();
|
||||
|
||||
// Add a small timeout after reconnecting. Just to make sure. It's not pretty, I know :(
|
||||
setTimeout(() => {
|
||||
keepass.generateNewKeyPair();
|
||||
keepass.changePublicKeys(tab).then((pkRes) => {
|
||||
keepass.getDatabaseHash((gdRes) => {
|
||||
if (gdRes) {
|
||||
keepass.testAssociation((response) => {
|
||||
keepass.isConfigured().then((configured) => {
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
}).catch((e) => {console.log(e);});
|
||||
}, tab);
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
}, 2000);
|
||||
// Add a small timeout after reconnecting. Just to make sure. It's not pretty, I know :(
|
||||
setTimeout(() => {
|
||||
keepass.generateNewKeyPair();
|
||||
keepass.changePublicKeys(tab).then((pkRes) => {
|
||||
keepass.getDatabaseHash((gdRes) => {
|
||||
if (gdRes) {
|
||||
keepass.testAssociation((response) => {
|
||||
keepass.isConfigured().then((configured) => {
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
}).catch((e) => {console.log(e);});
|
||||
}, tab);
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
kpxcEvent.lockDatabase = function(callback, tab) {
|
||||
keepass.lockDatabase(tab).then((response => {
|
||||
kpxcEvent.showStatus(true, tab, callback);
|
||||
}));
|
||||
keepass.lockDatabase(tab).then((response => {
|
||||
kpxcEvent.showStatus(true, tab, callback);
|
||||
}));
|
||||
};
|
||||
|
||||
kpxcEvent.onPopStack = function(callback, tab) {
|
||||
browserAction.stackPop(tab.id);
|
||||
browserAction.show(null, tab);
|
||||
browserAction.stackPop(tab.id);
|
||||
browserAction.show(null, tab);
|
||||
};
|
||||
|
||||
kpxcEvent.onGetTabInformation = function(callback, tab) {
|
||||
const id = tab.id || page.currentTabId;
|
||||
callback(page.tabs[id]);
|
||||
const id = tab.id || page.currentTabId;
|
||||
callback(page.tabs[id]);
|
||||
};
|
||||
|
||||
kpxcEvent.onGetConnectedDatabase = function(callback, tab) {
|
||||
callback({
|
||||
count: Object.keys(keepass.keyRing).length,
|
||||
identifier: (keepass.keyRing[keepass.associated.hash]) ? keepass.keyRing[keepass.associated.hash].id : null
|
||||
});
|
||||
callback({
|
||||
count: Object.keys(keepass.keyRing).length,
|
||||
identifier: (keepass.keyRing[keepass.associated.hash]) ? keepass.keyRing[keepass.associated.hash].id : null
|
||||
});
|
||||
};
|
||||
|
||||
kpxcEvent.onGetKeePassXCVersions = function(callback, tab) {
|
||||
if(keepass.currentKeePassXC.version == 0) {
|
||||
keepass.getDatabaseHash((res) => {
|
||||
callback({"current": keepass.currentKeePassXC.version, "latest": keepass.currentKeePassXC.version});
|
||||
}, tab);
|
||||
} else {
|
||||
callback({"current": keepass.currentKeePassXC.version, "latest": keepass.currentKeePassXC.version});
|
||||
}
|
||||
if(keepass.currentKeePassXC.version == 0) {
|
||||
keepass.getDatabaseHash((res) => {
|
||||
callback({"current": keepass.currentKeePassXC.version, "latest": keepass.currentKeePassXC.version});
|
||||
}, tab);
|
||||
} else {
|
||||
callback({"current": keepass.currentKeePassXC.version, "latest": keepass.currentKeePassXC.version});
|
||||
}
|
||||
};
|
||||
|
||||
kpxcEvent.onCheckUpdateKeePassXC = function(callback, tab) {
|
||||
keepass.checkForNewKeePassXCVersion();
|
||||
callback({current: keepass.currentKeePassXC.version, latest: keepass.latestKeePassXC.version});
|
||||
keepass.checkForNewKeePassXCVersion();
|
||||
callback({current: keepass.currentKeePassXC.version, latest: keepass.latestKeePassXC.version});
|
||||
};
|
||||
|
||||
kpxcEvent.onUpdateAvailableKeePassXC = function(callback, tab) {
|
||||
callback(keepass.keePassXCUpdateAvailable());
|
||||
callback(keepass.keePassXCUpdateAvailable());
|
||||
};
|
||||
|
||||
kpxcEvent.onRemoveCredentialsFromTabInformation = function(callback, tab) {
|
||||
const id = tab.id || page.currentTabId;
|
||||
page.clearCredentials(id);
|
||||
const id = tab.id || page.currentTabId;
|
||||
page.clearCredentials(id);
|
||||
};
|
||||
|
||||
kpxcEvent.onSetRememberPopup = function(callback, tab, username, password, url, usernameExists, credentialsList) {
|
||||
browserAction.setRememberPopup(tab.id, username, password, url, usernameExists, credentialsList);
|
||||
browserAction.setRememberPopup(tab.id, username, password, url, usernameExists, credentialsList);
|
||||
};
|
||||
|
||||
kpxcEvent.onLoginPopup = function(callback, tab, logins) {
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'questionmark',
|
||||
popup: 'popup_login.html'
|
||||
};
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
page.tabs[tab.id].loginList = logins;
|
||||
browserAction.show(null, tab);
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'questionmark',
|
||||
popup: 'popup_login.html'
|
||||
};
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
page.tabs[tab.id].loginList = logins;
|
||||
browserAction.show(null, tab);
|
||||
};
|
||||
|
||||
kpxcEvent.initHttpAuth = function(callback) {
|
||||
httpAuth.init();
|
||||
callback();
|
||||
httpAuth.init();
|
||||
callback();
|
||||
}
|
||||
|
||||
kpxcEvent.onHTTPAuthPopup = function(callback, tab, data) {
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'questionmark',
|
||||
popup: 'popup_httpauth.html'
|
||||
};
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
page.tabs[tab.id].loginList = data;
|
||||
browserAction.show(null, tab);
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'questionmark',
|
||||
popup: 'popup_httpauth.html'
|
||||
};
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
page.tabs[tab.id].loginList = data;
|
||||
browserAction.show(null, tab);
|
||||
};
|
||||
|
||||
kpxcEvent.onMultipleFieldsPopup = function(callback, tab) {
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'normal',
|
||||
popup: 'popup_multiple-fields.html'
|
||||
};
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
browserAction.show(null, tab);
|
||||
let stackData = {
|
||||
level: 1,
|
||||
iconType: 'normal',
|
||||
popup: 'popup_multiple-fields.html'
|
||||
};
|
||||
browserAction.stackUnshift(stackData, tab.id);
|
||||
browserAction.show(null, tab);
|
||||
};
|
||||
|
||||
kpxcEvent.pageClearLogins = function(callback, tab) {
|
||||
page.clearLogins(tab.id);
|
||||
callback();
|
||||
kpxcEvent.pageClearLogins = function(callback, tab, alreadyCalled) {
|
||||
if (!alreadyCalled) {
|
||||
page.clearLogins(tab.id);
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
kpxcEvent.oldDatabaseHash = 'no-hash';
|
||||
kpxcEvent.checkDatabaseHash = function(callback, tab) {
|
||||
keepass.checkDatabaseHash((response) => {
|
||||
callback({old: kpxcEvent.oldDatabaseHash, new: response});
|
||||
kpxcEvent.oldDatabaseHash = response;
|
||||
});
|
||||
keepass.checkDatabaseHash((response) => {
|
||||
callback({old: kpxcEvent.oldDatabaseHash, new: response});
|
||||
kpxcEvent.oldDatabaseHash = response;
|
||||
});
|
||||
};
|
||||
|
||||
// all methods named in this object have to be declared BEFORE this!
|
||||
kpxcEvent.messageHandlers = {
|
||||
'add_credentials': keepass.addCredentials,
|
||||
'alert': kpxcEvent.onShowAlert,
|
||||
'associate': keepass.associate,
|
||||
'check_update_keepassxc': kpxcEvent.onCheckUpdateKeePassXC,
|
||||
'get_connected_database': kpxcEvent.onGetConnectedDatabase,
|
||||
'get_keepassxc_versions': kpxcEvent.onGetKeePassXCVersions,
|
||||
'get_status': kpxcEvent.onGetStatus,
|
||||
'get_tab_information': kpxcEvent.onGetTabInformation,
|
||||
'init_http_auth': kpxcEvent.initHttpAuth,
|
||||
'load_keyring': kpxcEvent.onLoadKeyRing,
|
||||
'load_settings': kpxcEvent.onLoadSettings,
|
||||
'page_clear_logins': kpxcEvent.pageClearLogins,
|
||||
'pop_stack': kpxcEvent.onPopStack,
|
||||
'popup_login': kpxcEvent.onLoginPopup,
|
||||
'popup_multiple-fields': kpxcEvent.onMultipleFieldsPopup,
|
||||
'remove_credentials_from_tab_information': kpxcEvent.onRemoveCredentialsFromTabInformation,
|
||||
'retrieve_credentials': keepass.retrieveCredentials,
|
||||
'show_default_browseraction': browserAction.showDefault,
|
||||
'update_credentials': keepass.updateCredentials,
|
||||
'save_settings': kpxcEvent.onSaveSettings,
|
||||
'set_remember_credentials': kpxcEvent.onSetRememberPopup,
|
||||
'stack_add': browserAction.stackAdd,
|
||||
'update_available_keepassxc': kpxcEvent.onUpdateAvailableKeePassXC,
|
||||
'generate_password': keepass.generatePassword,
|
||||
'reconnect': kpxcEvent.onReconnect,
|
||||
'lock-database': kpxcEvent.lockDatabase,
|
||||
'check_databasehash': kpxcEvent.checkDatabaseHash
|
||||
'add_credentials': keepass.addCredentials,
|
||||
'alert': kpxcEvent.onShowAlert,
|
||||
'associate': keepass.associate,
|
||||
'check_databasehash': kpxcEvent.checkDatabaseHash,
|
||||
'check_update_keepassxc': kpxcEvent.onCheckUpdateKeePassXC,
|
||||
'generate_password': keepass.generatePassword,
|
||||
'get_connected_database': kpxcEvent.onGetConnectedDatabase,
|
||||
'get_keepassxc_versions': kpxcEvent.onGetKeePassXCVersions,
|
||||
'get_status': kpxcEvent.onGetStatus,
|
||||
'get_tab_information': kpxcEvent.onGetTabInformation,
|
||||
'init_http_auth': kpxcEvent.initHttpAuth,
|
||||
'load_keyring': kpxcEvent.onLoadKeyRing,
|
||||
'load_settings': kpxcEvent.onLoadSettings,
|
||||
'lock-database': kpxcEvent.lockDatabase,
|
||||
'page_clear_logins': kpxcEvent.pageClearLogins,
|
||||
'pop_stack': kpxcEvent.onPopStack,
|
||||
'popup_login': kpxcEvent.onLoginPopup,
|
||||
'popup_multiple-fields': kpxcEvent.onMultipleFieldsPopup,
|
||||
'reconnect': kpxcEvent.onReconnect,
|
||||
'remove_credentials_from_tab_information': kpxcEvent.onRemoveCredentialsFromTabInformation,
|
||||
'retrieve_credentials': keepass.retrieveCredentials,
|
||||
'show_default_browseraction': browserAction.showDefault,
|
||||
'update_credentials': keepass.updateCredentials,
|
||||
'save_settings': kpxcEvent.onSaveSettings,
|
||||
'set_remember_credentials': kpxcEvent.onSetRememberPopup,
|
||||
'stack_add': browserAction.stackAdd,
|
||||
'update_available_keepassxc': kpxcEvent.onUpdateAvailableKeePassXC
|
||||
};
|
||||
|
|
|
|||
122
keepassxc-browser/background/httpauth.js
Normal file → Executable file
122
keepassxc-browser/background/httpauth.js
Normal file → Executable file
|
|
@ -4,82 +4,92 @@ httpAuth.requests = [];
|
|||
httpAuth.pendingCallbacks = [];
|
||||
|
||||
httpAuth.init = function() {
|
||||
let handleReq = httpAuth.handleRequestPromise;
|
||||
let reqType = 'blocking';
|
||||
let handleReq = httpAuth.handleRequestPromise;
|
||||
let reqType = 'blocking';
|
||||
|
||||
if (!isFirefox()) {
|
||||
handleReq = httpAuth.handleRequestCallback;
|
||||
reqType = 'asyncBlocking';
|
||||
}
|
||||
if (!isFirefox()) {
|
||||
handleReq = httpAuth.handleRequestCallback;
|
||||
reqType = 'asyncBlocking';
|
||||
}
|
||||
|
||||
if (browser.webRequest.onAuthRequired.hasListener(handleReq)) {
|
||||
browser.webRequest.onAuthRequired.removeListener(handleReq);
|
||||
browser.webRequest.onCompleted.removeListener(httpAuth.requestCompleted);
|
||||
browser.webRequest.onErrorOccurred.removeListener(httpAuth.requestCompleted);
|
||||
}
|
||||
if (browser.webRequest.onAuthRequired.hasListener(handleReq)) {
|
||||
browser.webRequest.onAuthRequired.removeListener(handleReq);
|
||||
browser.webRequest.onCompleted.removeListener(httpAuth.requestCompleted);
|
||||
browser.webRequest.onErrorOccurred.removeListener(httpAuth.requestCompleted);
|
||||
}
|
||||
|
||||
// only intercept http auth requests if the option is turned on.
|
||||
if (page.settings.autoFillAndSend) {
|
||||
const opts = { urls: ['<all_urls>'] };
|
||||
// only intercept http auth requests if the option is turned on.
|
||||
if (page.settings.autoFillAndSend) {
|
||||
const opts = { urls: ['<all_urls>'] };
|
||||
|
||||
browser.webRequest.onAuthRequired.addListener(handleReq, opts, [reqType]);
|
||||
browser.webRequest.onCompleted.addListener(httpAuth.requestCompleted, opts);
|
||||
browser.webRequest.onErrorOccurred.addListener(httpAuth.requestCompleted, opts);
|
||||
}
|
||||
browser.webRequest.onAuthRequired.addListener(handleReq, opts, [reqType]);
|
||||
browser.webRequest.onCompleted.addListener(httpAuth.requestCompleted, opts);
|
||||
browser.webRequest.onErrorOccurred.addListener(httpAuth.requestCompleted, opts);
|
||||
}
|
||||
};
|
||||
|
||||
httpAuth.requestCompleted = function(details) {
|
||||
let index = httpAuth.requests.indexOf(details.requestId);
|
||||
if (index >= 0) {
|
||||
httpAuth.requests.splice(index, 1);
|
||||
}
|
||||
let index = httpAuth.requests.indexOf(details.requestId);
|
||||
if (index >= 0) {
|
||||
httpAuth.requests.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
httpAuth.handleRequestPromise = function(details) {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpAuth.processPendingCallbacks(details, resolve, reject);
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
httpAuth.processPendingCallbacks(details, resolve, reject);
|
||||
});
|
||||
};
|
||||
|
||||
httpAuth.handleRequestCallback = function(details, callback) {
|
||||
httpAuth.processPendingCallbacks(details, callback, callback);
|
||||
httpAuth.processPendingCallbacks(details, callback, callback);
|
||||
};
|
||||
|
||||
httpAuth.processPendingCallbacks = function(details, resolve, reject) {
|
||||
if (httpAuth.requests.indexOf(details.requestId) >= 0 || !page.tabs[details.tabId]) {
|
||||
reject({});
|
||||
return;
|
||||
}
|
||||
httpAuth.retrieveCredentials = function(tabId, url, submitUrl, forceCallback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
keepass.retrieveCredentials((logins) => {
|
||||
resolve(logins);
|
||||
}, tabId, url, submitUrl, forceCallback);
|
||||
});
|
||||
};
|
||||
|
||||
httpAuth.requests.push(details.requestId);
|
||||
httpAuth.processPendingCallbacks = async function(details, resolve, reject) {
|
||||
if (httpAuth.requests.indexOf(details.requestId) >= 0 || !page.tabs[details.tabId]) {
|
||||
reject({cancel: false});
|
||||
return;
|
||||
}
|
||||
|
||||
if (details.challenger) {
|
||||
details.proxyUrl = details.challenger.host;
|
||||
}
|
||||
httpAuth.requests.push(details.requestId);
|
||||
|
||||
details.searchUrl = (details.isProxy && details.proxyUrl) ? details.proxyUrl : details.url;
|
||||
if (details.challenger) {
|
||||
details.proxyUrl = details.challenger.host;
|
||||
}
|
||||
|
||||
keepass.retrieveCredentials((logins) => {
|
||||
httpAuth.loginOrShowCredentials(logins, details, resolve, reject);
|
||||
}, { "id": details.tabId }, details.searchUrl, details.searchUrl, true);
|
||||
details.searchUrl = (details.isProxy && details.proxyUrl) ? details.proxyUrl : details.url;
|
||||
|
||||
const logins = await httpAuth.retrieveCredentials({ 'id': details.tabId }, details.searchUrl, details.searchUrl, true);
|
||||
httpAuth.loginOrShowCredentials(logins, details, resolve, reject);
|
||||
};
|
||||
|
||||
httpAuth.loginOrShowCredentials = function(logins, details, resolve, reject) {
|
||||
// at least one login found --> use first to login
|
||||
if (logins.length > 0 && page.settings.autoFillAndSend) {
|
||||
if (logins.length === 1) {
|
||||
resolve({
|
||||
authCredentials: {
|
||||
username: logins[0].login,
|
||||
password: logins[0].password
|
||||
}
|
||||
});
|
||||
} else {
|
||||
kpxcEvent.onHTTPAuthPopup(null, { 'id': details.tabId }, { 'logins': logins, 'url': details.searchUrl, 'resolve': resolve });
|
||||
}
|
||||
}
|
||||
// no logins found
|
||||
else {
|
||||
reject({});
|
||||
}
|
||||
// at least one login found --> use first to login
|
||||
if (logins.length > 0 && page.settings.autoFillAndSend) {
|
||||
if (logins.length === 1) {
|
||||
resolve({
|
||||
authCredentials: {
|
||||
username: logins[0].login,
|
||||
password: logins[0].password
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (page.settings.showNotifications) {
|
||||
showNotification('Multiple credentials detected. Click on the extension icon to choose the correct one.');
|
||||
}
|
||||
kpxcEvent.onHTTPAuthPopup(null, { 'id': details.tabId }, { 'logins': logins, 'url': details.searchUrl, 'resolve': resolve });
|
||||
}
|
||||
}
|
||||
// no logins found
|
||||
else {
|
||||
reject({cancel: false});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
keepass.migrateKeyRing().then(() => {
|
||||
page.initSettings().then(() => {
|
||||
page.initOpenedTabs().then(() => {
|
||||
httpAuth.init();
|
||||
keepass.connectToNative();
|
||||
keepass.generateNewKeyPair();
|
||||
keepass.changePublicKeys(null).then((pkRes) => {
|
||||
keepass.getDatabaseHash((gdRes) => {}, null);
|
||||
});
|
||||
});
|
||||
});
|
||||
page.initSettings().then(() => {
|
||||
page.initOpenedTabs().then(() => {
|
||||
httpAuth.init();
|
||||
keepass.connectToNative();
|
||||
keepass.generateNewKeyPair();
|
||||
keepass.changePublicKeys(null).then((pkRes) => {
|
||||
keepass.getDatabaseHash((gdRes) => {}, null);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Milliseconds for intervall (e.g. to update browserAction)
|
||||
|
|
@ -21,13 +21,13 @@ const _interval = 250;
|
|||
* @param {object} tab
|
||||
*/
|
||||
browser.tabs.onCreated.addListener((tab) => {
|
||||
if (tab.id > 0) {
|
||||
//console.log('browser.tabs.onCreated(' + tab.id+ ')');
|
||||
if (tab.selected) {
|
||||
page.currentTabId = tab.id;
|
||||
kpxcEvent.invoke(page.switchTab, null, tab.id, []);
|
||||
}
|
||||
}
|
||||
if (tab.id > 0) {
|
||||
//console.log('browser.tabs.onCreated(' + tab.id+ ')');
|
||||
if (tab.selected) {
|
||||
page.currentTabId = tab.id;
|
||||
kpxcEvent.invoke(page.switchTab, null, tab.id, []);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -36,10 +36,10 @@ browser.tabs.onCreated.addListener((tab) => {
|
|||
* @param {object} removeInfo
|
||||
*/
|
||||
browser.tabs.onRemoved.addListener((tabId, removeInfo) => {
|
||||
delete page.tabs[tabId];
|
||||
if (page.currentTabId === tabId) {
|
||||
page.currentTabId = -1;
|
||||
}
|
||||
delete page.tabs[tabId];
|
||||
if (page.currentTabId === tabId) {
|
||||
page.currentTabId = -1;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -48,19 +48,19 @@ browser.tabs.onRemoved.addListener((tabId, removeInfo) => {
|
|||
* @param {object} activeInfo
|
||||
*/
|
||||
browser.tabs.onActivated.addListener((activeInfo) => {
|
||||
// remove possible credentials from old tab information
|
||||
// remove possible credentials from old tab information
|
||||
page.clearCredentials(page.currentTabId, true);
|
||||
browserAction.removeRememberPopup(null, {'id': page.currentTabId}, true);
|
||||
browserAction.removeRememberPopup(null, {'id': page.currentTabId}, true);
|
||||
|
||||
browser.tabs.get(activeInfo.tabId).then((info) => {
|
||||
if (info && info.id) {
|
||||
page.currentTabId = info.id;
|
||||
if (info.status === 'complete') {
|
||||
//console.log('kpxcEvent.invoke(page.switchTab, null, '+info.id + ', []);');
|
||||
kpxcEvent.invoke(page.switchTab, null, info.id, []);
|
||||
}
|
||||
}
|
||||
});
|
||||
browser.tabs.get(activeInfo.tabId).then((info) => {
|
||||
if (info && info.id) {
|
||||
page.currentTabId = info.id;
|
||||
if (info.status === 'complete') {
|
||||
//console.log('kpxcEvent.invoke(page.switchTab, null, '+info.id + ', []);');
|
||||
kpxcEvent.invoke(page.switchTab, null, info.id, []);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -69,60 +69,68 @@ browser.tabs.onActivated.addListener((activeInfo) => {
|
|||
* @param {object} changeInfo
|
||||
*/
|
||||
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
if (changeInfo.status === 'complete') {
|
||||
kpxcEvent.invoke(browserAction.removeRememberPopup, null, tabId, []);
|
||||
}
|
||||
if (changeInfo.status === 'complete') {
|
||||
kpxcEvent.invoke(browserAction.removeRememberPopup, null, tabId, []);
|
||||
}
|
||||
});
|
||||
|
||||
browser.runtime.onMessage.addListener(kpxcEvent.onMessage);
|
||||
|
||||
const contextMenuItems = [
|
||||
{title: 'Fill User + Pass', action: 'fill_user_pass'},
|
||||
{title: 'Fill Pass Only', action: 'fill_pass_only'},
|
||||
{title: 'Fill TOTP', action: 'fill_totp'},
|
||||
{title: 'Show Password Generator Icons', action: 'activate_password_generator'},
|
||||
{title: 'Save credentials', action: 'remember_credentials'}
|
||||
{title: 'Fill User + Pass', action: 'fill_user_pass'},
|
||||
{title: 'Fill Pass Only', action: 'fill_pass_only'},
|
||||
{title: 'Fill TOTP', action: 'fill_totp'},
|
||||
{title: 'Show Password Generator Icons', action: 'activate_password_generator'},
|
||||
{title: 'Save credentials', action: 'remember_credentials'}
|
||||
];
|
||||
|
||||
let menuContexts = ['editable'];
|
||||
|
||||
if (isFirefox()) {
|
||||
menuContexts.push('password');
|
||||
menuContexts.push('password');
|
||||
}
|
||||
|
||||
// Create context menu items
|
||||
for (const item of contextMenuItems) {
|
||||
browser.contextMenus.create({
|
||||
title: item.title,
|
||||
contexts: menuContexts,
|
||||
onclick: (info, tab) => {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: item.action
|
||||
}).catch((e) => {console.log(e);});
|
||||
}
|
||||
});
|
||||
browser.contextMenus.create({
|
||||
title: item.title,
|
||||
contexts: menuContexts,
|
||||
onclick: (info, tab) => {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: item.action
|
||||
}).catch((e) => {console.log(e);});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Listen for keyboard shortcuts specified by user
|
||||
browser.commands.onCommand.addListener((command) => {
|
||||
if (command === 'fill-username-password') {
|
||||
browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length) {
|
||||
browser.tabs.sendMessage(tabs[0].id, { action: 'fill_user_pass' });
|
||||
}
|
||||
});
|
||||
}
|
||||
if (command === 'fill-username-password') {
|
||||
browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length) {
|
||||
browser.tabs.sendMessage(tabs[0].id, { action: 'fill_user_pass' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (command === 'fill-password') {
|
||||
browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length) {
|
||||
browser.tabs.sendMessage(tabs[0].id, { action: 'fill_pass_only' });
|
||||
}
|
||||
});
|
||||
}
|
||||
if (command === 'fill-password') {
|
||||
browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length) {
|
||||
browser.tabs.sendMessage(tabs[0].id, { action: 'fill_pass_only' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (command === 'fill-totp') {
|
||||
browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length) {
|
||||
browser.tabs.sendMessage(tabs[0].id, { action: 'fill_totp' });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Interval which updates the browserAction (e.g. blinking icon)
|
||||
window.setInterval(function() {
|
||||
browserAction.update(_interval);
|
||||
browserAction.update(_interval);
|
||||
}, _interval);
|
||||
|
|
|
|||
1514
keepassxc-browser/background/keepass.js
Normal file → Executable file
1514
keepassxc-browser/background/keepass.js
Normal file → Executable file
File diff suppressed because it is too large
Load diff
192
keepassxc-browser/background/page.js
Normal file → Executable file
192
keepassxc-browser/background/page.js
Normal file → Executable file
|
|
@ -1,10 +1,11 @@
|
|||
const defaultSettings = {
|
||||
checkUpdateKeePassXC: 3,
|
||||
autoCompleteUsernames: true,
|
||||
autoFillAndSend: true,
|
||||
usePasswordGenerator: true,
|
||||
autoFillSingleEntry: false,
|
||||
autoRetrieveCredentials: true
|
||||
checkUpdateKeePassXC: 3,
|
||||
autoCompleteUsernames: true,
|
||||
autoFillAndSend: true,
|
||||
usePasswordGenerator: true,
|
||||
autoFillSingleEntry: false,
|
||||
autoRetrieveCredentials: true,
|
||||
showNotifications: true
|
||||
};
|
||||
|
||||
var page = {};
|
||||
|
|
@ -13,72 +14,75 @@ page.currentTabId = -1;
|
|||
page.blockedTabs = {};
|
||||
|
||||
page.initSettings = function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.storage.local.get({'settings': {}}).then((item) => {
|
||||
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 (!('usePasswordGenerator' in page.settings)) {
|
||||
page.settings.usePasswordGenerator = defaultSettings.usePasswordGenerator;
|
||||
}
|
||||
if (!('autoFillSingleEntry' in page.settings)) {
|
||||
page.settings.autoFillSingleEntry = defaultSettings.autoFillSingleEntry;
|
||||
}
|
||||
if (!('autoRetrieveCredentials' in page.settings)) {
|
||||
page.settings.autoRetrieveCredentials = defaultSettings.autoRetrieveCredentials;
|
||||
}
|
||||
browser.storage.local.set({'settings': page.settings});
|
||||
resolve(page.settings);
|
||||
});
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.storage.local.get({'settings': {}}).then((item) => {
|
||||
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 (!('usePasswordGenerator' in page.settings)) {
|
||||
page.settings.usePasswordGenerator = defaultSettings.usePasswordGenerator;
|
||||
}
|
||||
if (!('autoFillSingleEntry' in page.settings)) {
|
||||
page.settings.autoFillSingleEntry = defaultSettings.autoFillSingleEntry;
|
||||
}
|
||||
if (!('autoRetrieveCredentials' in page.settings)) {
|
||||
page.settings.autoRetrieveCredentials = defaultSettings.autoRetrieveCredentials;
|
||||
}
|
||||
if (!('showNotifications' in page.settings)) {
|
||||
page.settings.showNotifications = defaultSettings.showNotifications;
|
||||
}
|
||||
browser.storage.local.set({'settings': page.settings});
|
||||
resolve(page.settings);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
page.initOpenedTabs = function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.tabs.query({}).then((tabs) => {
|
||||
for (const i of tabs) {
|
||||
page.createTabEntry(i.id);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.tabs.query({}).then((tabs) => {
|
||||
for (const i of tabs) {
|
||||
page.createTabEntry(i.id);
|
||||
}
|
||||
|
||||
// set initial tab-ID
|
||||
browser.tabs.query({ 'active': true, 'currentWindow': true }).then((tabs) => {
|
||||
if (tabs.length === 0) {
|
||||
resolve();
|
||||
return; // For example: only the background devtools or a popup are opened
|
||||
}
|
||||
page.currentTabId = tabs[0].id;
|
||||
browserAction.show(null, tabs[0]);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
// set initial tab-ID
|
||||
browser.tabs.query({ 'active': true, 'currentWindow': true }).then((tabs) => {
|
||||
if (tabs.length === 0) {
|
||||
resolve();
|
||||
return; // For example: only the background devtools or a popup are opened
|
||||
}
|
||||
page.currentTabId = tabs[0].id;
|
||||
browserAction.show(null, tabs[0]);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
page.isValidProtocol = function(url) {
|
||||
let protocol = url.substring(0, url.indexOf(':'));
|
||||
protocol = protocol.toLowerCase();
|
||||
return !(url.indexOf('.') === -1 || (protocol !== 'http' && protocol !== 'https' && protocol !== 'ftp' && protocol !== 'sftp'));
|
||||
let protocol = url.substring(0, url.indexOf(':'));
|
||||
protocol = protocol.toLowerCase();
|
||||
return !(url.indexOf('.') === -1 || (protocol !== 'http' && protocol !== 'https' && protocol !== 'ftp' && protocol !== 'sftp'));
|
||||
};
|
||||
|
||||
page.switchTab = function(callback, tab) {
|
||||
browserAction.showDefault(null, tab);
|
||||
browser.tabs.sendMessage(tab.id, {action: 'activated_tab'}).catch((e) => {});
|
||||
browserAction.showDefault(null, tab);
|
||||
browser.tabs.sendMessage(tab.id, {action: 'activated_tab'}).catch((e) => {});
|
||||
};
|
||||
|
||||
page.clearCredentials = function(tabId, complete) {
|
||||
if (!page.tabs[tabId]) {
|
||||
return;
|
||||
}
|
||||
if (!page.tabs[tabId]) {
|
||||
return;
|
||||
}
|
||||
|
||||
page.tabs[tabId].credentials = {};
|
||||
delete page.tabs[tabId].credentials;
|
||||
page.tabs[tabId].credentials = {};
|
||||
delete page.tabs[tabId].credentials;
|
||||
|
||||
if (complete) {
|
||||
page.clearLogins(tabId);
|
||||
|
|
@ -90,48 +94,48 @@ page.clearCredentials = function(tabId, complete) {
|
|||
};
|
||||
|
||||
page.clearLogins = function(tabId) {
|
||||
page.tabs[tabId].loginList = [];
|
||||
page.tabs[tabId].loginList = [];
|
||||
};
|
||||
|
||||
page.createTabEntry = function(tabId) {
|
||||
page.tabs[tabId] = {
|
||||
'stack': [],
|
||||
'errorMessage': null,
|
||||
'loginList': {}
|
||||
};
|
||||
page.tabs[tabId] = {
|
||||
'stack': [],
|
||||
'errorMessage': null,
|
||||
'loginList': {}
|
||||
};
|
||||
};
|
||||
|
||||
page.removePageInformationFromNotExistingTabs = function() {
|
||||
let rand = Math.floor(Math.random()*1001);
|
||||
if (rand === 28) {
|
||||
browser.tabs.query({}).then(function(tabs) {
|
||||
let $tabIds = {};
|
||||
const $infoIds = Object.keys(page.tabs);
|
||||
let rand = Math.floor(Math.random()*1001);
|
||||
if (rand === 28) {
|
||||
browser.tabs.query({}).then(function(tabs) {
|
||||
let $tabIds = [];
|
||||
const $infoIds = Object.keys(page.tabs);
|
||||
|
||||
for (const t of tabs) {
|
||||
$tabIds[t.id] = true;
|
||||
}
|
||||
for (const t of tabs) {
|
||||
$tabIds[t.id] = true;
|
||||
}
|
||||
|
||||
for (const i of $infoIds) {
|
||||
if (!(i in $tabIds)) {
|
||||
delete page.tabs[i];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
for (const i of $infoIds) {
|
||||
if (!(i in $tabIds)) {
|
||||
delete page.tabs[i];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
page.debugConsole = function() {
|
||||
if (arguments.length > 1) {
|
||||
console.log(page.sprintf(arguments[0], arguments));
|
||||
}
|
||||
else {
|
||||
console.log(arguments[0]);
|
||||
}
|
||||
if (arguments.length > 1) {
|
||||
console.log(page.sprintf(arguments[0], arguments));
|
||||
}
|
||||
else {
|
||||
console.log(arguments[0]);
|
||||
}
|
||||
};
|
||||
|
||||
page.sprintf = function(input, args) {
|
||||
return input.replace(/{(\d+)}/g, (match, number) => {
|
||||
return input.replace(/{(\d+)}/g, (match, number) => {
|
||||
return typeof args[number] !== 'undefined' ? (typeof args[number] === 'object' ? JSON.stringify(args[number]) : args[number]) : match;
|
||||
});
|
||||
};
|
||||
|
|
@ -141,12 +145,12 @@ page.debugDummy = function() {};
|
|||
page.debug = page.debugDummy;
|
||||
|
||||
page.setDebug = function(bool) {
|
||||
if (bool) {
|
||||
page.debug = page.debugConsole;
|
||||
return 'Debug mode enabled';
|
||||
}
|
||||
else {
|
||||
page.debug = page.debugDummy;
|
||||
return 'Debug mode disabled';
|
||||
}
|
||||
if (bool) {
|
||||
page.debug = page.debugConsole;
|
||||
return 'Debug mode enabled';
|
||||
}
|
||||
else {
|
||||
page.debug = page.debugDummy;
|
||||
return 'Debug mode disabled';
|
||||
}
|
||||
};
|
||||
|
|
|
|||
17
keepassxc-browser/global.js
Normal file → Executable file
17
keepassxc-browser/global.js
Normal file → Executable file
|
|
@ -1,6 +1,15 @@
|
|||
var isFirefox = function() {
|
||||
if (!(/Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (!(/Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var showNotification = function(message) {
|
||||
browser.notifications.create({
|
||||
'type': 'basic',
|
||||
'iconUrl': browser.extension.getURL('icons/keepassxc_64x64.png'),
|
||||
'title': 'KeePassXC-Browser',
|
||||
'message': message
|
||||
});
|
||||
};
|
||||
|
|
|
|||
4
keepassxc-browser/jquery-3.2.1.min.js
vendored
4
keepassxc-browser/jquery-3.2.1.min.js
vendored
File diff suppressed because one or more lines are too long
2
keepassxc-browser/jquery-3.3.1.min.js
vendored
Normal file
2
keepassxc-browser/jquery-3.3.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,22 +1,23 @@
|
|||
.kpxc .ui-autocomplete li.ui-menu-item {
|
||||
text-align: left !important;
|
||||
font-size: .9em !important;
|
||||
font-weight: normal !important;
|
||||
font-style: normal !important;
|
||||
font-family: Verdana, Arial, sans-serif !important;
|
||||
color: #222222 !important;
|
||||
text-align: left !important;
|
||||
font-size: .9em !important;
|
||||
font-weight: normal !important;
|
||||
font-style: normal !important;
|
||||
font-family: 'Lato',sans-serif !important;
|
||||
color: #222222 !important;
|
||||
}
|
||||
|
||||
.ui-helper-hidden-accessible {
|
||||
display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.kpxc .ui-dialog-titlebar-close {
|
||||
visibility: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.kpxc .ui-dialog {
|
||||
font-size: 12px !important;
|
||||
font-size: 12px !important;
|
||||
box-shadow: 0 4px 6px 0 hsla(0, 0%, 0%, 0.2);
|
||||
}
|
||||
|
||||
.kpxc .ui-widget-overlay {
|
||||
|
|
@ -24,12 +25,13 @@
|
|||
}
|
||||
|
||||
.kpxc .dialog-form .ui-dialog-content .ui-widget-content {
|
||||
max-height: 80px !important;
|
||||
max-height: 80px !important;
|
||||
}
|
||||
|
||||
.kpxc .ui-dialog-titlebar {
|
||||
background-color: #3a8233;
|
||||
color: #fff;
|
||||
font-family: 'Lato',sans-serif;
|
||||
background-color: #6cac4d;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.kpxc .ui-dialog .ui-dialog-buttonpane {
|
||||
|
|
@ -41,164 +43,164 @@
|
|||
}
|
||||
|
||||
.kpxc .ui-button .ui-button-text .ui-button {
|
||||
font-size: .10em !important;
|
||||
font-size: .10em !important;
|
||||
}
|
||||
|
||||
input.genpw-text {
|
||||
font-size: .9em !important;
|
||||
padding: .4em;
|
||||
border-radius: 4px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-collapse: separate;
|
||||
width: 100%;
|
||||
font-size: .9em !important;
|
||||
padding: .4em;
|
||||
border-radius: 4px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-collapse: separate;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.genpw-input-group-addon {
|
||||
font-size: inherit !important;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
padding: .4em;
|
||||
border-radius: 4px;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
border-collapse: separate;
|
||||
font-size: inherit !important;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
padding: .4em;
|
||||
border-radius: 4px;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.kpxc .genpw-input-group {
|
||||
position: relative;
|
||||
display: table;
|
||||
border-collapse: separate;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
display: table;
|
||||
border-collapse: separate;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cip-genpw-icon {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cip-genpw-icon.key {
|
||||
background: url('chrome-extension://__MSG_@@extension_id__/icons/key.png') right no-repeat;
|
||||
background-size: contain;
|
||||
background: url('chrome-extension://__MSG_@@extension_id__/icons/key.png') right no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.cip-genpw-icon.key-moz {
|
||||
background: url('moz-extension://__MSG_@@extension_id__/icons/key.png') right no-repeat;
|
||||
background-size: contain;
|
||||
background: url('moz-extension://__MSG_@@extension_id__/icons/key.png') right no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.kpxc .cip-genpw-checkbox {
|
||||
-webkit-appearance: checkbox !important;
|
||||
-moz-appearance: checkbox !important;
|
||||
appearance: checkbox !important;
|
||||
-webkit-appearance: checkbox !important;
|
||||
-moz-appearance: checkbox !important;
|
||||
appearance: checkbox !important;
|
||||
}
|
||||
|
||||
#cip-genpw-btn-fillin {
|
||||
margin-right: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.b2c-modal-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 2147483645;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 2147483645;
|
||||
}
|
||||
|
||||
.b2c-modal-backdrop:after {
|
||||
content:'';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #000000;
|
||||
opacity: 0.8;
|
||||
filter: alpha(opacity=80);
|
||||
content:'';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #000000;
|
||||
opacity: 0.8;
|
||||
filter: alpha(opacity=80);
|
||||
}
|
||||
|
||||
#b2c-cipDefine-fields {
|
||||
z-index: 2147483646;
|
||||
z-index: 2147483646;
|
||||
}
|
||||
|
||||
#b2c-cipDefine-description {
|
||||
z-index: 2147483646;
|
||||
color: #efefef;
|
||||
border: 2px solid #555555;
|
||||
padding: 7px 5px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 150px;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
background-color:rgba(255,255,255,0.3);
|
||||
font-size: 15px;
|
||||
z-index: 2147483646;
|
||||
color: #efefef;
|
||||
border: 2px solid #555555;
|
||||
padding: 7px 5px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 150px;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
background-color:rgba(255,255,255,0.3);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#b2c-cipDefine-description div:first-of-type {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
text-align: left;
|
||||
color: #efefef;
|
||||
padding-bottom: 8px;
|
||||
font-weight: bold;
|
||||
font-size: 160%;
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
text-align: left;
|
||||
color: #efefef;
|
||||
padding-bottom: 8px;
|
||||
font-weight: bold;
|
||||
font-size: 160%;
|
||||
}
|
||||
|
||||
#b2c-cipDefine-description p {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
color: #efefef;
|
||||
border-top: 2px solid #666666;
|
||||
line-height: 110%;
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
color: #efefef;
|
||||
border-top: 2px solid #666666;
|
||||
line-height: 110%;
|
||||
}
|
||||
|
||||
#b2c-help {
|
||||
margin-bottom: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.b2c-fixed-field {
|
||||
position: absolute;
|
||||
border: 2px solid #efefef;
|
||||
cursor: pointer;
|
||||
z-index: 2147483646;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
background-color:rgba(239,239,239,0.4);
|
||||
position: absolute;
|
||||
border: 2px solid #efefef;
|
||||
cursor: pointer;
|
||||
z-index: 2147483646;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
background-color:rgba(239,239,239,0.4);
|
||||
}
|
||||
|
||||
.b2c-fixed-hover-field {
|
||||
border: 2px solid orange;
|
||||
background-color:rgba(255,165,239,0.4);
|
||||
border: 2px solid orange;
|
||||
background-color:rgba(255,165,239,0.4);
|
||||
}
|
||||
|
||||
.b2c-fixed-password-field {
|
||||
border: 2px solid red;
|
||||
color: #efefef;
|
||||
background-color:rgba(255,0,0,0.4);
|
||||
border: 2px solid red;
|
||||
color: #efefef;
|
||||
background-color:rgba(255,0,0,0.4);
|
||||
}
|
||||
|
||||
.b2c-fixed-username-field {
|
||||
border: 2px solid limegreen;
|
||||
color: #efefef;
|
||||
background-color:rgba(50,205,50,0.4);
|
||||
border: 2px solid limegreen;
|
||||
color: #efefef;
|
||||
background-color:rgba(50,205,50,0.4);
|
||||
}
|
||||
|
||||
.b2c-fixed-string-field {
|
||||
border: 2px solid deepskyblue;
|
||||
color: #efefef;
|
||||
background-color:rgba(30,144,255,0.4);
|
||||
border: 2px solid deepskyblue;
|
||||
color: #efefef;
|
||||
background-color:rgba(30,144,255,0.4);
|
||||
}
|
||||
|
||||
.b2c-input-append {
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.b2c-input-append input,
|
||||
|
|
@ -206,23 +208,23 @@ input.genpw-text {
|
|||
.b2c-input-append .b2c-uneditable-input,
|
||||
.b2c-input-append .b2c-dropdown-menu,
|
||||
.b2c-input-append .b2c-popover {
|
||||
font-size: 14px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.b2c-input-append input,
|
||||
.b2c-input-append select,
|
||||
.b2c-input-append .b2c-uneditable-input {
|
||||
position: relative;
|
||||
margin-bottom: 0;
|
||||
*margin-left: 0;
|
||||
vertical-align: top;
|
||||
-webkit-border-radius: 0 4px 4px 0;
|
||||
-moz-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
position: relative;
|
||||
margin-bottom: 0;
|
||||
*margin-left: 0;
|
||||
vertical-align: top;
|
||||
-webkit-border-radius: 0 4px 4px 0;
|
||||
-moz-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.b2c-input-append input:focus,
|
||||
.b2c-input-append select:focus,
|
||||
.b2c-input-append .b2c-b2c-uneditable-input:focus {
|
||||
z-index: 2;
|
||||
z-index: 2;
|
||||
}
|
||||
|
|
|
|||
2692
keepassxc-browser/keepassxc-browser.js
Normal file → Executable file
2692
keepassxc-browser/keepassxc-browser.js
Normal file → Executable file
File diff suppressed because it is too large
Load diff
32
keepassxc-browser/manifest.json
Normal file → Executable file
32
keepassxc-browser/manifest.json
Normal file → Executable file
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "keepassxc-browser",
|
||||
"version": "0.4.4",
|
||||
"name": "KeePassXC-Browser",
|
||||
"version": "1.0.0",
|
||||
"version_name": "1.0.0",
|
||||
"description": "KeePassXC integration for modern web browsers",
|
||||
"author": "Sami Vänttinen",
|
||||
"author": "KeePassXC Team",
|
||||
"icons": {
|
||||
"16": "icons/keepassxc_16x16.png",
|
||||
"48": "icons/keepassxc_48x48.png",
|
||||
|
|
@ -15,7 +16,7 @@
|
|||
"19": "icons/keepassxc_19x19.png",
|
||||
"38": "icons/keepassxc_38x38.png"
|
||||
},
|
||||
"default_title": "keepassxc-browser",
|
||||
"default_title": "KeePassXC-Browser",
|
||||
"default_popup": "popups/popup.html"
|
||||
},
|
||||
"options_ui": {
|
||||
|
|
@ -42,12 +43,13 @@
|
|||
"<all_urls>"
|
||||
],
|
||||
"exclude_matches": [
|
||||
"*://*/*.xml"
|
||||
"*://*/*.xml",
|
||||
"*://*/*.xsd"
|
||||
],
|
||||
"js": [
|
||||
"browser-polyfill.min.js",
|
||||
"global.js",
|
||||
"jquery-3.2.1.min.js",
|
||||
"jquery-3.3.1.min.js",
|
||||
"jquery-ui.min.js",
|
||||
"keepassxc-browser.js"
|
||||
],
|
||||
|
|
@ -63,17 +65,24 @@
|
|||
"fill-username-password": {
|
||||
"description": "Insert username + password",
|
||||
"suggested_key": {
|
||||
"default": "Ctrl+Shift+U",
|
||||
"mac": "Command+Shift+U"
|
||||
"default": "Alt+Shift+U",
|
||||
"mac": "MacCtrl+Shift+U"
|
||||
}
|
||||
},
|
||||
"fill-password": {
|
||||
"description": "Insert a password",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+P",
|
||||
"mac": "Alt+Shift+P"
|
||||
"mac": "MacCtrl+Shift+P"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fill-totp": {
|
||||
"description": "Insert a TOTP",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+T",
|
||||
"mac": "MacCtrl+Shift+T"
|
||||
}
|
||||
}
|
||||
},
|
||||
"web_accessible_resources": [
|
||||
"icons/key.png"
|
||||
|
|
@ -83,6 +92,7 @@
|
|||
"contextMenus",
|
||||
"clipboardWrite",
|
||||
"nativeMessaging",
|
||||
"notifications",
|
||||
"storage",
|
||||
"tabs",
|
||||
"webRequest",
|
||||
|
|
@ -93,7 +103,7 @@
|
|||
],
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "keepassxc-browser@sami.vanttinen",
|
||||
"id": "keepassxc-browser@keepassxc.org",
|
||||
"strict_min_version": "55.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,143 +1,144 @@
|
|||
body {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 60px;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
/* Custom container */
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
max-width: 1000px;
|
||||
}
|
||||
.container > hr {
|
||||
margin: 30px 0;
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
/* Custom navbar */
|
||||
.navbar-default {
|
||||
background-color: #3a8233;
|
||||
border-color: #01520e;
|
||||
display: inline-block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
font-family: 'Lato',sans-serif;
|
||||
background-color: #6cac4d;
|
||||
border: 0px;
|
||||
box-shadow: 0 2px 6px 0;
|
||||
display: inline-block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
}
|
||||
.navbar-default .navbar-brand {
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-brand:hover,
|
||||
.navbar-default .navbar-brand:focus {
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-text {
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav > li > a {
|
||||
color: #ffffff;
|
||||
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
}
|
||||
.navbar-default .navbar-nav > li > a:hover,
|
||||
.navbar-default .navbar-nav > li > a:focus {
|
||||
color: #cccccc;
|
||||
color: #cccccc;
|
||||
}
|
||||
.navbar-default .navbar-nav > .active > a,
|
||||
.navbar-default .navbar-nav > .active > a:hover,
|
||||
.navbar-default .navbar-nav > .active > a:focus {
|
||||
color: #ffffff;
|
||||
background-color: #01520e;
|
||||
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: #01520e;
|
||||
color: #ffffff;
|
||||
background-color: #3a8233;
|
||||
}
|
||||
.navbar-default .navbar-toggle {
|
||||
border-color: #01520e;
|
||||
border-color: #3a8233;
|
||||
}
|
||||
.navbar-default .navbar-toggle:hover,
|
||||
.navbar-default .navbar-toggle:focus {
|
||||
background-color: #01520e;
|
||||
background-color: #3a8233;
|
||||
}
|
||||
.navbar-default .navbar-toggle .icon-bar {
|
||||
background-color: #ffffff;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-collapse,
|
||||
.navbar-default .navbar-form {
|
||||
border-color: #ffffff;
|
||||
border-color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-link {
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-link:hover {
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #ffffff;
|
||||
background-color: #01520e;
|
||||
}
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #ffffff;
|
||||
background-color: #3a8233;
|
||||
}
|
||||
}
|
||||
|
||||
.tab {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
h2+hr {
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#tab-connected-databases .color.dropdown .dropdown-menu {
|
||||
width: 180px;
|
||||
padding: 7px 10px;
|
||||
line-height: 175%;
|
||||
width: 180px;
|
||||
padding: 7px 10px;
|
||||
line-height: 175%;
|
||||
}
|
||||
|
||||
#tab-connected-databases .color.dropdown .dropdown-menu a {
|
||||
margin-right: 3px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
#tab-connected-databases .color.dropdown a.dropdown-toggle img {
|
||||
margin-right: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
tr.clone {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
td.last-used,
|
||||
td.created {
|
||||
white-space: nowrap;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.radio.inline,
|
||||
.checkbox.inline {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.radio.inline + .radio.inline,
|
||||
.checkbox.inline + .checkbox.inline {
|
||||
margin-left: 40px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.checkUpdateKeePassXC {
|
||||
margin-left: 40px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
#dangerousSettings {
|
||||
display: none;
|
||||
}
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,297 +1,311 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Settings | keepassxc-browser</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="options.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.2.1.min.js"></script>
|
||||
<script type="text/javascript" src="bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="options.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h3 class="muted"><img src="/icons/keepassxc_48x48.png" alt="logo" /> keepassxc-browser</h3>
|
||||
<head>
|
||||
<title>Settings | KeePassXC-Browser</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="options.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="options.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h3 class="muted"><img src="/icons/keepassxc_48x48.png" alt="logo" /> KeePassXC-Browser</h3>
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#general-settings">General</a></li>
|
||||
<li><a href="#connected-databases">Connected Databases</a></li>
|
||||
<li><a href="#specified-fields">Specified credential fields</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="navbar navbar-default">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#general-settings">General</a></li>
|
||||
<li><a href="#connected-databases">Connected Databases</a></li>
|
||||
<li><a href="#specified-fields">Specified credential fields</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- General Settings -->
|
||||
<div class="tab" id="tab-general-settings">
|
||||
<h2>General Settings</h2>
|
||||
<hr />
|
||||
<p>
|
||||
If you just want to insert username + password into the fields where your focus is, press <code>Ctrl + Shift + U</code>.
|
||||
<br />
|
||||
If you only want to insert the password, just press <code>Ctrl + Shift + P</code>.
|
||||
<span id="chrome-only">You can customize these shortcuts on <code>chrome://extensions/configureCommands</code> page</span>
|
||||
</p>
|
||||
<p>
|
||||
<div class="form-group">
|
||||
<label for="blinkTimeout">Blink Time:</label>
|
||||
<div class="control-group">
|
||||
<div class="input-append">
|
||||
<input type="number" id="blinkTimeout" placeholder="7500" value="7500" />
|
||||
<button class="btn btn-sm btn-primary" id="blinkTimeoutButton" type="button"><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-inline">
|
||||
What is the maximum time (ms) the icon should blink after detecting new credentials
|
||||
<br />
|
||||
Default: 7500
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<div class="form-group">
|
||||
<label for="blinkMinTimeout">Redirect Offset:</label>
|
||||
<div class="control-group">
|
||||
<div class="input-append">
|
||||
<input type="number" id="blinkMinTimeout" placeholder="2000" value="2000" />
|
||||
<button class="btn btn-sm btn-primary" id="blinkMinTimeoutButton" type="button"><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-inline">
|
||||
What is the minimum time (ms) the icon should blink before deactivating due to page redirects.
|
||||
<br />
|
||||
-1 to only use <i>Blink Time</i> ignoring Redirect Allowance (old behavior)
|
||||
<br />
|
||||
Default: -1, Recommended: 2000
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<div class="form-group">
|
||||
<label for="allowedRedirect">Redirect Allowance:</label>
|
||||
<div class="control-group">
|
||||
<div class="input-append">
|
||||
<input type="number" id="allowedRedirect" placeholder="1" value="1" />
|
||||
<button class="btn btn-sm btn-primary" id="allowedRedirectButton" type="button"><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-inline">
|
||||
How many pages should the tab cycle through after the redirect offset before deactivating the icon
|
||||
<br />
|
||||
Default: 1
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="usePasswordGenerator" value="true" /> Activate password generator.
|
||||
</label>
|
||||
<span class="help-block">For all password-fields there will be an icon added to generate a new password.<br />
|
||||
It is generated by KeePassXC with the profile for automatically generated passwords for new entries.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoRetrieveCredentials" value="true" /> Automatically retrieve credentials.
|
||||
</label>
|
||||
<span class="help-block">keepassxc-browser will immediately retrieve the credentials when the tab is activated.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoFillSingleEntry" value="false" /> Automatically fill-in single credentials entry.
|
||||
</label>
|
||||
<span class="help-block">If keepassxc-browser does only receive a single entry from KeePassXC it automatically fills this credentials into the found credential fields.</span>
|
||||
<span class="bg-danger">Warning! Using auto-fill is not safe. Use at your own risk.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoCompleteUsernames" value="true" /> Activate autocomplete for username fields.
|
||||
</label>
|
||||
<span class="help-block">For all username fields on a page a dropdown list appears which contains all available credentials.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
Check for updates of KeePassXC:
|
||||
<br />
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="3" /> every 3 days</label>
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="7" /> every week</label>
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="30" /> every month</label>
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="0" /> never</label>
|
||||
</p>
|
||||
<div class="help-block kphVersion">
|
||||
keepassxc-browser needs KeePassXC to retrieve credentials.
|
||||
<br />
|
||||
You can download the latest stable version from here: <a target="_blank" href="https://keepassxc.org/">https://keepassxc.org/</a>
|
||||
<br />
|
||||
<br />
|
||||
<div>
|
||||
Your running version of KeePassXC: <em class="yourVersion"></em>
|
||||
</div>
|
||||
<div>
|
||||
Latest available version of KeePassXC: <em class="latestVersion"></em>
|
||||
<button class="btn btn-sm btn-primary checkUpdateKeePassXC"><span class="glyphicon glyphicon-refresh"></span> Check for updates</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoFillAndSend" value="1" /> Auto fill HTTP Auth dialogs and send them.
|
||||
</label>
|
||||
<span class="help-block">
|
||||
If credentials are found for a page and the login-type is an HTTP Auth request, keepassxc-browser tries to login with the first given credentials.
|
||||
<br />
|
||||
An HTTP Auth dialog looks like this:
|
||||
</span>
|
||||
</div>
|
||||
<img src="/options/http-auth-dialog.png" alt="http-auth-dialog" />
|
||||
</p>
|
||||
</div>
|
||||
<!-- General Settings -->
|
||||
<div class="tab" id="tab-general-settings">
|
||||
<h2>General Settings</h2>
|
||||
<hr />
|
||||
<p>
|
||||
If you just want to insert username + password into the fields where your focus is, press <code>Alt + Shift + U</code>.
|
||||
<br />
|
||||
If you only want to insert the password, just press <code>Alt + Shift + P</code>.
|
||||
<span id="chrome-only">You can customize these shortcuts on <code>chrome://extensions/configureCommands</code> page</span>
|
||||
</p>
|
||||
<p>
|
||||
<div class="form-group">
|
||||
<label for="blinkTimeout">Blink Time:</label>
|
||||
<div class="control-group">
|
||||
<div class="input-append">
|
||||
<input type="number" id="blinkTimeout" placeholder="7500" value="7500" />
|
||||
<button class="btn btn-sm btn-primary" id="blinkTimeoutButton" type="button"><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-inline">
|
||||
What is the maximum time (ms) the icon should blink after detecting new credentials
|
||||
<br />
|
||||
Default: 7500
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<div class="form-group">
|
||||
<label for="blinkMinTimeout">Redirect Offset:</label>
|
||||
<div class="control-group">
|
||||
<div class="input-append">
|
||||
<input type="number" id="blinkMinTimeout" placeholder="2000" value="2000" />
|
||||
<button class="btn btn-sm btn-primary" id="blinkMinTimeoutButton" type="button"><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-inline">
|
||||
What is the minimum time (ms) the icon should blink before deactivating due to page redirects.
|
||||
<br />
|
||||
-1 to only use <i>Blink Time</i> ignoring Redirect Allowance (old behavior)
|
||||
<br />
|
||||
Default: -1, Recommended: 2000
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<div class="form-group">
|
||||
<label for="allowedRedirect">Redirect Allowance:</label>
|
||||
<div class="control-group">
|
||||
<div class="input-append">
|
||||
<input type="number" id="allowedRedirect" placeholder="1" value="1" />
|
||||
<button class="btn btn-sm btn-primary" id="allowedRedirectButton" type="button"><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-inline">
|
||||
How many pages should the tab cycle through after the redirect offset before deactivating the icon
|
||||
<br />
|
||||
Default: 1
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="usePasswordGenerator" value="true" /> Activate password generator.
|
||||
</label>
|
||||
<span class="help-block">
|
||||
For all password-fields there will be an icon added to generate a new password.
|
||||
<br />
|
||||
It is generated by KeePassXC with the profile for automatically generated passwords for new entries.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoRetrieveCredentials" value="true" /> Automatically retrieve credentials.
|
||||
</label>
|
||||
<span class="help-block">KeePassXC-Browser will immediately retrieve the credentials when the tab is activated.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoFillSingleEntry" value="false" /> Automatically fill-in single credentials entry.
|
||||
</label>
|
||||
<span class="help-block">If KeePassXC-Browser does only receive a single entry from KeePassXC it automatically fills this credentials into the found credential fields.</span>
|
||||
<span class="bg-danger">Warning! Using auto-fill is not safe. Use at your own risk.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoCompleteUsernames" value="true" /> Activate autocomplete for username fields.
|
||||
</label>
|
||||
<span class="help-block">For all username fields on a page a dropdown list appears which contains all available credentials.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="showNotifications" value="true" /> Show notifications.
|
||||
</label>
|
||||
<span class="help-block">Allow KeePassXC-Browser to show notifications when user interaction is needed from the extension icon.</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
Check for updates of KeePassXC:
|
||||
<br />
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="3" /> every 3 days</label>
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="7" /> every week</label>
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="30" /> every month</label>
|
||||
<label class="radio-inline"><input type="radio" name="checkUpdateKeePassXC" value="0" /> never</label>
|
||||
</p>
|
||||
<div class="help-block kphVersion">
|
||||
KeePassXC-Browser needs KeePassXC to retrieve credentials.
|
||||
<br />
|
||||
You can download the latest stable version from here: <a target="_blank" href="https://keepassxc.org/">https://keepassxc.org/</a>
|
||||
<br />
|
||||
<br />
|
||||
<div>
|
||||
You are running KeePassXC version: <em class="yourVersion"></em>
|
||||
</div>
|
||||
<div>
|
||||
Latest available version of KeePassXC: <em class="latestVersion"></em>
|
||||
<button class="btn btn-sm btn-primary checkUpdateKeePassXC"><span class="glyphicon glyphicon-refresh"></span> Check for updates</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="autoFillAndSend" value="1" /> Auto fill HTTP Auth dialogs and send them.
|
||||
</label>
|
||||
<span class="help-block">
|
||||
If credentials are found for a page and the login-type is an HTTP Auth request, KeePassXC-Browser tries to login with the first given credentials.
|
||||
<br />
|
||||
An HTTP Auth dialog looks like this:
|
||||
</span>
|
||||
</div>
|
||||
<img src="/options/http-auth-dialog.png" alt="http-auth-dialog" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Connected Databases -->
|
||||
<div class="tab" id="tab-connected-databases">
|
||||
<h2>Connected Databases</h2>
|
||||
<hr />
|
||||
<p>
|
||||
The following KeePassXC databases are connected to keepassxc-browser.
|
||||
</p>
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Identifier</th>
|
||||
<th>Key</th>
|
||||
<th>Last used</th>
|
||||
<th>Created</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="empty">
|
||||
<td colspan="5">No connected databases found.</td>
|
||||
</tr>
|
||||
<tr class="clone">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="last-used"></td>
|
||||
<td class="created"></td>
|
||||
<td><button class="btn delete btn-danger"><span class="glyphicon glyphicon-remove-sign"></span> Remove</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="text-align: right">
|
||||
<button id="connect-button" class="btn btn-primary"><span class="glyphicon glyphicon-link"></span> Connect</button>
|
||||
</div>
|
||||
<!-- Connected Databases -->
|
||||
<div class="tab" id="tab-connected-databases">
|
||||
<h2>Connected Databases</h2>
|
||||
<hr />
|
||||
<p>
|
||||
The following KeePassXC databases are connected to KeePassXC-Browser.
|
||||
</p>
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Identifier</th>
|
||||
<th>Key</th>
|
||||
<th>Last used</th>
|
||||
<th>Created</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="empty">
|
||||
<td colspan="5">No connected databases found.</td>
|
||||
</tr>
|
||||
<tr class="clone">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="last-used"></td>
|
||||
<td class="created"></td>
|
||||
<td><button class="btn delete btn-danger"><span class="glyphicon glyphicon-remove-sign"></span> Remove</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="text-align: right">
|
||||
<button id="connect-button" class="btn btn-primary"><span class="glyphicon glyphicon-link"></span> Connect</button>
|
||||
</div>
|
||||
|
||||
<div id="dialogDeleteConnectedDatabase" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 class="modal-title" id="myModalLabel">Remove identifier from database list?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Do you really want to remove the identifier <span class="bold"></span> from the database list?</p>
|
||||
<p class="help-block">You can reconnect your database at any time.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true"><span class="glyphicon glyphicon-remove"></span> Cancel</button>
|
||||
<button class="btn yes btn-primary"><span class="glyphicon glyphicon-ok"></span> Yes, remove now</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dialogDeleteConnectedDatabase" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 class="modal-title" id="myModalLabel">Remove identifier from database list?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Do you really want to remove the identifier <span class="bold"></span> from the database list?</p>
|
||||
<p class="help-block">You can reconnect your database at any time.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true"><span class="glyphicon glyphicon-remove"></span> Cancel</button>
|
||||
<button class="btn yes btn-primary"><span class="glyphicon glyphicon-ok"></span> Yes, remove now</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Specified credential fields -->
|
||||
<div class="tab" id="tab-specified-fields">
|
||||
<h2>Specified credential fields</h2>
|
||||
<hr />
|
||||
<p>
|
||||
If keepassxc-browser detects the wrong credential fields, you are able to specify the correct fields by yourself.
|
||||
<br />
|
||||
Just go to the page and click on the keepassxc-browser-Icon, now select <em>Choose own credential fields for this page</em>.
|
||||
<br />
|
||||
On this page you can manage theses specified credential fields.
|
||||
</p>
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Page URL</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="empty">
|
||||
<td colspan="2">No specified credential fields found.</td>
|
||||
</tr>
|
||||
<tr class="clone">
|
||||
<td></td>
|
||||
<td><button class="btn delete btn-danger btn"><span class="glyphicon glyphicon-remove-sign"></span> Remove</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="dialogDeleteSpecifiedCredentialFields" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Remove specified credential fields?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Do you really want to remove the specified credential fields on the page <strong></strong>?</p>
|
||||
<p class="help-block">keepassxc-browser will automatically detect the credential fields the next time you visit this page.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
|
||||
<button class="btn yes btn-primary">Yes, remove now</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Specified credential fields -->
|
||||
<div class="tab" id="tab-specified-fields">
|
||||
<h2>Specified credential fields</h2>
|
||||
<hr />
|
||||
<p>
|
||||
If KeePassXC-Browser detects the wrong credential fields, you are able to specify the correct fields by yourself.
|
||||
<br />
|
||||
Just go to the page and click on the KeePassXC-Browser-Icon, now select <em>Choose own credential fields for this page</em>.
|
||||
<br />
|
||||
On this page you can manage theses specified credential fields.
|
||||
</p>
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Page URL</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="empty">
|
||||
<td colspan="2">No specified credential fields found.</td>
|
||||
</tr>
|
||||
<tr class="clone">
|
||||
<td></td>
|
||||
<td><button class="btn delete btn-danger btn"><span class="glyphicon glyphicon-remove-sign"></span> Remove</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="dialogDeleteSpecifiedCredentialFields" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Remove specified credential fields?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Do you really want to remove the specified credential fields on the page <strong></strong>?</p>
|
||||
<p class="help-block">KeePassXC-Browser will automatically detect the credential fields the next time you visit this page.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
|
||||
<button class="btn yes btn-primary">Yes, remove now</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About -->
|
||||
<div class="tab" id="tab-about">
|
||||
<h2>About</h2>
|
||||
<hr />
|
||||
<p>
|
||||
Developed by <a target="_blank" href="https://github.com/pfn/">Perry Nguyen</a>, <a target="_blank" href="http://lukas-schulze.de">Lukas Schulze</a> and
|
||||
<a target="_blank" href="https://github.com/varjolintu/">Sami Vänttinen</a>
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="https://chrome.google.com/webstore/detail/keepassxc-browser/iopaggbpplllidnfmcghoonnokmjoicf">Visit extension's page in Chrome Web store</a>
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/">Visit extension's page in Mozilla's Add-ons page</a>
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="https://github.com/varjolintu/keepassxc-browser">Visit project's page in GitHub</a>.
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
keepassxc-browser Version: <em class="versionCIP"></em>
|
||||
</p>
|
||||
<p>
|
||||
KeePassXC Version: <em class="versionKPH"></em>
|
||||
</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="footer">
|
||||
<p>2010-2017 - Perry Nguyen, Lukas Schulze, Angus Gratton, Andy Brandt, Sami Vänttinen</p>
|
||||
</div>
|
||||
</div> <!-- /container -->
|
||||
</body>
|
||||
<!-- About -->
|
||||
<div class="tab" id="tab-about">
|
||||
<h2>About</h2>
|
||||
<hr />
|
||||
<p>
|
||||
<a target="_blank" href="https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk">Visit extension's page in Chrome Web store</a>
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/">Visit extension's page in Mozilla's Add-ons page</a>
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="https://github.com/keepassxreboot/keepassxc-browser">Visit project's page in GitHub</a>.
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
KeePassXC-Browser Version: <em class="versionCIP"></em>
|
||||
</p>
|
||||
<p>
|
||||
KeePassXC Version: <em class="versionKPH"></em>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
Contributors:<br>
|
||||
<a target="_blank" href="https://github.com/pfn/">Perry Nguyen</a>, <a target="_blank" href="http://lukas-schulze.de">Lukas Schulze</a>,
|
||||
<a target="_blank" href="https://github.com/smorks">Andy Brandt</a>, <a target="_blank" href="https://github.com/varjolintu/">Sami Vänttinen</a>
|
||||
and <a target="_blank" href="https://github.com/keepassxreboot/keepassxc-browser">KeePassXC Team</a>.
|
||||
</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="footer">
|
||||
<p>(C) 2017-2018 - KeePassXC Team</p>
|
||||
</div>
|
||||
</div> <!-- /container -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,264 +1,264 @@
|
|||
if (jQuery) {
|
||||
var $ = jQuery.noConflict(true);
|
||||
var $ = jQuery.noConflict(true);
|
||||
}
|
||||
|
||||
$(function() {
|
||||
browser.runtime.sendMessage({ action: 'load_settings' }).then((settings) => {
|
||||
options.settings = settings;
|
||||
browser.runtime.sendMessage({ action: 'load_keyring' }).then((keyRing) => {
|
||||
options.keyRing = keyRing;
|
||||
options.initMenu();
|
||||
options.initGeneralSettings();
|
||||
options.initConnectedDatabases();
|
||||
options.initSpecifiedCredentialFields();
|
||||
options.initAbout();
|
||||
});
|
||||
});
|
||||
browser.runtime.sendMessage({ action: 'load_settings' }).then((settings) => {
|
||||
options.settings = settings;
|
||||
browser.runtime.sendMessage({ action: 'load_keyring' }).then((keyRing) => {
|
||||
options.keyRing = keyRing;
|
||||
options.initMenu();
|
||||
options.initGeneralSettings();
|
||||
options.initConnectedDatabases();
|
||||
options.initSpecifiedCredentialFields();
|
||||
options.initAbout();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var options = options || {};
|
||||
|
||||
options.initMenu = function() {
|
||||
$('.navbar:first ul.nav:first li a').click(function(e) {
|
||||
e.preventDefault();
|
||||
$('.navbar:first ul.nav:first li').removeClass('active');
|
||||
$(this).parent('li').addClass('active');
|
||||
$('div.tab').hide();
|
||||
$('div.tab#tab-' + $(this).attr('href').substring(1)).fadeIn();
|
||||
});
|
||||
$('.navbar:first ul.nav:first li a').click(function(e) {
|
||||
e.preventDefault();
|
||||
$('.navbar:first ul.nav:first li').removeClass('active');
|
||||
$(this).parent('li').addClass('active');
|
||||
$('div.tab').hide();
|
||||
$('div.tab#tab-' + $(this).attr('href').substring(1)).fadeIn();
|
||||
});
|
||||
|
||||
$('div.tab:first').show();
|
||||
$('div.tab:first').show();
|
||||
};
|
||||
|
||||
options.saveSettingsPromise = function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.storage.local.set({'settings': options.settings}).then((item) => {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_settings'
|
||||
}).then((settings) => {
|
||||
resolve(settings);
|
||||
});
|
||||
});
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.storage.local.set({'settings': options.settings}).then((item) => {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_settings'
|
||||
}).then((settings) => {
|
||||
resolve(settings);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
options.saveSetting = function(name) {
|
||||
const $id = '#' + name;
|
||||
$($id).closest('.control-group').removeClass('error').addClass('success');
|
||||
setTimeout(() => { $($id).closest('.control-group').removeClass('success'); }, 2500);
|
||||
const $id = '#' + name;
|
||||
$($id).closest('.control-group').removeClass('error').addClass('success');
|
||||
setTimeout(() => { $($id).closest('.control-group').removeClass('success'); }, 2500);
|
||||
|
||||
browser.storage.local.set({'settings': options.settings});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_settings'
|
||||
});
|
||||
browser.storage.local.set({'settings': options.settings});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_settings'
|
||||
});
|
||||
};
|
||||
|
||||
options.saveSettings = function() {
|
||||
browser.storage.local.set({'settings': options.settings});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_settings'
|
||||
});
|
||||
browser.storage.local.set({'settings': options.settings});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_settings'
|
||||
});
|
||||
};
|
||||
|
||||
options.saveKeyRing = function() {
|
||||
browser.storage.local.set({'keyRing': options.keyRing});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_keyring'
|
||||
});
|
||||
browser.storage.local.set({'keyRing': options.keyRing});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'load_keyring'
|
||||
});
|
||||
};
|
||||
|
||||
options.initGeneralSettings = function() {
|
||||
$('#tab-general-settings input[type=checkbox]').each(function() {
|
||||
$(this).attr('checked', options.settings[$(this).attr('name')]);
|
||||
});
|
||||
$('#tab-general-settings input[type=checkbox]').each(function() {
|
||||
$(this).attr('checked', options.settings[$(this).attr('name')]);
|
||||
});
|
||||
|
||||
$('#tab-general-settings input[type=checkbox]').change(function() {
|
||||
const name = $(this).attr('name');
|
||||
options.settings[name] = $(this).is(':checked');
|
||||
options.saveSettingsPromise().then((x) => {
|
||||
if (name === 'autoFillAndSend') {
|
||||
browser.runtime.sendMessage({action: 'init_http_auth'});
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#tab-general-settings input[type=checkbox]').change(function() {
|
||||
const name = $(this).attr('name');
|
||||
options.settings[name] = $(this).is(':checked');
|
||||
options.saveSettingsPromise().then((x) => {
|
||||
if (name === 'autoFillAndSend') {
|
||||
browser.runtime.sendMessage({action: 'init_http_auth'});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#tab-general-settings input[type=radio]').each(function() {
|
||||
if ($(this).val() === options.settings[$(this).attr('name')]) {
|
||||
$(this).attr('checked', options.settings[$(this).attr('name')]);
|
||||
}
|
||||
});
|
||||
$('#tab-general-settings input[type=radio]').each(function() {
|
||||
if ($(this).val() === options.settings[$(this).attr('name')]) {
|
||||
$(this).attr('checked', options.settings[$(this).attr('name')]);
|
||||
}
|
||||
});
|
||||
|
||||
$('#tab-general-settings input[type=radio]').change(function() {
|
||||
options.settings[$(this).attr('name')] = $(this).val();
|
||||
options.saveSettings();
|
||||
});
|
||||
$('#tab-general-settings input[type=radio]').change(function() {
|
||||
options.settings[$(this).attr('name')] = $(this).val();
|
||||
options.saveSettings();
|
||||
});
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_keepassxc_versions'
|
||||
}).then(options.showKeePassXCVersions);
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_keepassxc_versions'
|
||||
}).then(options.showKeePassXCVersions);
|
||||
|
||||
$('#tab-general-settings button.checkUpdateKeePassXC:first').click(function(e) {
|
||||
e.preventDefault();
|
||||
$(this).attr('disabled', true);
|
||||
browser.runtime.sendMessage({
|
||||
action: 'check_update_keepassxc'
|
||||
}).then(options.showKeePassXCVersions);
|
||||
});
|
||||
$('#tab-general-settings button.checkUpdateKeePassXC:first').click(function(e) {
|
||||
e.preventDefault();
|
||||
$(this).attr('disabled', true);
|
||||
browser.runtime.sendMessage({
|
||||
action: 'check_update_keepassxc'
|
||||
}).then(options.showKeePassXCVersions);
|
||||
});
|
||||
|
||||
$('#blinkTimeout').val(options.settings['blinkTimeout']);
|
||||
$('#blinkMinTimeout').val(options.settings['blinkMinTimeout']);
|
||||
$('#allowedRedirect').val(options.settings['allowedRedirect']);
|
||||
$('#blinkTimeout').val(options.settings['blinkTimeout']);
|
||||
$('#blinkMinTimeout').val(options.settings['blinkMinTimeout']);
|
||||
$('#allowedRedirect').val(options.settings['allowedRedirect']);
|
||||
|
||||
$('#blinkTimeoutButton').click(function(){
|
||||
const blinkTimeout = $.trim($('#blinkTimeout').val());
|
||||
const blinkTimeoutval = Number(blinkTimeout);
|
||||
$('#blinkTimeoutButton').click(function(){
|
||||
const blinkTimeout = $.trim($('#blinkTimeout').val());
|
||||
const blinkTimeoutval = Number(blinkTimeout);
|
||||
|
||||
options.settings['blinkTimeout'] = String(blinkTimeoutval);
|
||||
options.saveSetting('blinkTimeout');
|
||||
});
|
||||
options.saveSetting('blinkTimeout');
|
||||
});
|
||||
|
||||
$('#blinkMinTimeoutButton').click(function(){
|
||||
const blinkMinTimeout = $.trim($('#blinkMinTimeout').val());
|
||||
const blinkMinTimeoutval = Number(blinkMinTimeout);
|
||||
$('#blinkMinTimeoutButton').click(function(){
|
||||
const blinkMinTimeout = $.trim($('#blinkMinTimeout').val());
|
||||
const blinkMinTimeoutval = Number(blinkMinTimeout);
|
||||
|
||||
options.settings['blinkMinTimeout'] = String(blinkMinTimeoutval);
|
||||
options.saveSetting('blinkMinTimeout');
|
||||
});
|
||||
options.saveSetting('blinkMinTimeout');
|
||||
});
|
||||
|
||||
$('#allowedRedirectButton').click(function(){
|
||||
const allowedRedirect = $.trim($('#allowedRedirect').val());
|
||||
const allowedRedirectval = Number(allowedRedirect);
|
||||
$('#allowedRedirectButton').click(function(){
|
||||
const allowedRedirect = $.trim($('#allowedRedirect').val());
|
||||
const allowedRedirectval = Number(allowedRedirect);
|
||||
|
||||
options.settings['allowedRedirect'] = String(allowedRedirectval);
|
||||
options.saveSetting('allowedRedirect');
|
||||
});
|
||||
options.saveSetting('allowedRedirect');
|
||||
});
|
||||
};
|
||||
|
||||
options.showKeePassXCVersions = function(response) {
|
||||
if (response.current <= 0) {
|
||||
response.current = 'unknown';
|
||||
}
|
||||
if (response.latest <= 0) {
|
||||
response.latest = 'unknown';
|
||||
}
|
||||
$('#tab-general-settings .kphVersion:first em.yourVersion:first').text(response.current);
|
||||
$('#tab-general-settings .kphVersion:first em.latestVersion:first').text(response.latest);
|
||||
$('#tab-about em.versionKPH').text(response.current);
|
||||
$('#tab-general-settings button.checkUpdateKeePassXC:first').attr('disabled', false);
|
||||
if (response.current <= 0) {
|
||||
response.current = 'unknown';
|
||||
}
|
||||
if (response.latest <= 0) {
|
||||
response.latest = 'unknown';
|
||||
}
|
||||
$('#tab-general-settings .kphVersion:first em.yourVersion:first').text(response.current);
|
||||
$('#tab-general-settings .kphVersion:first em.latestVersion:first').text(response.latest);
|
||||
$('#tab-about em.versionKPH').text(response.current);
|
||||
$('#tab-general-settings button.checkUpdateKeePassXC:first').attr('disabled', false);
|
||||
};
|
||||
|
||||
options.initConnectedDatabases = function() {
|
||||
$('#dialogDeleteConnectedDatabase').modal({keyboard: true, show: false, backdrop: true});
|
||||
$('#tab-connected-databases tr.clone:first button.delete:first').click(function(e) {
|
||||
e.preventDefault();
|
||||
$('#dialogDeleteConnectedDatabase').data('hash', $(this).closest('tr').data('hash'));
|
||||
$('#dialogDeleteConnectedDatabase .modal-body:first span:first').text($(this).closest('tr').children('td:first').text());
|
||||
$('#dialogDeleteConnectedDatabase').modal('show');
|
||||
});
|
||||
$('#dialogDeleteConnectedDatabase').modal({keyboard: true, show: false, backdrop: true});
|
||||
$('#tab-connected-databases tr.clone:first button.delete:first').click(function(e) {
|
||||
e.preventDefault();
|
||||
$('#dialogDeleteConnectedDatabase').data('hash', $(this).closest('tr').data('hash'));
|
||||
$('#dialogDeleteConnectedDatabase .modal-body:first span:first').text($(this).closest('tr').children('td:first').text());
|
||||
$('#dialogDeleteConnectedDatabase').modal('show');
|
||||
});
|
||||
|
||||
$('#dialogDeleteConnectedDatabase .modal-footer:first button.yes:first').click(function(e) {
|
||||
$('#dialogDeleteConnectedDatabase').modal('hide');
|
||||
$('#dialogDeleteConnectedDatabase .modal-footer:first button.yes:first').click(function(e) {
|
||||
$('#dialogDeleteConnectedDatabase').modal('hide');
|
||||
|
||||
const $hash = $('#dialogDeleteConnectedDatabase').data('hash');
|
||||
$('#tab-connected-databases #tr-cd-' + $hash).remove();
|
||||
const $hash = $('#dialogDeleteConnectedDatabase').data('hash');
|
||||
$('#tab-connected-databases #tr-cd-' + $hash).remove();
|
||||
|
||||
delete options.keyRing[$hash];
|
||||
options.saveKeyRing();
|
||||
delete options.keyRing[$hash];
|
||||
options.saveKeyRing();
|
||||
|
||||
if ($('#tab-connected-databases table tbody:first tr').length > 2) {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').show();
|
||||
}
|
||||
});
|
||||
if ($('#tab-connected-databases table tbody:first tr').length > 2) {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').show();
|
||||
}
|
||||
});
|
||||
|
||||
$('#tab-connected-databases tr.clone:first .dropdown-menu:first').width('230px');
|
||||
$('#tab-connected-databases tr.clone:first .dropdown-menu:first').width('230px');
|
||||
|
||||
const $trClone = $('#tab-connected-databases table tr.clone:first').clone(true);
|
||||
$trClone.removeClass('clone');
|
||||
for (let hash in options.keyRing) {
|
||||
const $tr = $trClone.clone(true);
|
||||
$tr.data('hash', hash);
|
||||
$tr.attr('id', 'tr-cd-' + hash);
|
||||
const $trClone = $('#tab-connected-databases table tr.clone:first').clone(true);
|
||||
$trClone.removeClass('clone');
|
||||
for (let hash in options.keyRing) {
|
||||
const $tr = $trClone.clone(true);
|
||||
$tr.data('hash', hash);
|
||||
$tr.attr('id', 'tr-cd-' + hash);
|
||||
|
||||
$('a.dropdown-toggle:first img:first', $tr).attr('src', '/icons/19x19/icon_normal_19x19.png');
|
||||
$('a.dropdown-toggle:first img:first', $tr).attr('src', '/icons/19x19/icon_normal_19x19.png');
|
||||
|
||||
$tr.children('td:first').text(options.keyRing[hash].id);
|
||||
$tr.children('td:eq(1)').text(options.keyRing[hash].key);
|
||||
const lastUsed = (options.keyRing[hash].lastUsed) ? new Date(options.keyRing[hash].lastUsed).toLocaleString() : 'unknown';
|
||||
$tr.children('td:eq(2)').text(lastUsed);
|
||||
const date = (options.keyRing[hash].created) ? new Date(options.keyRing[hash].created).toLocaleDateString() : 'unknown';
|
||||
$tr.children('td:eq(3)').text(date);
|
||||
$('#tab-connected-databases table tbody:first').append($tr);
|
||||
}
|
||||
$tr.children('td:first').text(options.keyRing[hash].id);
|
||||
$tr.children('td:eq(1)').text(options.keyRing[hash].key);
|
||||
const lastUsed = (options.keyRing[hash].lastUsed) ? new Date(options.keyRing[hash].lastUsed).toLocaleString() : 'unknown';
|
||||
$tr.children('td:eq(2)').text(lastUsed);
|
||||
const date = (options.keyRing[hash].created) ? new Date(options.keyRing[hash].created).toLocaleDateString() : 'unknown';
|
||||
$tr.children('td:eq(3)').text(date);
|
||||
$('#tab-connected-databases table tbody:first').append($tr);
|
||||
}
|
||||
|
||||
if ($('#tab-connected-databases table tbody:first tr').length > 2) {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').show();
|
||||
}
|
||||
if ($('#tab-connected-databases table tbody:first tr').length > 2) {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-connected-databases table tbody:first tr.empty:first').show();
|
||||
}
|
||||
|
||||
$('#connect-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'associate'
|
||||
});
|
||||
});
|
||||
$('#connect-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'associate'
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
options.initSpecifiedCredentialFields = function() {
|
||||
$('#dialogDeleteSpecifiedCredentialFields').modal({keyboard: true, show: false, backdrop: true});
|
||||
$('#tab-specified-fields tr.clone:first button.delete:first').click(function(e) {
|
||||
e.preventDefault();
|
||||
$('#dialogDeleteSpecifiedCredentialFields').data('url', $(this).closest('tr').data('url'));
|
||||
$('#dialogDeleteSpecifiedCredentialFields').data('tr-id', $(this).closest('tr').attr('id'));
|
||||
$('#dialogDeleteSpecifiedCredentialFields .modal-body:first strong:first').text($(this).closest('tr').children('td:first').text());
|
||||
$('#dialogDeleteSpecifiedCredentialFields').modal('show');
|
||||
});
|
||||
$('#dialogDeleteSpecifiedCredentialFields').modal({keyboard: true, show: false, backdrop: true});
|
||||
$('#tab-specified-fields tr.clone:first button.delete:first').click(function(e) {
|
||||
e.preventDefault();
|
||||
$('#dialogDeleteSpecifiedCredentialFields').data('url', $(this).closest('tr').data('url'));
|
||||
$('#dialogDeleteSpecifiedCredentialFields').data('tr-id', $(this).closest('tr').attr('id'));
|
||||
$('#dialogDeleteSpecifiedCredentialFields .modal-body:first strong:first').text($(this).closest('tr').children('td:first').text());
|
||||
$('#dialogDeleteSpecifiedCredentialFields').modal('show');
|
||||
});
|
||||
|
||||
$('#dialogDeleteSpecifiedCredentialFields .modal-footer:first button.yes:first').click(function(e) {
|
||||
$('#dialogDeleteSpecifiedCredentialFields').modal('hide');
|
||||
$('#dialogDeleteSpecifiedCredentialFields .modal-footer:first button.yes:first').click(function(e) {
|
||||
$('#dialogDeleteSpecifiedCredentialFields').modal('hide');
|
||||
|
||||
const $url = $('#dialogDeleteSpecifiedCredentialFields').data('url');
|
||||
const $trId = $('#dialogDeleteSpecifiedCredentialFields').data('tr-id');
|
||||
$('#tab-specified-fields #' + $trId).remove();
|
||||
const $url = $('#dialogDeleteSpecifiedCredentialFields').data('url');
|
||||
const $trId = $('#dialogDeleteSpecifiedCredentialFields').data('tr-id');
|
||||
$('#tab-specified-fields #' + $trId).remove();
|
||||
|
||||
delete options.settings['defined-credential-fields'][$url];
|
||||
options.saveSettings();
|
||||
delete options.settings['defined-credential-fields'][$url];
|
||||
options.saveSettings();
|
||||
|
||||
if ($('#tab-specified-fields table tbody:first tr').length > 2) {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').show();
|
||||
}
|
||||
});
|
||||
if ($('#tab-specified-fields table tbody:first tr').length > 2) {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').show();
|
||||
}
|
||||
});
|
||||
|
||||
const $trClone = $('#tab-specified-fields table tr.clone:first').clone(true);
|
||||
$trClone.removeClass('clone');
|
||||
let counter = 1;
|
||||
for (let url in options.settings['defined-credential-fields']) {
|
||||
const $tr = $trClone.clone(true);
|
||||
$tr.data('url', url);
|
||||
$tr.attr('id', 'tr-scf' + counter);
|
||||
counter += 1;
|
||||
const $trClone = $('#tab-specified-fields table tr.clone:first').clone(true);
|
||||
$trClone.removeClass('clone');
|
||||
let counter = 1;
|
||||
for (let url in options.settings['defined-credential-fields']) {
|
||||
const $tr = $trClone.clone(true);
|
||||
$tr.data('url', url);
|
||||
$tr.attr('id', 'tr-scf' + counter);
|
||||
counter += 1;
|
||||
|
||||
$tr.children('td:first').text(url);
|
||||
$('#tab-specified-fields table tbody:first').append($tr);
|
||||
}
|
||||
$tr.children('td:first').text(url);
|
||||
$('#tab-specified-fields table tbody:first').append($tr);
|
||||
}
|
||||
|
||||
if ($('#tab-specified-fields table tbody:first tr').length > 2) {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').show();
|
||||
}
|
||||
if ($('#tab-specified-fields table tbody:first tr').length > 2) {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').hide();
|
||||
}
|
||||
else {
|
||||
$('#tab-specified-fields table tbody:first tr.empty:first').show();
|
||||
}
|
||||
};
|
||||
|
||||
options.initAbout = function() {
|
||||
$('#tab-about em.versionCIP').text(browser.runtime.getManifest().version);
|
||||
if (isFirefox()) {
|
||||
$('#chrome-only').remove();
|
||||
}
|
||||
$('#tab-about em.versionCIP').text(browser.runtime.getManifest().version);
|
||||
if (isFirefox()) {
|
||||
$('#chrome-only').remove();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,74 +1,75 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
min-width: 440px;
|
||||
max-width: 440px;
|
||||
overflow-x: hidden;
|
||||
background-color: #eee;
|
||||
font-size: 15px;
|
||||
padding: 8px;
|
||||
font-family: sans-serif;
|
||||
min-width: 440px;
|
||||
max-width: 440px;
|
||||
overflow-x: hidden;
|
||||
background-color: #eee;
|
||||
font-size: 15px;
|
||||
padding: 8px;
|
||||
}
|
||||
.credentials ul {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
list-style-position: inside;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
list-style-position: inside;
|
||||
}
|
||||
.credentials li {
|
||||
list-style: none;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
margin-left: 10px;
|
||||
margin-right: 5px;
|
||||
list-style: none;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
margin-left: 10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.credentials a {
|
||||
color: #333;
|
||||
color: #333;
|
||||
}
|
||||
.credentials a:hover {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
.credentials li:hover {
|
||||
cursor: pointer;
|
||||
background: #ddd;
|
||||
cursor: pointer;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.settings {
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #333;
|
||||
font-size: 90%;
|
||||
text-align: left;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #333;
|
||||
font-size: 90%;
|
||||
text-align: left;
|
||||
}
|
||||
.settings label {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
.settings label input {
|
||||
vertical-align: middle;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.settings .description {
|
||||
margin-top: 3px;
|
||||
font-size: 80%;
|
||||
color: #787878;
|
||||
margin-top: 3px;
|
||||
font-size: 80%;
|
||||
color: #787878;
|
||||
}
|
||||
.small {
|
||||
margin-top: 3px;
|
||||
margin-left: 12px;
|
||||
font-size: 80%;
|
||||
color: #787878;
|
||||
margin-top: 3px;
|
||||
margin-left: 12px;
|
||||
font-size: 80%;
|
||||
color: #787878;
|
||||
}
|
||||
#update-available {
|
||||
padding-top: 10px;
|
||||
margin-top: 10px;
|
||||
padding-bottom: 0px;
|
||||
margin-bottom: 0px;
|
||||
text-align: left;
|
||||
padding-top: 10px;
|
||||
margin-top: 10px;
|
||||
padding-bottom: 0px;
|
||||
margin-bottom: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
#update-available a:hover,
|
||||
#update-available a:active {
|
||||
text-decoration: underline;
|
||||
text-decoration: underline;
|
||||
}
|
||||
#lock-database-button {
|
||||
float: right;
|
||||
float: right;
|
||||
height: 30px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,99 +1,99 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>KeePassXC - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.2.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js" /></script>
|
||||
<script type="text/javascript" src="popup.js" /></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
<head>
|
||||
<title>KeePassXC - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js" /></script>
|
||||
<script type="text/javascript" src="popup.js" /></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="initial-state">
|
||||
<p><img style="margin-right: 1em" src="throbber.gif"/> Checking status...</p>
|
||||
</div>
|
||||
<div id="initial-state">
|
||||
<p><img style="margin-right: 1em" src="throbber.gif"/> Checking status...</p>
|
||||
</div>
|
||||
|
||||
<div id="not-configured" style="display: none">
|
||||
<p>
|
||||
keepassxc-browser has not been configured.
|
||||
Press the connect button to register and pair with KeePassXC.
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="connect-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-link"></span> Connect</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="not-configured" style="display: none">
|
||||
<p>
|
||||
KeePassXC-Browser has not been configured.
|
||||
Press the connect button to register and pair with KeePassXC.
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="connect-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-link"></span> Connect</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="need-reconfigure" style="display: none">
|
||||
<p>
|
||||
keepassxc-browser has been disconnected from KeePassXC.
|
||||
</p>
|
||||
<code id="need-reconfigure-message"></code>
|
||||
<p>
|
||||
Press the reconnect button to establish a new connection.
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="reconnect-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-refresh"></span> Reconnect</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="need-reconfigure" style="display: none">
|
||||
<p>
|
||||
KeePassXC-Browser has been disconnected from KeePassXC.
|
||||
</p>
|
||||
<code id="need-reconfigure-message"></code>
|
||||
<p>
|
||||
Press the reconnect button to establish a new connection.
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="reconnect-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-refresh"></span> Reconnect</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="configured-not-associated" style="display: none">
|
||||
<p>
|
||||
keepassxc-browser has been configured using the identifier
|
||||
<em id="unassociated-identifier"></em> and has not yet
|
||||
connected to KeePassXC.
|
||||
</p>
|
||||
</div>
|
||||
<div id="configured-not-associated" style="display: none">
|
||||
<p>
|
||||
KeePassXC-Browser has been configured using the identifier
|
||||
<em id="unassociated-identifier"></em> and has not yet
|
||||
connected to KeePassXC.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="configured-and-associated" style="display: none">
|
||||
<p>
|
||||
keepassxc-browser has been configured using the identifier
|
||||
"<em id="associated-identifier"></em>" and is successfully
|
||||
connected to KeePassXC.
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="redetect-fields-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-list-alt"></span> Redetect credential fields</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="configured-and-associated" style="display: none">
|
||||
<p>
|
||||
KeePassXC-Browser has been configured using the identifier
|
||||
"<em id="associated-identifier"></em>" and is successfully
|
||||
connected to KeePassXC.
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="redetect-fields-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-list-alt"></span> Redetect credential fields</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="error-encountered" style="display: none">
|
||||
<p>
|
||||
keepassxc-browser has encountered an error:
|
||||
</p>
|
||||
<p style="margin-left: 1em">
|
||||
<code id="error-message"></code>
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="reload-status-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-refresh"></span> Reload</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="error-encountered" style="display: none">
|
||||
<p>
|
||||
KeePassXC-Browser has encountered an error:
|
||||
</p>
|
||||
<p style="margin-left: 1em">
|
||||
<code id="error-message"></code>
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="reload-status-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-refresh"></span> Reload</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="database-not-opened" style="display: none">
|
||||
<p>
|
||||
keepassxc-browser has encountered an error:
|
||||
</p>
|
||||
<p style="margin-left: 1em">
|
||||
<code id="database-error-message"></code>
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="reopen-database-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-lock"></span> Reopen database</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<div id="database-not-opened" style="display: none">
|
||||
<p>
|
||||
KeePassXC-Browser has encountered an error:
|
||||
</p>
|
||||
<p style="margin-left: 1em">
|
||||
<code id="database-error-message"></code>
|
||||
</p>
|
||||
<div style="text-align: right">
|
||||
<button id="reopen-database-button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-lock"></span> Reopen database</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,88 +1,90 @@
|
|||
function status_response(r) {
|
||||
$('#initial-state').hide();
|
||||
$('#error-encountered').hide();
|
||||
$('#need-reconfigure').hide();
|
||||
$('#not-configured').hide();
|
||||
$('#configured-and-associated').hide();
|
||||
$('#configured-not-associated').hide();
|
||||
$('#lock-database-button').hide();
|
||||
$('#initial-state').hide();
|
||||
$('#error-encountered').hide();
|
||||
$('#need-reconfigure').hide();
|
||||
$('#not-configured').hide();
|
||||
$('#configured-and-associated').hide();
|
||||
$('#configured-not-associated').hide();
|
||||
$('#lock-database-button').hide();
|
||||
|
||||
if (!r.keePassXCAvailable) {
|
||||
$('#error-message').html(r.error);
|
||||
$('#error-encountered').show();
|
||||
}
|
||||
else if (r.keePassXCAvailable && r.databaseClosed) {
|
||||
$('#database-error-message').html(r.error);
|
||||
$('#database-not-opened').show();
|
||||
}
|
||||
else if (!r.configured) {
|
||||
$('#not-configured').show();
|
||||
}
|
||||
else if (r.encryptionKeyUnrecognized) {
|
||||
$('#need-reconfigure').show();
|
||||
$('#need-reconfigure-message').html(r.error);
|
||||
}
|
||||
else if (!r.associated) {
|
||||
$('#need-reconfigure').show();
|
||||
$('#need-reconfigure-message').html(r.error);
|
||||
}
|
||||
else if (r.error !== null) {
|
||||
$('#error-encountered').show();
|
||||
$('#error-message').html(r.error);
|
||||
}
|
||||
else {
|
||||
$('#configured-and-associated').show();
|
||||
$('#associated-identifier').html(r.identifier);
|
||||
$('#lock-database-button').show();
|
||||
}
|
||||
if (!r.keePassXCAvailable) {
|
||||
$('#error-message').html(r.error);
|
||||
$('#error-encountered').show();
|
||||
}
|
||||
else if (r.keePassXCAvailable && r.databaseClosed) {
|
||||
$('#database-error-message').html(r.error);
|
||||
$('#database-not-opened').show();
|
||||
}
|
||||
else if (!r.configured) {
|
||||
$('#not-configured').show();
|
||||
}
|
||||
else if (r.encryptionKeyUnrecognized) {
|
||||
$('#need-reconfigure').show();
|
||||
$('#need-reconfigure-message').html(r.error);
|
||||
}
|
||||
else if (!r.associated) {
|
||||
$('#need-reconfigure').show();
|
||||
$('#need-reconfigure-message').html(r.error);
|
||||
}
|
||||
else if (r.error !== null) {
|
||||
$('#error-encountered').show();
|
||||
$('#error-message').html(r.error);
|
||||
}
|
||||
else {
|
||||
$('#configured-and-associated').show();
|
||||
$('#associated-identifier').html(r.identifier);
|
||||
$('#lock-database-button').show();
|
||||
}
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('#connect-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'associate'
|
||||
});
|
||||
close();
|
||||
});
|
||||
$('#connect-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'associate'
|
||||
});
|
||||
close();
|
||||
});
|
||||
|
||||
$('#reconnect-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'associate'
|
||||
});
|
||||
close();
|
||||
});
|
||||
$('#reconnect-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'associate'
|
||||
});
|
||||
close();
|
||||
});
|
||||
|
||||
$('#reload-status-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'reconnect'
|
||||
}).then(status_response);
|
||||
});
|
||||
$('#reload-status-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'reconnect'
|
||||
}).then(status_response);
|
||||
});
|
||||
|
||||
$('#reopen-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_status'
|
||||
}).then(status_response);
|
||||
});
|
||||
$('#reopen-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_status',
|
||||
args: [ false, true ] // Set forcePopup to true
|
||||
}).then(status_response);
|
||||
});
|
||||
|
||||
$('#redetect-fields-button').click(function() {
|
||||
browser.tabs.query({"active": true, "currentWindow": true}).then(function(tabs) {
|
||||
if (tabs.length === 0)
|
||||
return; // For example: only the background devtools or a popup are opened
|
||||
let tab = tabs[0];
|
||||
$('#redetect-fields-button').click(function() {
|
||||
browser.tabs.query({"active": true, "currentWindow": true}).then(function(tabs) {
|
||||
if (tabs.length === 0) {
|
||||
return; // For example: only the background devtools or a popup are opened
|
||||
}
|
||||
let tab = tabs[0];
|
||||
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'redetect_fields'
|
||||
});
|
||||
});
|
||||
});
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'redetect_fields'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$('#lock-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'lock-database'
|
||||
}).then(status_response);
|
||||
});
|
||||
$('#lock-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'lock-database'
|
||||
}).then(status_response);
|
||||
});
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
action: "get_status"
|
||||
}).then(status_response);
|
||||
browser.runtime.sendMessage({
|
||||
action: "get_status"
|
||||
}).then(status_response);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,34 +1,34 @@
|
|||
var $ = jQuery.noConflict(true);
|
||||
|
||||
function updateAvailableResponse(available) {
|
||||
if (available) {
|
||||
$('#update-available').show();
|
||||
}
|
||||
else {
|
||||
$('#update-available').hide();
|
||||
}
|
||||
if (available) {
|
||||
$('#update-available').show();
|
||||
}
|
||||
else {
|
||||
$('#update-available').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function initSettings() {
|
||||
$ ('#settings #btn-options').click(function() {
|
||||
browser.runtime.openOptionsPage().then(close());
|
||||
});
|
||||
$('#settings #btn-options').click(function() {
|
||||
browser.runtime.openOptionsPage().then(close());
|
||||
});
|
||||
|
||||
$ ('#settings #btn-choose-credential-fields').click(function() {
|
||||
browser.runtime.getBackgroundPage().then((global) => {
|
||||
browser.tabs.sendMessage(global.page.currentTabId, {
|
||||
action: 'choose_credential_fields'
|
||||
});
|
||||
close();
|
||||
});
|
||||
});
|
||||
$('#settings #btn-choose-credential-fields').click(function() {
|
||||
browser.runtime.getBackgroundPage().then((global) => {
|
||||
browser.tabs.sendMessage(global.page.currentTabId, {
|
||||
action: 'choose_credential_fields'
|
||||
});
|
||||
close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(function() {
|
||||
initSettings();
|
||||
initSettings();
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
action: 'update_available_keepassxc'
|
||||
}).then(updateAvailableResponse);
|
||||
browser.runtime.sendMessage({
|
||||
action: 'update_available_keepassxc'
|
||||
}).then(updateAvailableResponse);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>keepassxc-browser - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.2.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
<script type="text/javascript" src="popup_httpauth.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
<head>
|
||||
<title>KeePassXC-Browser - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
<script type="text/javascript" src="popup_httpauth.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="credentials">
|
||||
<p>
|
||||
Select the login information you would like to get logged in with:
|
||||
</p>
|
||||
<ul id="login-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<div class="credentials">
|
||||
<p>
|
||||
Select the login information you would like to get logged in with:
|
||||
</p>
|
||||
<ul id="login-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
$(function() {
|
||||
browser.runtime.getBackgroundPage().then((global) => {
|
||||
browser.tabs.query({'active': true, 'currentWindow': true}).then((tabs) => {
|
||||
let tab = tabs[0];
|
||||
const data = global.page.tabs[tab.id].loginList;
|
||||
let ul = document.getElementById('login-list');
|
||||
for (let i = 0; i < data.logins.length; i++) {
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
a.textContent = data.logins[i].login + " (" + data.logins[i].name + ")";
|
||||
li.appendChild(a);
|
||||
$(a).data('creds', data.logins[i]);
|
||||
$(a).click(function () {
|
||||
if (data.resolve) {
|
||||
const creds = $(this).data('creds');
|
||||
data.resolve({
|
||||
authCredentials: {
|
||||
username: creds.login,
|
||||
password: creds.password
|
||||
}
|
||||
});
|
||||
}
|
||||
close();
|
||||
});
|
||||
ul.appendChild(li);
|
||||
}
|
||||
});
|
||||
});
|
||||
browser.runtime.getBackgroundPage().then((global) => {
|
||||
browser.tabs.query({'active': true, 'currentWindow': true}).then((tabs) => {
|
||||
let tab = tabs[0];
|
||||
const data = global.page.tabs[tab.id].loginList;
|
||||
let ul = document.getElementById('login-list');
|
||||
for (let i = 0; i < data.logins.length; i++) {
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
a.textContent = data.logins[i].login + " (" + data.logins[i].name + ")";
|
||||
li.appendChild(a);
|
||||
$(a).data('creds', data.logins[i]);
|
||||
$(a).click(function () {
|
||||
if (data.resolve) {
|
||||
const creds = $(this).data('creds');
|
||||
data.resolve({
|
||||
authCredentials: {
|
||||
username: creds.login,
|
||||
password: creds.password
|
||||
}
|
||||
});
|
||||
}
|
||||
close();
|
||||
});
|
||||
ul.appendChild(li);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#lock-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'lock-database'
|
||||
}).then(status_response);
|
||||
$('#lock-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'lock-database'
|
||||
}).then(status_response);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>KeePassXC - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.2.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
<script type="text/javascript" src="popup_login.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
<head>
|
||||
<title>KeePassXC - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
<script type="text/javascript" src="popup_login.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="credentials">
|
||||
<p>
|
||||
Select the login information you would like to get entered into the page:
|
||||
</p>
|
||||
<ul id="login-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<div class="credentials">
|
||||
<p>
|
||||
Select the login information you would like to get entered into the page:
|
||||
</p>
|
||||
<ul id="login-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
$(function() {
|
||||
browser.runtime.getBackgroundPage().then((global) => {
|
||||
browser.tabs.query({"active": true, "currentWindow": true}).then((tabs) => {
|
||||
if (tabs.length === 0) {
|
||||
return; // For example: only the background devtools or a popup are opened
|
||||
}
|
||||
const tab = tabs[0];
|
||||
browser.runtime.getBackgroundPage().then((global) => {
|
||||
browser.tabs.query({'active': true, 'currentWindow': true}).then((tabs) => {
|
||||
if (tabs.length === 0) {
|
||||
return; // For example: only the background devtools or a popup are opened
|
||||
}
|
||||
const tab = tabs[0];
|
||||
|
||||
const logins = global.page.tabs[tab.id].loginList;
|
||||
let ul = document.getElementById('login-list');
|
||||
for (let i = 0; i < logins.length; i++) {
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
a.textContent = logins[i];
|
||||
li.setAttribute('class', 'list-group-item');
|
||||
li.appendChild(a);
|
||||
a.setAttribute('id', '' + i);
|
||||
a.addEventListener('click', (e) => {
|
||||
const id = e.target.id;
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'fill_user_pass_with_specific_login',
|
||||
id: id
|
||||
});
|
||||
close();
|
||||
});
|
||||
ul.appendChild(li);
|
||||
}
|
||||
});
|
||||
});
|
||||
const logins = global.page.tabs[tab.id].loginList;
|
||||
let ul = document.getElementById('login-list');
|
||||
for (let i = 0; i < logins.length; i++) {
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
a.textContent = logins[i];
|
||||
li.setAttribute('class', 'list-group-item');
|
||||
li.appendChild(a);
|
||||
a.setAttribute('id', '' + i);
|
||||
a.addEventListener('click', (e) => {
|
||||
const id = e.target.id;
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'fill_user_pass_with_specific_login',
|
||||
id: id
|
||||
});
|
||||
close();
|
||||
});
|
||||
ul.appendChild(li);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#lock-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'lock-database'
|
||||
});
|
||||
});
|
||||
$('#lock-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'lock-database'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>keepassxc-browser - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.2.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
<head>
|
||||
<title>KeePassXC-Browser - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="settings" class="settings">
|
||||
<button id="btn-options" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-cog"></span> Settings</button>
|
||||
<button id="btn-choose-credential-fields" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-list-alt"></span> Choose own credential fields for this page</button>
|
||||
<button id="lock-database-button" class="btn btn-danger" title="Lock database"><span class="glyphicon glyphicon-lock"></span></button>
|
||||
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
keepassxc-browser found more than one password field on this page. To enter your
|
||||
logins, right-click on one of the password fields, and choose either the
|
||||
"<code>Fill User + Pass</code>" or "<code>Fill Pass Only</code>" command.
|
||||
</p>
|
||||
</div>
|
||||
<div id="update-available" class="alert alert-danger">
|
||||
You use an old version of KeePassXC.
|
||||
<br />
|
||||
<a target="_blank" class="alert-link" href="https://keepassxc.org/download">Please download the latest version from keepassxc.org</a>.
|
||||
</div>
|
||||
</body>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
KeePassXC-Browser found more than one password field on this page. To enter your
|
||||
logins, right-click on one of the password fields, and choose either the
|
||||
"<code>Fill User + Pass</code>" or "<code>Fill Pass Only</code>" command.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,51 +1,51 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>keepassxc-browser - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.2.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
<script type="text/javascript" src="popup_remember.js"></script>
|
||||
<style type="text/css">
|
||||
.credentials {display: none; border-top: 1px solid #333;}
|
||||
.connected-database {display: none; font-size: 85%; color: #787878;}
|
||||
.credentials .username-new {display: none;}
|
||||
.credentials .username-exists {display: none;}
|
||||
.small { font-weight: bold; }
|
||||
.small .normal { font-weight: normal; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="buttons">
|
||||
<p>
|
||||
Username or password changed! Save it?
|
||||
<br />
|
||||
<span class="small information-url">Url: <span class="normal"></span></span>
|
||||
<br />
|
||||
<span class="small information-username">Username: <span class="normal"></span></span>
|
||||
</p>
|
||||
<p>
|
||||
<button id="btn-new" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-pencil"></span> New</button>
|
||||
<button id="btn-update" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-refresh"></span> Update</button>
|
||||
<button id="btn-dismiss" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove"></span> Dismiss</button>
|
||||
</p>
|
||||
</div>
|
||||
<head>
|
||||
<title>KeePassXC-Browser - Popup</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="../options/bootstrap.min.css" />
|
||||
<script type="text/javascript" src="../browser-polyfill.min.js"></script>
|
||||
<script type="text/javascript" src="../global.js"></script>
|
||||
<script type="text/javascript" src="../jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="../options/bootstrap.min.js" /></script>
|
||||
<script type="text/javascript" src="popup_functions.js"></script>
|
||||
<script type="text/javascript" src="popup_remember.js"></script>
|
||||
<style type="text/css">
|
||||
.credentials {display: none; border-top: 1px solid #333;}
|
||||
.connected-database {display: none; font-size: 85%; color: #787878;}
|
||||
.credentials .username-new {display: none;}
|
||||
.credentials .username-exists {display: none;}
|
||||
.small { font-weight: bold; }
|
||||
.small .normal { font-weight: normal; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="buttons">
|
||||
<p>
|
||||
Username or password changed! Save it?
|
||||
<br />
|
||||
<span class="small information-url">Url: <span class="normal"></span></span>
|
||||
<br />
|
||||
<span class="small information-username">Username: <span class="normal"></span></span>
|
||||
</p>
|
||||
<p>
|
||||
<button id="btn-new" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-pencil"></span> New</button>
|
||||
<button id="btn-update" class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-refresh"></span> Update</button>
|
||||
<button id="btn-dismiss" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove"></span> Dismiss</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="connected-database">
|
||||
<p>Credentials will be saved in connected database with identifier <em></em>.</p>
|
||||
</div>
|
||||
<div class="connected-database">
|
||||
<p>Credentials will be saved in connected database with identifier <em></em>.</p>
|
||||
</div>
|
||||
|
||||
<div class="credentials">
|
||||
<p class="username-new">The used username <strong></strong> is currently not saved!</p>
|
||||
<p class="username-exists">The credentials with the used username <strong></strong> are marked bold.</p>
|
||||
<p>
|
||||
Please choose the credentials you want to update:
|
||||
</p>
|
||||
<ul id="list"></ul>
|
||||
</div>
|
||||
</body>
|
||||
<div class="credentials">
|
||||
<p class="username-new">The used username <strong></strong> is currently not saved!</p>
|
||||
<p class="username-exists">The credentials with the used username <strong></strong> are marked bold.</p>
|
||||
<p>
|
||||
Please choose the credentials you want to update:
|
||||
</p>
|
||||
<ul id="list"></ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,124 +1,124 @@
|
|||
var _tab;
|
||||
|
||||
function _initialize(tab) {
|
||||
_tab = tab;
|
||||
_tab = tab;
|
||||
|
||||
// no credentials set or credentials already cleared
|
||||
if (!_tab.credentials.username) {
|
||||
_close();
|
||||
return;
|
||||
}
|
||||
// no credentials set or credentials already cleared
|
||||
if (!_tab.credentials.username) {
|
||||
_close();
|
||||
return;
|
||||
}
|
||||
|
||||
// no existing credentials to update --> disable update-button
|
||||
if (_tab.credentials.list.length === 0) {
|
||||
$('#btn-update').attr('disabled', true).removeClass('btn-warning');
|
||||
}
|
||||
// no existing credentials to update --> disable update-button
|
||||
if (_tab.credentials.list.length === 0) {
|
||||
$('#btn-update').attr('disabled', true).removeClass('btn-warning');
|
||||
}
|
||||
|
||||
let url = _tab.credentials.url;
|
||||
url = (url.length > 50) ? url.substring(0, 50) + '...' : url;
|
||||
$('.information-url:first span:first').text(url);
|
||||
$('.information-username:first span:first').text(_tab.credentials.username);
|
||||
let url = _tab.credentials.url;
|
||||
url = (url.length > 50) ? url.substring(0, 50) + '...' : url;
|
||||
$('.information-url:first span:first').text(url);
|
||||
$('.information-username:first span:first').text(_tab.credentials.username);
|
||||
|
||||
$('#btn-new').click(function(e) {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'add_credentials',
|
||||
args: [_tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
|
||||
}).then(_verifyResult);
|
||||
});
|
||||
$('#btn-new').click(function(e) {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'add_credentials',
|
||||
args: [_tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
|
||||
}).then(_verifyResult);
|
||||
});
|
||||
|
||||
$('#btn-update').click(function(e) {
|
||||
e.preventDefault();
|
||||
$('#btn-update').click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// only one entry which could be updated
|
||||
if(_tab.credentials.list.length === 1) {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'update_credentials',
|
||||
args: [_tab.credentials.list[0].uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
|
||||
}).then(_verifyResult);
|
||||
}
|
||||
else {
|
||||
$('.credentials:first .username-new:first strong:first').text(_tab.credentials.username);
|
||||
$('.credentials:first .username-exists:first strong:first').text(_tab.credentials.username);
|
||||
// only one entry which could be updated
|
||||
if(_tab.credentials.list.length === 1) {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'update_credentials',
|
||||
args: [_tab.credentials.list[0].uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
|
||||
}).then(_verifyResult);
|
||||
}
|
||||
else {
|
||||
$('.credentials:first .username-new:first strong:first').text(_tab.credentials.username);
|
||||
$('.credentials:first .username-exists:first strong:first').text(_tab.credentials.username);
|
||||
|
||||
if (_tab.credentials.usernameExists) {
|
||||
$('.credentials:first .username-new:first').hide();
|
||||
$('.credentials:first .username-exists:first').show();
|
||||
}
|
||||
else {
|
||||
$('.credentials:first .username-new:first').show();
|
||||
$('.credentials:first .username-exists:first').hide();
|
||||
}
|
||||
if (_tab.credentials.usernameExists) {
|
||||
$('.credentials:first .username-new:first').hide();
|
||||
$('.credentials:first .username-exists:first').show();
|
||||
}
|
||||
else {
|
||||
$('.credentials:first .username-new:first').show();
|
||||
$('.credentials:first .username-exists:first').hide();
|
||||
}
|
||||
|
||||
for (let i = 0; i < _tab.credentials.list.length; i++) {
|
||||
let $a = $('<a>')
|
||||
.attr('href', '#')
|
||||
.text(_tab.credentials.list[i].login + ' (' + _tab.credentials.list[i].name + ')')
|
||||
.data('entryId', i)
|
||||
.click(function(e) {
|
||||
e.preventDefault();
|
||||
browser.runtime.sendMessage({
|
||||
action: 'update_credentials',
|
||||
args: [_tab.credentials.list[$(this).data('entryId')].uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
|
||||
}).then(_verifyResult);
|
||||
});
|
||||
for (let i = 0; i < _tab.credentials.list.length; i++) {
|
||||
let $a = $('<a>')
|
||||
.attr('href', '#')
|
||||
.text(_tab.credentials.list[i].login + ' (' + _tab.credentials.list[i].name + ')')
|
||||
.data('entryId', i)
|
||||
.click(function(e) {
|
||||
e.preventDefault();
|
||||
browser.runtime.sendMessage({
|
||||
action: 'update_credentials',
|
||||
args: [_tab.credentials.list[$(this).data('entryId')].uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
|
||||
}).then(_verifyResult);
|
||||
});
|
||||
|
||||
if (_tab.credentials.usernameExists && _tab.credentials.username === _tab.credentials.list[i].login) {
|
||||
$a.css('font-weight', 'bold');
|
||||
}
|
||||
if (_tab.credentials.usernameExists && _tab.credentials.username === _tab.credentials.list[i].login) {
|
||||
$a.css('font-weight', 'bold');
|
||||
}
|
||||
|
||||
const $li = $('<li class=\"list-group-item\">').append($a);
|
||||
$('ul#list').append($li);
|
||||
}
|
||||
const $li = $('<li class=\"list-group-item\">').append($a);
|
||||
$('ul#list').append($li);
|
||||
}
|
||||
|
||||
$('.credentials').show();
|
||||
}
|
||||
});
|
||||
$('.credentials').show();
|
||||
}
|
||||
});
|
||||
|
||||
$('#btn-dismiss').click(function(e) {
|
||||
e.preventDefault();
|
||||
_close();
|
||||
});
|
||||
$('#btn-dismiss').click(function(e) {
|
||||
e.preventDefault();
|
||||
_close();
|
||||
});
|
||||
}
|
||||
|
||||
function _connected_database(db) {
|
||||
if (db.count > 1 && db.identifier) {
|
||||
$('.connected-database:first em:first').text(db.identifier);
|
||||
$('.connected-database:first').show();
|
||||
}
|
||||
else {
|
||||
$('.connected-database:first').hide();
|
||||
}
|
||||
if (db.count > 1 && db.identifier) {
|
||||
$('.connected-database:first em:first').text(db.identifier);
|
||||
$('.connected-database:first').show();
|
||||
}
|
||||
else {
|
||||
$('.connected-database:first').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function _verifyResult(code) {
|
||||
if (code === 'success') {
|
||||
_close();
|
||||
}
|
||||
if (code === 'success') {
|
||||
_close();
|
||||
}
|
||||
}
|
||||
|
||||
function _close() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'remove_credentials_from_tab_information'
|
||||
});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'remove_credentials_from_tab_information'
|
||||
});
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
action: 'pop_stack'
|
||||
});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'pop_stack'
|
||||
});
|
||||
|
||||
close();
|
||||
close();
|
||||
}
|
||||
|
||||
$(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'stack_add',
|
||||
args: ['icon_remember_red_background_19x19.png', 'popup_remember.html', 10, true, 0]
|
||||
});
|
||||
browser.runtime.sendMessage({
|
||||
action: 'stack_add',
|
||||
args: ['icon_remember_red_background_19x19.png', 'popup_remember.html', 10, true, 0]
|
||||
});
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_tab_information'
|
||||
}).then(_initialize);
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_tab_information'
|
||||
}).then(_initialize);
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_connected_database'
|
||||
}).then(_connected_database);
|
||||
browser.runtime.sendMessage({
|
||||
action: 'get_connected_database'
|
||||
}).then(_connected_database);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue