Use native KeePassXC password generator (2.7.0+)

This commit is contained in:
varjolintu 2021-10-11 21:26:20 +03:00 committed by Jonathan White
parent 1579838617
commit 98eb4ab0a9
No known key found for this signature in database
GPG key ID: 440FC65F2E0C6E01
4 changed files with 87 additions and 17 deletions

View file

@ -326,7 +326,7 @@ keepass.generatePassword = async function(tab) {
return [];
}
let passwords = [];
let password;
const kpAction = kpActions.GENERATE_PASSWORD;
const [ nonce, incrementedNonce ] = keepass.getNonces();
@ -349,22 +349,18 @@ keepass.generatePassword = async function(tab) {
keepass.setcurrentKeePassXCVersion(parsed.version);
if (keepass.verifyResponse(parsed, incrementedNonce)) {
if (parsed.entries) {
passwords = parsed.entries;
keepass.updateLastUsed(keepass.databaseHash);
} else {
console.log('No entries returned. Is KeePassXC up-to-date?');
}
password = parsed.entries ?? parsed.password;
keepass.updateLastUsed(keepass.databaseHash);
} else {
console.log('GeneratePassword rejected');
}
return passwords;
return password;
} else if (response.error && response.errorCode) {
keepass.handleError(tab, response.errorCode, response.error);
}
return passwords;
return password;
} catch (err) {
console.log('generatePassword failed: ', err);
return [];
@ -1318,6 +1314,12 @@ keepass.compareVersion = function(minimum, current, canBeEqual = true) {
return false;
}
// Handle snapshot builds as stable version
const snapshot = '-snapshot';
if (current.endsWith(snapshot)) {
current = current.slice(0, -snapshot.length);
}
const min = minimum.split('.', 3).map(s => s.padStart(4, '0')).join('.');
const cur = current.split('.', 3).map(s => s.padStart(4, '0')).join('.');
return (canBeEqual ? (min <= cur) : (min < cur));

View file

@ -187,7 +187,10 @@ page.switchTab = async function(tab) {
browser.contextMenus.update('fill_attribute', { visible: false });
// Clears all logins from other tabs after a timeout
clearTimeout(page.clearCredentialsTimeout);
if (page.clearCredentialsTimeout) {
clearTimeout(page.clearCredentialsTimeout);
}
page.clearCredentialsTimeout = setTimeout(() => {
for (const pageTabId of Object.keys(page.tabs)) {
if (tab.id !== Number(pageTabId)) {

View file

@ -70,12 +70,18 @@ PasswordIcon.prototype.createIcon = function(field) {
icon.style.filter = 'saturate(0%)';
}
icon.addEventListener('click', function(e) {
icon.addEventListener('click', async function(e) {
if (!e.isTrusted) {
return;
}
e.stopPropagation();
if (await useKeePassXCPasswordGenerator()) {
kpxcPasswordDialog.generate(null, field);
return;
}
kpxcPasswordDialog.showDialog(field, icon);
});
@ -207,7 +213,12 @@ kpxcPasswordDialog.openDialog = function() {
}
};
kpxcPasswordDialog.trigger = function() {
kpxcPasswordDialog.trigger = async function() {
if (await useKeePassXCPasswordGenerator()) {
kpxcPasswordDialog.generate(null, document.activeElement);
return;
}
kpxcPasswordDialog.showDialog(document.activeElement, kpxcPasswordDialog.icon);
};
@ -244,7 +255,7 @@ kpxcPasswordDialog.showDialog = function(field, icon) {
}
};
kpxcPasswordDialog.generate = async function(e) {
kpxcPasswordDialog.generate = async function(e, field) {
// This function can be also called from non-events
if (e) {
if (!e.isTrusted) {
@ -253,6 +264,11 @@ kpxcPasswordDialog.generate = async function(e) {
e.preventDefault();
}
if (await useKeePassXCPasswordGenerator()) {
kpxcPasswordDialog.newFill(field, await sendMessage('generate_password'));
return;
}
callbackGeneratedPassword(await sendMessage('generate_password'));
};
@ -278,7 +294,7 @@ kpxcPasswordDialog.fill = function(e) {
const message = tr('passwordGeneratorErrorTooLong') + '\r\n'
+ tr('passwordGeneratorErrorTooLongCut') + '\r\n' + tr('passwordGeneratorErrorTooLongRemember');
message.style.whiteSpace = 'pre';
sendMessage('show_notification', [ message ]);
kpxcUI.createNotification('error', message);
return;
}
}
@ -298,6 +314,32 @@ kpxcPasswordDialog.fill = function(e) {
}
};
// New way to fill the password
kpxcPasswordDialog.newFill = function(elem, password) {
if (!elem || !password) {
return;
}
if (password.length === 0) {
kpxcUI.createNotification('error', tr('usernameLockedFieldText'));
return;
}
if (elem.getAttribute('maxlength')) {
if (password.length > elem.getAttribute('maxlength')) {
const message = tr('passwordGeneratorErrorTooLong') + '\r\n'
+ tr('passwordGeneratorErrorTooLongCut') + '\r\n' + tr('passwordGeneratorErrorTooLongRemember');
message.style.whiteSpace = 'pre';
kpxcUI.createNotification('error', message);
return;
}
}
elem.value = password;
elem.dispatchEvent(new Event('input', { bubbles: true }));
elem.dispatchEvent(new Event('change', { bubbles: true }));
};
kpxcPasswordDialog.copyPasswordToClipboard = function() {
kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input').select();
try {
@ -308,8 +350,8 @@ kpxcPasswordDialog.copyPasswordToClipboard = function() {
return false;
};
const callbackGeneratedPassword = function(entries) {
if (entries && entries.length >= 1) {
const callbackGeneratedPassword = function(passwords) {
if (passwords && passwords.length >= 1) {
const errorMessage = kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-error');
if (errorMessage) {
enableButtons();
@ -319,7 +361,7 @@ const callbackGeneratedPassword = function(entries) {
errorMessage.remove();
}
kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input').value = entries[0].password;
kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input').value = passwords[0].password;
} else {
if (kpxcPasswordDialog.shadowSelectorAll('div#kpxc-pwgen-error').length === 0) {
const input = kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input');
@ -346,3 +388,16 @@ const disableButtons = function() {
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-copy').style.display = 'none';
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-fill').style.display = 'none';
};
const useKeePassXCPasswordGenerator = async function() {
const response = await browser.runtime.sendMessage({
action: 'get_keepassxc_versions'
});
const result = await browser.runtime.sendMessage({
action: 'compare_version',
args: [ '2.7.0', response.current ]
});
return result;
};

View file

@ -169,6 +169,16 @@ Response message data (success, decrypted):
}
```
Response message data (success, decrypted, KeePassXC 2.7.0 and later):
```json
{
"version": "2.7.0",
"password": "thePassword",
"success": "true",
"nonce": "tZvLrBzkQ9GxXq9PvKJj4iAnfPT0VZ3Q"
}
```
### get-logins
Unencrypted message:
```json