Open tremby opened 4 years ago
I assume you have already tried using String Fields with Choose Custom login fields for this page
? That would do exactly the thing you are proposing.
EDIT: The issue you linked has a comment about it: https://github.com/keepassxreboot/keepassxc-browser/issues/390#issuecomment-457808066
That won't work because, exactly like in the comment following the one you just linked, each time I visit the page the fields are different and need different responses.
I see. The attribute filling should be much simpler feature to make. This kind of scripting is a major feature and it would take a lot of time to implement and test.
Expected Behavior
I'd like to be able to script autofill. I want to be able to specify, with a bit of JS code if necessary, which fields should be filled with which "additional attributes" present in the entry, so that when the page is autofilled the right things go in the right places.
Current Behavior
Some websites (one of my banks for example) have extra fields which need to be entered. I know of the "string fields" feature, but the fields aren't always the same or in the same order (such as security questions) and aren't always on the same page (security question on one page, password on the next), and the "string fields" only let custom fields be filled in a specific order. Basing things on order also seems somewhat brittle to me.
At the moment, on my bank website's security question page, it asks me one of my security questions at random, and the field is of type password so it gets autofilled with my password, which isn't correct in this context. I correct it manually, then on the next page my password gets autofilled correctly.
I'm aware of the workaround of adding extra entries for each particular form. I don't like this workaround, since it distributes related data in my database.
Possible Solution
390 would help, since I could click the field in question and select the relevant question from the list, but it'd like much more if this were automatic.
I'd like if there were some scheme for "additional attributes" which would target them to fields with specific names or IDs or with specific labels. I'm a web developer and so know CSS selectors and JS, and it seems to me doing this by CSS selector would be a nice way to do it, or using JS if it's too complicated for a simple query.
By CSS selector
These attributes might put their value into the first matching element found on the page:
Selector: input[name="securityQuestion"]
fills the firstinput
element with aname="securityQuestion"
attributeSelector: input#pin
fills theinput
element with IDpin
These could be done simply with
document.querySelector(attributeName.replace(/^Selector:\s*/i, '')).value = attributeValue
, though with a check to see if a matching element was actually found.By JS function
Some fields (my bank's security question for example) can't be selected with a simple CSS selector, since I need to know the contents of a text node to know if it matches. CSS can't select based on that. So I'd like to also be able to use some JS to select an element.
Perhaps we give a function which would return the element, given the parameter which is the root node being searched (like
document
). Ifnull
orundefined
are returned the value wouldn't get filled anywhere. Examples:Function: (root) => root.querySelector('#pin')
would select an element with IDpin
as in the second example aboveFunction: (root) => { const label = root.querySelector('label#login_secretQuestion_label'); return label && l.innerText.includes('favourite teacher') ? label.control : null }
is what I'd need on my bank website: it'd find the label with IDlogin_secretQuestion_label
, and then return the input control this points to (via itsfor
attribute) as long as the label contains the phrase "favourite teacher", otherwise it'd returnnull
(and then that field might get filled by another additional attribute)Function: (root) => { const input = root.querySelector('input#login_secretQuestion'); return [...input.labels || []].some(label => label.innerText.includes('favourite teacher')) ? input : null }
would be another way to do the same thing, just the other way around -- this one first selects the input, then returns it only if one of its labels contains the text I want to matchFunction: (root) => [...root.querySelectorAll('input')].find(input => [...input.labels || []].some(label => label.innerText.includes('favourite teacher')))
would loop through all inputs and return the first with a label containing the matching textShorthands
Maybe shorthands to some of the most common forms could be available:
Field name: securityQuestion
as a shorthand for the first field with that name attributeField ID: pin
as a shorthand for the field with that ID attributeField label containing: favourite teacher
as a shorthand for the first field with a label whose innerText contains that stringField label: What was the name of your favourite teacher?
as a shorthand for the first field with a label whose innerText (or its trimmed version perhaps) is exactly that string.Other thoughts:
select
,textarea
andinput
rather than justinput
in the shorthands above. And I guess it'd be good if radio buttons and checkboxes were supported too.aria-label
attribute when looking for labels of a control (input.labels
only gives a list of actuallabel
elements associated, whether byid
/for="id"
or as an enclosing element).KPH
attributes can be labelled. Maybe the syntax would have to change to accommodate:Selector{selector string goes here}: Friendly label
,Function{(root) => whatever}: Other label
or similar.Discussion
Would this be a desirable feature? Likely to be merged if it works well?
I'd be potentially interested in having a go at implementing it if so. Before doing so I'd want to discuss and make sure I'm on the same page about featureset and direction.