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');
+};