diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /toolkit/components/formautofill/android/FormAutofillStorage.jsm | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/formautofill/android/FormAutofillStorage.jsm')
-rw-r--r-- | toolkit/components/formautofill/android/FormAutofillStorage.jsm | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/toolkit/components/formautofill/android/FormAutofillStorage.jsm b/toolkit/components/formautofill/android/FormAutofillStorage.jsm new file mode 100644 index 0000000000..794b8ecdbd --- /dev/null +++ b/toolkit/components/formautofill/android/FormAutofillStorage.jsm @@ -0,0 +1,277 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Implements an interface of the storage of Form Autofill for GeckoView. + */ + +"use strict"; + +// We expose a singleton from this module. Some tests may import the +// constructor via a backstage pass. +const EXPORTED_SYMBOLS = ["formAutofillStorage", "FormAutofillStorage"]; + +const { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); + +const { + FormAutofillStorageBase, + CreditCardsBase, + AddressesBase, +} = ChromeUtils.import("resource://autofill/FormAutofillStorageBase.jsm"); +const { JSONFile } = ChromeUtils.importESModule( + "resource://gre/modules/JSONFile.sys.mjs" +); + +const lazy = {}; + +XPCOMUtils.defineLazyModuleGetters(lazy, { + Address: "resource://gre/modules/GeckoViewAutocomplete.jsm", + CreditCard: "resource://gre/modules/GeckoViewAutocomplete.jsm", + GeckoViewAutocomplete: "resource://gre/modules/GeckoViewAutocomplete.jsm", +}); + +class GeckoViewStorage extends JSONFile { + constructor() { + super({ path: null, sanitizedBasename: "GeckoViewStorage" }); + } + + async updateCreditCards() { + const creditCards = await lazy.GeckoViewAutocomplete.fetchCreditCards().then( + results => results?.map(r => lazy.CreditCard.parse(r).toGecko()) ?? [], + _ => [] + ); + super.data.creditCards = creditCards; + } + + async updateAddresses() { + const addresses = await lazy.GeckoViewAutocomplete.fetchAddresses().then( + results => results?.map(r => lazy.Address.parse(r).toGecko()) ?? [], + _ => [] + ); + super.data.addresses = addresses; + } + + async load() { + super.data = { creditCards: {}, addresses: {} }; + await this.updateCreditCards(); + await this.updateAddresses(); + } + + ensureDataReady() { + if (this.dataReady) { + return; + } + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } + + async _save() { + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } +} + +class Addresses extends AddressesBase { + // Override AutofillRecords methods. + + _initialize() { + this._initializePromise = Promise.resolve(); + } + + async _saveRecord(record, { sourceSync = false } = {}) { + lazy.GeckoViewAutocomplete.onAddressSave(lazy.Address.fromGecko(record)); + } + + /** + * Returns the record with the specified GUID. + * + * @param {string} guid + * Indicates which record to retrieve. + * @param {object} options + * @param {boolean} [options.rawData = false] + * Returns a raw record without modifications and the computed fields + * (this includes private fields) + * @returns {Promise<object>} + * A clone of the record. + */ + async get(guid, { rawData = false } = {}) { + await this._store.updateAddresses(); + return super.get(guid, { rawData }); + } + + /** + * Returns all records. + * + * @param {object} options + * @param {boolean} [options.rawData = false] + * Returns raw records without modifications and the computed fields. + * @param {boolean} [options.includeDeleted = false] + * Also return any tombstone records. + * @returns {Promise<Array.<object>>} + * An array containing clones of all records. + */ + async getAll({ rawData = false, includeDeleted = false } = {}) { + await this._store.updateAddresses(); + return super.getAll({ rawData, includeDeleted }); + } + + /** + * Return all saved field names in the collection. + * + * @returns {Set} Set containing saved field names. + */ + async getSavedFieldNames() { + await this._store.updateAddresses(); + return super.getSavedFieldNames(); + } + + async reconcile(remoteRecord) { + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } + + async findDuplicateGUID(remoteRecord) { + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } + + async mergeToStorage(targetRecord, strict = false) { + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } +} + +class CreditCards extends CreditCardsBase { + async _encryptNumber(creditCard) { + // Don't encrypt or obfuscate for GV, since we don't store or show + // the number. The API has to always provide the original number. + } + + // Override AutofillRecords methods. + + _initialize() { + this._initializePromise = Promise.resolve(); + } + + async _saveRecord(record, { sourceSync = false } = {}) { + lazy.GeckoViewAutocomplete.onCreditCardSave( + lazy.CreditCard.fromGecko(record) + ); + } + + /** + * Returns the record with the specified GUID. + * + * @param {string} guid + * Indicates which record to retrieve. + * @param {object} options + * @param {boolean} [options.rawData = false] + * Returns a raw record without modifications and the computed fields + * (this includes private fields) + * @returns {Promise<object>} + * A clone of the record. + */ + async get(guid, { rawData = false } = {}) { + await this._store.updateCreditCards(); + return super.get(guid, { rawData }); + } + + /** + * Returns all records. + * + * @param {object} options + * @param {boolean} [options.rawData = false] + * Returns raw records without modifications and the computed fields. + * @param {boolean} [options.includeDeleted = false] + * Also return any tombstone records. + * @returns {Promise<Array.<object>>} + * An array containing clones of all records. + */ + async getAll({ rawData = false, includeDeleted = false } = {}) { + await this._store.updateCreditCards(); + return super.getAll({ rawData, includeDeleted }); + } + + /** + * Return all saved field names in the collection. + * + * @returns {Set} Set containing saved field names. + */ + async getSavedFieldNames() { + await this._store.updateCreditCards(); + return super.getSavedFieldNames(); + } + + /** + * Normalize the given record and return the first matched guid if storage has the same record. + * + * @param {object} targetCreditCard + * The credit card for duplication checking. + * @returns {Promise<string|null>} + * Return the first guid if storage has the same credit card and null otherwise. + */ + async getDuplicateGuid(targetCreditCard) { + let clonedTargetCreditCard = this._clone(targetCreditCard); + this._normalizeRecord(clonedTargetCreditCard); + if (!clonedTargetCreditCard["cc-number"]) { + return null; + } + + await this._store.updateCreditCards(); + for (let creditCard of this._data) { + if (creditCard.deleted) { + continue; + } + + if (creditCard["cc-number"] == clonedTargetCreditCard["cc-number"]) { + return creditCard.guid; + } + } + return null; + } + + async reconcile(remoteRecord) { + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } + + async findDuplicateGUID(remoteRecord) { + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } + + async mergeToStorage(targetRecord, strict = false) { + throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); + } +} + +class FormAutofillStorage extends FormAutofillStorageBase { + constructor() { + super(null); + } + + getAddresses() { + if (!this._addresses) { + this._store.ensureDataReady(); + this._addresses = new Addresses(this._store); + } + return this._addresses; + } + + getCreditCards() { + if (!this._creditCards) { + this._store.ensureDataReady(); + this._creditCards = new CreditCards(this._store); + } + return this._creditCards; + } + + /** + * Initializes the in-memory async store API. + * + * @returns {JSONFile} + * The JSONFile store. + */ + _initializeStore() { + return new GeckoViewStorage(); + } +} + +// The singleton exposed by this module. +const formAutofillStorage = new FormAutofillStorage(); |