mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Improve TOTP detection and custom field overriding
This commit is contained in:
parent
bfb3c77b6e
commit
ce31969160
5 changed files with 53 additions and 28 deletions
|
|
@ -632,7 +632,9 @@ kpxcFields.useDefinedCredentialFields = function() {
|
|||
|
||||
// Handle custom TOTP field
|
||||
if (_f(creds.totp)) {
|
||||
kpxcTOTPIcons.newIcon(_f(creds.totp), _databaseState);
|
||||
const totpField = _f(creds.totp);
|
||||
totpField.setAttribute('kpxc-defined', 'totp');
|
||||
kpxcTOTPIcons.newIcon(totpField, _databaseState, true);
|
||||
}
|
||||
|
||||
let found = _f(creds.username) || _f(creds.password);
|
||||
|
|
@ -644,6 +646,14 @@ kpxcFields.useDefinedCredentialFields = function() {
|
|||
}
|
||||
|
||||
if (found) {
|
||||
if (creds.username) {
|
||||
_f(creds.username).setAttribute('kpxc-defined', 'username');
|
||||
}
|
||||
|
||||
if (creds.password) {
|
||||
_f(creds.password).setAttribute('kpxc-defined', 'password');
|
||||
}
|
||||
|
||||
const fields = {
|
||||
username: creds.username,
|
||||
password: creds.password,
|
||||
|
|
@ -1036,6 +1046,12 @@ kpxc.initCredentialFields = async function(forceCall, inputs) {
|
|||
|
||||
_databaseState = !res.keePassXCAvailable ? DatabaseState.DISCONNECTED : DatabaseState.LOCKED;
|
||||
|
||||
if (!kpxcFields.useDefinedCredentialFields()) {
|
||||
// Get all combinations of username + password fields
|
||||
kpxcFields.combinations = kpxcFields.getAllCombinations(inputs);
|
||||
}
|
||||
kpxcFields.prepareCombinations(kpxcFields.combinations);
|
||||
|
||||
kpxcFields.prepareVisibleFieldsWithID('select');
|
||||
kpxc.initPasswordGenerator(inputs);
|
||||
|
||||
|
|
@ -1043,12 +1059,6 @@ kpxc.initCredentialFields = async function(forceCall, inputs) {
|
|||
kpxc.initOTPFields(inputs);
|
||||
}
|
||||
|
||||
if (!kpxcFields.useDefinedCredentialFields()) {
|
||||
// Get all combinations of username + password fields
|
||||
kpxcFields.combinations = kpxcFields.getAllCombinations(inputs);
|
||||
}
|
||||
kpxcFields.prepareCombinations(kpxcFields.combinations);
|
||||
|
||||
if (kpxcFields.combinations.length === 0 && inputs.length === 0) {
|
||||
browser.runtime.sendMessage({
|
||||
action: 'show_default_browseraction'
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ PasswordIcon.prototype.initField = function(field, inputs, pos) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (field.getAttribute('kpxc-password-generator')) {
|
||||
if (field.getAttribute('kpxc-password-generator')
|
||||
|| (field.hasAttribute('kpxc-defined') && field.getAttribute('kpxc-defined') !== 'password')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -62,8 +63,7 @@ PasswordIcon.prototype.initField = function(field, inputs, pos) {
|
|||
PasswordIcon.prototype.createIcon = function(field) {
|
||||
const className = (isFirefox() ? 'key-moz' : 'key');
|
||||
const size = (field.offsetHeight > 28) ? 24 : 16;
|
||||
let offset = Math.floor((field.offsetHeight - size) / 3);
|
||||
offset = (offset < 0) ? 0 : offset;
|
||||
const offset = kpxcUI.calculateIconOffset(field, size);
|
||||
|
||||
const icon = kpxcUI.createElement('div', 'kpxc kpxc-pwgen-icon ' + className,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ const ignoredTypes = [ 'email', 'password', 'username' ];
|
|||
var kpxcTOTPIcons = {};
|
||||
kpxcTOTPIcons.icons = [];
|
||||
|
||||
kpxcTOTPIcons.newIcon = function(field, databaseState = DatabaseState.DISCONNECTED) {
|
||||
kpxcTOTPIcons.icons.push(new TOTPFieldIcon(field, databaseState));
|
||||
kpxcTOTPIcons.newIcon = function(field, databaseState = DatabaseState.DISCONNECTED, forced = false) {
|
||||
kpxcTOTPIcons.icons.push(new TOTPFieldIcon(field, databaseState, forced));
|
||||
};
|
||||
|
||||
kpxcTOTPIcons.switchIcon = function(state) {
|
||||
|
|
@ -17,29 +17,40 @@ kpxcTOTPIcons.switchIcon = function(state) {
|
|||
|
||||
|
||||
class TOTPFieldIcon extends Icon {
|
||||
constructor(field, databaseState = DatabaseState.DISCONNECTED) {
|
||||
constructor(field, databaseState = DatabaseState.DISCONNECTED, forced = false) {
|
||||
super();
|
||||
this.icon = null;
|
||||
this.inputField = null;
|
||||
this.databaseState = databaseState;
|
||||
|
||||
this.initField(field);
|
||||
this.initField(field, forced);
|
||||
kpxcUI.monitorIconPosition(this);
|
||||
}
|
||||
}
|
||||
|
||||
TOTPFieldIcon.prototype.initField = function(field) {
|
||||
if (!field
|
||||
|| ignoredTypes.some(t => t === field.type)
|
||||
|| field.getAttribute('kpxc-totp-field') === 'true'
|
||||
|| field.offsetWidth < MINIMUM_SIZE
|
||||
|| field.size < 2
|
||||
|| (field.maxLength > 0 && (field.maxLength < 6 || field.maxLength > 8))
|
||||
|| field.id.match(ignoreRegex)
|
||||
|| field.name.match(ignoreRegex)) {
|
||||
TOTPFieldIcon.prototype.initField = function(field, forced) {
|
||||
if (!field) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forced) {
|
||||
if (ignoredTypes.some(t => t === field.type)
|
||||
|| ignoredTypes.some(t => t === field.autocomplete)
|
||||
|| field.getAttribute('kpxc-totp-field') === 'true'
|
||||
|| (field.hasAttribute('kpxc-defined') && field.getAttribute('kpxc-defined') !== 'totp')
|
||||
|| field.offsetWidth < MINIMUM_SIZE
|
||||
|| field.size < 2
|
||||
|| (field.maxLength > 0 && (field.maxLength < 6 || field.maxLength > 8))
|
||||
|| field.id.match(ignoreRegex)
|
||||
|| field.name.match(ignoreRegex)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (field.getAttribute('kpxc-totp-field') === 'true') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
field.setAttribute('kpxc-totp-field', 'true');
|
||||
|
||||
// Observer the visibility
|
||||
|
|
@ -56,8 +67,7 @@ TOTPFieldIcon.prototype.createIcon = function(field) {
|
|||
|
||||
// Size the icon dynamically, but not greater than 24 or smaller than 14
|
||||
const size = Math.max(Math.min(24, field.offsetHeight - 4), 14);
|
||||
let offset = Math.floor((field.offsetHeight - size) / 3);
|
||||
offset = (offset < 0) ? 0 : offset;
|
||||
const offset = kpxcUI.calculateIconOffset(field, size);
|
||||
|
||||
const icon = kpxcUI.createElement('div', 'kpxc kpxc-totp-icon ' + className,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,12 +80,17 @@ kpxcUI.updateIconPosition = function(iconClass) {
|
|||
}
|
||||
};
|
||||
|
||||
kpxcUI.calculateIconOffset = function(field, size) {
|
||||
const offset = Math.floor((field.offsetHeight - size) / 3);
|
||||
return (offset < 0) ? 0 : offset;
|
||||
};
|
||||
|
||||
kpxcUI.setIconPosition = function(icon, field) {
|
||||
const rect = field.getBoundingClientRect();
|
||||
const bodyRect = document.body.getBoundingClientRect();
|
||||
const bodyStyle = getComputedStyle(document.body);
|
||||
const offset = Number(icon.getAttribute('offset'));
|
||||
const size = (document.dir !== 'rtl') ? Number(icon.getAttribute('size')) : 0;
|
||||
const offset = kpxcUI.calculateIconOffset(field, size);
|
||||
|
||||
if (bodyStyle.position.toLowerCase() === 'relative') {
|
||||
icon.style.top = Pixels(rect.top - bodyRect.top + document.scrollingElement.scrollTop + offset + 1);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ UsernameFieldIcon.prototype.initField = function(field) {
|
|||
if (!field
|
||||
|| field.getAttribute('kpxc-username-field') === 'true'
|
||||
|| field.getAttribute('kpxc-totp-field') === 'true'
|
||||
|| (field.hasAttribute('kpxc-defined') && field.getAttribute('kpxc-defined') !== 'username')
|
||||
|| !kpxcFields.isVisible(field)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -71,8 +72,7 @@ UsernameFieldIcon.prototype.createIcon = function(target) {
|
|||
return;
|
||||
}
|
||||
|
||||
let offset = Math.floor((field.offsetHeight - size) / 3);
|
||||
offset = (offset < 0) ? 0 : offset;
|
||||
const offset = kpxcUI.calculateIconOffset(field, size);
|
||||
|
||||
const icon = kpxcUI.createElement('div', 'kpxc kpxc-username-icon ' + className,
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue