Better implementation of non-hidden forms detection. Code verified via JSHint.

This commit is contained in:
varjolintu 2017-09-17 10:03:57 +03:00
parent db603a4c66
commit 61d2090496
12 changed files with 210 additions and 193 deletions

View file

@ -5,6 +5,7 @@
- HTTP auth works with all browsers
- Fixed showing credentials from previous logins in the popup (credits to smorks/passifox)
- Automatic detection of div's with forms that are non-hidden by user interaction
- Verified the source code via JSHint
0.2.9 (2017-08-27)
=========================

View file

@ -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) and [smorks'](https://github.com/smorks/passifox) fork.
Some changes merged also from [smorks'](https://github.com/smorks/keepasshttp-connector) KeePassHttp-Connector 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).

View file

@ -27,7 +27,7 @@ browserAction.show = function(callback, tab) {
popup: 'popups/' + data.popup
});
}
}
};
browserAction.update = function(interval) {
if (!page.tabs[page.currentTabId] || page.tabs[page.currentTabId].stack.length === 0) {
@ -79,14 +79,14 @@ browserAction.update = function(interval) {
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((response) => {
if (!response || keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable || page.tabs[tab.id].errorMessage) {
stackData.iconType = 'cross';
@ -100,7 +100,7 @@ browserAction.showDefault = function(callback, 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;
@ -112,7 +112,7 @@ browserAction.stackAdd = function(callback, tab, icon, popup, level, push, visib
let stackData = {
level: level,
icon: icon
}
};
if (popup) {
stackData.popup = popup;
@ -140,8 +140,7 @@ browserAction.stackAdd = function(callback, tab, icon, popup, level, push, visib
if (!dontShow) {
browserAction.show(null, {'id': id});
}
}
};
browserAction.removeLevelFromStack = function(callback, tab, level, type, dontShow) {
if (!page.tabs[tab.id]) {
@ -172,7 +171,7 @@ browserAction.removeLevelFromStack = function(callback, tab, level, type, dontSh
if (!dontShow) {
browserAction.show(callback, tab);
}
}
};
browserAction.stackPop = function(tabId) {
const id = tabId || page.currentTabId;
@ -242,7 +241,7 @@ browserAction.setRememberPopup = function(tabId, username, password, url, userna
},
icon: 'icon_remember_red_background_19x19.png',
popup: 'popup_remember.html'
}
};
browserAction.stackPush(stackData, id);
@ -255,7 +254,7 @@ browserAction.setRememberPopup = function(tabId, username, password, url, userna
};
browserAction.show(null, {'id': id});
}
};
function getValueOrDefault(settings, key, defaultVal, min) {
try {
@ -280,4 +279,4 @@ browserAction.generateIconName = function(iconType, icon) {
name += '_19x19.png';
return name;
}
};

View file

@ -16,7 +16,7 @@ event.onMessage = function(request, sender, callback) {
return true;
}
}
}
};
/**
* Get interesting information about the given tab.
@ -73,13 +73,12 @@ event.invoke = function(handler, callback, senderTabId, args, secondTime) {
console.log('undefined handler for tab ' + tab.id);
}
});
}
};
event.onShowAlert = function(callback, tab, message) {
if (page.settings.supressAlerts) { console.log(message); }
else { alert(message); }
}
};
event.showStatus = function(configured, tab, callback) {
let keyId = null;
@ -98,11 +97,11 @@ event.showStatus = function(configured, tab, callback) {
associated: keepass.isAssociated(),
error: errorMessage ? errorMessage : null
});
}
};
event.onLoadSettings = function(callback, tab) {
page.settings = (typeof(localStorage.settings) === 'undefined') ? {} : JSON.parse(localStorage.settings);
}
};
event.onLoadKeyRing = function(callback, tab) {
keepass.keyRing = (typeof(localStorage.keyRing) === 'undefined') ? {} : JSON.parse(localStorage.keyRing);
@ -112,17 +111,17 @@ event.onLoadKeyRing = function(callback, tab) {
hash: null
};
}
}
};
event.onGetSettings = function(callback, tab) {
event.onLoadSettings();
callback({ data: page.settings });
}
};
event.onSaveSettings = function(callback, tab, settings) {
localStorage.settings = JSON.stringify(settings);
event.onLoadSettings();
}
};
event.onGetStatus = function(callback, tab) {
keepass.testAssociation((response) => {
@ -130,7 +129,7 @@ event.onGetStatus = function(callback, tab) {
event.showStatus(configured, tab, callback);
});
}, tab);
}
};
event.onReconnect = function(callback, tab) {
keepass.connectToNative();
@ -150,24 +149,24 @@ event.onReconnect = function(callback, tab) {
}, null);
});
}, 2000);
}
};
event.onPopStack = function(callback, tab) {
browserAction.stackPop(tab.id);
browserAction.show(null, tab);
}
};
event.onGetTabInformation = function(callback, tab) {
const id = tab.id || page.currentTabId;
callback(page.tabs[id]);
}
};
event.onGetConnectedDatabase = function(callback, tab) {
callback({
count: Object.keys(keepass.keyRing).length,
identifier: (keepass.keyRing[keepass.associated.hash]) ? keepass.keyRing[keepass.associated.hash].id : null
});
}
};
event.onGetKeePassXCVersions = function(callback, tab) {
if (keepass.currentKeePassXC.version === 0) {
@ -176,62 +175,62 @@ event.onGetKeePassXCVersions = function(callback, tab) {
}, tab);
}
callback({current: keepass.currentKeePassXC.version, latest: keepass.latestKeePassXC.version});
}
};
event.onCheckUpdateKeePassXC = function(callback, tab) {
keepass.checkForNewKeePassXCVersion();
callback({current: keepass.currentKeePassXC.version, latest: keepass.latestKeePassXC.version});
}
};
event.onUpdateAvailableKeePassXC = function(callback, tab) {
callback(keepass.keePassXCUpdateAvailable());
}
};
event.onRemoveCredentialsFromTabInformation = function(callback, tab) {
const id = tab.id || page.currentTabId;
page.clearCredentials(id);
}
};
event.onSetRememberPopup = function(callback, tab, username, password, url, usernameExists, credentialsList) {
browserAction.setRememberPopup(tab.id, username, password, url, usernameExists, credentialsList);
}
};
event.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);
}
};
event.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);
}
};
event.onMultipleFieldsPopup = function(callback, tab) {
let stackData = {
level: 1,
iconType: 'normal',
popup: 'popup_multiple-fields.html'
}
};
browserAction.stackUnshift(stackData, tab.id);
browserAction.show(null, tab);
}
};
event.pageClearLogins = function(callback, tab) {
page.clearLogins(tab.id);
callback();
}
};
// all methods named in this object have to be declared BEFORE this!

View file

@ -8,17 +8,17 @@ httpAuth.requestCompleted = function(details) {
if (index > -1) {
httpAuth.requests.splice(index, 1);
}
}
};
httpAuth.handleRequestPromise = function(details) {
return new Promise((resolve, reject) => {
httpAuth.processPendingCallbacks(details, resolve, reject);
});
}
};
httpAuth.handleRequestCallback = function(details, callback) {
httpAuth.processPendingCallbacks(details, callback, callback);
}
};
httpAuth.processPendingCallbacks = function(details, resolve, reject) {
if (httpAuth.requests.indexOf(details.requestId) >= 0 || !page.tabs[details.tabId]) {
@ -36,7 +36,7 @@ httpAuth.processPendingCallbacks = function(details, resolve, reject) {
keepass.retrieveCredentials((logins) => {
httpAuth.loginOrShowCredentials(logins, details, resolve, reject);
}, { "id": details.tabId }, details.searchUrl, details.searchUrl, true);
}
};
httpAuth.loginOrShowCredentials = function(logins, details, resolve, reject) {
// at least one login found --> use first to login
@ -59,4 +59,4 @@ httpAuth.loginOrShowCredentials = function(logins, details, resolve, reject) {
else {
reject({});
}
}
};

View file

@ -94,7 +94,7 @@ const contextMenuItems = [
{title: 'Fill &Pass Only', action: 'fill_pass_only'},
{title: 'Show Password &Generator Icons', action: 'activate_password_generator'},
{title: '&Save credentials', action: 'remember_credentials'}
]
];
// Create context menu items
for (const item of contextMenuItems) {

View file

@ -3,6 +3,7 @@ var keepass = {};
keepass.associated = {'value': false, 'hash': null};
keepass.keyPair = {publicKey: null, secretKey: null};
keepass.serverPublicKey = '';
keepass.clientID = '';
keepass.isConnected = false;
keepass.isDatabaseClosed = false;
keepass.isKeePassXCAvailable = false;
@ -66,7 +67,7 @@ const kpErrors = {
keepass.addCredentials = function(callback, tab, username, password, url) {
keepass.updateCredentials(callback, tab, null, username, password, url);
}
};
keepass.updateCredentials = function(callback, tab, entryId, username, password, url) {
page.debug('keepass.updateCredentials(callback, {1}, {2}, {3}, [password], {4})', tab.id, entryId, username, url);
@ -76,9 +77,7 @@ keepass.updateCredentials = function(callback, tab, entryId, username, password,
if (!response)
{
browserAction.showDefault(null, tab);
if (forceCallback) {
callback([]);
}
callback([]);
return;
}
@ -102,7 +101,8 @@ keepass.updateCredentials = function(callback, tab, entryId, username, password,
const request = {
action: kpAction,
message: keepass.encrypt(messageData, nonce),
nonce: keepass.b64e(nonce)
nonce: keepass.b64e(nonce),
clientID: keepass.clientID
};
console.log(request);
@ -124,7 +124,7 @@ keepass.updateCredentials = function(callback, tab, entryId, username, password,
});
keepass.nativePort.postMessage(request);
});
}
};
keepass.retrieveCredentials = function (callback, tab, url, submiturl, forceCallback, triggerUnlock) {
page.debug('keepass.retrieveCredentials(callback, {1}, {2}, {3}, {4})', tab.id, url, submiturl, forceCallback);
@ -164,7 +164,8 @@ keepass.retrieveCredentials = function (callback, tab, url, submiturl, forceCall
const request = {
action: kpAction,
message: keepass.encrypt(messageData, nonce),
nonce: keepass.b64e(nonce)
nonce: keepass.b64e(nonce),
clientID: keepass.clientID
};
keepass.callbackOnId(keepass.nativePort.onMessage, kpAction, (response) => {
@ -199,7 +200,7 @@ keepass.retrieveCredentials = function (callback, tab, url, submiturl, forceCall
});
keepass.nativePort.postMessage(request);
}, tab);
}
};
// Redirects the callback to a listener (handleReply())
keepass.callbackOnId = function (ev, id, callback) {
@ -209,11 +210,11 @@ keepass.callbackOnId = function (ev, id, callback) {
ev.removeListener(handler);
callback(msg);
}
}
};
return handler;
})(ev, id, callback);
ev.addListener(listener);
}
};
keepass.generatePassword = function (callback, tab, forceCallback) {
if (!keepass.isConnected) {
@ -242,7 +243,8 @@ keepass.generatePassword = function (callback, tab, forceCallback) {
const request = {
action: kpAction,
nonce: keepass.b64e(nonce)
nonce: keepass.b64e(nonce),
clientID: keepass.clientID
};
keepass.callbackOnId(keepass.nativePort.onMessage, kpAction, (response) => {
@ -254,7 +256,6 @@ keepass.generatePassword = function (callback, tab, forceCallback) {
keepass.setcurrentKeePassXCVersion(parsed.version);
if (keepass.verifyResponse(parsed, response.nonce)) {
const rIv = response.nonce;
if (parsed.entries) {
passwords = parsed.entries;
keepass.updateLastUsed(keepass.databaseHash);
@ -275,7 +276,7 @@ keepass.generatePassword = function (callback, tab, forceCallback) {
});
keepass.nativePort.postMessage(request);
}, tab);
}
};
keepass.associate = function(callback, tab) {
if (keepass.isAssociated()) {
@ -303,7 +304,8 @@ keepass.associate = function(callback, tab) {
const request = {
action: kpAction,
message: keepass.encrypt(messageData, nonce),
nonce: keepass.b64e(nonce)
nonce: keepass.b64e(nonce),
clientID: keepass.clientID
};
keepass.callbackOnId(keepass.nativePort.onMessage, kpAction, (response) => {
@ -333,7 +335,7 @@ keepass.associate = function(callback, tab) {
});
keepass.nativePort.postMessage(request);
}, tab);
}
};
keepass.testAssociation = function (callback, tab, triggerUnlock) {
if (tab && page.tabs[tab.id]) {
@ -358,7 +360,7 @@ keepass.testAssociation = function (callback, tab, triggerUnlock) {
if (!keepass.serverPublicKey) {
if (tab && page.tabs[tab.id]) {
handleError(tab, kpErrors.PUBLIC_KEY_NOT_FOUND);
keepass.handleError(tab, kpErrors.PUBLIC_KEY_NOT_FOUND);
}
callback(false);
return false;
@ -385,7 +387,8 @@ keepass.testAssociation = function (callback, tab, triggerUnlock) {
const request = {
action: kpAction,
message: keepass.encrypt(messageData, nonce),
nonce: keepass.b64e(nonce)
nonce: keepass.b64e(nonce),
clientID: keepass.clientID
};
keepass.callbackOnId(keepass.nativePort.onMessage, kpAction, (response) => {
@ -395,7 +398,6 @@ keepass.testAssociation = function (callback, tab, triggerUnlock) {
const message = nacl.util.encodeUTF8(res);
const parsed = JSON.parse(message);
keepass.setcurrentKeePassXCVersion(parsed.version);
const id = parsed.id;
keepass.isEncryptionKeyUnrecognized = false;
if (!keepass.verifyResponse(parsed, response.nonce)) {
@ -423,7 +425,7 @@ keepass.testAssociation = function (callback, tab, triggerUnlock) {
});
keepass.nativePort.postMessage(request);
}, tab, triggerUnlock);
}
};
keepass.getDatabaseHash = function (callback, tab, triggerUnlock) {
if (!keepass.isConnected) {
@ -453,7 +455,8 @@ keepass.getDatabaseHash = function (callback, tab, triggerUnlock) {
const request = {
action: kpAction,
message: encrypted,
nonce: keepass.b64e(nonce)
nonce: keepass.b64e(nonce),
clientID: keepass.clientID
};
keepass.callbackOnId(keepass.nativePort.onMessage, kpAction, (response) => {
@ -493,7 +496,7 @@ keepass.getDatabaseHash = function (callback, tab, triggerUnlock) {
}
});
keepass.nativePort.postMessage(request);
}
};
keepass.changePublicKeys = function(tab, callback) {
if (!keepass.isConnected) {
@ -504,14 +507,16 @@ keepass.changePublicKeys = function(tab, callback) {
const kpAction = kpActions.CHANGE_PUBLIC_KEYS;
const key = keepass.b64e(keepass.keyPair.publicKey);
let nonce = nacl.randomBytes(keepass.keySize);
nonce = keepass.b64e(nonce)
nonce = keepass.b64e(nonce);
keepass.clientID = keepass.b64e(nacl.randomBytes(keepass.keySize));
const message = {
action: kpAction,
publicKey: key,
proxyPort: (page.settings.port ? page.settings.port : 19700),
nonce: nonce
}
nonce: nonce,
clientID: keepass.clientID
};
keepass.callbackOnId(keepass.nativePort.onMessage, kpAction, (response) => {
keepass.setcurrentKeePassXCVersion(response.version);
@ -529,12 +534,12 @@ keepass.changePublicKeys = function(tab, callback) {
callback(true);
});
keepass.nativePort.postMessage(message);
}
};
keepass.generateNewKeyPair = function() {
keepass.keyPair = nacl.box.keyPair();
//console.log(keepass.b64e(keepass.keyPair.publicKey) + ' ' + keepass.b64e(keepass.keyPair.secretKey));
}
};
keepass.isConfigured = function(callback) {
if (typeof(keepass.databaseHash) === 'undefined') {
@ -545,11 +550,11 @@ keepass.isConfigured = function(callback) {
else {
callback(keepass.databaseHash in keepass.keyRing);
}
}
};
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)) {
@ -567,7 +572,7 @@ keepass.convertKeyToKeyRing = function() {
delete localStorage[keepass.keyId];
delete localStorage[keepass.keyBody];
}
}
};
keepass.saveKey = function(hash, id, key) {
if (!(hash in keepass.keyRing)) {
@ -577,7 +582,7 @@ keepass.saveKey = function(hash, id, key) {
hash: hash,
created: new Date(),
lastUsed: new Date()
}
};
}
else {
keepass.keyRing[hash].id = id;
@ -585,19 +590,19 @@ keepass.saveKey = function(hash, id, key) {
keepass.keyRing[hash].hash = hash;
}
localStorage.keyRing = JSON.stringify(keepass.keyRing);
}
};
keepass.updateLastUsed = function(hash) {
if ((hash in keepass.keyRing)) {
keepass.keyRing[hash].lastUsed = new Date();
localStorage.keyRing = JSON.stringify(keepass.keyRing);
}
}
};
keepass.deleteKey = function(hash) {
delete keepass.keyRing[hash];
localStorage.keyRing = JSON.stringify(keepass.keyRing);
}
};
keepass.setcurrentKeePassXCVersion = function(version) {
if (version) {
@ -606,7 +611,7 @@ keepass.setcurrentKeePassXCVersion = function(version) {
versionParsed: Number(version.replace(/\./g, ''))
};
}
}
};
keepass.keePassXCUpdateAvailable = function() {
if (page.settings.checkUpdateKeePassXC && page.settings.checkUpdateKeePassXC > 0) {
@ -618,7 +623,7 @@ keepass.keePassXCUpdateAvailable = function() {
}
return (keepass.currentKeePassXC.versionParsed > 0 && keepass.currentKeePassXC.versionParsed < keepass.latestKeePassXC.versionParsed);
}
};
keepass.checkForNewKeePassXCVersion = function() {
let xhr = new XMLHttpRequest();
@ -641,7 +646,7 @@ keepass.checkForNewKeePassXCVersion = function() {
xhr.onerror = function(e) {
console.log('checkForNewKeePassXCVersion error:' + e);
}
};
try {
xhr.open('GET', keepass.latestVersionUrl, true);
@ -651,17 +656,17 @@ keepass.checkForNewKeePassXCVersion = function() {
console.log(ex);
}
keepass.latestKeePassXC.lastChecked = new Date();
}
};
keepass.connectToNative = function() {
if (!keepass.isConnected) {
keepass.nativeConnect();
}
}
};
keepass.onNativeMessage = function (response) {
//console.log('Received message: ' + JSON.stringify(response));
}
};
function onDisconnected() {
keepass.nativePort = null;
@ -674,12 +679,12 @@ function onDisconnected() {
}
keepass.nativeConnect = function() {
console.log('Connecting to native messaging host ' + keepass.nativeHostName)
console.log('Connecting to native messaging host ' + keepass.nativeHostName);
keepass.nativePort = browser.runtime.connectNative(keepass.nativeHostName);
keepass.nativePort.onMessage.addListener(keepass.onNativeMessage);
keepass.nativePort.onDisconnect.addListener(onDisconnected);
keepass.isConnected = true;
}
};
keepass.verifyKeyResponse = function(response, key, nonce) {
if (!response.success || !response.publicKey) {
@ -699,8 +704,7 @@ keepass.verifyKeyResponse = function(response, key, nonce) {
}
return reply;
}
};
keepass.verifyResponse = function(response, nonce, id) {
keepass.associated.value = response.success;
@ -723,8 +727,7 @@ keepass.verifyResponse = function(response, nonce, id) {
keepass.associated.hash = (keepass.associated.value) ? keepass.databaseHash : null;
return keepass.isAssociated();
}
};
keepass.handleError = function(tab, errorCode, errorMessage = '') {
if (errorMessage.length === 0) {
@ -734,15 +737,15 @@ keepass.handleError = function(tab, errorCode, errorMessage = '') {
if (tab && page.tabs[tab.id]) {
page.tabs[tab.id].errorMessage = errorMessage;
}
}
};
keepass.b64e = function(d) {
return nacl.util.encodeBase64(d);
}
};
keepass.b64d = function(d) {
return nacl.util.decodeBase64(d);
}
};
keepass.getCryptoKey = function() {
let dbkey = null;
@ -758,11 +761,11 @@ keepass.getCryptoKey = function() {
}
return {dbid, dbkey};
}
};
keepass.setCryptoKey = function(id, key) {
keepass.saveKey(keepass.databaseHash, id, key);
}
};
keepass.encrypt = function(input, nonce) {
const messageData = nacl.util.decodeUTF8(JSON.stringify(input));
@ -774,11 +777,11 @@ keepass.encrypt = function(input, nonce) {
}
}
return '';
}
};
keepass.decrypt = function(input, nonce, toStr) {
const m = keepass.b64d(input);
const n = keepass.b64d(nonce);
const res = nacl.box.open(m, n, keepass.serverPublicKey, keepass.keyPair.secretKey);
return res;
}
};

View file

@ -6,7 +6,7 @@ const defaultSettings = {
autoFillSingleEntry: false,
autoRetrieveCredentials: true,
proxyPort: '19700'
}
};
var page = {};
page.tabs = {};
@ -39,7 +39,7 @@ page.initSettings = function() {
page.settings.port = defaultSettings.proxyPort;
}
localStorage.settings = JSON.stringify(page.settings);
}
};
page.initOpenedTabs = function() {
browser.tabs.query({}).then((tabs) => {
@ -56,18 +56,18 @@ page.initOpenedTabs = function() {
browserAction.show(null, tabs[0]);
});
});
}
};
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'));
}
};
page.switchTab = function(callback, tab) {
browserAction.showDefault(null, tab);
browser.tabs.sendMessage(tab.id, {action: 'activated_tab'}).catch((e) => {console.log(e);});
}
};
page.clearCredentials = function(tabId, complete) {
if (!page.tabs[tabId]) {
@ -84,11 +84,11 @@ page.clearCredentials = function(tabId, complete) {
action: 'clear_credentials'
}).catch((e) => {console.log(e);});
}
}
};
page.clearLogins = function(tabId) {
page.tabs[tabId].loginList = [];
}
};
page.createTabEntry = function(tabId) {
page.tabs[tabId] = {
@ -96,7 +96,7 @@ page.createTabEntry = function(tabId) {
'errorMessage': null,
'loginList': {}
};
}
};
page.removePageInformationFromNotExistingTabs = function() {
let rand = Math.floor(Math.random()*1001);
@ -129,12 +129,9 @@ page.debugConsole = function() {
page.sprintf = function(input, args) {
return input.replace(/{(\d+)}/g, (match, number) => {
return typeof args[number] !== 'undefined'
? (typeof args[number] === 'object' ? JSON.stringify(args[number]) : args[number])
: match
;
return typeof args[number] !== 'undefined' ? (typeof args[number] === 'object' ? JSON.stringify(args[number]) : args[number]) : match;
});
}
};
page.debugDummy = function() {};

View file

@ -94,17 +94,17 @@ cipAutocomplete.init = function(field) {
.click(cipAutocomplete.onClick)
.blur(cipAutocomplete.onBlur)
.focus(cipAutocomplete.onFocus);
}
};
cipAutocomplete.onClick = function() {
jQuery(this).autocomplete('search', jQuery(this).val());
}
};
cipAutocomplete.onOpen = function(event, ui) {
// NOT BEAUTIFUL!
// modifies ALL ui-autocomplete menus of class .cip-ui-menu
jQuery('ul.ui-autocomplete.ui-menu').css('z-index', 2147483636);
}
};
cipAutocomplete.onSource = function (request, callback) {
const matches = jQuery.map(cipAutocomplete.elements, (tag) => {
@ -113,7 +113,7 @@ cipAutocomplete.onSource = function (request, callback) {
}
});
callback(matches);
}
};
cipAutocomplete.onSelect = function (e, ui) {
e.preventDefault();
@ -123,7 +123,7 @@ cipAutocomplete.onSelect = function (e, ui) {
combination.loginId = ui.item.loginId;
cip.fillInCredentials(combination, true, false);
jQuery(this).data('fetched', true);
}
};
cipAutocomplete.onBlur = function() {
if (jQuery(this).data('fetched') === true) {
@ -136,7 +136,7 @@ cipAutocomplete.onBlur = function() {
cip.fillInCredentials(fields, true, true);
}
}
}
};
cipAutocomplete.onFocus = function() {
cip.u = jQuery(this);
@ -144,7 +144,7 @@ cipAutocomplete.onFocus = function() {
if (jQuery(this).val() === '') {
jQuery(this).autocomplete('search', '');
}
}
};
@ -162,7 +162,7 @@ cipPassword.init = function() {
window.setInterval(function() {
cipPassword.checkObservedElements();
}, 400);
}
};
cipPassword.initField = function(field, inputs, pos) {
if (!field || field.length !== 1) {
@ -190,7 +190,7 @@ cipPassword.initField = function(field, inputs, pos) {
}
field.data('cip-genpw-next-field-exists', $found);
}
};
cipPassword.createDialog = function() {
if ('passwordCreateDialog' in _called) {
@ -276,7 +276,7 @@ cipPassword.createDialog = function() {
const fieldId = jQuery('#cip-genpw-dialog:first').data('cip-genpw-field-id');
const field = jQuery('input[data-cip-id=\''+fieldId+'\']:first');
if (field.length === 1) {
const $password = jQuery('input#cip-genpw-textfield-password:first').val();
let $password = jQuery('input#cip-genpw-textfield-password:first').val();
if (field.attr('maxlength')) {
if ($password.length > field.attr('maxlength')) {
@ -313,7 +313,7 @@ cipPassword.createDialog = function() {
}
}
});
}
};
cipPassword.createIcon = function(field) {
const $className = (isFirefox ? 'key-moz' : 'key');
@ -359,12 +359,12 @@ cipPassword.createIcon = function(field) {
cipPassword.observedIcons.push($icon);
jQuery('body').append($icon);
}
};
cipPassword.setIconPosition = function($icon, $field) {
$icon.css('top', $field.offset().top + $icon.data('offset') + 1)
.css('left', $field.offset().left + $field.outerWidth() - $icon.data('size') - $icon.data('offset'))
}
.css('left', $field.offset().left + $field.outerWidth() - $icon.data('size') - $icon.data('offset'));
};
cipPassword.copyPasswordToClipboard = function(e) {
if (e) {
@ -372,7 +372,7 @@ cipPassword.copyPasswordToClipboard = function(e) {
}
const input = jQuery("input#cip-genpw-textfield-password");
input.select()
input.select();
try {
const success = document.execCommand('copy');
if (success) {
@ -384,13 +384,13 @@ cipPassword.copyPasswordToClipboard = function(e) {
catch (err) {
console.log('Could not copy password to clipboard: ' + err);
}
}
};
cipPassword.callbackPasswordCopied = function(bool) {
if (bool) {
jQuery('#cip-genpw-btn-clipboard').addClass('btn-success');
}
}
};
cipPassword.callbackGeneratedPassword = function(entries) {
if (entries && entries.length >= 1) {
@ -414,13 +414,13 @@ cipPassword.callbackGeneratedPassword = function(entries) {
jQuery('button#cip-genpw-btn-fillin').hide();
}
}
}
};
cipPassword.onRequestPassword = function() {
browser.runtime.sendMessage({
action: 'generate_password'
}).then(cipPassword.callbackGeneratedPassword);
}
};
cipPassword.checkObservedElements = function() {
if (cipPassword.observingLock) {
@ -451,7 +451,7 @@ cipPassword.checkObservedElements = function() {
}
});
cipPassword.observingLock = false;
}
};
@ -466,7 +466,7 @@ cipForm.init = function(form, credentialFields) {
cipForm.setInputFields(form, credentialFields);
form.submit(cipForm.onSubmit);
}
}
};
cipForm.destroy = function(form, credentialFields) {
if (form === false && credentialFields) {
@ -479,12 +479,12 @@ cipForm.destroy = function(form, credentialFields) {
if (form && jQuery(form).length > 0) {
jQuery(form).unbind('submit', cipForm.onSubmit);
}
}
};
cipForm.setInputFields = function(form, credentialFields) {
form.data('cipUsername', credentialFields.username);
form.data('cipPassword', credentialFields.password);
}
};
cipForm.onSubmit = function() {
const usernameId = jQuery(this).data('cipUsername');
@ -535,7 +535,7 @@ cipDefine.init = function () {
cipDefine.resetSelection();
cipDefine.prepareStep1();
cipDefine.markAllUsernameFields($chooser);
}
};
cipDefine.initDescription = function() {
const $description = jQuery('div#b2c-cipDefine-description');
@ -586,7 +586,6 @@ cipDefine.initDescription = function() {
cipDefine.selection.username = cipFields.prepareId(cipDefine.selection.username);
}
const passwordId = jQuery('div#b2c-cipDefine-fields').data('password');
if (cipDefine.selection.password) {
cipDefine.selection.password = cipFields.prepareId(cipDefine.selection.password);
}
@ -645,7 +644,7 @@ cipDefine.initDescription = function() {
}
jQuery('div#b2c-cipDefine-description').draggable();
}
};
cipDefine.resetSelection = function() {
cipDefine.selection = {
@ -653,7 +652,7 @@ cipDefine.resetSelection = function() {
password: null,
fields: {}
};
}
};
cipDefine.isFieldSelected = function($cipId) {
return (
@ -661,7 +660,7 @@ cipDefine.isFieldSelected = function($cipId) {
$cipId === cipDefine.selection.password ||
$cipId in cipDefine.selection.fields
);
}
};
cipDefine.markAllUsernameFields = function($chooser) {
cipDefine.eventFieldClick = function(e) {
@ -671,7 +670,7 @@ cipDefine.markAllUsernameFields = function($chooser) {
cipDefine.markAllPasswordFields(jQuery('#b2c-cipDefine-fields'));
};
cipDefine.markFields($chooser, cipFields.inputQueryPattern);
}
};
cipDefine.markAllPasswordFields = function($chooser) {
cipDefine.eventFieldClick = function(e) {
@ -681,7 +680,7 @@ cipDefine.markAllPasswordFields = function($chooser) {
cipDefine.markAllStringFields(jQuery('#b2c-cipDefine-fields'));
};
cipDefine.markFields($chooser, 'input[type=\'password\']');
}
};
cipDefine.markAllStringFields = function($chooser) {
cipDefine.eventFieldClick = function(e) {
@ -691,7 +690,7 @@ cipDefine.markAllStringFields = function($chooser) {
jQuery('button#b2c-btn-confirm:first').addClass('b2c-btn-primary').attr('disabled', false);
};
cipDefine.markFields($chooser, cipFields.inputQueryPattern + ', select');
}
};
cipDefine.markFields = function ($chooser, $pattern) {
//var $found = false;
@ -721,7 +720,7 @@ cipDefine.markFields = function ($chooser, $pattern) {
jQuery('button#b2c-btn-skip').click();
}
*/
}
};
cipDefine.prepareStep1 = function() {
jQuery('div#b2c-help').text('').css('margin-bottom', 0);
@ -732,7 +731,7 @@ cipDefine.prepareStep1 = function() {
jQuery('button#b2c-btn-skip:first').data('step', '1').show();
jQuery('button#b2c-btn-confirm:first').hide();
jQuery('button#b2c-btn-again:first').hide();
}
};
cipDefine.prepareStep2 = function() {
jQuery('div#b2c-help').text('').css('margin-bottom', 0);
@ -740,7 +739,7 @@ cipDefine.prepareStep2 = function() {
jQuery('div:first', jQuery('div#b2c-cipDefine-description')).text('2. Now choose a password field');
jQuery('button#b2c-btn-skip:first').data('step', '2');
jQuery('button#b2c-btn-again:first').show();
}
};
cipDefine.prepareStep3 = function() {
/* skip step if no entry was found
@ -760,11 +759,11 @@ cipDefine.prepareStep3 = function() {
jQuery('button#b2c-btn-confirm:first').show();
jQuery('button#b2c-btn-skip:first').data('step', '3').hide();
jQuery('div:first', jQuery('div#b2c-cipDefine-description')).text('3. Confirm selection');
}
};
var cipFields = {}
var cipFields = {};
cipFields.inputQueryPattern = 'input[type=\'text\'], input[type=\'email\'], input[type=\'password\'], input[type=\'tel\'], input[type=\'number\'], input:not([type])';
// unique number as new IDs for input fields
@ -789,11 +788,11 @@ cipFields.setUniqueId = function(field) {
cipFields.uniqueNumber += 1;
field.attr('data-cip-id', 'jQuery'+String(cipFields.uniqueNumber));
}
}
};
cipFields.prepareId = function(id) {
return id.replace(/[:#.,\[\]\(\)' "]/g, function(m) { return '\\'+m });
}
return id.replace(/[:#.,\[\]\(\)' "]/g, function(m) { return '\\'+m; });
};
cipFields.getAllFields = function() {
let fields = [];
@ -807,7 +806,19 @@ cipFields.getAllFields = function() {
});
return fields;
}
};
cipFields.getHiddenFieldCount = function() {
let count = 0;
jQuery(cipFields.inputQueryPattern).each(function() {
if (jQuery(this).is(':hidden')) {
count++;
}
});
return count;
};
cipFields.prepareVisibleFieldsWithID = function($pattern) {
jQuery($pattern).each(function() {
@ -815,7 +826,7 @@ cipFields.prepareVisibleFieldsWithID = function($pattern) {
cipFields.setUniqueId(jQuery(this));
}
});
}
};
cipFields.getAllCombinations = function(inputs) {
let fields = [];
@ -843,7 +854,7 @@ cipFields.getAllCombinations = function(inputs) {
}
return fields;
}
};
cipFields.getCombination = function(givenType, fieldId) {
if (cipFields.combinations.length === 0) {
@ -908,7 +919,7 @@ cipFields.getCombination = function(givenType, fieldId) {
combination.isNew = true;
}
return combination;
}
};
/**
* return the username field or null if it not exists
@ -969,7 +980,7 @@ cipFields.getUsernameField = function(passwordId, checkDisabled) {
cipFields.setUniqueId(usernameField);
return usernameField;
}
};
/**
* return the password field or null if it not exists
@ -1026,7 +1037,7 @@ cipFields.getPasswordField = function(usernameId, checkDisabled) {
cipFields.setUniqueId(passwordField);
return passwordField;
}
};
cipFields.prepareCombinations = function(combinations) {
for (const c of combinations) {
@ -1049,7 +1060,7 @@ cipFields.prepareCombinations = function(combinations) {
}
}
}
}
};
cipFields.useDefinedCredentialFields = function() {
if (cip.settings['defined-credential-fields'] && cip.settings['defined-credential-fields'][document.location.origin]) {
@ -1077,7 +1088,7 @@ cipFields.useDefinedCredentialFields = function() {
}
return false;
}
};
@ -1098,15 +1109,7 @@ cip.credentials = [];
jQuery(function() {
cip.init();
// Detect div's that include forms and are visible
const divDetect = setInterval(function() {
const fields = cipFields.getAllFields();
if (fields.length > 0) {
cip.initCredentialFields(true);
clearInterval(divDetect);
}
}, 1000);
cip.detectNewActiveFields();
});
cip.init = function() {
@ -1116,7 +1119,21 @@ cip.init = function() {
cip.settings = response.data;
cip.initCredentialFields();
});
}
};
cip.detectNewActiveFields = function() {
const hiddenFields = cipFields.getHiddenFieldCount();
if (hiddenFields > 0) {
const divDetect = setInterval(function() {
const fields = cipFields.getAllFields();
if (fields.length > 0) {
cip.initCredentialFields(true);
clearInterval(divDetect);
}
}, 1000);
}
};
cip.initCredentialFields = function(forceCall) {
if (_called.initCredentialFields && !forceCall) {
@ -1152,7 +1169,7 @@ cip.initCredentialFields = function(forceCall) {
}).then(cip.retrieveCredentialsCallback);
}
});
} // end function init
};
cip.initPasswordGenerator = function(inputs) {
if (cip.settings.usePasswordGenerator) {
@ -1164,7 +1181,7 @@ cip.initPasswordGenerator = function(inputs) {
}
}
}
}
};
cip.receiveCredentialsIfNecessary = function () {
if (cip.credentials.length === 0) {
@ -1173,7 +1190,7 @@ cip.receiveCredentialsIfNecessary = function () {
args: [ cip.url, cip.submitUrl ]
}).then(cip.retrieveCredentialsCallback);
}
}
};
cip.retrieveCredentialsCallback = function (credentials, dontAutoFillIn) {
if (cipFields.combinations.length > 0) {
@ -1185,7 +1202,7 @@ cip.retrieveCredentialsCallback = function (credentials, dontAutoFillIn) {
cip.credentials = credentials;
cip.prepareFieldsForCredentials(!Boolean(dontAutoFillIn));
}
}
};
cip.prepareFieldsForCredentials = function(autoFillInForSingle) {
// only one login for this site
@ -1222,7 +1239,7 @@ cip.prepareFieldsForCredentials = function(autoFillInForSingle) {
else if (cip.credentials.length > 1 || (cip.credentials.length > 0 && (!cip.settings.autoFillSingleEntry || !autoFillInForSingle))) {
cip.preparePageForMultipleCredentials(cip.credentials);
}
}
};
cip.preparePageForMultipleCredentials = function(credentials) {
// add usernames + descriptions to autocomplete-list and popup-list
@ -1254,7 +1271,7 @@ cip.preparePageForMultipleCredentials = function(credentials) {
}
}
}
}
};
cip.getFormActionUrl = function(combination) {
const field = _f(combination.password) || _f(combination.username);
@ -1275,7 +1292,7 @@ cip.getFormActionUrl = function(combination) {
}
return action;
}
};
cip.fillInCredentials = function(combination, onlyPassword, suppressWarnings) {
const action = cip.getFormActionUrl(combination);
@ -1317,7 +1334,7 @@ cip.fillInCredentials = function(combination, onlyPassword, suppressWarnings) {
cip.fillIn(combination, onlyPassword, suppressWarnings);
});
}
}
};
cip.fillInFromActiveElement = function(suppressWarnings) {
const el = document.activeElement;
@ -1340,7 +1357,7 @@ cip.fillInFromActiveElement = function(suppressWarnings) {
delete combination.loginId;
cip.fillInCredentials(combination, false, suppressWarnings);
}
};
cip.fillInFromActiveElementPassOnly = function(suppressWarnings) {
const el = document.activeElement;
@ -1373,7 +1390,7 @@ cip.fillInFromActiveElementPassOnly = function(suppressWarnings) {
delete combination.loginId;
cip.fillInCredentials(combination, true, suppressWarnings);
}
};
cip.setValue = function(field, value) {
if (field.is('select')) {
@ -1389,7 +1406,7 @@ cip.setValue = function(field, value) {
cip.setValueWithChange(field, value);
field.trigger('input');
}
}
};
cip.fillInStringFields = function(fields, StringFields, filledInFields) {
let $filledIn = false;
@ -1408,7 +1425,7 @@ cip.fillInStringFields = function(fields, StringFields, filledInFields) {
}
return $filledIn;
}
};
cip.setValueWithChange = function(field, value) {
@ -1425,7 +1442,7 @@ cip.setValueWithChange = function(field, value) {
field.val(value);
field[0].dispatchEvent(new Event('input', {'bubbles': true}));
field[0].dispatchEvent(new Event('change', {'bubbles': true}));
}
};
cip.fillIn = function(combination, onlyPassword, suppressWarnings) {
// no credentials available
@ -1576,7 +1593,7 @@ cip.fillIn = function(combination, onlyPassword, suppressWarnings) {
}
}
}
}
};
cip.contextMenuRememberCredentials = function() {
const el = document.activeElement;
@ -1691,7 +1708,7 @@ cipEvents.clearCredentials = function() {
}
}
}
}
};
cipEvents.triggerActivatedTab = function() {
// doesn't run a second time because of _called.initCredentialFields set to true
@ -1705,4 +1722,4 @@ cipEvents.triggerActivatedTab = function() {
args: [ cip.url, cip.submitUrl ]
}).then(cip.retrieveCredentialsCallback);
}
}
};

View file

@ -25,33 +25,33 @@ options.initMenu = function() {
});
$('div.tab:first').show();
}
};
options.saveSetting = function(name) {
const $id = '#' + name;
$($id).closest('.control-group').removeClass('error').addClass('success');
setTimeout(() => { $($id).closest('.control-group').removeClass('success') }, 2500);
setTimeout(() => { $($id).closest('.control-group').removeClass('success'); }, 2500);
localStorage.settings = JSON.stringify(options.settings);
browser.runtime.sendMessage({
action: 'load_settings'
});
}
};
options.saveSettings = function() {
localStorage.settings = JSON.stringify(options.settings);
browser.runtime.sendMessage({
action: 'load_settings'
});
}
};
options.saveKeyRing = function() {
localStorage.keyRing = JSON.stringify(options.keyRing);
browser.runtime.sendMessage({
action: 'load_keyring'
});
}
};
options.initGeneralSettings = function() {
$('#tab-general-settings input[type=checkbox]').each(function() {
@ -140,7 +140,7 @@ options.showKeePassXCVersions = function(response) {
$('#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});
@ -200,7 +200,7 @@ options.initConnectedDatabases = function() {
action: 'associate'
});
});
}
};
options.initSpecifiedCredentialFields = function() {
$('#dialogDeleteSpecifiedCredentialFields').modal({keyboard: true, show: false, backdrop: true});
@ -249,11 +249,11 @@ options.initSpecifiedCredentialFields = function() {
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();
}
}
};

View file

@ -1,6 +1,6 @@
$(function() {
browser.runtime.getBackgroundPage().then((global) => {
browser.tabs.query({"active": true, "currentWindow": true}.then((tab) => {
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++) {

View file

@ -1,8 +1,9 @@
$(function() {
browser.runtime.getBackgroundPage().then((global) => {
browser.tabs.query({"active": true, "currentWindow": true}).then((tabs) => {
if (tabs.length === 0)
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;