diff --git a/keepassxc-browser/_locales/en/messages.json b/keepassxc-browser/_locales/en/messages.json
index 9495ee1..acf912e 100644
--- a/keepassxc-browser/_locales/en/messages.json
+++ b/keepassxc-browser/_locales/en/messages.json
@@ -163,6 +163,10 @@
"message": "Database is locked",
"description": "Username field icon hover text when database is locked."
},
+ "usernameDisconnectedFieldText": {
+ "message": "KeePassXC is disconnected",
+ "description": "Username field icon hover text when KeePassXC is disconnected."
+ },
"usernameFieldIcon": {
"message": "Username field icon",
"description": "Username field icon text."
diff --git a/keepassxc-browser/background/browserAction.js b/keepassxc-browser/background/browserAction.js
index 4bf4179..282cd96 100755
--- a/keepassxc-browser/background/browserAction.js
+++ b/keepassxc-browser/background/browserAction.js
@@ -35,8 +35,10 @@ browserAction.showDefault = async function(tab) {
console.log('Error: Cannot show default popup: ' + err);
});
- if (!response || keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable) {
+ if (!response && !keepass.isKeePassXCAvailable) {
stackData.iconType = 'cross';
+ } else if (keepass.isKeePassXCAvailable && keepass.isDatabaseClosed) {
+ stackData.iconType = 'locked';
}
if (page.tabs[tab.id] && page.tabs[tab.id].loginList.length > 0) {
diff --git a/keepassxc-browser/background/keepass.js b/keepassxc-browser/background/keepass.js
index 5c261c0..49a9ab5 100755
--- a/keepassxc-browser/background/keepass.js
+++ b/keepassxc-browser/background/keepass.js
@@ -512,6 +512,7 @@ keepass.getDatabaseHash = async function(tab, args = []) {
const encrypted = keepass.encrypt(messageData, nonce);
if (encrypted.length <= 0) {
keepass.handleError(tab, kpErrors.PUBLIC_KEY_NOT_FOUND);
+ keepass.updateDatabaseHashToContent();
return keepass.databaseHash;
}
@@ -599,6 +600,7 @@ keepass.changePublicKeys = async function(tab, enableTimeout = false, connection
keepass.handleError(tab, kpErrors.KEY_CHANGE_FAILED);
}
+ keepass.updateDatabaseHashToContent();
return false;
}
@@ -1169,7 +1171,7 @@ keepass.updateDatabase = async function() {
keepass.associated.hash = null;
await keepass.testAssociation(null);
const configured = await keepass.isConfigured();
- keepass.updatePopup(configured ? 'normal' : 'cross');
+ keepass.updatePopup(configured ? 'normal' : 'locked');
keepass.updateDatabaseHashToContent();
};
@@ -1180,7 +1182,8 @@ keepass.updateDatabaseHashToContent = async function() {
// Send message to content script
browser.tabs.sendMessage(tabs[0].id, {
action: 'check_database_hash',
- hash: { old: keepass.previousDatabaseHash, new: keepass.databaseHash }
+ hash: { old: keepass.previousDatabaseHash, new: keepass.databaseHash },
+ connected: keepass.isKeePassXCAvailable
}).catch((err) => {
console.log('Error: No content script available for this tab.');
});
diff --git a/keepassxc-browser/content/keepassxc-browser.js b/keepassxc-browser/content/keepassxc-browser.js
index b5f6231..a1b6ea8 100755
--- a/keepassxc-browser/content/keepassxc-browser.js
+++ b/keepassxc-browser/content/keepassxc-browser.js
@@ -6,6 +6,12 @@ const ManualFill = {
BOTH: 2
};
+const DatabaseState = {
+ DISCONNECTED: 0,
+ LOCKED: 1,
+ UNLOCKED: 2
+}
+
const acceptedOTPFields = [
'2fa',
'auth',
@@ -22,7 +28,7 @@ _called.retrieveCredentials = false;
_called.clearLogins = false;
_called.manualFillRequested = ManualFill.NONE;
let _singleInputEnabledForPage = false;
-let _databaseClosed = true;
+let _databaseState = DatabaseState.DISCONNECTED;
const _maximumInputs = 100;
const _maximumMutations = 200;
@@ -60,7 +66,7 @@ browser.runtime.onMessage.addListener(async function(req, sender) {
} else if (req.action === 'ignore_site') {
kpxc.ignoreSite(req.args);
} else if (req.action === 'check_database_hash' && 'hash' in req) {
- kpxc.detectDatabaseChange(req.hash);
+ kpxc.detectDatabaseChange(req);
} else if (req.action === 'remember_credentials') {
kpxc.contextMenuRememberCredentials();
} else if (req.action === 'choose_credential_fields') {
@@ -544,7 +550,7 @@ kpxcFields.getPasswordField = function(usernameId, checkDisabled) {
passwordField = null;
}
- kpxcPasswordIcons.newIcon(kpxc.settings.usePasswordGeneratorIcons, passwordField, [], undefined, _databaseClosed);
+ kpxcPasswordIcons.newIcon(kpxc.settings.usePasswordGeneratorIcons, passwordField, [], undefined, _databaseState);
} else {
// Search all inputs on page
const inputs = kpxcFields.getAllFields();
@@ -595,7 +601,7 @@ kpxcFields.prepareCombinations = async function(combinations) {
const usernameField = c.username ? _f(c.username) : field;
if (kpxc.settings.showLoginFormIcon && await kpxc.passwordFilled() === false) {
- kpxcUsernameIcons.newIcon(usernameField, _databaseClosed);
+ kpxcUsernameIcons.newIcon(usernameField, _databaseState);
}
// Initialize form-submit for remembering credentials
@@ -615,7 +621,7 @@ kpxcFields.useDefinedCredentialFields = function() {
// Handle custom TOTP field
if (_f(creds.totp)) {
- kpxcTOTPIcons.newIcon(_f(creds.totp), _databaseClosed);
+ kpxcTOTPIcons.newIcon(_f(creds.totp), _databaseState);
}
let found = _f(creds.username) || _f(creds.password);
@@ -929,20 +935,20 @@ kpxc.clearAllFromPage = function() {
// Switch credentials if database is changed or closed
kpxc.detectDatabaseChange = async function(response) {
- _databaseClosed = true;
+ _databaseState = DatabaseState.LOCKED;
kpxc.clearAllFromPage();
- kpxc.switchIcons(true);
+ kpxc.switchIcons();
if (document.visibilityState !== 'hidden') {
- if (response.new !== '' && response.new !== response.old) {
+ if (response.hash.new !== '' && response.hash.new !== response.hash.old) {
_called.retrieveCredentials = false;
const settings = await browser.runtime.sendMessage({
action: 'load_settings'
});
kpxc.settings = settings;
await kpxc.initCredentialFields(true);
- kpxc.switchIcons(false); // Unlocked
- _databaseClosed = false;
+ _databaseState = DatabaseState.UNLOCKED;
+ kpxc.switchIcons();
// If user has requested a manual fill through context menu the actual credential filling
// is handled here when the opened database has been regognized. It's not a pretty hack.
@@ -950,6 +956,9 @@ kpxc.detectDatabaseChange = async function(response) {
await kpxc.fillInFromActiveElement(false, _called.manualFillRequested === ManualFill.PASS);
_called.manualFillRequested = ManualFill.NONE;
}
+ } else if (!response.connected) {
+ _databaseState = DatabaseState.DISCONNECTED;
+ kpxc.switchIcons();
}
}
};
@@ -1008,12 +1017,13 @@ kpxc.initCredentialFields = async function(forceCall, inputs) {
return;
}
- // Update database closed status
+ // Check database closed status
const res = await browser.runtime.sendMessage({
action: 'get_status',
args: [ true ]
});
- _databaseClosed = res.databaseClosed;
+
+ _databaseState = !res.keePassXCAvailable ? DatabaseState.DISCONNECTED : DatabaseState.LOCKED;
kpxcFields.prepareVisibleFieldsWithID('select');
kpxc.initPasswordGenerator(inputs);
@@ -1061,7 +1071,7 @@ kpxc.initPasswordGenerator = function(inputs) {
for (let i = 0; i < inputs.length; i++) {
if (inputs[i] && inputs[i].getLowerCaseAttribute('type') === 'password') {
- kpxcPasswordIcons.newIcon(true, inputs[i], inputs, i, _databaseClosed);
+ kpxcPasswordIcons.newIcon(true, inputs[i], inputs, i, _databaseState);
}
}
};
@@ -1073,7 +1083,7 @@ kpxc.initOTPFields = function(inputs) {
const autocomplete = i.getLowerCaseAttribute('autocomplete');
if (autocomplete === 'one-time-code' || acceptedOTPFields.some(f => (id && id.includes(f)) || (name && name.includes(f)))) {
- kpxcTOTPIcons.newIcon(i, _databaseClosed);
+ kpxcTOTPIcons.newIcon(i, _databaseState);
}
}
};
@@ -1876,10 +1886,10 @@ kpxc.getDocumentLocation = function() {
};
// Sets the icons to corresponding database lock status
-kpxc.switchIcons = function(locked) {
- kpxcUsernameIcons.switchIcon(locked);
- kpxcPasswordIcons.switchIcon(locked);
- kpxcTOTPIcons.switchIcon(locked);
+kpxc.switchIcons = function() {
+ kpxcUsernameIcons.switchIcon(_databaseState);
+ kpxcPasswordIcons.switchIcon(_databaseState);
+ kpxcTOTPIcons.switchIcon(_databaseState);
};
kpxc.setPasswordFilled = function(state) {
@@ -1918,8 +1928,13 @@ kpxcEvents.triggerActivatedTab = async function() {
kpxc.init();
// Update username field lock state
- const state = await browser.runtime.sendMessage({ action: 'check_database_hash' });
- kpxc.switchIcons(state === '');
+ const res = await browser.runtime.sendMessage({
+ action: 'get_status',
+ args: [ true ]
+ });
+
+ _databaseState = !res.keePassXCAvailable ? DatabaseState.DISCONNECTED : DatabaseState.LOCKED;
+ kpxc.switchIcons();
// initCredentialFields calls also "retrieve_credentials", to prevent it
// check of init() was already called
diff --git a/keepassxc-browser/content/pwgen.js b/keepassxc-browser/content/pwgen.js
index e25f0d5..8fa0687 100644
--- a/keepassxc-browser/content/pwgen.js
+++ b/keepassxc-browser/content/pwgen.js
@@ -3,20 +3,20 @@
const kpxcPasswordIcons = {};
kpxcPasswordIcons.icons = [];
-kpxcPasswordIcons.newIcon = function(useIcons, field, inputs, pos, databaseClosed = true) {
- kpxcPasswordIcons.icons.push(new PasswordIcon(useIcons, field, inputs, pos, databaseClosed));
+kpxcPasswordIcons.newIcon = function(useIcons, field, inputs, pos, databaseState = DatabaseState.DISCONNECTED) {
+ kpxcPasswordIcons.icons.push(new PasswordIcon(useIcons, field, inputs, pos, databaseState));
};
-kpxcPasswordIcons.switchIcon = function(locked) {
- kpxcPasswordIcons.icons.forEach(u => u.switchIcon(locked));
+kpxcPasswordIcons.switchIcon = function(state) {
+ kpxcPasswordIcons.icons.forEach(u => u.switchIcon(state));
};
class PasswordIcon extends Icon {
- constructor(useIcons, field, inputs, pos, databaseClosed) {
+ constructor(useIcons, field, inputs, pos, databaseState) {
super();
this.useIcons = useIcons;
- this.databaseClosed = databaseClosed;
+ this.databaseState = databaseState;
this.initField(field, inputs, pos);
kpxcUI.monitorIconPosition(this);
@@ -77,7 +77,7 @@ PasswordIcon.prototype.createIcon = function(field) {
icon.style.width = Pixels(size);
icon.style.height = Pixels(size);
- if (this.databaseClosed) {
+ if (this.databaseState === DatabaseState.DISCONNECTED || this.databaseState === DatabaseState.LOCKED) {
icon.style.filter = 'saturate(0%)';
}
diff --git a/keepassxc-browser/content/totp-field.js b/keepassxc-browser/content/totp-field.js
index 1d676ac..2de8d1d 100644
--- a/keepassxc-browser/content/totp-field.js
+++ b/keepassxc-browser/content/totp-field.js
@@ -7,21 +7,21 @@ const ignoredTypes = [ 'email', 'password', 'username' ];
var kpxcTOTPIcons = {};
kpxcTOTPIcons.icons = [];
-kpxcTOTPIcons.newIcon = function(field, databaseClosed = true) {
- kpxcTOTPIcons.icons.push(new TOTPFieldIcon(field, databaseClosed));
+kpxcTOTPIcons.newIcon = function(field, databaseState = DatabaseState.DISCONNECTED) {
+ kpxcTOTPIcons.icons.push(new TOTPFieldIcon(field, databaseState));
};
-kpxcTOTPIcons.switchIcon = function(locked) {
- kpxcTOTPIcons.icons.forEach(u => u.switchIcon(locked));
+kpxcTOTPIcons.switchIcon = function(state) {
+ kpxcTOTPIcons.icons.forEach(u => u.switchIcon(state));
};
class TOTPFieldIcon extends Icon {
- constructor(field, databaseClosed = true) {
+ constructor(field, databaseState = DatabaseState.DISCONNECTED) {
super();
this.icon = null;
this.inputField = null;
- this.databaseClosed = databaseClosed;
+ this.databaseState = databaseState;
this.initField(field);
kpxcUI.monitorIconPosition(this);
@@ -70,7 +70,7 @@ TOTPFieldIcon.prototype.createIcon = function(field) {
icon.style.width = Pixels(size);
icon.style.height = Pixels(size);
- if (this.databaseClosed) {
+ if (this.databaseState === DatabaseState.DISCONNECTED || this.databaseState === DatabaseState.LOCKED) {
icon.style.filter = 'saturate(0%)';
}
diff --git a/keepassxc-browser/content/ui.js b/keepassxc-browser/content/ui.js
index 87e83da..83a78f5 100644
--- a/keepassxc-browser/content/ui.js
+++ b/keepassxc-browser/content/ui.js
@@ -22,15 +22,15 @@ class Icon {
}
}
- switchIcon(locked) {
+ switchIcon(state) {
if (!this.icon) {
return;
}
- if (locked) {
- this.icon.style.filter = 'saturate(0%)';
- } else {
+ if (state === DatabaseState.UNLOCKED) {
this.icon.style.filter = 'saturate(100%)';
+ } else {
+ this.icon.style.filter = 'saturate(0%)';
}
}
}
@@ -94,7 +94,6 @@ kpxcUI.setIconPosition = function(icon, field) {
icon.style.top = Pixels(rect.top + document.scrollingElement.scrollTop + offset + 1);
icon.style.left = Pixels(rect.left + document.scrollingElement.scrollLeft + field.offsetWidth - size - offset);
}
-
};
/**
diff --git a/keepassxc-browser/content/username-field.js b/keepassxc-browser/content/username-field.js
index 504d9bb..86b0296 100644
--- a/keepassxc-browser/content/username-field.js
+++ b/keepassxc-browser/content/username-field.js
@@ -3,8 +3,8 @@
const kpxcUsernameIcons = {};
kpxcUsernameIcons.icons = [];
-kpxcUsernameIcons.newIcon = function(field, databaseClosed = true) {
- kpxcUsernameIcons.icons.push(new UsernameFieldIcon(field, databaseClosed));
+kpxcUsernameIcons.newIcon = function(field, databaseState = DatabaseState.DISCONNECTED) {
+ kpxcUsernameIcons.icons.push(new UsernameFieldIcon(field, databaseState));
};
kpxcUsernameIcons.switchIcon = function(locked) {
@@ -13,30 +13,24 @@ kpxcUsernameIcons.switchIcon = function(locked) {
class UsernameFieldIcon extends Icon {
- constructor(field, databaseClosed = true) {
+ constructor(field, databaseState = DatabaseState.DISCONNECTED) {
super();
- this.databaseClosed = databaseClosed;
+ this.databaseState = databaseState;
this.icon = null;
this.inputField = null;
- this.initField(field,);
+ this.initField(field);
kpxcUI.monitorIconPosition(this);
}
- switchIcon(locked) {
+ switchIcon(state) {
if (!this.icon) {
return;
}
- if (locked) {
- this.icon.classList.remove(getIconClassName());
- this.icon.classList.add(getIconClassName(true));
- this.icon.title = tr('usernameLockedFieldText');
- } else {
- this.icon.classList.remove(getIconClassName(true));
- this.icon.classList.add(getIconClassName());
- this.icon.title = tr('usernameFieldText');
- }
+ this.icon.classList.remove('lock', 'moz-lock', 'unlock', 'moz-unlock', 'disconnected', 'moz-disconnected');
+ this.icon.classList.add(getIconClassName(state));
+ this.icon.title = getIconText(state);
}
}
@@ -66,7 +60,7 @@ UsernameFieldIcon.prototype.createIcon = function(target) {
}
const field = target;
- const className = getIconClassName(this.databaseClosed);
+ const className = getIconClassName(this.databaseState);
// Size the icon dynamically, but not greater than 24 or smaller than 14
const size = Math.max(Math.min(24, field.offsetHeight - 4), 14);
@@ -82,7 +76,7 @@ UsernameFieldIcon.prototype.createIcon = function(target) {
const icon = kpxcUI.createElement('div', 'kpxc kpxc-username-icon ' + className,
{
- 'title': this.databaseClosed ? tr('usernameLockedFieldText') : tr('usernameFieldText'),
+ 'title': getIconText(this.databaseState),
'alt': tr('usernameFieldIcon'),
'size': size,
'offset': offset,
@@ -143,13 +137,25 @@ const iconClicked = async function(field, icon) {
}
};
-const getIconClassName = function(locked = false) {
- if (locked) {
+const getIconClassName = function(state = DatabaseState.UNLOCKED) {
+ if (state === DatabaseState.LOCKED) {
return (isFirefox() ? 'lock-moz' : 'lock');
+ } else if (state === DatabaseState.DISCONNECTED) {
+ return (isFirefox() ? 'lock-disconnected' : 'disconnected');
}
return (isFirefox() ? 'unlock-moz' : 'unlock');
};
+const getIconText = function(state) {
+ if (state === DatabaseState.LOCKED) {
+ return tr('usernameLockedFieldText');
+ } else if (state === DatabaseState.DISCONNECTED) {
+ return tr('usernameDisconnectedFieldText');
+ }
+
+ return tr('usernameFieldText');
+};
+
const fillCredentials = function(field) {
const fieldId = field.getAttribute('data-kpxc-id');
kpxcFields.prepareId(fieldId);
diff --git a/keepassxc-browser/css/username.css b/keepassxc-browser/css/username.css
index 9321a03..6b2e32a 100644
--- a/keepassxc-browser/css/username.css
+++ b/keepassxc-browser/css/username.css
@@ -3,6 +3,16 @@
cursor: pointer;
}
+.kpxc-username-icon.disconnected {
+ background: url('chrome-extension://__MSG_@@extension_id__/icons/disconnected.svg') right no-repeat;
+ background-size: contain;
+}
+
+.kpxc-username-icon.disconnected-moz {
+ background: url('moz-extension://__MSG_@@extension_id__/icons/disconnected.svg') right no-repeat;
+ background-size: contain;
+}
+
.kpxc-username-icon.lock {
background: url('chrome-extension://__MSG_@@extension_id__/icons/locked.svg') right no-repeat;
background-size: contain;
@@ -21,4 +31,4 @@
.kpxc-username-icon.unlock-moz {
background: url('moz-extension://__MSG_@@extension_id__/icons/keepassxc.svg') right no-repeat;
background-size: contain;
-}
\ No newline at end of file
+}
diff --git a/keepassxc-browser/icons/disconnected.svg b/keepassxc-browser/icons/disconnected.svg
new file mode 100644
index 0000000..89ebacc
--- /dev/null
+++ b/keepassxc-browser/icons/disconnected.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/keepassxc-browser/icons/keepassxc-dark.svg b/keepassxc-browser/icons/keepassxc-dark.svg
index a000706..7a756e5 100644
--- a/keepassxc-browser/icons/keepassxc-dark.svg
+++ b/keepassxc-browser/icons/keepassxc-dark.svg
@@ -1,126 +1,19 @@
diff --git a/keepassxc-browser/icons/keepassxc-dark_128x128.png b/keepassxc-browser/icons/keepassxc-dark_128x128.png
index 57ad320..6ea5610 100644
Binary files a/keepassxc-browser/icons/keepassxc-dark_128x128.png and b/keepassxc-browser/icons/keepassxc-dark_128x128.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_16x16.png b/keepassxc-browser/icons/keepassxc-dark_16x16.png
index 3c10ad4..6426d01 100644
Binary files a/keepassxc-browser/icons/keepassxc-dark_16x16.png and b/keepassxc-browser/icons/keepassxc-dark_16x16.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_18x18.png b/keepassxc-browser/icons/keepassxc-dark_18x18.png
new file mode 100644
index 0000000..03797cb
Binary files /dev/null and b/keepassxc-browser/icons/keepassxc-dark_18x18.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_19x19.png b/keepassxc-browser/icons/keepassxc-dark_19x19.png
new file mode 100644
index 0000000..19340e1
Binary files /dev/null and b/keepassxc-browser/icons/keepassxc-dark_19x19.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_32x32.png b/keepassxc-browser/icons/keepassxc-dark_32x32.png
index b209235..7f2cd88 100644
Binary files a/keepassxc-browser/icons/keepassxc-dark_32x32.png and b/keepassxc-browser/icons/keepassxc-dark_32x32.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_36x36.png b/keepassxc-browser/icons/keepassxc-dark_36x36.png
new file mode 100644
index 0000000..0374a7d
Binary files /dev/null and b/keepassxc-browser/icons/keepassxc-dark_36x36.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_38x38.png b/keepassxc-browser/icons/keepassxc-dark_38x38.png
new file mode 100644
index 0000000..62b8479
Binary files /dev/null and b/keepassxc-browser/icons/keepassxc-dark_38x38.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_48x48.png b/keepassxc-browser/icons/keepassxc-dark_48x48.png
index 08e396c..79dd7a6 100644
Binary files a/keepassxc-browser/icons/keepassxc-dark_48x48.png and b/keepassxc-browser/icons/keepassxc-dark_48x48.png differ
diff --git a/keepassxc-browser/icons/keepassxc-dark_64x64.png b/keepassxc-browser/icons/keepassxc-dark_64x64.png
index 439ca7e..fea3857 100644
Binary files a/keepassxc-browser/icons/keepassxc-dark_64x64.png and b/keepassxc-browser/icons/keepassxc-dark_64x64.png differ
diff --git a/keepassxc-browser/icons/key.svg b/keepassxc-browser/icons/key.svg
old mode 100755
new mode 100644
index d5c5c0e..59f9c26
--- a/keepassxc-browser/icons/key.svg
+++ b/keepassxc-browser/icons/key.svg
@@ -1,83 +1 @@
-
-
+
\ No newline at end of file
diff --git a/keepassxc-browser/icons/locked.svg b/keepassxc-browser/icons/locked.svg
index a578bd1..7d84d53 100644
--- a/keepassxc-browser/icons/locked.svg
+++ b/keepassxc-browser/icons/locked.svg
@@ -1,208 +1 @@
-
-
+
\ No newline at end of file
diff --git a/keepassxc-browser/icons/otp.svg b/keepassxc-browser/icons/otp.svg
index f0fe378..670c2ac 100644
--- a/keepassxc-browser/icons/otp.svg
+++ b/keepassxc-browser/icons/otp.svg
@@ -1,216 +1 @@
-
-
+
\ No newline at end of file
diff --git a/keepassxc-browser/icons/toolbar/icon_cross.png b/keepassxc-browser/icons/toolbar/icon_cross.png
index 8b3ad87..5e6b16d 100644
Binary files a/keepassxc-browser/icons/toolbar/icon_cross.png and b/keepassxc-browser/icons/toolbar/icon_cross.png differ
diff --git a/keepassxc-browser/icons/toolbar/icon_dark.png b/keepassxc-browser/icons/toolbar/icon_dark.png
new file mode 100644
index 0000000..62b8479
Binary files /dev/null and b/keepassxc-browser/icons/toolbar/icon_dark.png differ
diff --git a/keepassxc-browser/icons/toolbar/icon_locked.png b/keepassxc-browser/icons/toolbar/icon_locked.png
new file mode 100644
index 0000000..3f4f112
Binary files /dev/null and b/keepassxc-browser/icons/toolbar/icon_locked.png differ
diff --git a/keepassxc-browser/icons/toolbar/icon_new_cross.png b/keepassxc-browser/icons/toolbar/icon_new_cross.png
index adaf0cc..c6080be 100644
Binary files a/keepassxc-browser/icons/toolbar/icon_new_cross.png and b/keepassxc-browser/icons/toolbar/icon_new_cross.png differ
diff --git a/keepassxc-browser/manifest.json b/keepassxc-browser/manifest.json
index e9a191c..d07ea0d 100755
--- a/keepassxc-browser/manifest.json
+++ b/keepassxc-browser/manifest.json
@@ -107,6 +107,7 @@
}
},
"web_accessible_resources": [
+ "icons/disconnected.svg",
"icons/keepassxc.svg",
"icons/key.svg",
"icons/locked.svg",