1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-19 02:51:14 +02:00

autofill improvements for readonly fields

This commit is contained in:
Kyle Spearrin 2019-04-06 10:34:44 -04:00
parent bb99b10f89
commit a25ceb49ce

View File

@ -110,7 +110,7 @@ export default class AutofillService implements AutofillServiceInterface {
getFormsWithPasswordFields(pageDetails: AutofillPageDetails): any[] { getFormsWithPasswordFields(pageDetails: AutofillPageDetails): any[] {
const formData: any[] = []; const formData: any[] = [];
const passwordFields = this.loadPasswordFields(pageDetails, true); const passwordFields = this.loadPasswordFields(pageDetails, true, true);
if (passwordFields.length === 0) { if (passwordFields.length === 0) {
return formData; return formData;
} }
@ -122,10 +122,10 @@ export default class AutofillService implements AutofillServiceInterface {
const formPasswordFields = passwordFields.filter((pf) => formKey === pf.form); const formPasswordFields = passwordFields.filter((pf) => formKey === pf.form);
if (formPasswordFields.length > 0) { if (formPasswordFields.length > 0) {
let uf = this.findUsernameField(pageDetails, formPasswordFields[0], false, false); let uf = this.findUsernameField(pageDetails, formPasswordFields[0], false, false, false);
if (uf == null) { if (uf == null) {
// not able to find any viewable username fields. maybe there are some "hidden" ones? // not able to find any viewable username fields. maybe there are some "hidden" ones?
uf = this.findUsernameField(pageDetails, formPasswordFields[0], true, false); uf = this.findUsernameField(pageDetails, formPasswordFields[0], true, true, false);
} }
formData.push({ formData.push({
form: pageDetails.forms[formKey], form: pageDetails.forms[formKey],
@ -264,6 +264,7 @@ export default class AutofillService implements AutofillServiceInterface {
filledFields[field.opid] = field; filledFields[field.opid] = field;
fillScript.script.push(['click_on_opid', field.opid]); fillScript.script.push(['click_on_opid', field.opid]);
fillScript.script.push(['focus_by_opid', field.opid]);
fillScript.script.push(['fill_by_opid', field.opid, val]); fillScript.script.push(['fill_by_opid', field.opid, val]);
} }
}); });
@ -304,10 +305,10 @@ export default class AutofillService implements AutofillServiceInterface {
return fillScript; return fillScript;
} }
let passwordFields = this.loadPasswordFields(pageDetails, false); let passwordFields = this.loadPasswordFields(pageDetails, false, false);
if (!passwordFields.length && !options.onlyVisibleFields) { if (!passwordFields.length && !options.onlyVisibleFields) {
// not able to find any viewable password fields. maybe there are some "hidden" ones? // not able to find any viewable password fields. maybe there are some "hidden" ones?
passwordFields = this.loadPasswordFields(pageDetails, true); passwordFields = this.loadPasswordFields(pageDetails, true, true);
} }
for (const formKey in pageDetails.forms) { for (const formKey in pageDetails.forms) {
@ -327,11 +328,11 @@ export default class AutofillService implements AutofillServiceInterface {
passwords.push(pf); passwords.push(pf);
if (login.username) { if (login.username) {
username = this.findUsernameField(pageDetails, pf, false, false); username = this.findUsernameField(pageDetails, pf, false, false, false);
if (!username && !options.onlyVisibleFields) { if (!username && !options.onlyVisibleFields) {
// not able to find any viewable username fields. maybe there are some "hidden" ones? // not able to find any viewable username fields. maybe there are some "hidden" ones?
username = this.findUsernameField(pageDetails, pf, true, false); username = this.findUsernameField(pageDetails, pf, true, true, false);
} }
if (username) { if (username) {
@ -349,11 +350,11 @@ export default class AutofillService implements AutofillServiceInterface {
passwords.push(pf); passwords.push(pf);
if (login.username && pf.elementNumber > 0) { if (login.username && pf.elementNumber > 0) {
username = this.findUsernameField(pageDetails, pf, false, true); username = this.findUsernameField(pageDetails, pf, false, false, true);
if (!username && !options.onlyVisibleFields) { if (!username && !options.onlyVisibleFields) {
// not able to find any viewable username fields. maybe there are some "hidden" ones? // not able to find any viewable username fields. maybe there are some "hidden" ones?
username = this.findUsernameField(pageDetails, pf, true, true); username = this.findUsernameField(pageDetails, pf, true, true, true);
} }
if (username) { if (username) {
@ -379,6 +380,7 @@ export default class AutofillService implements AutofillServiceInterface {
filledFields[u.opid] = u; filledFields[u.opid] = u;
fillScript.script.push(['click_on_opid', u.opid]); fillScript.script.push(['click_on_opid', u.opid]);
fillScript.script.push(['focus_by_opid', u.opid]);
fillScript.script.push(['fill_by_opid', u.opid, login.username]); fillScript.script.push(['fill_by_opid', u.opid, login.username]);
}); });
@ -389,6 +391,7 @@ export default class AutofillService implements AutofillServiceInterface {
filledFields[p.opid] = p; filledFields[p.opid] = p;
fillScript.script.push(['click_on_opid', p.opid]); fillScript.script.push(['click_on_opid', p.opid]);
fillScript.script.push(['focus_by_opid', p.opid]);
fillScript.script.push(['fill_by_opid', p.opid, login.password]); fillScript.script.push(['fill_by_opid', p.opid, login.password]);
}); });
@ -504,6 +507,7 @@ export default class AutofillService implements AutofillServiceInterface {
filledFields[fillFields.expMonth.opid] = fillFields.expMonth; filledFields[fillFields.expMonth.opid] = fillFields.expMonth;
fillScript.script.push(['click_on_opid', fillFields.expMonth.opid]); fillScript.script.push(['click_on_opid', fillFields.expMonth.opid]);
fillScript.script.push(['focus_by_opid', fillFields.expMonth.opid]);
fillScript.script.push(['fill_by_opid', fillFields.expMonth.opid, expMonth]); fillScript.script.push(['fill_by_opid', fillFields.expMonth.opid, expMonth]);
} }
@ -541,6 +545,7 @@ export default class AutofillService implements AutofillServiceInterface {
filledFields[fillFields.expYear.opid] = fillFields.expYear; filledFields[fillFields.expYear.opid] = fillFields.expYear;
fillScript.script.push(['click_on_opid', fillFields.expYear.opid]); fillScript.script.push(['click_on_opid', fillFields.expYear.opid]);
fillScript.script.push(['focus_by_opid', fillFields.expYear.opid]);
fillScript.script.push(['fill_by_opid', fillFields.expYear.opid, expYear]); fillScript.script.push(['fill_by_opid', fillFields.expYear.opid, expYear]);
} }
@ -847,18 +852,21 @@ export default class AutofillService implements AutofillServiceInterface {
if (doFill) { if (doFill) {
filledFields[field.opid] = field; filledFields[field.opid] = field;
fillScript.script.push(['click_on_opid', field.opid]); fillScript.script.push(['click_on_opid', field.opid]);
fillScript.script.push(['focus_by_opid', field.opid]);
fillScript.script.push(['fill_by_opid', field.opid, dataValue]); fillScript.script.push(['fill_by_opid', field.opid, dataValue]);
} }
} }
private loadPasswordFields(pageDetails: AutofillPageDetails, canBeHidden: boolean) { private loadPasswordFields(pageDetails: AutofillPageDetails, canBeHidden: boolean, canBeReadOnly: boolean) {
const arr: AutofillField[] = []; const arr: AutofillField[] = [];
pageDetails.fields.forEach((f) => { pageDetails.fields.forEach((f) => {
const isPassword = f.type === 'password'; const isPassword = f.type === 'password';
const isLikePassword = f.type === 'text' && ((f.htmlID != null && f.htmlID.toLowerCase() === 'password') || const isLikePassword = () => f.type === 'text' &&
(f.htmlName != null && f.htmlName.toLowerCase() === 'password') || ((f.htmlID != null && f.htmlID.toLowerCase().indexOf('password') > 0) ||
(f.placeholder != null && f.placeholder.toLowerCase() === 'password')); (f.htmlName != null && f.htmlName.toLowerCase().indexOf('password') > 0) ||
if (!f.disabled && !f.readonly && (isPassword || isLikePassword) && (canBeHidden || f.viewable)) { (f.placeholder != null && f.placeholder.toLowerCase().indexOf('password') > 0));
if (!f.disabled && (canBeReadOnly || !f.readonly) && (isPassword || isLikePassword())
&& (canBeHidden || f.viewable)) {
arr.push(f); arr.push(f);
} }
}); });
@ -866,7 +874,7 @@ export default class AutofillService implements AutofillServiceInterface {
} }
private findUsernameField(pageDetails: AutofillPageDetails, passwordField: AutofillField, canBeHidden: boolean, private findUsernameField(pageDetails: AutofillPageDetails, passwordField: AutofillField, canBeHidden: boolean,
withoutForm: boolean) { canBeReadOnly: boolean, withoutForm: boolean) {
let usernameField: AutofillField = null; let usernameField: AutofillField = null;
for (let i = 0; i < pageDetails.fields.length; i++) { for (let i = 0; i < pageDetails.fields.length; i++) {
const f = pageDetails.fields[i]; const f = pageDetails.fields[i];
@ -874,7 +882,7 @@ export default class AutofillService implements AutofillServiceInterface {
break; break;
} }
if (!f.disabled && !f.readonly && if (!f.disabled && (canBeReadOnly || !f.readonly) &&
(withoutForm || f.form === passwordField.form) && (canBeHidden || f.viewable) && (withoutForm || f.form === passwordField.form) && (canBeHidden || f.viewable) &&
(f.type === 'text' || f.type === 'email' || f.type === 'tel')) { (f.type === 'text' || f.type === 'email' || f.type === 'tel')) {
usernameField = f; usernameField = f;