From 233721bf5136b1ef973ae768339cf1fa97411407 Mon Sep 17 00:00:00 2001 From: antelle Date: Fri, 23 Apr 2021 23:17:35 +0200 Subject: [PATCH] extension installation on Windows --- app/templates/settings/settings-about.hbs | 1 - .../util/browser-extension-installer.js | 115 +++++++++++++----- desktop/scripts/util/windows-registry.js | 13 ++ 3 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 desktop/scripts/util/windows-registry.js diff --git a/app/templates/settings/settings-about.hbs b/app/templates/settings/settings-about.hbs index 469bb6e5..6414dfca 100644 --- a/app/templates/settings/settings-about.hbs +++ b/app/templates/settings/settings-about.hbs @@ -40,7 +40,6 @@
  • node-yubikey-chalresp, YubiKey challenge-response API for node.js, © 2020 Antelle
  • node-secure-enclave, Secure Enclave module for node.js and Electron, © 2020 Antelle
  • node-keyboard-auto-type, node.js bindings for keyboard-auto-type, © 2021 Antelle
  • -
  • windows-native-registry, native windows registry access for Node, © 2020 Eugeny
  • {{/if}} diff --git a/desktop/scripts/util/browser-extension-installer.js b/desktop/scripts/util/browser-extension-installer.js index 3cf3a852..ab15105b 100644 --- a/desktop/scripts/util/browser-extension-installer.js +++ b/desktop/scripts/util/browser-extension-installer.js @@ -1,5 +1,6 @@ const fs = require('fs'); const path = require('path'); +const windowsRegistry = require('./windows-registry'); const { isDev } = require('./app-info'); const { app } = require('electron'); @@ -17,8 +18,6 @@ function getManifestDir(browser) { default: return undefined; } - case 'win32': - throw new Error('not implemented'); case 'linux': switch (browser) { case 'Chrome': @@ -33,15 +32,39 @@ function getManifestDir(browser) { } } -function getManifestFileName(extension) { +function getWindowsRegistryPath(browser) { + switch (browser) { + case 'Chrome': + return 'HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\'; + case 'Firefox': + return 'HKCU\\Software\\Mozilla\\NativeMessagingHosts\\'; + case 'Edge': + return 'HKCU\\Software\\Microsoft\\Edge\\NativeMessagingHosts\\'; + default: + return undefined; + } +} + +function getWindowsManifestFileName(browser) { + const suffix = browser === 'Firefox' ? 'firefox' : 'chrome'; + const manifestName = `native-messaging.${suffix}.json`; + return path.join(app.getPath('userData'), manifestName); +} + +function getNativeHostName(extension) { switch (extension) { case 'KWC': - return 'net.antelle.keeweb.keeweb_connect.json'; + return 'net.antelle.keeweb.keeweb_connect'; case 'KPXC': - return 'org.keepassxc.keepassxc_browser.json'; + return 'org.keepassxc.keepassxc_browser'; } } +function getManifestFileName(extension) { + const nativeHostName = getNativeHostName(extension); + return nativeHostName ? nativeHostName + '.json' : undefined; +} + function createManifest(browser, extension) { switch (extension) { case 'KWC': @@ -92,41 +115,71 @@ function getNativeMessagingHostPath() { } 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); - const manifest = createManifest(browser, extension); if (!manifest) { return; } - manifest.path = getNativeMessagingHostPath(); - await fs.promises.writeFile(fullPath, JSON.stringify(manifest, null, 4)); + if (process.platform === 'win32') { + const registryPath = getWindowsRegistryPath(browser); + if (!registryPath) { + return; + } + + const registryKeyName = getNativeHostName(extension); + if (!registryKeyName) { + return; + } + + const manifestFileName = getWindowsManifestFileName(browser); + await fs.promises.writeFile(manifestFileName, JSON.stringify(manifest, null, 4)); + + windowsRegistry.createKey(registryPath + registryKeyName, manifestFileName); + } else { + 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); + + await fs.promises.writeFile(fullPath, JSON.stringify(manifest, null, 4)); + } }; module.exports.uninstall = async function (browser, extension) { - const manifestDir = getManifestDir(browser); - if (!manifestDir) { - return; - } + if (process.platform === 'win32') { + const registryPath = getWindowsRegistryPath(browser); + if (!registryPath) { + return; + } - const manifestFileName = getManifestFileName(extension); - if (!manifestFileName) { - return; - } - const fullPath = path.join(manifestDir, manifestFileName); + const registryKeyName = getNativeHostName(extension); + if (!registryKeyName) { + return; + } - await fs.promises.unlink(fullPath); + windowsRegistry.deleteKey(registryPath + registryKeyName); + } else { + const manifestDir = getManifestDir(browser); + if (!manifestDir) { + return; + } + + const manifestFileName = getManifestFileName(extension); + if (!manifestFileName) { + return; + } + const fullPath = path.join(manifestDir, manifestFileName); + + await fs.promises.unlink(fullPath); + } }; diff --git a/desktop/scripts/util/windows-registry.js b/desktop/scripts/util/windows-registry.js new file mode 100644 index 00000000..0a2d3b5c --- /dev/null +++ b/desktop/scripts/util/windows-registry.js @@ -0,0 +1,13 @@ +const { spawn } = require('child_process'); + +function reg(...args) { + spawn('REG', args); +} + +module.exports.createKey = function (key, value) { + return reg('ADD', key, '/ve', '/d', value, '/f'); +}; + +module.exports.deleteKey = function (key) { + return reg('DELETE', key, '/f'); +};