mirror of https://github.com/keeweb/keeweb
creating native manifests
This commit is contained in:
parent
dd4ad6d72b
commit
ccb9b03287
|
@ -116,15 +116,9 @@ const BrowserExtensionConnector = {
|
|||
window.removeEventListener('message', this.browserWindowMessage);
|
||||
},
|
||||
|
||||
isEnabledOnDesktop() {
|
||||
for (const browser of SupportedBrowsers) {
|
||||
for (const ext of SupportedExtensions) {
|
||||
if (AppSettingsModel[`extensionEnabled${ext.alias}${browser}`]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
enable(browser, extension, enabled) {
|
||||
const { ipcRenderer } = Launcher.electron();
|
||||
ipcRenderer.invoke('browserExtensionConnectorEnable', browser, extension, enabled);
|
||||
},
|
||||
|
||||
async startDesktopAppListener() {
|
||||
|
|
|
@ -4,7 +4,11 @@ import { Features } from 'util/features';
|
|||
import { Links } from 'const/links';
|
||||
import { AppSettingsModel } from 'models/app-settings-model';
|
||||
import { Locale } from 'util/locale';
|
||||
import { SupportedBrowsers, SupportedExtensions } from 'comp/extension/browser-extension-connector';
|
||||
import {
|
||||
BrowserExtensionConnector,
|
||||
SupportedBrowsers,
|
||||
SupportedExtensions
|
||||
} from 'comp/extension/browser-extension-connector';
|
||||
|
||||
class SettingsBrowserView extends View {
|
||||
template = template;
|
||||
|
@ -23,9 +27,7 @@ class SettingsBrowserView extends View {
|
|||
if (Features.isDesktop) {
|
||||
data.extensionNames = ['KeeWeb Connect', 'KeePassXC-Browser'];
|
||||
data.settingsPerBrowser = this.getSettingsPerBrowser();
|
||||
data.anyBrowserIsEnabled = data.settingsPerBrowser.some((perBrowser) =>
|
||||
perBrowser.extensions.some((ext) => ext.enabled)
|
||||
);
|
||||
data.anyBrowserIsEnabled = BrowserExtensionConnector.isEnabled();
|
||||
} else {
|
||||
const extensionBrowserFamily = Features.extensionBrowserFamily;
|
||||
data.extensionBrowserFamily = Features.extensionBrowserFamily;
|
||||
|
@ -69,6 +71,8 @@ class SettingsBrowserView extends View {
|
|||
delete AppSettingsModel[setting];
|
||||
}
|
||||
|
||||
BrowserExtensionConnector.enable(browser, extension, enabled);
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@ const net = require('net');
|
|||
const { ipcMain, app } = require('electron');
|
||||
const { Logger } = require('../logger');
|
||||
const { getProcessInfo } = require('../util/process-utils');
|
||||
const browserExtensionInstaller = require('../util/browser-extension-installer');
|
||||
|
||||
ipcMain.handle('browserExtensionConnectorStart', browserExtensionConnectorStart);
|
||||
ipcMain.handle('browserExtensionConnectorStop', browserExtensionConnectorStop);
|
||||
ipcMain.handle('browserExtensionConnectorEnable', browserExtensionConnectorEnable);
|
||||
ipcMain.handle('browserExtensionConnectorSocketResult', browserExtensionConnectorSocketResult);
|
||||
ipcMain.handle('browserExtensionConnectorSocketEvent', browserExtensionConnectorSocketEvent);
|
||||
|
||||
|
@ -15,11 +17,11 @@ const logger = new Logger('browser-extension-connector');
|
|||
|
||||
const MaxIncomingDataLength = 10_000;
|
||||
const ExtensionOrigins = {
|
||||
'chrome-extension://aphablpbogbpmocgkpeeadeljldnphon/': 'keeweb-connect',
|
||||
'safari-keeweb-connect': 'keeweb-connect',
|
||||
'keeweb-connect@keeweb.info': 'keeweb-connect',
|
||||
'chrome-extension://oboonakemofpalcgghocfoadofidjkkk/': 'keepassxc-browser',
|
||||
'chrome-extension://aphablpbogbpmocgkpeeadeljldnphon/': 'keeweb-connect',
|
||||
'keepassxc-browser@keepassxc.org': 'keepassxc-browser',
|
||||
'chrome-extension://oboonakemofpalcgghocfoadofidjkkk/': 'keepassxc-browser',
|
||||
'chrome-extension://pdffhmdngciaglkoonimfcmckehcpafo/': 'keepassxc-browser'
|
||||
};
|
||||
|
||||
|
@ -67,9 +69,24 @@ function browserExtensionConnectorStop() {
|
|||
}
|
||||
connectedSockets = new Map();
|
||||
connectedSocketState = new WeakMap();
|
||||
|
||||
logger.info('Stopped');
|
||||
}
|
||||
|
||||
async function browserExtensionConnectorEnable(e, browser, extension, enabled) {
|
||||
logger.info(enabled ? 'Enable' : 'Disable', browser, extension);
|
||||
|
||||
try {
|
||||
if (enabled) {
|
||||
await browserExtensionInstaller.install(browser, extension);
|
||||
} else {
|
||||
await browserExtensionInstaller.uninstall(browser, extension);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(`Error installing extension: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
function browserExtensionConnectorSocketResult(e, socketId, result) {
|
||||
sendResultToSocket(socketId, result);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { isDev } = require('./app-info');
|
||||
const { app } = require('electron');
|
||||
|
||||
function getManifestDir(browser) {
|
||||
const home = app.getPath('home');
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
switch (browser) {
|
||||
case 'Chrome':
|
||||
return `${home}/Library/Application Support/Google/Chrome/NativeMessagingHosts/`;
|
||||
case 'Firefox':
|
||||
return `${home}/Library/Application Support/Mozilla/NativeMessagingHosts/`;
|
||||
case 'Edge':
|
||||
return `${home}/Library/Application Support/Microsoft Edge/NativeMessagingHosts/`;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
case 'win32':
|
||||
throw new Error('not implemented');
|
||||
case 'linux':
|
||||
switch (browser) {
|
||||
case 'Chrome':
|
||||
return `${home}/.config/google-chrome/NativeMessagingHosts/`;
|
||||
case 'Firefox':
|
||||
return `${home}/.mozilla/native-messaging-hosts/`;
|
||||
case 'Edge':
|
||||
return `${home}/.config/microsoft-edge/NativeMessagingHosts/`;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getManifestFileName(extension) {
|
||||
switch (extension) {
|
||||
case 'KWC':
|
||||
return 'net.antelle.keeweb.keeweb_connect.json';
|
||||
case 'KPXC':
|
||||
return 'org.keepassxc.keepassxc_browser.json';
|
||||
}
|
||||
}
|
||||
|
||||
function createManifest(extension) {
|
||||
switch (extension) {
|
||||
case 'KWC':
|
||||
return {
|
||||
'allowed_origins': ['chrome-extension://aphablpbogbpmocgkpeeadeljldnphon/'],
|
||||
'allowed_extensions': ['keeweb-connect@keeweb.info'],
|
||||
description: 'KeeWeb native messaging host',
|
||||
name: 'net.antelle.keeweb.keeweb_connect',
|
||||
type: 'stdio'
|
||||
};
|
||||
case 'KPXC':
|
||||
return {
|
||||
'allowed_origins': [
|
||||
'chrome-extension://pdffhmdngciaglkoonimfcmckehcpafo/',
|
||||
'chrome-extension://oboonakemofpalcgghocfoadofidjkkk/'
|
||||
],
|
||||
'allowed_extensions': ['keepassxc-browser@keepassxc.org'],
|
||||
description: 'Native messaging host created by KeeWeb',
|
||||
name: 'org.keepassxc.keepassxc_browser',
|
||||
type: 'stdio'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getNativeMessagingHostPath() {
|
||||
if (isDev) {
|
||||
const packageBase = path.resolve('node_modules/@keeweb/keeweb-native-messaging-host');
|
||||
const extension = process.platform === 'win32' ? '.exe' : '';
|
||||
const exeName = `keeweb-native-messaging-host${extension}`;
|
||||
return path.join(packageBase, `${process.platform}-${process.arch}`, exeName);
|
||||
}
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return path.join(app.getPath('exe'), '..', 'util', 'keeweb-native-messaging-host');
|
||||
case 'win32':
|
||||
return path.join(app.getPath('exe'), '..', 'keeweb-native-messaging-host.exe');
|
||||
case 'linux':
|
||||
return path.join(app.getPath('exe'), '..', 'keeweb-native-messaging-host');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.install = async function (browser, extension) {
|
||||
const manifestDir = getManifestDir(browser);
|
||||
if (!manifestDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
await fs.promises.mkdir(manifestDir, { recursive: true });
|
||||
|
||||
const manifestFileName = getManifestFileName(extension);
|
||||
if (!manifestFileName) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fullPath = path.join(manifestDir, manifestFileName);
|
||||
|
||||
let manifest;
|
||||
if (extension === 'KPXC') {
|
||||
try {
|
||||
await fs.promises.access(fullPath);
|
||||
manifest = JSON.parse(await fs.promises.readFile(fullPath, 'utf8'));
|
||||
manifest.pathKPXC = manifest.path;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (!manifest) {
|
||||
manifest = createManifest(extension);
|
||||
}
|
||||
if (!manifest) {
|
||||
return;
|
||||
}
|
||||
|
||||
manifest.path = getNativeMessagingHostPath();
|
||||
|
||||
await fs.promises.writeFile(fullPath, JSON.stringify(manifest, null, 4));
|
||||
};
|
||||
|
||||
module.exports.uninstall = async function (browser, extension) {
|
||||
const manifestDir = getManifestDir(browser);
|
||||
if (!manifestDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
const manifestFileName = getManifestFileName(extension);
|
||||
if (!manifestFileName) {
|
||||
return;
|
||||
}
|
||||
const fullPath = path.join(manifestDir, manifestFileName);
|
||||
|
||||
try {
|
||||
await fs.promises.access(fullPath);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
if (extension === 'KPXC') {
|
||||
const manifest = JSON.parse(await fs.promises.readFile(fullPath, 'utf8'));
|
||||
if (manifest.pathKPXC) {
|
||||
manifest.path = manifest.pathKPXC;
|
||||
delete manifest.pathKPXC;
|
||||
await fs.promises.writeFile(fullPath, JSON.stringify(manifest, null, 4));
|
||||
} else {
|
||||
await fs.promises.unlink(fullPath);
|
||||
}
|
||||
} else {
|
||||
await fs.promises.unlink(fullPath);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue