From b1135c232d41cd260d4ddeb1732db11129a40134 Mon Sep 17 00:00:00 2001
From: varjolintu
Date: Sat, 2 Sep 2017 13:12:36 +0300
Subject: [PATCH] Added browser-polyfill, merged changes from latest passifox,
fixed HTTP auth
---
CHANGELOG | 7 ++
README.md | 39 +---------
keepassxc-browser/background/browserAction.js | 64 ++++++++--------
keepassxc-browser/background/event.js | 38 +++++-----
keepassxc-browser/background/httpauth.js | 51 +++++++++----
keepassxc-browser/background/init.js | 47 +++++++++---
keepassxc-browser/background/keepass.js | 48 +++++++-----
keepassxc-browser/background/page.js | 74 ++++++++++++-------
keepassxc-browser/browser-polyfill.min.js | 9 +++
keepassxc-browser/global.js | 6 +-
keepassxc-browser/keepassxc-browser.js | 26 +++----
keepassxc-browser/manifest.json | 9 ++-
keepassxc-browser/options/options.html | 3 +-
keepassxc-browser/options/options.js | 72 +++++++++---------
keepassxc-browser/popups/popup.html | 1 +
keepassxc-browser/popups/popup.js | 9 +--
keepassxc-browser/popups/popup_functions.js | 9 +--
keepassxc-browser/popups/popup_httpauth.html | 5 +-
keepassxc-browser/popups/popup_httpauth.js | 4 +-
keepassxc-browser/popups/popup_login.html | 5 +-
keepassxc-browser/popups/popup_login.js | 6 +-
.../popups/popup_multiple-fields.html | 1 +
keepassxc-browser/popups/popup_remember.html | 1 +
keepassxc-browser/popups/popup_remember.js | 10 +--
24 files changed, 311 insertions(+), 233 deletions(-)
create mode 100644 keepassxc-browser/browser-polyfill.min.js
diff --git a/CHANGELOG b/CHANGELOG
index adf145c..31eaa61 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+0.3.0 (2017-??-??)
+=========================
+- Added Mozilla's browser-polyfill
+- Merged changes from the latest passifox (credits to smorks):
+- HTTP auth works with all browsers
+- TODO: Automatic detectal of div's with forms that are non-hidden by user interaction
+
0.2.9 (2017-08-27)
=========================
- Code cleaning, global functions moved to global.js
diff --git a/README.md b/README.md
index b65cfd0..be48651 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
Chrome 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 [projectgus'](https://github.com/projectgus/passifox) fork.
+Some changes merged also from [projectgus'](https://github.com/projectgus/passifox) and [smorks'](https://github.com/smorks/passifox) fork.
For testing purposes, please use following unofficial KeePassXC [release's](https://github.com/varjolintu/keepassxc/releases).
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).
@@ -269,41 +269,10 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
```
-The following quick method to determine which browser is used with API calls by [David Rousset](https://github.com/davrous):
-```javascript
-window.browser = (function () {
- return window.msBrowser ||
- window.browser ||
- window.chrome;
-})();
-```
-
-```
-MIT License
-
-Copyright (c) 2016 David Rousset
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-```
-
## Donations
Feel free to support this project:
- Donate via [PayPal](https://paypal.me/varjolintu)
-- Donate via Bitcoin: 1LHbD69CcmpLW5hjUXs2MGJhw3GxwqLdw3
\ No newline at end of file
+- Donate via Bitcoin: 1LHbD69CcmpLW5hjUXs2MGJhw3GxwqLdw3
+
+Also consider donating to [KeePassXC](https://flattr.com/submit/auto?fid=x7yqz0&url=https%3A%2F%2Fkeepassxc.org) and passifox teams [(1)](https://github.com/smorks/passifox),[(2)](https://github.com/projectgus/passifox),[(3)](https://github.com/pfn/passifox). They are doing great job.
\ No newline at end of file
diff --git a/keepassxc-browser/background/browserAction.js b/keepassxc-browser/background/browserAction.js
index 39fa94c..7c0dbfd 100644
--- a/keepassxc-browser/background/browserAction.js
+++ b/keepassxc-browser/background/browserAction.js
@@ -218,43 +218,45 @@ browserAction.removeRememberPopup = function(callback, tab, removeImmediately) {
};
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((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});
+ });
}
function getValueOrDefault(settings, key, defaultVal, min) {
diff --git a/keepassxc-browser/background/event.js b/keepassxc-browser/background/event.js
index 0a09842..eb3b40b 100644
--- a/keepassxc-browser/background/event.js
+++ b/keepassxc-browser/background/event.js
@@ -41,7 +41,7 @@ event.invoke = function(handler, callback, senderTabId, args, secondTime) {
// remove information from no longer existing tabs
page.removePageInformationFromNotExistingTabs();
- browser.tabs.get(senderTabId, (tab) => {
+ browser.tabs.get(senderTabId).then((tab) => {
if (!tab) {
return;
}
@@ -101,27 +101,32 @@ event.showStatus = function(configured, tab, callback) {
}
event.onLoadSettings = function(callback, tab) {
- page.settings = (typeof(localStorage.settings) === 'undefined') ? {} : JSON.parse(localStorage.settings);
+ browser.storage.local.get({'settings': {}}).then((item) => {
+ callback(item.settings);
+ }, (err) => {
+ console.log('error loading settings: ' + err);
+ });
}
event.onLoadKeyRing = function(callback, tab) {
- keepass.keyRing = (typeof(localStorage.keyRing) === 'undefined') ? {} : JSON.parse(localStorage.keyRing);
- if (keepass.isAssociated() && !keepass.keyRing[keepass.associated.hash]) {
- keepass.associated = {
- value: false,
- hash: null
- };
- }
-}
-
-event.onGetSettings = function(callback, tab) {
- event.onLoadSettings();
- callback({ data: page.settings });
+ 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);
+ });
}
event.onSaveSettings = function(callback, tab, settings) {
- localStorage.settings = JSON.stringify(settings);
- event.onLoadSettings();
+ browser.storage.local.set({'settings': settings}).then(function() {
+ event.onLoadSettings();
+ });
}
event.onGetStatus = function(callback, tab) {
@@ -237,7 +242,6 @@ event.messageHandlers = {
'check_update_keepassxc': event.onCheckUpdateKeePassXC,
'get_connected_database': event.onGetConnectedDatabase,
'get_keepassxc_versions': event.onGetKeePassXCVersions,
- 'get_settings': event.onGetSettings,
'get_status': event.onGetStatus,
'get_tab_information': event.onGetTabInformation,
'load_keyring': event.onLoadKeyRing,
diff --git a/keepassxc-browser/background/httpauth.js b/keepassxc-browser/background/httpauth.js
index 5c91eca..04f64e9 100644
--- a/keepassxc-browser/background/httpauth.js
+++ b/keepassxc-browser/background/httpauth.js
@@ -9,7 +9,21 @@ httpAuth.proxyUrl = null;
httpAuth.resolve = null;
httpAuth.reject = null;
-httpAuth.handleRequest = function (details, callback) {
+httpAuth.handleRequest = function(details) {
+ return new Promise((resolve, reject) => {
+ if (httpAuth.requestId == details.requestId || !page.tabs[details.tabId]) {
+ reject({});
+ }
+ else {
+ httpAuth.requestId = details.requestId;
+ httpAuth.resolve = resolve;
+ httpAuth.reject = reject;
+ httpAuth.processPendingCallbacks(details);
+ }
+ });
+}
+
+httpAuth.handleRequestChrome = function(details, callback) {
if (httpAuth.requestId == details.requestId || !page.tabs[details.tabId]) {
callback({});
}
@@ -21,12 +35,14 @@ httpAuth.handleRequest = function (details, callback) {
}
httpAuth.processPendingCallbacks = function(details) {
- httpAuth.callback = httpAuth.pendingCallbacks.pop();
+ if (!isFirefox) {
+ httpAuth.callback = httpAuth.pendingCallbacks.pop();
+ }
httpAuth.tabId = details.tabId;
httpAuth.url = details.url;
httpAuth.isProxy = details.isProxy;
- if (details.challenger){
+ if (details.challenger) {
httpAuth.proxyUrl = details.challenger.host;
}
@@ -35,8 +51,7 @@ httpAuth.processPendingCallbacks = function(details) {
// chrome.tabs.get(tabId, callback) <-- but what should callback be?
const url = (httpAuth.isProxy && httpAuth.proxyUrl) ? httpAuth.proxyUrl : httpAuth.url;
-
- keepass.retrieveCredentials(httpAuth.loginOrShowCredentials, { 'id' : details.tabId }, url, url, true);
+ keepass.retrieveCredentials(httpAuth.loginOrShowCredentials, { "id" : details.tabId }, url, url, true);
}
httpAuth.loginOrShowCredentials = function(logins) {
@@ -47,19 +62,29 @@ httpAuth.loginOrShowCredentials = function(logins) {
//generate popup-list for HTTP Auth usernames + descriptions
if (page.settings.autoFillAndSend) {
- httpAuth.callback({
- authCredentials: {
- username: logins[0].login,
- password: logins[0].password
- }
- });
+ if (isFirefox) {
+ httpAuth.resolve({
+ authCredentials: {
+ username: logins[0].login,
+ password: logins[0].password
+ }
+ });
+ }
+ else {
+ httpAuth.callback({
+ authCredentials: {
+ username: logins[0].login,
+ password: logins[0].password
+ }
+ });
+ }
}
else {
- httpAuth.callback({});
+ isFirefox ? httpAuth.reject({}) : httpAuth.callback({});
}
}
// no logins found
else {
- httpAuth.callback({});
+ isFirefox ? httpAuth.reject({}) : httpAuth.callback({});
}
}
\ No newline at end of file
diff --git a/keepassxc-browser/background/init.js b/keepassxc-browser/background/init.js
index 3f94f04..e9ee7e4 100644
--- a/keepassxc-browser/background/init.js
+++ b/keepassxc-browser/background/init.js
@@ -1,3 +1,4 @@
+/*
keepass.convertKeyToKeyRing();
page.initSettings();
page.initOpenedTabs();
@@ -6,12 +7,30 @@ keepass.generateNewKeyPair();
keepass.changePublicKeys(null, (pkRes) => {
keepass.getDatabaseHash((gdRes) => {}, null);
});
+*/
-// Set initial tab-ID
-browser.tabs.query({"active": true, "currentWindow": true}, (tabs) => {
- if (tabs.length === 0)
- return; // For example: only the background devtools or a popup are opened
- page.currentTabId = tabs[0].id;
+// since version 2.0 the extension is using a keyRing instead of a single key-name-pair
+keepass.migrateKeyRing().then(() => {
+ // load settings
+ page.initSettings().then(() => {
+ // initial connection with KeePassHttp
+ keepass.connectToNative();
+ keepass.generateNewKeyPair();
+ keepass.changePublicKeys(null, (pkRes) => {
+ keepass.getDatabaseHash((gdRes) => {
+ // create tab information structure for every opened tab
+ page.initOpenedTabs();
+
+ // set initial tab-ID
+ 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
+ page.currentTabId = tabs[0].id;
+ browserAction.show(null, tabs[0]);
+ });
+ }, null);
+ });
+ });
});
// Milliseconds for intervall (e.g. to update browserAction)
@@ -55,8 +74,7 @@ browser.tabs.onActivated.addListener((activeInfo) => {
page.clearCredentials(page.currentTabId, true);
browserAction.removeRememberPopup(null, {'id': page.currentTabId}, true);
- browser.tabs.get(activeInfo.tabId, (info) => {
- //console.log(info.id + ': ' + info.url);
+ browser.tabs.get(activeInfo.tabId).then((info) => {
if (info && info.id) {
page.currentTabId = info.id;
if (info.status === 'complete') {
@@ -79,9 +97,16 @@ browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
});
// Retrieve Credentials and try auto-login for HTTPAuth requests
-browser.webRequest.onAuthRequired.addListener(httpAuth.handleRequest,
- { urls: [''] }, ['asyncBlocking']
-);
+if (browser.webRequest.onAuthRequired) {
+ if (isFirefox) {
+ browser.webRequest.onAuthRequired.addListener(httpAuth.handleRequest,
+ { urls: [""] }, ["blocking"]);
+ }
+ else {
+ browser.webRequest.onAuthRequired.addListener(httpAuth.handleRequestChrome,
+ { urls: [""] }, ["asyncBlocking"]);
+ }
+}
browser.runtime.onMessage.addListener(event.onMessage);
@@ -100,7 +125,7 @@ for (const item of contextMenuItems) {
onclick: (info, tab) => {
browser.tabs.sendMessage(tab.id, {
action: item.action
- });
+ }).catch((e) => {console.log(e);});
}
});
}
diff --git a/keepassxc-browser/background/keepass.js b/keepassxc-browser/background/keepass.js
index 8b0a662..506f15b 100644
--- a/keepassxc-browser/background/keepass.js
+++ b/keepassxc-browser/background/keepass.js
@@ -64,6 +64,14 @@ const kpErrors = {
}
};
+browser.storage.local.get({
+ 'latestKeePassXC': {'version': 0, 'versionParsed': 0, 'lastChecked': null},
+ 'keyRing': {}})
+ .then((item) => {
+ keepass.latestKeePassHttp = item.latestKeePassHttp;
+ keepass.keyRing = item.keyRing;
+});
+
keepass.addCredentials = function(callback, tab, username, password, url) {
keepass.updateCredentials(callback, tab, null, username, password, url);
}
@@ -551,23 +559,29 @@ keepass.isAssociated = function() {
return (keepass.associated.value && keepass.associated.hash && keepass.associated.hash === keepass.databaseHash);
}
-keepass.convertKeyToKeyRing = function() {
- if (keepass.keyId in localStorage && keepass.keyBody in localStorage && !('keyRing' in localStorage)) {
- keepass.getDatabaseHash((hash) => {
- keepass.saveKey(hash, localStorage[keepass.keyId], localStorage[keepass.keyBody]);
-
+keepass.migrateKeyRing = () => {
+ return new Promise((resolve, reject) => {
+ browser.storage.local.get('keyRing').then((item) => {
+ var keyring = item.keyRing;
if ('keyRing' in localStorage) {
+ if (!keyring) {
+ keyring = JSON.parse(localStorage['keyRing']);
+ browser.storage.local.set({'keyRing': keyring});
+ }
+ delete localStorage['keyRing'];
+ }
+ if (keepass.keyId in localStorage && keepass.keyBody in localStorage) {
+ if (!keyring) {
+ var hash = keepass.getDatabaseHash(null);
+ keepass.saveKey(hash, localStorage[keepass.keyId], localStorage[keepass.keyBody]);
+ }
delete localStorage[keepass.keyId];
delete localStorage[keepass.keyBody];
}
- }, null);
- }
-
- if ('keyRing' in localStorage) {
- delete localStorage[keepass.keyId];
- delete localStorage[keepass.keyBody];
- }
-}
+ resolve();
+ });
+ });
+};
keepass.saveKey = function(hash, id, key) {
if (!(hash in keepass.keyRing)) {
@@ -584,19 +598,19 @@ keepass.saveKey = function(hash, id, key) {
keepass.keyRing[hash].key = key;
keepass.keyRing[hash].hash = hash;
}
- localStorage.keyRing = JSON.stringify(keepass.keyRing);
+ browser.storage.local.set({'keyRing': keepass.keyRing});
}
keepass.updateLastUsed = function(hash) {
if ((hash in keepass.keyRing)) {
keepass.keyRing[hash].lastUsed = new Date();
- localStorage.keyRing = JSON.stringify(keepass.keyRing);
+ browser.storage.local.set({'keyRing': keepass.keyRing});
}
}
keepass.deleteKey = function(hash) {
delete keepass.keyRing[hash];
- localStorage.keyRing = JSON.stringify(keepass.keyRing);
+ browser.storage.local.set({'keyRing': keepass.keyRing});
}
keepass.setcurrentKeePassXCVersion = function(version) {
@@ -635,7 +649,7 @@ keepass.checkForNewKeePassXCVersion = function() {
}
if (version !== -1) {
- localStorage.latestKeePassXC = JSON.stringify(keepass.latestKeePassXC);
+ browser.storage.local.set({'latestKeePassXC': keepass.latestKeePassXC});
}
};
diff --git a/keepassxc-browser/background/page.js b/keepassxc-browser/background/page.js
index 0063dc0..1500c81 100644
--- a/keepassxc-browser/background/page.js
+++ b/keepassxc-browser/background/page.js
@@ -15,34 +15,56 @@ page.currentTabId = -1;
page.settings = (typeof(localStorage.settings) === 'undefined') ? {} : JSON.parse(localStorage.settings);
page.blockedTabs = {};
+page.migrateSettings = () => {
+ return new Promise((resolve, reject) => {
+ const old = localStorage.getItem('settings');
+ if (old) {
+ const settings = JSON.parse(old);
+ browser.storage.local.set({'settings': settings}).then(() => {
+ localStorage.removeItem('settings');
+ resolve(obj);
+ });
+ } else {
+ event.onLoadSettings((settings) => {
+ resolve(settings);
+ });
+ }
+ });
+};
+
page.initSettings = function() {
- event.onLoadSettings();
- 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 (!('port' in page.settings)) {
- page.settings.port = defaultSettings.proxyPort;
- }
- localStorage.settings = JSON.stringify(page.settings);
+ return new Promise((resolve, reject) => {
+ page.migrateSettings().then((settings) => {
+ page.settings = 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 (!('port' in page.settings)) {
+ page.settings.port = defaultSettings.proxyPort;
+ }
+ browser.storage.local.set({'settings': page.settings});
+ resolve();
+ });
+ });
}
page.initOpenedTabs = function() {
- browser.tabs.query({}, (tabs) => {
+ browser.tabs.query({}).then((tabs) => {
for (const i of tabs) {
page.createTabEntry(i.id);
}
@@ -57,7 +79,7 @@ page.isValidProtocol = function(url) {
page.switchTab = function(callback, tab) {
browserAction.showDefault(null, tab);
- browser.tabs.sendMessage(tab.id, {action: 'activated_tab'});
+ browser.tabs.sendMessage(tab.id, {action: 'activated_tab'}).catch((e) => {console.log(e);});
}
page.clearCredentials = function(tabId, complete) {
@@ -73,7 +95,7 @@ page.clearCredentials = function(tabId, complete) {
browser.tabs.sendMessage(tabId, {
action: 'clear_credentials'
- });
+ }).catch((e) => {console.log(e);});
}
}
diff --git a/keepassxc-browser/browser-polyfill.min.js b/keepassxc-browser/browser-polyfill.min.js
new file mode 100644
index 0000000..47125a6
--- /dev/null
+++ b/keepassxc-browser/browser-polyfill.min.js
@@ -0,0 +1,9 @@
+"use strict";if("undefined"==typeof browser){this.browser=(()=>{class c extends WeakMap{constructor(m,n=void 0){super(n),this.createItem=m}get(m){return this.has(m)||this.set(m,this.createItem(m)),super.get(m)}}const d=m=>{return m&&"object"==typeof m&&"function"==typeof m.then},e=m=>{return(...n)=>{chrome.runtime.lastError?m.reject(chrome.runtime.lastError):1===n.length?m.resolve(n[0]):m.resolve(n)}},f=(m,n)=>{const o=p=>1==p?"argument":"arguments";return function(q,...r){if(r.lengthn.maxArgs)throw new Error(`Expected at most ${n.maxArgs} ${o(n.maxArgs)} for ${m}(), got ${r.length}`);return new Promise((s,t)=>{q[m](...r,e({resolve:s,reject:t}))})}},g=(m,n,o)=>{return new Proxy(n,{apply(p,q,r){return o.call(q,m,...r)}})};let h=Function.call.bind(Object.prototype.hasOwnProperty);const i=(m,n={},o={})=>{let p=Object.create(null),q={has(r,s){return s in r||s in p},get(r,s){if(s in p)return p[s];if(s in r){let u=r[s];if("function"==typeof u){if("function"==typeof n[s])u=g(r,r[s],n[s]);else if(h(o,s)){let v=f(s,o[s]);u=g(r,r[s],v)}else u=u.bind(r);}else if("object"==typeof u&&null!==u&&(h(n,s)||h(o,s)))u=i(u,n[s],o[s]);else return Object.defineProperty(p,s,{configurable:!0,enumerable:!0,get(){return r[s]},set(v){r[s]=v}}),u;return p[s]=u,u}},set(r,s,t){return s in p?p[s]=t:r[s]=t,!0},defineProperty(r,s,t){return Reflect.defineProperty(p,s,t)},deleteProperty(r,s){return Reflect.deleteProperty(p,s)}};return new Proxy(m,q)},k=new c(m=>{return"function"==typeof m?function(o,p,q){let r=!1,s=m(o,p,function(t){r=!0,q(t)});return r||!0===s?s:d(s)?(s.then(q,t=>{console.error(t),q(t)}),!0):void(void 0!==s&&q(s))}:m}),l={runtime:{onMessage:(m=>({addListener(n,o,...p){n.addListener(m.get(o),...p)},hasListener(n,o){return n.hasListener(m.get(o))},removeListener(n,o){n.removeListener(m.get(o))}}))(k)}};return i(chrome,l,{alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},"export":{minArgs:0,maxArgs:0},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},getSubTree:{minArgs:1,maxArgs:1},"import":{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},setIcon:{minArgs:1,maxArgs:1}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{update:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},downloads:{download:{minArgs:1,maxArgs:1},cancel:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:0,maxArgs:0},setIcon:{minArgs:1,maxArgs:1},show:{minArgs:0,maxArgs:0}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getBrowserInfo:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{create:{minArgs:1,maxArgs:1},captureVisibleTab:{minArgs:0,maxArgs:2},detectLanguage:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},query:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}})})()}
+//# sourceMappingURL=browser-polyfill.min.js.map
+
+
+// webextension-polyfill v.0.1.0 (https://github.com/mozilla/webextension-polyfill)
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
\ No newline at end of file
diff --git a/keepassxc-browser/global.js b/keepassxc-browser/global.js
index 245478b..c6b5df2 100644
--- a/keepassxc-browser/global.js
+++ b/keepassxc-browser/global.js
@@ -1,6 +1,4 @@
var isFirefox = false;
-if (typeof browser !== 'undefined') {
+if (!(/Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor))) {
isFirefox = true;
-}
-
-window.browser = (function () { return window.msBrowser || window.browser || window.chrome; })();
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/keepassxc-browser/keepassxc-browser.js b/keepassxc-browser/keepassxc-browser.js
index a1927d4..77d387a 100644
--- a/keepassxc-browser/keepassxc-browser.js
+++ b/keepassxc-browser/keepassxc-browser.js
@@ -52,9 +52,9 @@ browser.runtime.onMessage.addListener(function(req, sender, callback) {
}
else if (req.action === 'redetect_fields') {
browser.runtime.sendMessage({
- action: 'get_settings',
- }, (response) => {
- cip.settings = response.data;
+ action: 'load_settings',
+ }).then((settings) => {
+ cip.settings = settings;
cip.initCredentialFields(true);
});
}
@@ -254,7 +254,7 @@ cipPassword.createDialog = function() {
e.preventDefault();
browser.runtime.sendMessage({
action: 'generate_password'
- }, cipPassword.callbackGeneratedPassword);
+ }).then(cipPassword.callbackGeneratedPassword);
}
},
'Copy':
@@ -419,7 +419,7 @@ cipPassword.callbackGeneratedPassword = function(entries) {
cipPassword.onRequestPassword = function() {
browser.runtime.sendMessage({
action: 'generate_password'
- }, cipPassword.callbackGeneratedPassword);
+ }).then(cipPassword.callbackGeneratedPassword);
}
cipPassword.checkObservedElements = function() {
@@ -1102,9 +1102,9 @@ jQuery(function() {
cip.init = function() {
browser.runtime.sendMessage({
- action: 'get_settings',
- }, (response) => {
- cip.settings = response.data;
+ action: 'load_settings',
+ }).then((settings) => {
+ cip.settings = settings;
cip.initCredentialFields();
});
}
@@ -1139,7 +1139,7 @@ cip.initCredentialFields = function(forceCall) {
browser.runtime.sendMessage({
action: 'retrieve_credentials',
args: [ cip.url, cip.submitUrl ]
- }, cip.retrieveCredentialsCallback);
+ }).then(cip.retrieveCredentialsCallback);
}
} // end function init
@@ -1160,11 +1160,11 @@ cip.receiveCredentialsIfNecessary = function () {
browser.runtime.sendMessage({
action: 'retrieve_credentials',
args: [ cip.url, cip.submitUrl ]
- }, cip.retrieveCredentialsCallback);
+ }).then(cip.retrieveCredentialsCallback);
}
}
-cip.retrieveCredentialsCallback = function (credentials, dontAutoFillIn) {
+cip.retrieveCredentialsCallback = function(credentials, dontAutoFillIn) {
if (cipFields.combinations.length > 0) {
cip.u = _f(cipFields.combinations[0].username);
cip.p = _f(cipFields.combinations[0].password);
@@ -1301,7 +1301,7 @@ cip.fillInCredentials = function(combination, onlyPassword, suppressWarnings) {
browser.runtime.sendMessage({
action: 'retrieve_credentials',
args: [ cip.url, cip.submitUrl, false, true ]
- }, (credentials) => {
+ }).then((credentials) => {
cip.retrieveCredentialsCallback(credentials, true);
cip.fillIn(combination, onlyPassword, suppressWarnings);
});
@@ -1692,6 +1692,6 @@ cipEvents.triggerActivatedTab = function() {
browser.runtime.sendMessage({
action: 'retrieve_credentials',
args: [ cip.url, cip.submitUrl ]
- }, cip.retrieveCredentialsCallback);
+ }).then(cip.retrieveCredentialsCallback);
}
}
diff --git a/keepassxc-browser/manifest.json b/keepassxc-browser/manifest.json
index 3dddae5..12882b8 100644
--- a/keepassxc-browser/manifest.json
+++ b/keepassxc-browser/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "keepassxc-browser",
- "version": "0.2.9",
+ "version": "0.3.0",
"description": "KeePassXC integration for modern web browsers",
"author": "Sami Vänttinen",
"icons": {
@@ -24,6 +24,7 @@
},
"background": {
"scripts": [
+ "browser-polyfill.min.js",
"global.js",
"background/nacl.min.js",
"background/nacl-util.min.js",
@@ -38,10 +39,10 @@
"content_scripts": [
{
"matches": [
- "http://*/*",
- "https://*/*"
+ ""
],
"js": [
+ "browser-polyfill.min.js",
"global.js",
"jquery-3.2.1.min.js",
"jquery-ui.min.js",
@@ -75,9 +76,11 @@
"icons/key.png"
],
"permissions": [
+ "activeTab",
"contextMenus",
"clipboardWrite",
"nativeMessaging",
+ "storage",
"tabs",
"webRequest",
"webRequestBlocking",
diff --git a/keepassxc-browser/options/options.html b/keepassxc-browser/options/options.html
index ad791ae..15b6ad9 100644
--- a/keepassxc-browser/options/options.html
+++ b/keepassxc-browser/options/options.html
@@ -5,6 +5,7 @@
+
@@ -307,7 +308,7 @@
-
-
+
+
You use an old version of KeePassXC.
diff --git a/keepassxc-browser/popups/popup_httpauth.js b/keepassxc-browser/popups/popup_httpauth.js
index 9425fef..b5f15ff 100644
--- a/keepassxc-browser/popups/popup_httpauth.js
+++ b/keepassxc-browser/popups/popup_httpauth.js
@@ -1,6 +1,6 @@
$(function() {
- browser.runtime.getBackgroundPage(function(global) {
- browser.tabs.query({"active": true, "currentWindow": true}, (tab) => {
+ browser.runtime.getBackgroundPage().then((global) => {
+ browser.tabs.query({"active": true, "currentWindow": true}.then((tab) => {
const data = global.page.tabs[tab.id].loginList;
let ul = document.getElementById('login-list');
for (let i = 0; i < data.logins.length; i++) {
diff --git a/keepassxc-browser/popups/popup_login.html b/keepassxc-browser/popups/popup_login.html
index d2e8af8..655104f 100644
--- a/keepassxc-browser/popups/popup_login.html
+++ b/keepassxc-browser/popups/popup_login.html
@@ -4,6 +4,7 @@
+
@@ -12,8 +13,8 @@
-
-
+
+
You use an old version of KeePassXC.
diff --git a/keepassxc-browser/popups/popup_login.js b/keepassxc-browser/popups/popup_login.js
index 389e982..23a6e1e 100644
--- a/keepassxc-browser/popups/popup_login.js
+++ b/keepassxc-browser/popups/popup_login.js
@@ -1,6 +1,6 @@
$(function() {
- browser.runtime.getBackgroundPage(function(global) {
- browser.tabs.query({"active": true, "currentWindow": true}, (tabs) => {
+ 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];
@@ -14,7 +14,7 @@ $(function() {
li.appendChild(a);
a.setAttribute('id', '' + i);
a.addEventListener('click', (e) => {
- var id = e.target.id;
+ const id = e.target.id;
browser.tabs.sendMessage(tab.id, {
action: 'fill_user_pass_with_specific_login',
id: id
diff --git a/keepassxc-browser/popups/popup_multiple-fields.html b/keepassxc-browser/popups/popup_multiple-fields.html
index 656c45b..663a7e6 100644
--- a/keepassxc-browser/popups/popup_multiple-fields.html
+++ b/keepassxc-browser/popups/popup_multiple-fields.html
@@ -4,6 +4,7 @@
+
diff --git a/keepassxc-browser/popups/popup_remember.html b/keepassxc-browser/popups/popup_remember.html
index 643a513..ec91f69 100644
--- a/keepassxc-browser/popups/popup_remember.html
+++ b/keepassxc-browser/popups/popup_remember.html
@@ -4,6 +4,7 @@
+
diff --git a/keepassxc-browser/popups/popup_remember.js b/keepassxc-browser/popups/popup_remember.js
index aac9fcb..1396ad8 100644
--- a/keepassxc-browser/popups/popup_remember.js
+++ b/keepassxc-browser/popups/popup_remember.js
@@ -23,7 +23,7 @@ function _initialize(tab) {
browser.runtime.sendMessage({
action: 'add_credentials',
args: [_tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
- }, _verifyResult);
+ }).then(_verifyResult);
});
$('#btn-update').click(function(e) {
@@ -34,7 +34,7 @@ function _initialize(tab) {
browser.runtime.sendMessage({
action: 'update_credentials',
args: [_tab.credentials.list[0].uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
- }, _verifyResult);
+ }).then(_verifyResult);
}
else {
$('.credentials:first .username-new:first strong:first').text(_tab.credentials.username);
@@ -59,7 +59,7 @@ function _initialize(tab) {
browser.runtime.sendMessage({
action: 'update_credentials',
args: [_tab.credentials.list[$(this).data('entryId')].uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url]
- }, _verifyResult);
+ }).then(_verifyResult);
});
if (_tab.credentials.usernameExists && _tab.credentials.username === _tab.credentials.list[i].login) {
@@ -116,9 +116,9 @@ $(function() {
browser.runtime.sendMessage({
action: 'get_tab_information'
- }, _initialize);
+ }).then(_initialize);
browser.runtime.sendMessage({
action: 'get_connected_database'
- }, _connected_database);
+ }).then(_connected_database);
});
\ No newline at end of file