chromium/components/autofill/core/browser/proto/server.proto

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Data models to interface with legacy Autofill API.

syntax = "proto2";

option optimize_for = LITE_RUNTIME;

package autofill;

// This message contains a randomized encoding of a string, where each bit
// in the encoded string is randomly sent as either the true value seen by
// the client, or random noise. The mapping of specific bits in the encoded
// string back to bits in the original string is specified by the EncodingType.
message AutofillRandomizedValue {
  enum EncodingType {
    // Reserved default value. Should never be sent over the wire.
    UNSPECIFIED_ENCODING_TYPE = -1;

    // This string encodes only one bit, bit N, for each byte.
    BIT_0 = 0;
    BIT_1 = 1;
    BIT_2 = 2;
    BIT_3 = 3;
    BIT_4 = 4;
    BIT_5 = 5;
    BIT_6 = 6;
    BIT_7 = 7;

    // For each byte, the encoded value contains even or odd bits only.
    EVEN_BITS = 8;
    ODD_BITS = 9;

    // The encoded value contains all of the bits.
    ALL_BITS = 10;
  }

  // Selector denoting the source bits to which the encoded bits correspond.
  optional EncodingType encoding_type = 1 [default = UNSPECIFIED_ENCODING_TYPE];

  // The encoded bits. Only the bits denoted by |encoding_type| are included in
  // |encoded_bits|.
  //
  // BIT_K encodings:
  //    each randomized bit i in |encoded_bits| corresponds to bit k of the byte
  //    at the corresponding offset i of the original metadata value, up to
  //    i=64 (8 bytes).
  //
  // EVEN_BITS encoding:
  //     each randomized bit i in |encoded_bits| corresponds to bit 2*i of the
  //     original metadata value, up to i=256 (32 bytes).
  //
  // ODD_BITS encoding:
  //     each randomized bit i in |encoded_bits| corresponds to bit 2*i+1 of the
  //     original metadata value, up to i=256 (32 bytes).
  //
  // ALL_BITS encoding:
  //     each bit i in |encoded_bits| corresponds to bit i of the original
  //     metadata value, up to i=512 (64 bytes).
  //
  // The encoded data is generally not user data, however, it is possible that
  // user visible metadata (like the Label for an input field) could be
  // personalized and thus contains user data (possibly PII). For the ALL_BITS
  // encoding, each randomized byte has a 10% probability of being encoded 1:1
  // as the true byte seen by the client, even if some of those bits were
  // transmitted as noise. For all of the other encodings, the encoded bits
  // does not encode any full bytes.
  optional bytes encoded_bits = 2;

  // 32-bit checksum before randomization (passed in clear text). Note that
  // this value may not be present; for now, it is only stored for metadata
  // values of type FORM_URL.
  optional fixed32 checksum = 3;
}

// Describes how the button is implemented in HTML source. Corresponds to
// the mojo ButtonTitleType enum defined in
// components/autofill/core/common/mojom/autofill_types.mojom.h
enum ButtonTitleType {
  NONE = 0;
  BUTTON_ELEMENT_SUBMIT_TYPE = 1;  // <button type='submit'>
  BUTTON_ELEMENT_BUTTON_TYPE = 2;  // <button type='button'>
  INPUT_ELEMENT_SUBMIT_TYPE = 3;   // <input type='submit'>
  INPUT_ELEMENT_BUTTON_TYPE = 4;   // <input type='button'>
  HYPERLINK = 5;                   // e.g. <a class='button'>
  DIV = 6;                         // e.g. <div id='submit'>
  SPAN = 7;                        // e.g. <span name='btn'>
}

