Compare commits

...

4 commits

Author SHA1 Message Date
Sami Vänttinen
7226e51d70
Merge 744e3c14e2 into eab53c6a90 2026-03-09 22:30:23 +13:00
Sami Vänttinen
eab53c6a90
Update to 1.10.0.1 (#2895) 2026-03-08 10:03:31 +02:00
Sami Vänttinen
f1f4c1e0ff
Fix dynamic password input detection when replacing usename (#2896) 2026-03-08 09:25:45 +02:00
varjolintu
744e3c14e2 Add support for WebSocket connection method 2026-01-24 12:46:27 +02:00
13 changed files with 113 additions and 14 deletions

View file

@ -1,3 +1,8 @@
1.10.0.1 (2026-03-08)
=========================
- Remove webRequestBlocking permission from V3 manifests [#2893]
- Fix dynamic password input detection when replacing username [#2896]
1.10.0 (2026-03-04)
=========================
- Add preliminary support for Safari [#2800]

View file

@ -1,8 +1,8 @@
{
"manifest_version": 3,
"name": "KeePassXC-Browser",
"version": "1.10.0",
"version_name": "1.10.0",
"version": "1.10.0.1",
"version_name": "1.10.0.1",
"minimum_chrome_version": "124",
"description": "__MSG_extensionDescription__",
"author": "KeePassXC Team",

View file

@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "KeePassXC-Browser",
"version": "1.10.0",
"version": "1.10.0.1",
"description": "__MSG_extensionDescription__",
"author": "KeePassXC Team",
"icons": {

View file

@ -874,6 +874,22 @@
"message": "Allow filling HTTP Basic Auth credentials",
"description": "Allow filling HTTP Basic Auth credentials checkbox text."
},
"optionsConnectionMethod": {
"message": "Connection method",
"description": "Connection method selection text."
},
"optionsConnectionMethodHelpText": {
"message": "If native messaging is blocked in your browser, you can switch to a direct WebSocket sonnection. The feature must be enabled from KeePassXC side to work. Browser restart is required.",
"description": "Connection method help text."
},
"optionsConnectionMethodNativeMessaging": {
"message": "Native messaging",
"description": "Native messaging option for Connection method."
},
"optionsConnectionMethodWebSocket": {
"message": "WebSocket",
"description": "WebSocket option for Connection method."
},
"optionsDebugLogging": {
"message": "Debug logging",
"description": "Debug logging checkbox text."

View file

@ -5,11 +5,12 @@ keepassClient.keySize = 24;
keepassClient.messageTimeout = 500; // Milliseconds
keepassClient.nativeHostName = 'org.keepassxc.keepassxc_browser';
keepassClient.nativePort = null;
keepassClient.webSocket = null;
const kpErrors = {
UNKNOWN_ERROR: 0,
DATABASE_NOT_OPENED: 1,
DATABASE_HASH_NOT_RECEIVED: 2,
DATABASE_HASH_NOT_RECEIVED: 2,
CLIENT_PUBLIC_KEY_NOT_RECEIVED: 3,
CANNOT_DECRYPT_MESSAGE: 4,
TIMEOUT_OR_NOT_CONNECTED: 5,
@ -157,7 +158,10 @@ class Message {
//--------------------------------------------------------------------------
keepassClient.sendNativeMessage = async function(request, enableTimeout = false, timeoutValue) {
if (!keepassClient.nativePort) {
if (page?.settings?.connectionMethod === ConnectionMethod.WEBSOCKET && !keepassClient.webSocket) {
logError('No WebSocket defined.');
return;
} else if (page?.settings?.connectionMethod === ConnectionMethod.NATIVE_MESSAGING && !keepassClient.nativePort) {
logError('No native messaging port defined.');
return;
}
@ -167,7 +171,11 @@ keepassClient.sendNativeMessage = async function(request, enableTimeout = false,
messageBuffer.addMessage(message);
});
keepassClient.nativePort.postMessage(request);
if (page?.settings?.connectionMethod === ConnectionMethod.WEBSOCKET) {
keepassClient.webSocket.send(JSON.stringify(request));
} else {
keepassClient.nativePort.postMessage(request);
}
const response = await message.promise;
@ -413,3 +421,42 @@ keepassClient.onNativeMessage = function(response) {
// Generic response handling
keepassClient.handleNativeMessage(response);
};
//--------------------------------------------------------------------------
// WebSocket related
//--------------------------------------------------------------------------
keepassClient.connectToWebSocket = async function() {
return new Promise((resolve, reject) => {
if (keepassClient.webSocket) {
keepassClient.webSocket.close();
}
console.log(`${EXTENSION_NAME}: Connecting to WebSocket`);
try {
keepassClient.webSocket = new WebSocket('ws://localhost:7580');
keepassClient.webSocket.addEventListener('close', (event) => {
logError('Close WebSocket:', event);
onDisconnected();
reject();
});
keepassClient.webSocket.addEventListener('error', (event) => {
logError('WebSocket error:', event);
onDisconnected();
reject();
});
keepassClient.webSocket.addEventListener('message', (event) => {
keepassClient.onNativeMessage(JSON.parse(event?.data));
});
keepassClient.webSocket.addEventListener('open', (event) => {
console.log(`${EXTENSION_NAME}: WebSocket connected`);
keepass.isConnected = true;
resolve();
});
} catch (e) {
keepassClient.webSocket = null;
onDisconnected();
}
});
};

View file

@ -822,7 +822,12 @@ keepass.disableAutomaticReconnect = function() {
};
keepass.reconnect = async function(tab = null, connectionTimeout = 1500) {
keepassClient.connectToNative();
if (page?.settings?.connectionMethod === ConnectionMethod.WEBSOCKET) {
await keepassClient.connectToWebSocket();
} else {
keepassClient.connectToNative();
}
keepass.generateNewKeyPair();
const keyChangeResult = await keepass
.changePublicKeys(tab, !!connectionTimeout, connectionTimeout)

View file

@ -1,5 +1,10 @@
'use strict';
const ConnectionMethod = {
NATIVE_MESSAGING: 'nativemessaging',
WEBSOCKET: 'websocket',
};
const defaultSettings = {
afterFillSorting: SORT_BY_MATCHING_CREDENTIALS_SETTING,
afterFillSortingTotp: SORT_BY_RELEVANT_ENTRY,
@ -15,6 +20,7 @@ const defaultSettings = {
checkUpdateKeePassXC: CHECK_UPDATE_NEVER,
clearCredentialsTimeout: 10,
colorTheme: 'system',
connectionMethod: ConnectionMethod.NATIVE_MESSAGING,
credentialSorting: SORT_BY_GROUP_AND_TITLE,
debugLogging: false,
defaultGroup: '',

View file

@ -124,9 +124,10 @@ kpxcSites.combinationExceptionFound = function(existingCombination) {
return false;
}
// Exception for e.g. Google. They replace the username input with password input using identical className.
// Exception for Google. They replace the username input with password input using identical className.
// If detected, remove the username from the combination.
if (existingCombination?.username?.className?.length > 0
if (document.location.origin === 'https://accounts.google.com'
&& existingCombination?.username?.className?.length > 0
&& existingCombination?.password?.className?.length > 0
&& existingCombination?.username?.className === existingCombination?.password?.className) {
return true;

View file

@ -1,8 +1,8 @@
{
"manifest_version": 3,
"name": "KeePassXC-Browser",
"version": "1.10.0",
"version_name": "1.10.0",
"version": "1.10.0.1",
"version_name": "1.10.0.1",
"minimum_chrome_version": "124",
"description": "__MSG_extensionDescription__",
"author": "KeePassXC Team",

View file

@ -537,6 +537,18 @@
<div class="form-text" data-i18n="optionsClearCredentialsTimeoutHelpText"></div>
</div>
<!-- Connection method -->
<div class="form-group col-sm-3 pb-2 py-2">
<label for="connectionMethod" class="form-label" data-i18n="optionsConnectionMethod"></label>
<select class="form-select form-select-sm col-md-3 col-lg-2" id="connectionMethod" data-i18n="[title]optionsConnectionMethodSelection">
<option value="nativemessaging" data-i18n="optionsConnectionMethodNativeMessaging"></option>
<option value="websocket" data-i18n="optionsConnectionMethodWebSocket"></option>
</select>
</div>
<div>
<span class="form-text text-muted" data-i18n="optionsConnectionMethodHelpText"></span>
</div>
<!-- Debug logging -->
<div class="form-group mt-2 pb-1">
<div class="form-check form-switch">

View file

@ -226,6 +226,13 @@ options.initGeneralSettings = async function() {
});
});
// Connection method
$('#tab-general-settings select#connectionMethod').value = options.settings['connectionMethod'];
$('#tab-general-settings select#connectionMethod').addEventListener('change', async function(e) {
options.settings['connectionMethod'] = e.currentTarget.value;
await options.saveSettings();
});
// Default group
$('#defaultGroupButton').addEventListener('click', async function() {
const value = $('#defaultGroup').value;

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "keepassxc-browser",
"version": "1.10.0",
"version": "1.10.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "keepassxc-browser",
"version": "1.10.0",
"version": "1.10.0.1",
"license": "GPL-3.0",
"dependencies": {
"@npmcli/fs": "^2.1.0"

View file

@ -1,6 +1,6 @@
{
"name": "keepassxc-browser",
"version": "1.10.0",
"version": "1.10.0.1",
"description": "KeePassXC-Browser",
"main": "build.js",
"devDependencies": {