Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc-browser.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'keepassxc-browser/content/keepassxc-browser.js')
-rwxr-xr-xkeepassxc-browser/content/keepassxc-browser.js88
1 files changed, 69 insertions, 19 deletions
diff --git a/keepassxc-browser/content/keepassxc-browser.js b/keepassxc-browser/content/keepassxc-browser.js
index f2f71cd..2ad8389 100755
--- a/keepassxc-browser/content/keepassxc-browser.js
+++ b/keepassxc-browser/content/keepassxc-browser.js
@@ -6,12 +6,23 @@ const ManualFill = {
BOTH: 2
};
-// contains already called method names
+const acceptedOTPFields = [
+ '2fa',
+ 'auth',
+ 'challenge',
+ 'code',
+ 'mfa',
+ 'otp',
+ 'token'
+];
+
+// Contains already called method names
const _called = {};
_called.retrieveCredentials = false;
_called.clearLogins = false;
_called.manualFillRequested = ManualFill.NONE;
let _singleInputEnabledForPage = false;
+let _databaseClosed = true;
const _maximumInputs = 100;
// Count of detected form fields on the page
@@ -425,7 +436,7 @@ kpxcFields.getCombination = function(givenType, fieldId) {
/**
* Return the username field or null if it not exists
*/
-kpxcFields.getUsernameField = function(passwordId, checkDisabled) {
+kpxcFields.getUsernameField = async function(passwordId, checkDisabled) {
const passwordField = _f(passwordId);
if (!passwordField) {
return null;
@@ -447,8 +458,8 @@ kpxcFields.getUsernameField = function(passwordId, checkDisabled) {
return true; // Continue
}
- if (kpxc.settings.showLoginFormIcon) {
- kpxcUsernameFields.newIcon(usernameField);
+ if (kpxc.settings.showLoginFormIcon && await kpxc.passwordFilled() === false) {
+ kpxcUsernameIcons.newIcon(usernameField);
}
usernameField = i;
}
@@ -506,7 +517,7 @@ kpxcFields.getPasswordField = function(usernameId, checkDisabled) {
passwordField = null;
}
- kpxcPasswordIcons.newIcon(kpxc.settings.usePasswordGeneratorIcons, passwordField);
+ kpxcPasswordIcons.newIcon(kpxc.settings.usePasswordGeneratorIcons, passwordField, [], undefined, _databaseClosed);
} else {
// Search all inputs on page
const inputs = kpxcFields.getAllFields();
@@ -556,14 +567,8 @@ kpxcFields.prepareCombinations = async function(combinations) {
// If no username field is found, handle the single password field as such
const usernameField = c.username ? _f(c.username) : field;
- // Change icon for username field
- const res = await browser.runtime.sendMessage({
- action: 'get_status',
- args: [ true ]
- });
-
- if (kpxc.settings.showLoginFormIcon) {
- kpxcUsernameFields.newIcon(usernameField, res.databaseClosed);
+ if (kpxc.settings.showLoginFormIcon && await kpxc.passwordFilled() === false) {
+ kpxcUsernameIcons.newIcon(usernameField, _databaseClosed);
}
// Initialize form-submit for remembering credentials
@@ -854,8 +859,9 @@ kpxc.clearAllFromPage = function() {
// Switch credentials if database is changed or closed
kpxc.detectDatabaseChange = async function(response) {
+ _databaseClosed = true;
kpxc.clearAllFromPage();
- kpxcUsernameFields.switchIcon(true);
+ kpxc.switchIcons(true);
if (document.visibilityState !== 'hidden') {
if (response.new !== '' && response.new !== response.old) {
@@ -865,7 +871,8 @@ kpxc.detectDatabaseChange = async function(response) {
});
kpxc.settings = settings;
await kpxc.initCredentialFields(true);
- kpxcUsernameFields.switchIcon(false); // Unlocked
+ kpxc.switchIcons(false); // Unlocked
+ _databaseClosed = false;
// If user has requested a manual fill through context menu the actual credential filling
// is handled here when the opened database has been regognized. It's not a pretty hack.
@@ -926,9 +933,20 @@ kpxc.initCredentialFields = async function(forceCall) {
return;
}
+ // Update database closed status
+ const res = await browser.runtime.sendMessage({
+ action: 'get_status',
+ args: [ true ]
+ });
+ _databaseClosed = res.databaseClosed;
+
kpxcFields.prepareVisibleFieldsWithID('select');
kpxc.initPasswordGenerator(inputs);
+ if (kpxc.settings.showOTPIcon) {
+ kpxc.initOTPFields(inputs);
+ }
+
if (!kpxcFields.useDefinedCredentialFields()) {
// Get all combinations of username + password fields
kpxcFields.combinations = kpxcFields.getAllCombinations(inputs);
@@ -964,7 +982,18 @@ kpxc.initCredentialFields = async function(forceCall) {
kpxc.initPasswordGenerator = function(inputs) {
for (let i = 0; i < inputs.length; i++) {
if (inputs[i] && inputs[i].getLowerCaseAttribute('type') === 'password') {
- kpxcPasswordIcons.newIcon(kpxc.settings.usePasswordGeneratorIcons, inputs[i], inputs, i);
+ kpxcPasswordIcons.newIcon(kpxc.settings.usePasswordGeneratorIcons, inputs[i], inputs, i, _databaseClosed);
+ }
+ }
+};
+
+kpxc.initOTPFields = function(inputs, databaseClosed) {
+ for (const i of inputs) {
+ const id = i.getLowerCaseAttribute('id');
+ const name = i.getLowerCaseAttribute('name');
+
+ if (acceptedOTPFields.some(f => (id && id.includes(f)) || (name && name.includes(f)))) {
+ kpxcTOTPIcons.newIcon(i, _databaseClosed);
}
}
};
@@ -1244,8 +1273,8 @@ kpxc.fillInFromActiveElement = function(suppressWarnings, passOnly = false) {
kpxc.fillInCredentials(combination, passOnly, suppressWarnings);
};
-kpxc.fillInFromActiveElementTOTPOnly = async function() {
- const el = document.activeElement;
+kpxc.fillInFromActiveElementTOTPOnly = async function(target) {
+ const el = target || document.activeElement;
kpxcFields.setUniqueId(el);
const fieldId = kpxcFields.prepareId(el.getAttribute('data-kpxc-id'));
@@ -1379,6 +1408,7 @@ kpxc.fillIn = function(combination, onlyPassword, suppressWarnings) {
action: 'page_set_login_id', args: 0
});
filledIn = true;
+ kpxc.setPasswordFilled(true);
}
let list = [];
@@ -1416,6 +1446,7 @@ kpxc.fillIn = function(combination, onlyPassword, suppressWarnings) {
action: 'page_set_login_id', args: combination.loginId
});
filledIn = true;
+ kpxc.setPasswordFilled(true);
}
let list = [];
@@ -1468,6 +1499,7 @@ kpxc.fillIn = function(combination, onlyPassword, suppressWarnings) {
if (pField) {
kpxc.setValueWithChange(pField, valPassword);
pField.setAttribute('unchanged', true);
+ kpxc.setPasswordFilled(true);
}
let list = [];
@@ -1754,6 +1786,24 @@ kpxc.getDocumentLocation = function() {
return kpxc.settings.saveDomainOnly ? document.location.origin : document.location.href;
};
+// Sets the icons to corresponding database lock status
+kpxc.switchIcons = function(locked) {
+ kpxcUsernameIcons.switchIcon(locked);
+ kpxcPasswordIcons.switchIcon(locked);
+ kpxcTOTPIcons.switchIcon(locked);
+};
+
+kpxc.setPasswordFilled = function(state) {
+ browser.runtime.sendMessage({
+ action: 'password_set_filled',
+ args: state
+ });
+};
+
+kpxc.passwordFilled = async function() {
+ return await browser.runtime.sendMessage({ action: 'password_get_filled' });
+};
+
const kpxcEvents = {};
@@ -1780,7 +1830,7 @@ kpxcEvents.triggerActivatedTab = async function() {
// Update username field lock state
const state = await browser.runtime.sendMessage({ action: 'check_database_hash' });
- kpxcUsernameFields.switchIcon(state === '');
+ kpxc.switchIcons(state === '');
// initCredentialFields calls also "retrieve_credentials", to prevent it
// check of init() was already called