// The collection of autofill field metadata to be sent using randomization.
message AutofillRandomizedFormMetadata {
  // Form element id. Example: <form id="XXXXXXXX">
  optional AutofillRandomizedValue id = 1;

  // Form element name. Example: <form name="XXXXXXXX">
  optional AutofillRandomizedValue name = 2;

  // Form element action. Example: <form action="XXXXXXXX">
  optional AutofillRandomizedValue action = 3;

  // Location of form as URL.
  optional AutofillRandomizedValue url = 4;

  // Information about a button's title (sync with another ButtonTitle in this
  // proto).
  message ButtonTitle {
    // Text showed on the button.
    optional AutofillRandomizedValue title = 1;

    // Describes how the button is implemented in HTML source.
    optional ButtonTitleType type = 2;
  }
  // Titles of form's buttons. Example: <input type="submit" value="XXXXX">
  repeated ButtonTitle button_title = 5;

  reserved 6;
}

// The collection of autofill field metadata to be sent using randomization.
message AutofillRandomizedFieldMetadata {
  // Input element id. Example: <input id="XXXXXXXX">
  optional AutofillRandomizedValue id = 1;

  // Input element name. Example:  <input name="XXXXXXXX">
  optional AutofillRandomizedValue name = 2;

  // Input element type. Example: <input type="XXXXXXXX">
  optional AutofillRandomizedValue type = 3;

  // Input field label value seen by the user, either explicitly annotated in
  // the DOM or inferred by the client.
  //
  // The value encountered by the client may be personalized (for example:
  // "Please enter the password for [email protected]"). The system will learn the
  // common/static prefix and determine that the personalized substring is
  // noise. That said, for a given upload using the ALL_BITS encoding, each
  // byte has a 10% probability or matching the original plaintext byte and
  // a 1 in 10^m chance of the full m-character string being uploaded as
  // plaintext. The other encodings only send partial bytes.
  //
  // Example:  <label for="id">XXXXXXX</label>
  optional AutofillRandomizedValue label = 4;

  // Input field label value exposed to the user via ARIA.
  // Example 1: <input aria-label="XXXXXX>
  // Example 2: <div id="foo">XXXXXXX</div>
  //            <input aria-labelledby="foo">
  optional AutofillRandomizedValue aria_label = 5;

  // Input field description exposed to the user via ARIA.
  // Example:
  //     <div id="foo">XXXXXXX</div>
  //     <input aria-describedby="foo">
  optional AutofillRandomizedValue aria_description = 6;

  // CSS class for the input element.
  // Example: <input class="XXXXXXXX">
  optional AutofillRandomizedValue css_class = 7;

  // Placeholder text for the input element.
  // Example: <input placeholder="XXXXXXXX">
  optional AutofillRandomizedValue placeholder = 8;

  // Hash of the initial value of the field. We want to learn if the initial
  // value of this field is personalized to the user (we will learn that the
  // value is noise) or if it is a placeholder in disguise (we will learn a
  // constant hash).
  //
  // Example: <input value="VVVVVVV">
  //          XXXXXXXX = hash("VVVVVVV"")
  optional AutofillRandomizedValue initial_value_hash = 9;

  // Value of the autocomplete attribute. Example: <input autocomplete="XXX">
  optional AutofillRandomizedValue autocomplete = 10;
}

// This message contains information about the field types in a single form.
// It is sent by the toolbar to contribute to the field type statistics.
// Next available id: 49
message AutofillUploadContents {
  required string client_version = 1;
  required fixed64 form_signature = 2;

  // The secondary form signature is calculated based on field types instead of
  // names and is used if the primary one is unstable, i.e. the field names
  // change on every page load. Not used currently.
  optional fixed64 secondary_form_signature = 34;

  // True if the autofill feature was used to fill this form, false otherwise.
  required bool autofill_used = 3;

  // A string representing a bit array of what personal information items
  // the user has entered in the autofill settings dialog.
  // The corresponding bit is set if the user has that particular
  // item entered and is not set otherwise.
  required string data_present = 4;

  // List of the fields in the form and their types.
  message Field {
    // Field identification inside the current form.
    required fixed32 signature = 6;

    // Type of the field, e.g. what type of personal information did the user
    // enter in that field before form submission. There is a predefined
    // enum of types located at
    // components/autofill/core/browser/field_types.h
    // AutoFillFieldType
    repeated fixed32 autofill_type = 7;

    // The value of the name attribute on the field, if present. Otherwise, the
    // value of the id attribute. See HTMLFormControlElement::nameForAutofill.
    // TODO(850606): Deprecate once randomized metadata is launched.
    optional string name = 8;

    // The value of the autocomplete attribute on the field, if present.
    // TODO(850606): Deprecate once randomized metadata is launched.
    optional string autocomplete = 9;

    // The type of input control for this field (e.g. text, textarea, email).
    // TODO(850606): Deprecate once randomized metadata is launched.
    optional string type = 10;

    // The field-level metadata associated with this field, randomized.
    optional AutofillRandomizedFieldMetadata randomized_field_metadata = 33;

    enum PasswordGenerationType {
      NO_GENERATION = 0;
      AUTOMATICALLY_TRIGGERED_GENERATION_ON_SIGN_UP_FORM = 1;
      AUTOMATICALLY_TRIGGERED_GENERATION_ON_CHANGE_PASSWORD_FORM = 2;
      MANUALLY_TRIGGERED_GENERATION_ON_SIGN_UP_FORM = 3;
      MANUALLY_TRIGGERED_GENERATION_ON_CHANGE_PASSWORD_FORM = 4;
      IGNORED_GENERATION_POPUP = 5;
    }
    // The type of password generation, if it happened.
    optional PasswordGenerationType generation_type = 17;

    // The value of the class attribute on the field, if present.
    // TODO(850606): Deprecate once randomized metadata is launched.
    optional string css_classes = 19;

    // The properties mask (i.e. whether the field was autofilled, user
    // modified, etc.) See FieldPropertiesFlags.
    optional uint32 properties_mask = 20;

    // The value of the id attribute, if it differs from the name attribute.
    // Otherwise, this field is absent.
    // TODO(850606): Deprecate once randomized metadata is launched.
    optional string id = 21;

    // True iff the user changed generated password. If there was no generation,
    // the field is absent.
    optional bool generated_password_changed = 22;

    enum VoteType {
      NO_INFORMATION = 0;
      // A credential saved on one form (typically a signup form) was used on a
      // login form. The vote applies to the first (signup) form.
      CREDENTIALS_REUSED = 1;
      // When reusing a credential, the username value is not the saved
      // username, but another value, which appeared on the form where we saved.
      // The correct field is voted for.
      USERNAME_OVERWRITTEN = 2;
      // In the save prompt, the user corrected the username value to another
      // value from the form. The new field is voted for.
      USERNAME_EDITED = 3;
      // The username field was detected by the base heuristic (take the last
      // non-password field before the first password field). The value is not
      // used at this point.
      BASE_HEURISTIC = 4;
      // The username field was detected by HTML-based detector. The value is
      // not used at this point.
      HTML_CLASSIFIER = 5;
      // A saved credential was used for the first time on a submitted form. The
      // vote applies to the form being submitted.
      FIRST_USE = 6;
    }

    // The type of password-related vote. If |autofill_type| is not a USERNAME
    // or any PASSWORD vote, then the field is absent. This field describes the
    // context of the vote.
    optional VoteType vote_type = 23;

    // Deleted field.
    reserved 35;
    reserved "autofill_type_validities";

    // A low-entropy hash of the field's initial value before user-interactions
    // or automatic fillings. This field is used to detect static
    // placeholders.
    optional uint32 initial_value_hash = 40;

    // The type of the username first flow signal.
    enum SingleUsernameVoteType {
      DEFAULT = 0;
      // Votes with low confidence (i.e. recorded if Save/Update prompt was
      // accepted without username edits) for UFF classifier.
      WEAK = 1;
      // Votes with high confidence (i.e. recorded if Save/Update prompt was
      // accepted after username edits) for UFF classifier.
      STRONG = 2;
      // Votes with low confidence (i.e. recorded if Save/Update prompt was
      // accepted without username edits) for forgot password form classifier.
      WEAK_FORGOT_PASSWORD = 3;
      // Votes with high confidence (i.e. recorded if Save/Update prompt was
      // accepted after username edits) for forgot password form classifier.
      STRONG_FORGOT_PASSWORD = 4;
      // If positive (`autofill_type` is `SINGLE_USERNAME`), votes signal that
      // user was prompted with a Save/Update bubble with a username value found
      // inside the password form and edited it to one of the values that was
      // found outside of the password form. If negative (`autofill_type` is
      // `NOT_USERNAME`), user was prompted with a username value outside the
      // password form and edited it to one of the values that is found inside
      // the password form.
      IN_FORM_OVERRULE = 5;
    }

    // The type of the username first flow vote signal, set iff |autofill_type|
    // is SINGLE_USERNAME, SINGLE_USERNAME_FORGOT_PASSWORD or NOT_USERNAME.
    optional SingleUsernameVoteType single_username_vote_type = 41;

    // Only set for Username First Flow votes (`autofill_type` is
    // `SINGLE_USERNAME` or `NOT_USERNAME`). Otherwise, set to `std::nullopt`.
    // If set to true, the field is username candidate in Username First Flow
    // and the field has no intermediate fields (like OTP/Captcha) between the
    // candidate and the password form.
    // If set to false, the field is username candidate in Username First Flow,
    // but has intermediate fields between the candidate and the password
    // form.
    optional bool is_most_recent_single_username_candidate = 46;

    // Set to `true` if the field had a value on page load and it was changed
    // between then and form submission. Set to `false` if the pre-filled value
    // wasn't changed. Not set if the field didn't have a pre-filled value.
    optional bool initial_value_changed = 47;
  }
  repeated Field field_data = 48;
  // Signature of the form action host (e.g. Hash64Bit("example.com")).
  optional fixed64 action_signature = 13;

  // Signature of the form. This is currently used when password generated on a
  // password field of a registration form is used on a password field of a
  // login form.
  optional fixed64 login_form_signature = 14;

  // Whether a form submission event was observed.
  optional bool submission = 15;

  // The form name.
  optional string form_name = 16;

  // True if the non-obfuscated password values were shown to the user.
  optional bool passwords_revealed = 24;

  // The section of noisified data about password.
  // Upload only one of character class attributes (|password_has_*|). Noisified
  // length is always uploaded.
  // Upload only when a password is saved.
  // Used to adjust the password generator's settings to site's requirements.

  // Whether the password has any letter.
  optional bool password_has_letter = 25;

  // Deprecated since M80: Whether the password has any uppercase letter.
  optional bool password_has_uppercase_letter = 26 [deprecated = true];

  // Deprecated since M80: Whether the password has any digit.
  optional bool password_has_numeric = 27 [deprecated = true];

  // Whether the password has any special symbol.
  optional bool password_has_special_symbol = 28;

  // Noisified password length.
  optional uint32 password_length = 29;

  // If |password_has_special_symbol| is true, this field contains noisified
  // information about a special symbol used in a user-created password stored
  // in ASCII code.
  // Otherwise, this field is unset.
  optional uint32 password_special_symbol = 39;

  // The end of the section of password attributes.

  // Event observed by the password manager which indicated that the form was
  // successfully submitted. Corresponds to |mojom::SubmissionIndicatorEvent|.
  enum SubmissionIndicatorEvent {
    NONE = 0;
    HTML_FORM_SUBMISSION = 1;
    SAME_DOCUMENT_NAVIGATION = 2;
    XHR_SUCCEEDED = 3;
    FRAME_DETACHED = 4;
    DEPRECATED_MANUAL_SAVE = 5;  // obsolete
    DEPRECATED_DOM_MUTATION_AFTER_XHR = 6;  // obsolete
    DEPRECATED_PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD =
        7;                                                           // unused
    DEPRECATED_FILLED_FORM_ON_START_PROVISIONAL_LOAD = 8;            // unused
    DEPRECATED_FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD = 9;  // unused
    PROBABLE_FORM_SUBMISSION = 10;
    CHANGE_PASSWORD_FORM_CLEARED = 11;
    DOM_MUTATION_AFTER_AUTOFILL = 12;
  }

  // The type of the event that was taken as an indication that the form has
  // been successfully submitted.
  optional SubmissionIndicatorEvent submission_event = 30;

  // The language of the page on which this form appears.
  optional string language = 31;

  // Form-level metadata observed by the client, randomized.
  optional AutofillRandomizedFormMetadata randomized_form_metadata = 32;

  // Information about a button's title (sync with another ButtonTitle in this
  // proto).
  message ButtonTitle {
    // Text showed on the button.
    optional string title = 1;

    // Describes how the button is implemented in HTML source.
    optional ButtonTitleType type = 2;
  }
  // Titles of form's buttons.
  // TODO(850606): Deprecate once randomized metadata is launched.
  repeated ButtonTitle button_title = 36;

  // Whether the fields are enclosed by a <form> tag or are unowned elements.
  optional bool has_form_tag = 37;

  // Captures whether or not this upload was a candidate for throttling.
  optional bool was_throttleable = 38 [deprecated = true];

  // Type of the value seen in the potential single username field.
  enum ValueType {
    TYPE_UNSPECIFIED = 0;
    NO_VALUE_TYPE = 1;
    STORED_FOR_CURRENT_DOMAIN = 2;
    // TODO(crbug.com/40626063) Not used yet. Check against all domains to be
    // implemented.
    STORED_FOR_ANOTHER_DOMAIN = 3;
    EMAIL = 4;
    PHONE = 5;
    USERNAME_LIKE = 6;
    VALUE_WITH_NO_WHITESPACE = 7;
    VALUE_WITH_WHITESPACE = 8;
  }
  // Information received from user interaction with the prompt.
  enum SingleUsernamePromptEdit {
    EDIT_UNSPECIFIED = 0;
    NOT_EDITED_POSITIVE = 1;
    NOT_EDITED_NEGATIVE = 2;
    EDITED_POSITIVE = 3;
    EDITED_NEGATIVE = 4;
  }
  message SingleUsernameData {
    optional fixed64 username_form_signature = 1;
    optional fixed32 username_field_signature = 2;
    optional ValueType value_type = 3;
    optional SingleUsernamePromptEdit prompt_edit = 4;
  }
  // This message is recorded on forms that do not have a username field.
  // The message contains data on preceding forms with potential username
  // fields.
  repeated SingleUsernameData single_username_data = 42;

  // The form signature of related forms, which were submitted on the same
  // origin shortly prior. If set, `last_address_form_submitted` or
  // `last_credit_card_form_submitted` is equal to `form_signature`.
  optional fixed64 last_address_form_submitted = 43;
  optional fixed64 second_last_address_form_submitted = 44;
  optional fixed64 last_credit_card_form_submitted = 45;

  reserved 5;
  reserved "Field";
}

// This proto contains information about the validity of each field in an
// autofill profile. It is used to transfer the results of running the profile
// validation pipeline on the server side to the client via ChromeSync
// PriorityPreferences. An identical copy of this proto is maintained in
// the server code base.
message ProfileValidityMap {
  // Map from autofill type to the validity of its value in the profile.
  //
  // Key should be one of the enum values from FieldType. Values should be
  // from the AutofillProfile::ValidityState. Plain integers are used
  // instead of enums because proto2 treats unknown enum values as unknown
  // fields, which is confusing when the enums are in maps.
  map<int32, int32> field_validity_states = 1;
}

// Map from profile GUIDs to profile validity maps for that profile. Each
// message should contain entries for all profiles from a single user.
message UserProfileValidityMap {
  map<string, ProfileValidityMap> profile_validity = 1;
}