Version 0.5.0

This commit is contained in:
varjolintu 2018-01-22 15:20:55 +02:00
parent c55999ea1c
commit ff03e5fc04
25 changed files with 3955 additions and 3861 deletions

View file

@ -1,3 +1,15 @@
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

View file

@ -5,261 +5,261 @@ 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));
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));
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 = {
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'
};
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) {
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;
};

View 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,272 @@ 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();
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
};

View file

@ -4,82 +4,82 @@ 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;
}
if (httpAuth.requests.indexOf(details.requestId) >= 0 || !page.tabs[details.tabId]) {
reject({});
return;
}
httpAuth.requests.push(details.requestId);
httpAuth.requests.push(details.requestId);
if (details.challenger) {
details.proxyUrl = details.challenger.host;
}
if (details.challenger) {
details.proxyUrl = details.challenger.host;
}
details.searchUrl = (details.isProxy && details.proxyUrl) ? details.proxyUrl : details.url;
details.searchUrl = (details.isProxy && details.proxyUrl) ? details.proxyUrl : details.url;
keepass.retrieveCredentials((logins) => {
httpAuth.loginOrShowCredentials(logins, details, resolve, reject);
}, { "id": details.tabId }, details.searchUrl, details.searchUrl, true);
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
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 {
kpxcEvent.onHTTPAuthPopup(null, { 'id': details.tabId }, { 'logins': logins, 'url': details.searchUrl, 'resolve': resolve });
}
}
// no logins found
else {
reject({});
}
};

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
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
};
var page = {};
@ -13,72 +13,72 @@ 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;
}
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 +90,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 +141,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';
}
};

View file

@ -1,6 +1,6 @@
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;
};

View file

@ -1,22 +1,22 @@
.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: Verdana, Arial, 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;
}
.kpxc .ui-widget-overlay {
@ -24,12 +24,12 @@
}
.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;
background-color: #3a8233;
color: #fff;
}
.kpxc .ui-dialog .ui-dialog-buttonpane {
@ -41,164 +41,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 +206,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;
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "keepassxc-browser",
"version": "0.4.8",
"name": "KeePassXC-Browser",
"version": "0.5.0",
"description": "KeePassXC integration for modern web browsers",
"author": "KeePassXC Team",
"icons": {
@ -15,7 +15,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": {
@ -65,16 +65,23 @@
"description": "Insert username + password",
"suggested_key": {
"default": "Alt+Shift+U",
"mac": "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"

View file

@ -1,143 +1,142 @@
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%;
background-color: #3a8233;
border-color: #01520e;
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: #01520e;
}
.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: #01520e;
}
.navbar-default .navbar-toggle {
border-color: #01520e;
border-color: #01520e;
}
.navbar-default .navbar-toggle:hover,
.navbar-default .navbar-toggle:focus {
background-color: #01520e;
background-color: #01520e;
}
.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: #01520e;
}
}
.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;
}

View file

@ -1,297 +1,300 @@
<!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.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>
<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>
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>
<!-- 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>
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>,
<a target="_blank" href="https://github.com/smorks">Andy Brandt</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>
Developed by <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> 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/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>
</div>
<hr>
<div class="footer">
<p>2010-2017 - Perry Nguyen, Lukas Schulze</p>
<p>2017-2018 - Angus Gratton, Andy Brandt, Sami Vänttinen</p>
</div>
</div> <!-- /container -->
</body>
</html>

View file

@ -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();
}
};

View file

@ -1,75 +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;
height: 30px;
float: right;
height: 30px;
}

View file

@ -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.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>
<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>

View file

@ -1,89 +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);
});

View file

@ -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);
});

View file

@ -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.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>
<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>

View file

@ -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);
});
});

View file

@ -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.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>
<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>

View file

@ -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'
});
});
});

View file

@ -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.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>
<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>

View file

@ -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.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>
<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>

View file

@ -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);
});