Skip to content

Commit

Permalink
Refactor [vXXX] auto update credential provider script
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] authored Sep 25, 2024
1 parent 05e7312 commit 2e6b1fa
Show file tree
Hide file tree
Showing 14 changed files with 1,779 additions and 1,814 deletions.
332 changes: 126 additions & 206 deletions firefox-ios/Client/Assets/CC_Script/AutofillTelemetry.sys.mjs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions firefox-ios/Client/Assets/CC_Script/Constants.ios.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const IOS_DEFAULT_PREFERENCES = {
"extensions.formautofill.heuristics.captureOnPageNavigation": false,
"extensions.formautofill.focusOnAutofill": false,
"extensions.formautofill.test.ignoreVisibilityCheck": false,
"extensions.formautofill.heuristics.autofillSameOriginWithTop": false,
"signon.generation.confidenceThreshold": 0.75,
};

// Used Mimic the behavior of .getAutocompleteInfo()
Expand Down
102 changes: 82 additions & 20 deletions firefox-ios/Client/Assets/CC_Script/FieldScanner.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,25 @@ export class FieldDetail {
// Reference to the elemenet
elementWeakRef = null;

// id/name. This is only used for debugging
// The identifier generated via ContentDOMReference for the associated DOM element
// of this field
elementId = null;

// The identifier generated via ContentDOMReference for the root element of
// this field
rootElementId = null;

// If the element is an iframe, it is the id of the BrowsingContext of the iframe,
// Otherwise, it is the id of the BrowsingContext the element is in
browsingContextId = null;

// string with `${element.id}/{element.name}`. This is only used for debugging.
identifier = "";

// The inferred field name for this element
// tag name attribute of the element
localName = null;

// The inferred field name for this element.
fieldName = null;

// The approach we use to infer the information for this element
Expand Down Expand Up @@ -50,41 +65,81 @@ export class FieldDetail {

constructor(
element,
form,
fieldName = null,
{ autocompleteInfo = {}, confidence = null } = {}
) {
this.elementWeakRef = new WeakRef(element);
this.elementId = lazy.FormAutofillUtils.getElementIdentifier(element);
this.rootElementId = lazy.FormAutofillUtils.getElementIdentifier(
form.rootElement
);
this.identifier = `${element.id}/${element.name}`;
this.fieldName = fieldName;
this.localName = element.localName;

if (autocompleteInfo) {
if (Array.isArray(fieldName)) {
this.fieldName = fieldName[0];
this.alternativeFieldName = fieldName[1];
} else {
this.fieldName = fieldName;
}

if (!this.fieldName) {
this.reason = "unknown";
} else if (autocompleteInfo) {
this.reason = "autocomplete";
this.section = autocompleteInfo.section;
this.addressType = autocompleteInfo.addressType;
this.contactType = autocompleteInfo.contactType;
this.credentialType = autocompleteInfo.credentialType;
this.sectionName = this.section || this.addressType;
} else if (confidence) {
this.reason = "fathom";
this.confidence = confidence;

// TODO: This should be removed once we support reference field info across iframe.
// Temporarily add an addtional "the field is the only visible input" constraint
// when determining whether a form has only a high-confidence cc-* field a valid
// credit card section. We can remove this restriction once we are confident
// about only using fathom.
this.isOnlyVisibleFieldWithHighConfidence = false;
if (
this.confidence > lazy.FormAutofillUtils.ccFathomHighConfidenceThreshold
) {
const root = element.form || element.ownerDocument;
const inputs = root.querySelectorAll("input:not([type=hidden])");
if (inputs.length == 1 && inputs[0] == element) {
this.isOnlyVisibleFieldWithHighConfidence = true;
}
}
} else {
this.reason = "regex-heuristic";
}

try {
this.browsingContextId =
element.localName == "iframe"
? element.browsingContext.id
: BrowsingContext.getFromWindow(element.ownerGlobal).id;
} catch {
/* unit test doesn't have ownerGlobal */
}

this.isVisible = lazy.FormAutofillUtils.isFieldVisible(this.element);
}

get element() {
return this.elementWeakRef.deref();
}

get sectionName() {
return this.section || this.addressType;
}

#isVisible = null;
get isVisible() {
if (this.#isVisible == null) {
this.#isVisible = lazy.FormAutofillUtils.isFieldVisible(this.element);
}
return this.#isVisible;
/**
* Convert FieldDetail class to an object that is suitable for
* sending over IPC. Avoid using this in other case.
*/
toVanillaObject() {
const json = { ...this };
delete json.elementWeakRef;
return json;
}
}

Expand All @@ -96,6 +151,7 @@ export class FieldDetail {
* `inferFieldInfo` function.
*/
export class FieldScanner {
#form = null;
#elementsWeakRef = null;
#inferFieldInfoFn = null;

Expand All @@ -107,12 +163,16 @@ export class FieldScanner {
* Create a FieldScanner based on form elements with the existing
* fieldDetails.
*
* @param {Array.DOMElement} elements
* The elements from a form for each parser.
* @param {FormLike} form
* @param {Funcion} inferFieldInfoFn
* The callback function that is used to infer the field info of a given element
*/
constructor(elements, inferFieldInfoFn) {
constructor(form, inferFieldInfoFn) {
const elements = Array.from(form.elements).filter(element =>
lazy.FormAutofillUtils.isCreditCardOrAddressFieldType(element)
);

this.#form = form;
this.#elementsWeakRef = new WeakRef(elements);
this.#inferFieldInfoFn = inferFieldInfoFn;
}
Expand Down Expand Up @@ -189,9 +249,11 @@ export class FieldScanner {
throw new Error("Try to push the non-existing element info.");
}
const element = this.#elements[elementIndex];
const [fieldName, autocompleteInfo, confidence] =
this.#inferFieldInfoFn(element);
const fieldDetail = new FieldDetail(element, fieldName, {
const [fieldName, autocompleteInfo, confidence] = this.#inferFieldInfoFn(
element,
this.#elements
);
const fieldDetail = new FieldDetail(element, this.#form, fieldName, {
autocompleteInfo,
confidence,
});
Expand Down
8 changes: 8 additions & 0 deletions firefox-ios/Client/Assets/CC_Script/FormAutofill.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,15 @@ const ENABLED_AUTOFILL_CAPTURE_ON_FORM_REMOVAL_PREF =
"extensions.formautofill.heuristics.captureOnFormRemoval";
const ENABLED_AUTOFILL_CAPTURE_ON_PAGE_NAVIGATION_PREF =
"extensions.formautofill.heuristics.captureOnPageNavigation";
const ENABLED_AUTOFILL_SAME_ORIGIN_WITH_TOP =
"extensions.formautofill.heuristics.autofillSameOriginWithTop";

export const FormAutofill = {
ENABLED_AUTOFILL_ADDRESSES_PREF,
ENABLED_AUTOFILL_ADDRESSES_CAPTURE_PREF,
ENABLED_AUTOFILL_CAPTURE_ON_FORM_REMOVAL_PREF,
ENABLED_AUTOFILL_CAPTURE_ON_PAGE_NAVIGATION_PREF,
ENABLED_AUTOFILL_SAME_ORIGIN_WITH_TOP,
ENABLED_AUTOFILL_CREDITCARDS_PREF,
AUTOFILL_CREDITCARDS_REAUTH_PREF,
AUTOFILL_CREDITCARDS_AUTOCOMPLETE_OFF_PREF,
Expand Down Expand Up @@ -284,6 +287,11 @@ XPCOMUtils.defineLazyPreferenceGetter(
null,
val => val?.split(",").filter(v => !!v)
);
XPCOMUtils.defineLazyPreferenceGetter(
FormAutofill,
"autofillSameOriginWithTop",
ENABLED_AUTOFILL_SAME_ORIGIN_WITH_TOP
);

XPCOMUtils.defineLazyPreferenceGetter(
FormAutofill,
Expand Down
Loading

0 comments on commit 2e6b1fa

Please sign in to comment.