Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const DEFAULT = 'manifest_default.json';
const BROWSERS = {
'Firefox': 'manifest_firefox.json',
'Chromium': 'manifest_chromium.json',
'Safari': 'manifest_safari.json'
};

const getVersion = async () => {
Expand Down Expand Up @@ -54,6 +55,10 @@ const createZipFile = async (fileName, path) => {
const version = await getVersion();

for (const browser in BROWSERS) {
if (params.includes('--safari-web-extension') && browser !== 'Safari') {
continue;
}

console.log(`KeePassXC-Browser: Creating extension package for ${browser}`);

const fileName = await getDestinationFilename(BROWSERS[browser], version);
Expand All @@ -64,7 +69,19 @@ const createZipFile = async (fileName, path) => {
await fs.rm(fileName);
}

await createZipFile(fileName, DEST);
if (params.includes('--safari-web-extension') && browser === 'Safari' && params.includes('-o')) {
let outputPath = params[params.indexOf('-o') + 1]

if (!outputPath) {
console.error('No ouput path specified!');
return;
}

await fs.cpSync(DEST, outputPath, { recursive: true })
} else {
await createZipFile(fileName, DEST);
}

console.log('Done');
}

Expand Down
3 changes: 2 additions & 1 deletion dist/manifest_chromium.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"content/pwgen.js",
"content/totp-autocomplete.js",
"content/totp-field.js",
"content/username-field.js"
"content/username-field.js",
"content/theme.js"
],
"run_at": "document_idle",
"all_frames": true
Expand Down
3 changes: 2 additions & 1 deletion dist/manifest_firefox.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
"content/pwgen.js",
"content/totp-autocomplete.js",
"content/totp-field.js",
"content/username-field.js"
"content/username-field.js",
"content/theme.js"
],
"run_at": "document_idle",
"all_frames": true
Expand Down
190 changes: 190 additions & 0 deletions dist/manifest_safari.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
{
"manifest_version": 3,
"name": "KeePassXC-Browser",
"version": "1.9.8",
"version_name": "1.9.8",
"minimum_chrome_version": "93",
"description": "__MSG_extensionDescription__",
"author": "KeePassXC Team",
"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": {
"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/offscreen.js",
"background/browserAction.js",
"background/page.js",
"background/event.js",
"background/init.js"
]
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"exclude_matches": [
"*://*/*.xml*",
"file:///*.xml*"
],
"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/theme.js"
],
"run_at": "document_idle",
"all_frames": true
},
{
"matches": [
"<all_urls>"
],
"exclude_matches": [
"*://*/*.xml*",
"file:///*.xml*"
],
"js": [
"content/passkeys-inject.js",
"content/passkeys-utils.js"
],
"run_at": "document_start",
"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+P",
"mac": "MacCtrl+Shift+P"
}
},
"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",
"clipboardWrite",
"contextMenus",
"cookies",
"nativeMessaging",
"notifications",
"offscreen",
"storage",
"tabs",
"webNavigation"
],
"content_security_policy": {
"extension_pages": "script-src 'self'"
},
"host_permissions": [
"<all_urls>",
"https://*/*",
"http://*/*"
],
"storage": {
"managed_schema": "managed_storage.json"
},
"default_locale": "en"
}
8 changes: 8 additions & 0 deletions keepassxc-browser/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1377,5 +1377,13 @@
"lockDatabase": {
"message": "Lock database",
"description": "Lock database button title text."
},
"optionsUnsupportedKeyboardShortcutsSafari": {
"message": "Changing keyboard shortcuts is not supported in Safari.",
"description": "Info message about unsupported ability to change keyboard shortcuts in Safari."
},
"optionsUnsupportedAutofillHTTPAuthDialogsSafari": {
"message": "Autofill HTTP Auth dialogs is not supported in Safari.",
"description": "Info message about autofilling HTTP Auth dialogs is unsupported in Safari."
}
}
12 changes: 9 additions & 3 deletions keepassxc-browser/background/browserAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
const browserActionWrapper = browser.action || browser.browserAction;
const browserAction = {};

