From de47d16c4df9788bb40681c427a8e6716c0ed319 Mon Sep 17 00:00:00 2001 From: Cesar Gonzalez Date: Wed, 9 Oct 2024 13:44:43 -0500 Subject: [PATCH] [PM-8833] Adjusting field qualification --- ...inline-menu-field-qualification.service.ts | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts index 941626db52..7e0a03e378 100644 --- a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts +++ b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts @@ -37,7 +37,13 @@ export class InlineMenuFieldQualificationService private autocompleteDisabledValues = new Set(["off", "false"]); private newFieldKeywords = new Set(["new", "neue", "ändern"]); private accountCreationFieldKeywords = [ - ...new Set(["register", "registration", "create", "confirm", ...this.newFieldKeywords]), + ...new Set([ + "register", + "registration", + "create", + "confirm password", + ...this.newFieldKeywords, + ]), ]; private updatePasswordFieldKeywords = ["update", "change", "current"]; private creditCardFieldKeywords = [ @@ -289,10 +295,22 @@ export class InlineMenuFieldQualificationService field: AutofillField, pageDetails: AutofillPageDetails, ): boolean { + const parentForm = pageDetails.forms[field.form]; + // If the provided field is set with an autocomplete value of "current-password", we should assume that // the page developer intends for this field to be interpreted as a password field for a login form. if (this.fieldContainsAutocompleteValues(field, this.currentPasswordAutocompleteValue)) { - return pageDetails.fields.filter(this.isNewPasswordField).length === 0; + if (!parentForm) { + return ( + pageDetails.fields.filter(this.isNewPasswordField).filter((f) => f.viewable).length === 0 + ); + } + + return ( + pageDetails.fields + .filter(this.isNewPasswordField) + .filter((f) => f.viewable && f.form === field.form).length === 0 + ); } const usernameFieldsInPageDetails = pageDetails.fields.filter(this.isUsernameField); @@ -306,7 +324,6 @@ export class InlineMenuFieldQualificationService // If the field is not structured within a form, we need to identify if the field is present on // a page with multiple password fields. If that isn't the case, we can assume this is a login form field. - const parentForm = pageDetails.forms[field.form]; if (!parentForm) { // If no parent form is found, and multiple password fields are present, we should assume that // the passed field belongs to a user account creation form. @@ -419,12 +436,18 @@ export class InlineMenuFieldQualificationService return false; } - // If the form that contains the field has more than one visible field, we should assume - // that the field is part of an account creation form. + // If the form that contains a single field, we should assume that it is part + // of a multistep login form. const fieldsWithinForm = pageDetails.fields.filter( (pageDetailsField) => pageDetailsField.form === field.form, ); - return fieldsWithinForm.length === 1; + if (fieldsWithinForm.length === 1) { + return true; + } + + // If multiple fields exist within the form, we should check if a single visible field exists. + // If so, we should assume that the field is part of a login form. + return fieldsWithinForm.filter((field) => field.viewable).length === 1; } // If a single password field exists within the page details, and that password field is part of @@ -442,8 +465,7 @@ export class InlineMenuFieldQualificationService return false; } - // If no visible fields are found on the page, but we have a single password - // field we should assume that the field is part of a login form. + // If we have a single password field we should assume that the field is part of a login form. if (passwordFieldsInPageDetails.length === 1) { return true; } @@ -817,7 +839,8 @@ export class InlineMenuFieldQualificationService isUsernameField = (field: AutofillField): boolean => { if ( !this.usernameFieldTypes.has(field.type) || - this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet) + this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet) || + this.keywordsFoundInFieldData(field, AutoFillConstants.FieldIgnoreList) ) { return false; }