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
16cfec31e0
13 changed files with 143 additions and 105 deletions
|
|
@ -1,3 +1,10 @@
|
|||
1.1.1 (10-05-2018)
|
||||
=========================
|
||||
- Improve dynamic input field detection [#117]
|
||||
- Fix HTTP Basic Auth dialog [#121]
|
||||
- Fix incorrect update notification [#141]
|
||||
- Do not try to detect database changes on page load [#142]
|
||||
|
||||
1.1.0 (09-05-2018)
|
||||
=========================
|
||||
- Allow specifying ignored sites
|
||||
|
|
|
|||
|
|
@ -158,22 +158,8 @@ kpxcEvent.onReconnect = function(callback, tab) {
|
|||
|
||||
// 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) => {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'redetect_fields'
|
||||
});
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}, tab);
|
||||
}
|
||||
}, null);
|
||||
keepass.reconnect(callback, tab).then((configured) => {
|
||||
kpxcEvent.showStatus(configured, tab, callback);
|
||||
});
|
||||
}, 500);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ httpAuth.loginOrShowCredentials = function(logins, details, resolve, reject) {
|
|||
});
|
||||
} else {
|
||||
if (page.settings.showNotifications) {
|
||||
showNotification('Multiple credentials detected. Click on the extension icon to choose the correct one.');
|
||||
showNotification('HTTP authentication with 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 });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ keepass.migrateKeyRing().then(() => {
|
|||
page.initOpenedTabs().then(() => {
|
||||
httpAuth.init();
|
||||
keepass.connectToNative();
|
||||
keepass.enableAutomaticReconnect();
|
||||
keepass.generateNewKeyPair();
|
||||
keepass.changePublicKeys(null).then((pkRes) => {
|
||||
keepass.getDatabaseHash((gdRes) => {}, null);
|
||||
|
|
|
|||
|
|
@ -838,20 +838,7 @@ keepass.onNativeMessage = function(response) {
|
|||
if (response.action === kpActions.DATABASE_LOCKED || response.action === kpActions.DATABASE_UNLOCKED) {
|
||||
keepass.testAssociation((associationResponse) => {
|
||||
keepass.isConfigured().then((configured) => {
|
||||
let data = page.tabs[page.currentTabId].stack[page.tabs[page.currentTabId].stack.length - 1];
|
||||
data.iconType = configured ? 'normal' : 'cross';
|
||||
browserAction.show(null, {'id': page.currentTabId});
|
||||
|
||||
// Send message to content script
|
||||
browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length) {
|
||||
browser.tabs.sendMessage(tabs[0].id, {
|
||||
action: 'check_database_hash',
|
||||
hash: {old: kpxcEvent.previousDatabaseHash, new: keepass.databaseHash}
|
||||
});
|
||||
keepass.previousDatabaseHash = keepass.databaseHash;
|
||||
}
|
||||
});
|
||||
keepass.updatePopup(configured ? 'normal' : 'cross');
|
||||
});
|
||||
}, null);
|
||||
}
|
||||
|
|
@ -864,6 +851,8 @@ function onDisconnected() {
|
|||
keepass.isKeePassXCAvailable = false;
|
||||
keepass.associated.value = false;
|
||||
keepass.associated.hash = null;
|
||||
page.clearCredentials(page.currentTabId, true);
|
||||
keepass.updatePopup('cross');
|
||||
console.log('Failed to connect: ' + (browser.runtime.lastError === null ? 'Unknown error' : browser.runtime.lastError.message));
|
||||
}
|
||||
|
||||
|
|
@ -1017,3 +1006,42 @@ keepass.decrypt = function(input, nonce) {
|
|||
const res = nacl.box.open(m, n, keepass.serverPublicKey, keepass.keyPair.secretKey);
|
||||
return res;
|
||||
};
|
||||
|
||||
keepass.enableAutomaticReconnect = function() {
|
||||
setInterval(() => {
|
||||
if (!keepass.isKeePassXCAvailable) {
|
||||
keepass.connectToNative();
|
||||
keepass.reconnect();
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
keepass.reconnect = function(callback, tab) {
|
||||
return new Promise((resolve, reject) => {
|
||||
keepass.generateNewKeyPair();
|
||||
keepass.changePublicKeys(tab).then((pkRes) => {
|
||||
// Database hash should be received if the reconnection succeeded
|
||||
keepass.getDatabaseHash((gdRes) => {
|
||||
if (!gdRes) {
|
||||
reject(false);
|
||||
return;
|
||||
}
|
||||
|
||||
keepass.testAssociation((response) => {
|
||||
keepass.isConfigured().then((configured) => {
|
||||
resolve(configured);
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
reject(e);
|
||||
});
|
||||
}, tab);
|
||||
}, null);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
keepass.updatePopup = function(iconType) {
|
||||
const data = page.tabs[page.currentTabId].stack[page.tabs[page.currentTabId].stack.length - 1];
|
||||
data.iconType = iconType;
|
||||
browserAction.show(null, {'id': page.currentTabId});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1140,7 +1140,34 @@ cipFields.useDefinedCredentialFields = function() {
|
|||
return false;
|
||||
};
|
||||
|
||||
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
|
||||
|
||||
// Detects DOM changes in the document
|
||||
let observer = new MutationObserver(function(mutations, observer) {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const mut of mutations) {
|
||||
if (mut.type === 'childList') {
|
||||
const fields = cipFields.getAllFields();
|
||||
|
||||
// If only password field is shown it's enough to have one field visible for initCredentialFields
|
||||
if (fields.length > (_detectedFields == 1 ? 0 : 1)) {
|
||||
cip.initCredentialFields(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// define what element should be observed by the observer
|
||||
// and what types of mutations trigger the callback
|
||||
observer.observe(document, {
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
childList: true,
|
||||
characterData: true
|
||||
});
|
||||
|
||||
var cip = {};
|
||||
cip.settings = {};
|
||||
|
|
@ -1152,7 +1179,6 @@ cip.credentials = [];
|
|||
|
||||
jQuery(function() {
|
||||
cip.init();
|
||||
cip.detectNewActiveFields();
|
||||
});
|
||||
|
||||
cip.init = function() {
|
||||
|
|
@ -1164,20 +1190,6 @@ cip.init = function() {
|
|||
});
|
||||
};
|
||||
|
||||
cip.detectNewActiveFields = function() {
|
||||
const divDetect = setInterval(function() {
|
||||
if (document.visibilityState !== 'hidden') {
|
||||
const fields = cipFields.getAllFields();
|
||||
|
||||
// If only password field is shown it's enough to have one field visible for initCredentialFields
|
||||
if (fields.length > (_detectedFields == 1 ? 0 : 1)) {
|
||||
cip.initCredentialFields(true);
|
||||
clearInterval(divDetect);
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// Switch credentials if database is changed or closed
|
||||
cip.detectDatabaseChange = function(response) {
|
||||
if (document.visibilityState !== 'hidden') {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "KeePassXC-Browser",
|
||||
"version": "1.1.0",
|
||||
"version_name": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"version_name": "1.1.1",
|
||||
"description": "KeePassXC integration for modern web browsers",
|
||||
"author": "KeePassXC Team",
|
||||
"icons": {
|
||||
|
|
|
|||
|
|
@ -7,33 +7,15 @@ body {
|
|||
font-size: 15px;
|
||||
padding: 8px;
|
||||
}
|
||||
.credentials ul {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
list-style-position: inside;
|
||||
.list-group {
|
||||
font-size: .9em !important;
|
||||
}
|
||||
.credentials li {
|
||||
list-style: none;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
margin-left: 10px;
|
||||
margin-right: 5px;
|
||||
.list-group-item {
|
||||
padding: 5px 10px !important;
|
||||
}
|
||||
.credentials a {
|
||||
color: #333;
|
||||
}
|
||||
.credentials a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
.credentials li:hover {
|
||||
.list-group-item:hover {
|
||||
cursor: pointer;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.settings {
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
|
@ -64,6 +46,7 @@ body {
|
|||
padding-bottom: 0px;
|
||||
margin-bottom: 0px;
|
||||
text-align: left;
|
||||
display: none;
|
||||
}
|
||||
#update-available a:hover,
|
||||
#update-available a:active {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<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" style="display: none">
|
||||
<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>.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@
|
|||
<p>
|
||||
Select the login information you would like to get logged in with:
|
||||
</p>
|
||||
<ul id="login-list"></ul>
|
||||
<div id="login-list" class="list-group"></div>
|
||||
<p>
|
||||
<button id="btn-dismiss" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove"></span> Dismiss and show the default authentication dialog</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -1,37 +1,57 @@
|
|||
'use strict';
|
||||
|
||||
$(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);
|
||||
}
|
||||
const getLoginData = function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.runtime.getBackgroundPage().then((global) => {
|
||||
browser.tabs.query({'active': true, 'currentWindow': true}).then((tabs) => {
|
||||
resolve(global.page.tabs[tabs[0].id].loginList);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$(function() {
|
||||
getLoginData().then((data) => {
|
||||
let ll = document.getElementById('login-list');
|
||||
for (let i = 0; i < data.logins.length; ++i) {
|
||||
const a = document.createElement('a');
|
||||
a.setAttribute('class', 'list-group-item');
|
||||
a.textContent = data.logins[i].login + " (" + data.logins[i].name + ")";
|
||||
$(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();
|
||||
});
|
||||
ll.appendChild(a);
|
||||
}
|
||||
});
|
||||
|
||||
$('#lock-database-button').click(function() {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'lock-database'
|
||||
}).then(status_response);
|
||||
});
|
||||
|
||||
$('#btn-dismiss').click(function() {
|
||||
getLoginData().then((data) => {
|
||||
// Using reject won't work with every browser. So return empty credentials instead.
|
||||
if (data.resolve) {
|
||||
data.resolve({
|
||||
authCredentials: {
|
||||
username: '',
|
||||
password: ''
|
||||
}
|
||||
});
|
||||
}
|
||||
close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
<p>
|
||||
Select the login information you would like to get entered into the page:
|
||||
</p>
|
||||
<ul id="login-list"></ul>
|
||||
<div id="login-list" class="list-group"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -9,13 +9,11 @@ $(function() {
|
|||
const tab = tabs[0];
|
||||
|
||||
const logins = global.page.tabs[tab.id].loginList;
|
||||
let ul = document.getElementById('login-list');
|
||||
let ll = 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('class', 'list-group-item');
|
||||
a.setAttribute('id', '' + i);
|
||||
a.addEventListener('click', (e) => {
|
||||
const id = e.target.id;
|
||||
|
|
@ -25,7 +23,7 @@ $(function() {
|
|||
});
|
||||
close();
|
||||
});
|
||||
ul.appendChild(li);
|
||||
ll.appendChild(a);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue