mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Add support for Manifest V3
This commit is contained in:
parent
2c07677207
commit
8e4ecdb59e
21 changed files with 475 additions and 117 deletions
|
|
@ -115,6 +115,7 @@
|
|||
"IGNORE_FULL": true,
|
||||
"IGNORE_NORMAL": true,
|
||||
"IGNORE_NOTHING": true,
|
||||
"importScripts": true,
|
||||
"initColorTheme": true,
|
||||
"isEdge": true,
|
||||
"isFirefox": true,
|
||||
|
|
|
|||
21
build.js
21
build.js
|
|
@ -13,25 +13,11 @@ const BROWSERS = {
|
|||
'Chromium': 'manifest_chromium.json',
|
||||
};
|
||||
|
||||
async function adjustManifest(manifest) {
|
||||
async function getDestinationFilename(manifest) {
|
||||
const manifestFile = await fs.readFile(DEFAULT, { encoding: 'utf8' });
|
||||
const data = JSON.parse(manifestFile);
|
||||
const browser = manifest.substring(manifest.indexOf('_') + 1, manifest.indexOf('.'));
|
||||
|
||||
if (manifest.includes('firefox')) {
|
||||
for (const elem in data['icons']) {
|
||||
data['icons'][elem] = 'icons/keepassxc.svg';
|
||||
}
|
||||
for (const elem in data['browser_action']['default_icon']) {
|
||||
data['browser_action']['default_icon'][elem] = 'icons/keepassxc.svg';
|
||||
}
|
||||
delete data['version_name'];
|
||||
delete data['minimum_chrome_version'];
|
||||
} else if (manifest.includes('chromium')) {
|
||||
delete data['applications'];
|
||||
}
|
||||
|
||||
await fs.writeFile(manifest, JSON.stringify(data, null, 4));
|
||||
return `keepassxc-browser_${data['version']}_${browser}.zip`;
|
||||
}
|
||||
|
||||
|
|
@ -52,15 +38,14 @@ async function updateTranslations() {
|
|||
for (const browser in BROWSERS) {
|
||||
console.log(`KeePassXC-Browser: Creating extension package for ${browser}`);
|
||||
|
||||
const fileName = await adjustManifest(BROWSERS[browser]);
|
||||
await fs.copyFile(BROWSERS[browser], `${DEST}/manifest.json`);
|
||||
const fileName = await getDestinationFilename(BROWSERS[browser]);
|
||||
await fs.copyFile(`./dist/${BROWSERS[browser]}`, `${DEST}/manifest.json`);
|
||||
|
||||
if (await fs.exists(fileName)) {
|
||||
await fs.rm(fileName);
|
||||
}
|
||||
|
||||
await zaf.zip(DEST, fileName);
|
||||
await fs.rm(BROWSERS[browser], { recursive: true });
|
||||
console.log('Done');
|
||||
}
|
||||
|
||||
|
|
|
|||
160
dist/manifest_chromium.json
vendored
Executable file
160
dist/manifest_chromium.json
vendored
Executable file
|
|
@ -0,0 +1,160 @@
|
|||
{
|
||||
"manifest_version": 3,
|
||||
"name": "KeePassXC-Browser",
|
||||
"version": "1.8.11",
|
||||
"version_name": "1.8.11",
|
||||
"minimum_chrome_version": "93",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"author": "KeePassXC Team",
|
||||
"icons": {
|
||||
"16": "icons/keepassxc_16x16.png",
|
||||
"48": "icons/keepassxc_48x48.png",
|
||||
"64": "icons/keepassxc_64x64.png",
|
||||
"96": "icons/keepassxc_96x96.png",
|
||||
"128": "icons/keepassxc_128x128.png"
|
||||
},
|
||||
"action": {
|
||||
"default_icon": {
|
||||
"16": "icons/keepassxc_16x16.png",
|
||||
"18": "icons/keepassxc_18x18.png",
|
||||
"19": "icons/keepassxc_19x19.png",
|
||||
"32": "icons/keepassxc_32x32.png",
|
||||
"36": "icons/keepassxc_36x36.png",
|
||||
"38": "icons/keepassxc_38x38.png",
|
||||
"64": "icons/keepassxc_64x64.png"
|
||||
},
|
||||
"default_title": "KeePassXC-Browser",
|
||||
"default_popup": "popups/popup.html"
|
||||
},
|
||||
"options_ui": {
|
||||
"page": "options/options.html",
|
||||
"open_in_tab": true
|
||||
},
|
||||
"background": {
|
||||
"service_worker": "background/background_service.js"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
],
|
||||
"js": [
|
||||
"common/browser-polyfill.min.js",
|
||||
"common/global.js",
|
||||
"common/global_ui.js",
|
||||
"common/sites.js",
|
||||
"content/ui.js",
|
||||
"content/banner.js",
|
||||
"content/autocomplete.js",
|
||||
"content/credential-autocomplete.js",
|
||||
"content/custom-fields-banner.js",
|
||||
"content/fields.js",
|
||||
"content/fill.js",
|
||||
"content/form.js",
|
||||
"content/icons.js",
|
||||
"content/keepassxc-browser.js",
|
||||
"content/observer-helper.js",
|
||||
"content/pwgen.js",
|
||||
"content/totp-autocomplete.js",
|
||||
"content/totp-field.js",
|
||||
"content/username-field.js",
|
||||
"content/passkeys-utils.js"
|
||||
],
|
||||
"run_at": "document_idle",
|
||||
"all_frames": true
|
||||
}
|
||||
],
|
||||
"commands": {
|
||||
"fill_username_password": {
|
||||
"description": "__MSG_contextMenuFillUsernameAndPassword__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+U",
|
||||
"mac": "MacCtrl+Shift+U"
|
||||
}
|
||||
},
|
||||
"fill_password": {
|
||||
"description": "__MSG_contextMenuFillPassword__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+I",
|
||||
"mac": "MacCtrl+Shift+I"
|
||||
}
|
||||
},
|
||||
"fill_totp": {
|
||||
"description": "__MSG_contextMenuFillTOTP__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+O",
|
||||
"mac": "MacCtrl+Shift+O"
|
||||
}
|
||||
},
|
||||
"show_password_generator": {
|
||||
"description": "__MSG_contextMenuShowPasswordGenerator__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+G",
|
||||
"mac": "MacCtrl+Shift+G"
|
||||
}
|
||||
},
|
||||
"save_credentials": {
|
||||
"description": "__MSG_contextMenuSaveCredentials__"
|
||||
},
|
||||
"redetect_fields": {
|
||||
"description": "__MSG_popupRedetectButton__"
|
||||
},
|
||||
"choose_credential_fields": {
|
||||
"description": "__MSG_popupChooseCredentialsText__"
|
||||
},
|
||||
"retrive_credentials_forced": {
|
||||
"description": "__MSG_popupReopenButton__"
|
||||
},
|
||||
"request_autotype": {
|
||||
"description": "__MSG_contextMenuRequestGlobalAutoType__"
|
||||
},
|
||||
"reload_extension": {
|
||||
"description": "__MSG_popupReloadButton__"
|
||||
}
|
||||
},
|
||||
"web_accessible_resources": [{
|
||||
"resources": [
|
||||
"icons/disconnected.svg",
|
||||
"icons/help.svg",
|
||||
"icons/keepassxc.svg",
|
||||
"icons/key.svg",
|
||||
"icons/locked.svg",
|
||||
"icons/otp.svg",
|
||||
"css/autocomplete.css",
|
||||
"css/banner.css",
|
||||
"css/button.css",
|
||||
"css/colors.css",
|
||||
"css/define.css",
|
||||
"css/notification.css",
|
||||
"css/pwgen.css",
|
||||
"css/username.css",
|
||||
"css/totp.css",
|
||||
"content/passkeys.js"
|
||||
],
|
||||
"matches": [
|
||||
"https://*/*",
|
||||
"http://*/*"
|
||||
]
|
||||
}],
|
||||
"permissions": [
|
||||
"activeTab",
|
||||
"contextMenus",
|
||||
"clipboardWrite",
|
||||
"nativeMessaging",
|
||||
"notifications",
|
||||
"storage",
|
||||
"tabs",
|
||||
"webNavigation",
|
||||
"webRequest",
|
||||
"webRequestAuthProvider",
|
||||
"webRequestBlocking"
|
||||
],
|
||||
"content_security_policy": {
|
||||
"extension_pages": "script-src 'self'"
|
||||
},
|
||||
"host_permissions": [
|
||||
"https://*/*",
|
||||
"http://*/*"
|
||||
],
|
||||
"default_locale": "en"
|
||||
}
|
||||
166
dist/manifest_firefox.json
vendored
Normal file
166
dist/manifest_firefox.json
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "KeePassXC-Browser",
|
||||
"version": "1.8.11",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"author": "KeePassXC Team",
|
||||
"icons": {
|
||||
"16": "icons/keepassxc.svg",
|
||||
"48": "icons/keepassxc.svg",
|
||||
"64": "icons/keepassxc.svg",
|
||||
"96": "icons/keepassxc.svg",
|
||||
"128": "icons/keepassxc.svg"
|
||||
},
|
||||
"browser_action": {
|
||||
"default_icon": {
|
||||
"16": "icons/keepassxc.svg",
|
||||
"18": "icons/keepassxc.svg",
|
||||
"19": "icons/keepassxc.svg",
|
||||
"32": "icons/keepassxc.svg",
|
||||
"36": "icons/keepassxc.svg",
|
||||
"38": "icons/keepassxc.svg",
|
||||
"64": "icons/keepassxc.svg"
|
||||
},
|
||||
"default_title": "KeePassXC-Browser",
|
||||
"default_popup": "popups/popup.html"
|
||||
},
|
||||
"options_ui": {
|
||||
"page": "options/options.html",
|
||||
"open_in_tab": true
|
||||
},
|
||||
"background": {
|
||||
"scripts": [
|
||||
"common/browser-polyfill.min.js",
|
||||
"common/global.js",
|
||||
"common/sites.js",
|
||||
"background/nacl.min.js",
|
||||
"background/nacl-util.min.js",
|
||||
"background/client.js",
|
||||
"background/keepass.js",
|
||||
"background/httpauth.js",
|
||||
"background/browserAction.js",
|
||||
"background/page.js",
|
||||
"background/event.js",
|
||||
"background/init.js"
|
||||
]
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
],
|
||||
"js": [
|
||||
"common/browser-polyfill.min.js",
|
||||
"common/global.js",
|
||||
"common/sites.js",
|
||||
"content/ui.js",
|
||||
"content/banner.js",
|
||||
"content/autocomplete.js",
|
||||
"content/credential-autocomplete.js",
|
||||
"content/custom-fields-banner.js",
|
||||
"content/fields.js",
|
||||
"content/fill.js",
|
||||
"content/form.js",
|
||||
"content/icons.js",
|
||||
"content/keepassxc-browser.js",
|
||||
"content/observer-helper.js",
|
||||
"content/pwgen.js",
|
||||
"content/totp-autocomplete.js",
|
||||
"content/totp-field.js",
|
||||
"content/username-field.js",
|
||||
"content/passkeys-utils.js"
|
||||
],
|
||||
"run_at": "document_idle",
|
||||
"all_frames": true
|
||||
}
|
||||
],
|
||||
"commands": {
|
||||
"fill_username_password": {
|
||||
"description": "__MSG_contextMenuFillUsernameAndPassword__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+U",
|
||||
"mac": "MacCtrl+Shift+U"
|
||||
}
|
||||
},
|
||||
"fill_password": {
|
||||
"description": "__MSG_contextMenuFillPassword__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+I",
|
||||
"mac": "MacCtrl+Shift+I"
|
||||
}
|
||||
},
|
||||
"fill_totp": {
|
||||
"description": "__MSG_contextMenuFillTOTP__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+O",
|
||||
"mac": "MacCtrl+Shift+O"
|
||||
}
|
||||
},
|
||||
"show_password_generator": {
|
||||
"description": "__MSG_contextMenuShowPasswordGenerator__",
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+G",
|
||||
"mac": "MacCtrl+Shift+G"
|
||||
}
|
||||
},
|
||||
"save_credentials": {
|
||||
"description": "__MSG_contextMenuSaveCredentials__"
|
||||
},
|
||||
"redetect_fields": {
|
||||
"description": "__MSG_popupRedetectButton__"
|
||||
},
|
||||
"choose_credential_fields": {
|
||||
"description": "__MSG_popupChooseCredentialsText__"
|
||||
},
|
||||
"retrive_credentials_forced": {
|
||||
"description": "__MSG_popupReopenButton__"
|
||||
},
|
||||
"request_autotype": {
|
||||
"description": "__MSG_contextMenuRequestGlobalAutoType__"
|
||||
},
|
||||
"reload_extension": {
|
||||
"description": "__MSG_popupReloadButton__"
|
||||
}
|
||||
},
|
||||
"web_accessible_resources": [
|
||||
"icons/disconnected.svg",
|
||||
"icons/help.svg",
|
||||
"icons/keepassxc.svg",
|
||||
"icons/key.svg",
|
||||
"icons/locked.svg",
|
||||
"icons/otp.svg",
|
||||
"css/autocomplete.css",
|
||||
"css/banner.css",
|
||||
"css/button.css",
|
||||
"css/colors.css",
|
||||
"css/define.css",
|
||||
"css/notification.css",
|
||||
"css/pwgen.css",
|
||||
"css/username.css",
|
||||
"css/totp.css",
|
||||
"content/passkeys.js"
|
||||
],
|
||||
"permissions": [
|
||||
"activeTab",
|
||||
"contextMenus",
|
||||
"clipboardWrite",
|
||||
"nativeMessaging",
|
||||
"notifications",
|
||||
"storage",
|
||||
"tabs",
|
||||
"webNavigation",
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"https://*/*",
|
||||
"http://*/*",
|
||||
"https://api.github.com/"
|
||||
],
|
||||
"content_security_policy": "script-src 'self' 'sha256-4nJ8uLezzRE3SiBFdkVN/uNwV9YTOGCqRXg6AvB5rCY='; object-src 'none'",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "keepassxc-browser@keepassxc.org",
|
||||
"strict_min_version": "67.0"
|
||||
}
|
||||
},
|
||||
"default_locale": "en"
|
||||
}
|
||||
20
keepassxc-browser/background/background_service.js
Normal file
20
keepassxc-browser/background/background_service.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
try {
|
||||
importScripts(
|
||||
'../common/browser-polyfill.min.js',
|
||||
'../common/global.js',
|
||||
'../common/sites.js',
|
||||
'nacl.min.js',
|
||||
'nacl-util.min.js',
|
||||
'client.js',
|
||||
'keepass.js',
|
||||
'httpauth.js',
|
||||
'browserAction.js',
|
||||
'page.js',
|
||||
'event.js',
|
||||
'init.js'
|
||||
);
|
||||
} catch (e) {
|
||||
console.log('Cannot import background scripts: ', e);
|
||||
}
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
const browserActionWrapper = browser.action || browser.browserAction;
|
||||
const browserAction = {};
|
||||
|
||||
browserAction.show = function(tab, popupData) {
|
||||
browserAction.show = async function(tab, popupData) {
|
||||
popupData ??= page.popupData;
|
||||
page.popupData = popupData;
|
||||
|
||||
browser.browserAction.setIcon({
|
||||
path: browserAction.generateIconName(popupData.iconType)
|
||||
browserActionWrapper.setIcon({
|
||||
path: await browserAction.generateIconName(popupData.iconType)
|
||||
});
|
||||
|
||||
if (popupData.popup) {
|
||||
browser.browserAction.setPopup({
|
||||
browserActionWrapper.setPopup({
|
||||
tabId: tab.id,
|
||||
popup: `popups/${popupData.popup}.html`
|
||||
});
|
||||
|
|
@ -47,12 +48,27 @@ browserAction.showDefault = async function(tab) {
|
|||
popupData.popup = 'popup_login';
|
||||
}
|
||||
|
||||
browserAction.show(tab, popupData);
|
||||
await browserAction.show(tab, popupData);
|
||||
};
|
||||
|
||||
browserAction.generateIconName = function(iconType) {
|
||||
browserAction.updateIcon = async function(tab, iconType) {
|
||||
if (!tab) {
|
||||
const tabs = await browser.tabs.query({ 'active': true, 'currentWindow': true });
|
||||
if (tabs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
tab = tabs[0];
|
||||
}
|
||||
|
||||
browserActionWrapper.setIcon({
|
||||
path: browserAction.generateIconName(iconType)
|
||||
});
|
||||
};
|
||||
|
||||
browserAction.generateIconName = async function(iconType) {
|
||||
let name = 'icon_';
|
||||
name += (keepass.keePassXCUpdateAvailable()) ? 'new_' : '';
|
||||
name += (await keepass.keePassXCUpdateAvailable()) ? 'new_' : '';
|
||||
name += (!iconType || iconType === 'normal') ? 'normal' : iconType;
|
||||
|
||||
let style = 'colored';
|
||||
|
|
@ -72,7 +88,6 @@ browserAction.ignoreSite = async function(url) {
|
|||
const tab = await getCurrentTab();
|
||||
|
||||
// Send the message to the current tab's content script
|
||||
await browser.runtime.getBackgroundPage();
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'ignore_site',
|
||||
args: [ url ]
|
||||
|
|
|
|||
|
|
@ -135,12 +135,12 @@ kpxcEvent.onGetKeePassXCVersions = async function(tab) {
|
|||
};
|
||||
|
||||
kpxcEvent.onCheckUpdateKeePassXC = async function() {
|
||||
keepass.checkForNewKeePassXCVersion();
|
||||
await keepass.checkForNewKeePassXCVersion();
|
||||
return { current: keepass.currentKeePassXC, latest: keepass.latestKeePassXC.version };
|
||||
};
|
||||
|
||||
kpxcEvent.onUpdateAvailableKeePassXC = async function() {
|
||||
return (Number(page.settings.checkUpdateKeePassXC) !== CHECK_UPDATE_NEVER) ? keepass.keePassXCUpdateAvailable() : false;
|
||||
return (Number(page.settings.checkUpdateKeePassXC) !== CHECK_UPDATE_NEVER) ? await keepass.keePassXCUpdateAvailable() : false;
|
||||
};
|
||||
|
||||
kpxcEvent.onRemoveCredentialsFromTabInformation = async function(tab) {
|
||||
|
|
@ -156,7 +156,7 @@ kpxcEvent.onLoginPopup = async function(tab, logins) {
|
|||
};
|
||||
|
||||
page.tabs[tab.id].loginList = logins;
|
||||
browserAction.show(tab, popupData);
|
||||
await browserAction.show(tab, popupData);
|
||||
};
|
||||
|
||||
kpxcEvent.initHttpAuth = async function() {
|
||||
|
|
@ -170,7 +170,7 @@ kpxcEvent.onHTTPAuthPopup = async function(tab, data) {
|
|||
};
|
||||
|
||||
page.tabs[tab.id].loginList = data;
|
||||
browserAction.show(tab, popupData);
|
||||
await browserAction.show(tab, popupData);
|
||||
};
|
||||
|
||||
kpxcEvent.onUsernameFieldDetected = async function(tab, detected) {
|
||||
|
|
|
|||
|
|
@ -130,14 +130,7 @@ for (const item of contextMenuItems) {
|
|||
title: item.title,
|
||||
contexts: menuContexts,
|
||||
visible: item.visible,
|
||||
id: item.id,
|
||||
onclick: (info, tab) => {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: item.action
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
});
|
||||
}
|
||||
id: item.id || item.action
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -154,3 +147,25 @@ browser.commands.onCommand.addListener(async (command) => {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
browser.contextMenus.onClicked.addListener(async (item, tab) => {
|
||||
if (item?.menuItemId?.startsWith('fill_attribute')) {
|
||||
const menuItem = page.attributeMenuItems.find(i => i?.action === item?.menuItemId);
|
||||
if (menuItem) {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'fill_attribute',
|
||||
args: menuItem?.args
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: item.menuItemId
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -715,6 +715,7 @@ keepass.saveKey = function(hash, id, key) {
|
|||
keepass.keyRing[hash].created = new Date().valueOf();
|
||||
keepass.keyRing[hash].lastUsed = new Date().valueOf();
|
||||
}
|
||||
|
||||
browser.storage.local.set({ 'keyRing': keepass.keyRing });
|
||||
};
|
||||
|
||||
|
|
@ -861,13 +862,13 @@ keepass.setcurrentKeePassXCVersion = function(version) {
|
|||
}
|
||||
};
|
||||
|
||||
keepass.keePassXCUpdateAvailable = function() {
|
||||
keepass.keePassXCUpdateAvailable = async function() {
|
||||
const checkUpdate = Number(page.settings.checkUpdateKeePassXC);
|
||||
if (checkUpdate !== CHECK_UPDATE_NEVER) {
|
||||
const lastChecked = (keepass.latestKeePassXC.lastChecked) ? new Date(keepass.latestKeePassXC.lastChecked) : new Date(1986, 11, 21);
|
||||
const daysSinceLastCheck = Math.floor(((new Date()).getTime() - lastChecked.getTime()) / 86400000);
|
||||
if (daysSinceLastCheck >= checkUpdate) {
|
||||
keepass.checkForNewKeePassXCVersion();
|
||||
await keepass.checkForNewKeePassXCVersion();
|
||||
}
|
||||
|
||||
return keepass.compareVersion(keepass.currentKeePassXC, keepass.latestKeePassXC.version, false);
|
||||
|
|
@ -876,33 +877,18 @@ keepass.keePassXCUpdateAvailable = function() {
|
|||
return false;
|
||||
};
|
||||
|
||||
keepass.checkForNewKeePassXCVersion = function() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
keepass.checkForNewKeePassXCVersion = async function() {
|
||||
let version = -1;
|
||||
|
||||
xhr.onload = function(e) {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
const json = JSON.parse(xhr.responseText);
|
||||
if (json.tag_name && json.prerelease === false) {
|
||||
version = json.tag_name;
|
||||
keepass.latestKeePassXC.version = version;
|
||||
}
|
||||
}
|
||||
|
||||
if (version !== -1) {
|
||||
browser.storage.local.set({ 'latestKeePassXC': keepass.latestKeePassXC });
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = function(err) {
|
||||
logError(`checkForNewKeePassXCVersion error: ${err}`);
|
||||
};
|
||||
|
||||
try {
|
||||
xhr.open('GET', keepass.latestVersionUrl, true);
|
||||
xhr.send();
|
||||
const response = await fetch(keepass.latestVersionUrl);
|
||||
const jsonData = await response.json();
|
||||
if (jsonData?.tag_name && jsonData?.prerelease === false) {
|
||||
version = jsonData.tag_name;
|
||||
keepass.latestKeePassXC.version = version;
|
||||
}
|
||||
} catch (ex) {
|
||||
logError(ex);
|
||||
logError(`checkForNewKeePassXCVersion error: ${ex}`);
|
||||
}
|
||||
keepass.latestKeePassXC.lastChecked = new Date().valueOf();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const AUTO_SUBMIT_TIMEOUT = 5000;
|
|||
|
||||
const page = {};
|
||||
page.autoSubmitPerformed = false;
|
||||
page.attributeMenuItemIds = [];
|
||||
page.attributeMenuItems = [];
|
||||
page.blockedTabs = [];
|
||||
page.clearCredentialsTimeout = null;
|
||||
page.currentRequest = {};
|
||||
|
|
@ -295,9 +295,10 @@ page.fillHttpAuth = async function(tab, credentials) {
|
|||
// Update context menu for attribute filling
|
||||
page.updateContextMenu = async function(tab, credentials) {
|
||||
// Remove any old attribute items
|
||||
while (page.attributeMenuItemIds.length) {
|
||||
browser.contextMenus.remove(page.attributeMenuItemIds.pop());
|
||||
}
|
||||
page.attributeMenuItems.forEach(item => {
|
||||
browser.contextMenus.remove(item?.action);
|
||||
});
|
||||
page.attributeMenuItems = [];
|
||||
|
||||
// Set parent item visibility
|
||||
browser.contextMenus.update('fill_attribute', { visible: true });
|
||||
|
|
@ -315,12 +316,15 @@ page.updateContextMenu = async function(tab, credentials) {
|
|||
? `[${cred.login}] ${attributeName}`
|
||||
: attributeName;
|
||||
|
||||
page.attributeMenuItemIds.push(createContextMenuItem({
|
||||
action: 'fill_attribute',
|
||||
const menuItem = {
|
||||
action: `fill_attribute_${finalName}`,
|
||||
args: attribute,
|
||||
parentId: 'fill_attribute',
|
||||
title: finalName
|
||||
}));
|
||||
};
|
||||
|
||||
createContextMenuItem(menuItem);
|
||||
page.attributeMenuItems.push(menuItem);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -332,14 +336,7 @@ page.updatePopup = function(tab) {
|
|||
const createContextMenuItem = function({ action, args, ...options }) {
|
||||
return browser.contextMenus.create({
|
||||
contexts: menuContexts,
|
||||
onclick: (info, tab) => {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: action,
|
||||
args: args
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
});
|
||||
},
|
||||
id: action,
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ const isEdge = function() {
|
|||
const showNotification = function(message) {
|
||||
browser.notifications.create({
|
||||
'type': 'basic',
|
||||
'iconUrl': browser.extension.getURL('icons/keepassxc_64x64.png'),
|
||||
'iconUrl': browser.runtime.getURL('icons/keepassxc_64x64.png'),
|
||||
'title': 'KeePassXC-Browser',
|
||||
'message': message
|
||||
});
|
||||
|
|
@ -158,11 +158,3 @@ const getCurrentTab = async function() {
|
|||
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||
return tabs.length > 0 ? tabs[0] : undefined;
|
||||
};
|
||||
|
||||
HTMLElement.prototype.show = function() {
|
||||
this.style.display = 'block';
|
||||
};
|
||||
|
||||
HTMLElement.prototype.hide = function() {
|
||||
this.style.display = 'none';
|
||||
};
|
||||
|
|
|
|||
9
keepassxc-browser/common/global_ui.js
Normal file
9
keepassxc-browser/common/global_ui.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
HTMLElement.prototype.show = function() {
|
||||
this.style.display = 'block';
|
||||
};
|
||||
|
||||
HTMLElement.prototype.hide = function() {
|
||||
this.style.display = 'none';
|
||||
};
|
||||
|
|
@ -10,7 +10,6 @@ const sendMessage = async function(action, args) {
|
|||
return await browser.runtime.sendMessage({ action: action, args: args });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @Object kpxc
|
||||
* The main content script object.
|
||||
|
|
|
|||
|
|
@ -13,18 +13,11 @@
|
|||
<link rel="icon" type="image/png" href="../icons/keepassxc_96x96.png" sizes="96x96">
|
||||
<script src="../common/browser-polyfill.min.js"></script>
|
||||
<script src="../common/global.js"></script>
|
||||
<script src="../common/global_ui.js"></script>
|
||||
<script src="../common/sites.js"></script>
|
||||
<script src="../bootstrap/bootstrap.min.js"></script>
|
||||
<script src="options.js"></script>
|
||||
<script src="../common/translate.js" defer></script>
|
||||
<script>
|
||||
// We eagerly load the theme here to avoid a white flash
|
||||
let theme = localStorage.getItem('colorTheme') || 'system';
|
||||
if (theme === 'system') {
|
||||
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
document.documentElement.setAttribute('data-bs-theme', theme);
|
||||
</script>
|
||||
</head>
|
||||
<body class="pt-3 pb-5">
|
||||
<div class="container-fluid">
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ options.saveKeyRing = async function() {
|
|||
});
|
||||
};
|
||||
|
||||
options.initGeneralSettings = function() {
|
||||
options.initGeneralSettings = async function() {
|
||||
const changeCheckboxValue = async function(e) {
|
||||
const name = e.currentTarget.name;
|
||||
const isChecked = e.currentTarget.checked;
|
||||
|
|
@ -173,7 +173,7 @@ options.initGeneralSettings = function() {
|
|||
await options.saveSettings();
|
||||
});
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
await browser.runtime.sendMessage({
|
||||
action: 'get_keepassxc_versions'
|
||||
}).then(options.showKeePassXCVersions);
|
||||
|
||||
|
|
@ -681,13 +681,20 @@ const getBrowserId = function() {
|
|||
|
||||
(async() => {
|
||||
try {
|
||||
// We eagerly load the theme here to avoid a white flash
|
||||
let theme = localStorage.getItem('colorTheme') || 'system';
|
||||
if (theme === 'system') {
|
||||
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
document.documentElement.setAttribute('data-bs-theme', theme);
|
||||
|
||||
const settings = await browser.runtime.sendMessage({ action: 'load_settings' });
|
||||
options.settings = settings;
|
||||
|
||||
const keyRing = await browser.runtime.sendMessage({ action: 'load_keyring' });
|
||||
options.keyRing = keyRing;
|
||||
options.initMenu();
|
||||
options.initGeneralSettings();
|
||||
await options.initGeneralSettings();
|
||||
options.initConnectedDatabases();
|
||||
options.initCustomLoginFields();
|
||||
options.initSitePreferences();
|
||||
|
|
|
|||
|
|
@ -116,6 +116,14 @@ code {
|
|||
text-align: start;
|
||||
}
|
||||
|
||||
#filter-block,
|
||||
#not-configured,
|
||||
#need-reconfigure,
|
||||
#configured-not-associated,
|
||||
#configured-and-associated,
|
||||
#error-encountered,
|
||||
#database-not-opened,
|
||||
#username-field-detected,
|
||||
#update-available,
|
||||
#getting-started-guide,
|
||||
#troubleshooting-guide {
|
||||
|
|
@ -163,6 +171,10 @@ code {
|
|||
text-align: right;
|
||||
}
|
||||
|
||||
#left-margin {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark), (prefers-color-scheme: light) {
|
||||
body {
|
||||
background: var(--kpxc-background-color) !important;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<link rel="stylesheet" href="../fonts/fork-awesome.min.css">
|
||||
<script src="../common/browser-polyfill.min.js"></script>
|
||||
<script src="../common/global.js"></script>
|
||||
<script src="../common/global_ui.js"></script>
|
||||
<script src="../bootstrap/bootstrap.min.js"></script>
|
||||
<script src="popup_functions.js"></script>
|
||||
<script defer src="popup.js"></script>
|
||||
|
|
@ -56,7 +57,7 @@
|
|||
<div class="loader"></div> <p data-i18n="popupCheckingStatus"></p>
|
||||
</div>
|
||||
|
||||
<div id="not-configured" style="display: none">
|
||||
<div id="not-configured">
|
||||
<p data-i18n="popupNotConfigured"></p>
|
||||
<div class="right-align">
|
||||
<button id="connect-button" class="btn btn-sm btn-primary">
|
||||
|
|
@ -66,9 +67,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="need-reconfigure" style="display: none">
|
||||
<div id="need-reconfigure">
|
||||
<p data-i18n="popupNeedReconfigure"></p>
|
||||
<p style="margin-left: 1em">
|
||||
<p id="left-margin">
|
||||
<code id="need-reconfigure-message"></code>
|
||||
</p>
|
||||
<p data-i18n="popupNeedReconfigureMessage"></p>
|
||||
|
|
@ -80,11 +81,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="configured-not-associated" style="display: none">
|
||||
<div id="configured-not-associated">
|
||||
<span data-i18n="popupConfiguredNotAssociated" data-i18n-placeholder="<span class='bg-warning' id='unassociated-identifier'></span>"></span>
|
||||
</div>
|
||||
|
||||
<div id="configured-and-associated" style="display: none">
|
||||
<div id="configured-and-associated">
|
||||
<p data-i18n="popupConfiguredAndAssociated" data-i18n-placeholder="<span class='bg-success' id='associated-identifier'></span>"></p>
|
||||
<div class="right-align">
|
||||
<button id="redetect-fields-button" class="btn btn-sm btn-primary">
|
||||
|
|
@ -94,9 +95,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="error-encountered" style="display: none">
|
||||
<div id="error-encountered">
|
||||
<p data-i18n="popupErrorEncountered"></p>
|
||||
<p style="margin-left: 1em">
|
||||
<p id="left-margin">
|
||||
<code id="error-message"></code>
|
||||
</p>
|
||||
<div class="right-align">
|
||||
|
|
@ -107,9 +108,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="database-not-opened" style="display: none">
|
||||
<div id="database-not-opened">
|
||||
<p data-i18n="popupErrorEncountered"></p>
|
||||
<p style="margin-left: 1em">
|
||||
<p id="left-margin">
|
||||
<code id="database-error-message"></code>
|
||||
</p>
|
||||
<div class="right-align">
|
||||
|
|
@ -120,7 +121,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="username-field-detected" style="display: none">
|
||||
<div id="username-field-detected">
|
||||
<hr>
|
||||
<p data-i18n="popupUsernameFieldDetected"></p>
|
||||
<div class="right-align">
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ async function initSettings() {
|
|||
}
|
||||
|
||||
customLoginFieldsButton.addEventListener('click', async () => {
|
||||
await browser.windows.getCurrent();
|
||||
const tab = await getCurrentTab();
|
||||
await browser.runtime.getBackgroundPage();
|
||||
|
||||
browser.tabs.sendMessage(tab?.id, {
|
||||
action: 'choose_credential_fields'
|
||||
});
|
||||
|
|
@ -49,7 +46,8 @@ async function getLoginData() {
|
|||
}
|
||||
|
||||
const logins = await browser.runtime.sendMessage({
|
||||
action: 'get_login_list'
|
||||
action: 'get_login_list',
|
||||
args: tab.id
|
||||
});
|
||||
|
||||
return logins;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<link rel="stylesheet" href="../fonts/fork-awesome.min.css">
|
||||
<script src="../common/browser-polyfill.min.js"></script>
|
||||
<script src="../common/global.js"></script>
|
||||
<script src="../common/global_ui.js"></script>
|
||||
<script src="../bootstrap/bootstrap.min.js"></script>
|
||||
<script src="popup_functions.js"></script>
|
||||
<script defer src="popup_httpauth.js"></script>
|
||||
|
|
@ -47,7 +48,7 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div id="database-not-opened" style="display: none">
|
||||
<div id="database-not-opened">
|
||||
<p data-i18n="popupErrorEncountered"></p>
|
||||
<p style="margin-left: 1em">
|
||||
<code id="database-error-message"></code>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<link rel="stylesheet" href="../fonts/fork-awesome.min.css">
|
||||
<script src="../common/browser-polyfill.min.js"></script>
|
||||
<script src="../common/global.js"></script>
|
||||
<script src="../common/global_ui.js"></script>
|
||||
<script src="../bootstrap/bootstrap.min.js"></script>
|
||||
<script src="popup_functions.js"></script>
|
||||
<script defer src="popup_login.js"></script>
|
||||
|
|
@ -38,14 +39,14 @@
|
|||
|
||||
<div id="credentialsList" class="credentials">
|
||||
<p data-i18n="popupLoginText"></p>
|
||||
<div id="filter-block" style="display: none;">
|
||||
<div id="filter-block">
|
||||
<label for="login-filter" data-i18n="popupFilterText"></label>
|
||||
<input type="text" id="login-filter">
|
||||
</div>
|
||||
<div id="login-list" class="list-group"></div>
|
||||
</div>
|
||||
|
||||
<div id="database-not-opened" style="display: none">
|
||||
<div id="database-not-opened">
|
||||
<p data-i18n="popupErrorEncountered"></p>
|
||||
<p style="margin-left: 1em">
|
||||
<code id="database-error-message"></code>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
|
||||
const id = e.target.id;
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
browser.tabs.sendMessage(tab?.id, {
|
||||
action: 'fill_user_pass_with_specific_login',
|
||||
id: Number(id),
|
||||
uuid: uuid
|
||||
|
|
|
|||
Loading…
Reference in a new issue