browserAction.show = async function(tab, popupData) {
browserAction.updateIcon = async function(popupData) {
popupData ??= page.popupData;
page.popupData = popupData;

browserActionWrapper.setIcon({
path: await browserAction.generateIconName(popupData.iconType)
});
}

browserAction.show = async function(tab, popupData) {
popupData ??= page.popupData;
page.popupData = popupData;

browserAction.updateIcon(popupData);

if (popupData.popup && tab?.id) {
browserActionWrapper.setPopup({
Expand Down Expand Up @@ -83,7 +89,7 @@ browserAction.generateIconName = async function(iconType) {
style = page.settings.colorTheme;
}
}
const filetype = (isFirefox() ? 'svg' : 'png');
const filetype = ((isFirefox() || isSafari()) ? 'svg' : 'png');
return `/icons/toolbar/${style}/${name}.${filetype}`;
};

Expand Down
5 changes: 5 additions & 0 deletions keepassxc-browser/background/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ function onDisconnected() {
}

keepassClient.onNativeMessage = function(response) {
// Due to limitiations on SFSafariApplication.dispatchMessage this is needed
if (response?.name === 'proxy_message') {
response = response.userInfo
}

// Handle database lock/unlock status
if (response.action === kpActions.DATABASE_LOCKED || response.action === kpActions.DATABASE_UNLOCKED) {
keepass.updateDatabase();
Expand Down
7 changes: 6 additions & 1 deletion keepassxc-browser/background/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ kpxcEvent.onLoginPopup = async function(tab, logins) {
}
};

kpxcEvent.themeChanged = async function () {
browserAction.updateIcon();
};

kpxcEvent.initHttpAuth = async function() {
httpAuth.init();
};
Expand Down Expand Up @@ -303,5 +307,6 @@ kpxcEvent.messageHandlers = {
'save_settings': kpxcEvent.onSaveSettings,
'update_available_keepassxc': kpxcEvent.onUpdateAvailableKeePassXC,
'update_context_menu': page.updateContextMenu,
'update_popup': page.updatePopup
'update_popup': page.updatePopup,
'theme_changed': kpxcEvent.themeChanged
};
4 changes: 4 additions & 0 deletions keepassxc-browser/background/httpauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ httpAuth.requests = [];
httpAuth.pendingCallbacks = [];

httpAuth.init = function() {
if (isSafari()) {
return;
}

let handleReq = httpAuth.handleRequestPromise;
let reqType = 'blocking';

Expand Down
1 change: 1 addition & 0 deletions keepassxc-browser/background/keepass.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ keepass.cacheTimeout = 30 * 1000; // Milliseconds
keepass.databaseHash = '';
keepass.previousDatabaseHash = '';
keepass.reconnectLoop = null;
keepass.isSafari = isSafari();

const kpActions = {
SET_LOGIN: 'set-login',
Expand Down
8 changes: 8 additions & 0 deletions keepassxc-browser/background/offscreen.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
'use strict';

async function retrieveColorScheme() {
if (isSafari()) {
const tab = await getCurrentTab();
const theme = tab?.id && await browser.tabs.sendMessage(tab.id, { action: 'get_theme' });
return theme ?? 'light';
}

if (typeof window !== 'undefined') {
// Firefox does not support the offscreen API but its background script still has a window (so far)
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
Expand All @@ -23,9 +29,11 @@ async function retrieveColorScheme() {
target: 'offscreen',
action: 'retrieve_color_scheme',
});

if (!style) {
// if messaging fails then use "light" icon
return 'light';
}

return style;
}
9 changes: 9 additions & 0 deletions keepassxc-browser/common/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ const isEdge = function() {
return navigator.userAgent.indexOf('Edg') !== -1;
};

let cachedIsSafari = null;

function isSafari() {
if (cachedIsSafari === null) {
cachedIsSafari = browser.runtime.getURL('').startsWith('safari');
}
return cachedIsSafari;
}

const showNotification = function(message) {
browser.notifications.create({
'type': 'basic',
Expand Down
2 changes: 1 addition & 1 deletion keepassxc-browser/content/banner.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ kpxcBanner.create = async function(credentials = {}) {
const bannerInfo = kpxcUI.createElement('div', 'banner-info');
const bannerButtons = kpxcUI.createElement('div', 'banner-buttons');

const className = (isFirefox() ? 'kpxc-banner-icon-moz' : 'kpxc-banner-icon');
const className = (isSafari() ? 'kpxc-banner-icon-safari' : (isFirefox() ? 'kpxc-banner-icon-moz' : 'kpxc-banner-icon'));
const icon = kpxcUI.createElement('span', className, { 'alt': 'logo' });

const infoText = kpxcUI.createElement('span', '', {}, tr('rememberInfoText'));
Expand Down
Loading