diff --git a/node_modules/@duckduckgo/autofill/README.md b/node_modules/@duckduckgo/autofill/README.md index 57bbd69e0c60..a409af6ff592 100644 --- a/node_modules/@duckduckgo/autofill/README.md +++ b/node_modules/@duckduckgo/autofill/README.md @@ -1,6 +1,6 @@ # DuckDuckGo Autofill -This code is installed using `npm` in our [extension](https://github.com/duckduckgo/duckduckgo-privacy-extension) and as a git submodule by native apps ([iOS](https://github.com/duckduckgo/iOS) and [Android](https://github.com/duckduckgo/Android)). +This code is installed using `npm` in our [extension](https://github.com/duckduckgo/duckduckgo-privacy-extension) and as a git submodule by native apps ([iOS/macOS](https://github.com/duckduckgo/apple-browsers) and [Android](https://github.com/duckduckgo/Android)). DuckDuckGo Autofill is distributed under the Apache 2.0 [License](LICENSE.md). @@ -21,7 +21,7 @@ Now you can run `npm start` in this repo and the changes will be picked up autom ### Apple apps (iOS and macOS) -On Apple clients, autofill is included as part of the [BrowserServicesKit](https://github.com/duckduckgo/BrowserServicesKit) (BSK) package. If your changes involve native code, you probably want to work within BSK, otherwise you can work directly within the client codebases. +On Apple clients, autofill is included as part of the [BrowserServicesKit](https://github.com/duckduckgo/apple-browsers) (BSK) package. If your changes involve native code, you probably want to work within BSK, otherwise you can work directly within the client codebases. The easiest way to override the client version of autofill is to drag-and-drop your local autofill folder from the Finder right into Xcode project navigator, at the root level. If you're working in BSK, you can drag-and-drop autofill in the BSK project and then drag-and-drop BSK itself in the platform project. diff --git a/node_modules/@duckduckgo/autofill/dist/autofill-debug.js b/node_modules/@duckduckgo/autofill/dist/autofill-debug.js index 4f7eab7d2c1b..e9defe38bc68 100644 --- a/node_modules/@duckduckgo/autofill/dist/autofill-debug.js +++ b/node_modules/@duckduckgo/autofill/dist/autofill-debug.js @@ -12188,16 +12188,16 @@ const formatPhoneNumber = phone => phone.replaceAll(/[^0-9|+]/g, ''); /** * Infer credentials from password and identities * @param {InternalDataStorageObject['credentials']} credentials - * @param {InternalDataStorageObject['identities']} identities - * @param {string|undefined} cardNumber - * @return {InternalDataStorageObject['credentials'] | undefined} + * @param {InternalIdentityObject} identities + * @param {InternalCreditCardObject|undefined} creditCards + * @return InternalCredentialsObject|undefined */ exports.formatPhoneNumber = formatPhoneNumber; -const inferCredentialsForPartialSave = (credentials, identities, cardNumber) => { +const inferCredentialsForPartialSave = (credentials, identities, creditCards) => { // Try to infer username from identity or card number - if (!credentials.username && ((0, _autofillUtils.hasUsernameLikeIdentity)(identities) || cardNumber)) { + if (!credentials.username) { // @ts-ignore - We know that username is not a useful value here - credentials.username = identities.emailAddress || identities.phone || cardNumber; + credentials.username = (0, _autofillUtils.getUsernameLikeIdentity)(identities, creditCards); } // Discard empty credentials if (Object.keys(credentials ?? {}).length === 0) { @@ -12209,18 +12209,18 @@ const inferCredentialsForPartialSave = (credentials, identities, cardNumber) => /** * Infer credentials from password and identities * @param {InternalDataStorageObject['credentials']} credentials - * @param {InternalDataStorageObject['identities']} identities - * @param {string|undefined} cardNumber - * @return {InternalDataStorageObject['credentials'] | undefined} + * @param {InternalIdentityObject} identities + * @param {InternalCreditCardObject|undefined} creditCards + * @return InternalCredentialsObject|undefined */ -const inferCredentials = (credentials, identities, cardNumber) => { +const inferCredentials = (credentials, identities, creditCards) => { if (!credentials.password) { return undefined; } // Try to use email as username if password exists but username is missing - if (credentials.password && !credentials.username && ((0, _autofillUtils.hasUsernameLikeIdentity)(identities) || cardNumber)) { + if (credentials.password && !credentials.username) { // @ts-ignore - We know that username is not a useful value here - credentials.username = identities.emailAddress || identities.phone || cardNumber; + credentials.username = (0, _autofillUtils.getUsernameLikeIdentity)(identities, creditCards); } return credentials; }; @@ -12229,6 +12229,7 @@ const inferCredentials = (credentials, identities, cardNumber) => { * Formats form data into an object to send to the device for storage * If values are insufficient for a complete entry, they are discarded * @param {InternalDataStorageObject} formValues + * @param {boolean} canTriggerPartialSave * @return {DataStorageObject} */ const prepareFormValuesForStorage = function (formValues) { @@ -12257,7 +12258,7 @@ const prepareFormValuesForStorage = function (formValues) { * but not reproducible with the current tests. Once the feature is stable, we should * revisit and remove the older logic. */ - credentials = canTriggerPartialSave ? inferCredentialsForPartialSave(credentials, identities, creditCards.cardNumber) : inferCredentials(credentials, identities, creditCards.cardNumber); + credentials = canTriggerPartialSave ? inferCredentialsForPartialSave(credentials, identities, creditCards) : inferCredentials(credentials, identities, creditCards); /** Fixes for identities **/ // Don't store if there isn't enough data @@ -17255,7 +17256,7 @@ exports.getActiveElement = getActiveElement; exports.getDaxBoundingBox = void 0; exports.getFormControlElements = getFormControlElements; exports.getTextShallow = void 0; -exports.hasUsernameLikeIdentity = hasUsernameLikeIdentity; +exports.getUsernameLikeIdentity = getUsernameLikeIdentity; exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = void 0; exports.isFormLikelyToBeUsedAsPageWrapper = isFormLikelyToBeUsedAsPageWrapper; exports.isLikelyASubmitButton = exports.isIncontextSignupEnabledFromProcessedConfig = void 0; @@ -17932,12 +17933,22 @@ function queryElementsWithShadow(element, selector) { } /** - * Checks if there is a single username-like identity, i.e. email or phone + * Checks if there is a single username-like identity, i.e. email or phone or credit card number + * If there is then returns that, otherwise returns undefined * @param {InternalIdentityObject} identities - * @returns {boolean} + * @param {InternalCreditCardObject} creditCards + * @returns {string | undefined} */ -function hasUsernameLikeIdentity(identities) { - return Object.keys(identities ?? {}).length === 1 && Boolean(identities?.emailAddress || identities.phone); +function getUsernameLikeIdentity(identities, creditCards) { + if (identities?.emailAddress) { + return identities.emailAddress; + } + if (Object.keys(identities ?? {}).length === 1 && Boolean(identities.phone)) { + return identities.phone; + } + if (Object.keys(creditCards ?? {}).length === 1 && Boolean(creditCards.cardNumber)) { + return creditCards.cardNumber; + } } },{"./Form/matching.js":44,"./constants.js":67,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],65:[function(require,module,exports){ diff --git a/node_modules/@duckduckgo/autofill/dist/autofill.js b/node_modules/@duckduckgo/autofill/dist/autofill.js index 2bfd7590c736..9ae608ef1728 100644 --- a/node_modules/@duckduckgo/autofill/dist/autofill.js +++ b/node_modules/@duckduckgo/autofill/dist/autofill.js @@ -7825,16 +7825,16 @@ const formatPhoneNumber = phone => phone.replaceAll(/[^0-9|+]/g, ''); /** * Infer credentials from password and identities * @param {InternalDataStorageObject['credentials']} credentials - * @param {InternalDataStorageObject['identities']} identities - * @param {string|undefined} cardNumber - * @return {InternalDataStorageObject['credentials'] | undefined} + * @param {InternalIdentityObject} identities + * @param {InternalCreditCardObject|undefined} creditCards + * @return InternalCredentialsObject|undefined */ exports.formatPhoneNumber = formatPhoneNumber; -const inferCredentialsForPartialSave = (credentials, identities, cardNumber) => { +const inferCredentialsForPartialSave = (credentials, identities, creditCards) => { // Try to infer username from identity or card number - if (!credentials.username && ((0, _autofillUtils.hasUsernameLikeIdentity)(identities) || cardNumber)) { + if (!credentials.username) { // @ts-ignore - We know that username is not a useful value here - credentials.username = identities.emailAddress || identities.phone || cardNumber; + credentials.username = (0, _autofillUtils.getUsernameLikeIdentity)(identities, creditCards); } // Discard empty credentials if (Object.keys(credentials ?? {}).length === 0) { @@ -7846,18 +7846,18 @@ const inferCredentialsForPartialSave = (credentials, identities, cardNumber) => /** * Infer credentials from password and identities * @param {InternalDataStorageObject['credentials']} credentials - * @param {InternalDataStorageObject['identities']} identities - * @param {string|undefined} cardNumber - * @return {InternalDataStorageObject['credentials'] | undefined} + * @param {InternalIdentityObject} identities + * @param {InternalCreditCardObject|undefined} creditCards + * @return InternalCredentialsObject|undefined */ -const inferCredentials = (credentials, identities, cardNumber) => { +const inferCredentials = (credentials, identities, creditCards) => { if (!credentials.password) { return undefined; } // Try to use email as username if password exists but username is missing - if (credentials.password && !credentials.username && ((0, _autofillUtils.hasUsernameLikeIdentity)(identities) || cardNumber)) { + if (credentials.password && !credentials.username) { // @ts-ignore - We know that username is not a useful value here - credentials.username = identities.emailAddress || identities.phone || cardNumber; + credentials.username = (0, _autofillUtils.getUsernameLikeIdentity)(identities, creditCards); } return credentials; }; @@ -7866,6 +7866,7 @@ const inferCredentials = (credentials, identities, cardNumber) => { * Formats form data into an object to send to the device for storage * If values are insufficient for a complete entry, they are discarded * @param {InternalDataStorageObject} formValues + * @param {boolean} canTriggerPartialSave * @return {DataStorageObject} */ const prepareFormValuesForStorage = function (formValues) { @@ -7894,7 +7895,7 @@ const prepareFormValuesForStorage = function (formValues) { * but not reproducible with the current tests. Once the feature is stable, we should * revisit and remove the older logic. */ - credentials = canTriggerPartialSave ? inferCredentialsForPartialSave(credentials, identities, creditCards.cardNumber) : inferCredentials(credentials, identities, creditCards.cardNumber); + credentials = canTriggerPartialSave ? inferCredentialsForPartialSave(credentials, identities, creditCards) : inferCredentials(credentials, identities, creditCards); /** Fixes for identities **/ // Don't store if there isn't enough data @@ -12892,7 +12893,7 @@ exports.getActiveElement = getActiveElement; exports.getDaxBoundingBox = void 0; exports.getFormControlElements = getFormControlElements; exports.getTextShallow = void 0; -exports.hasUsernameLikeIdentity = hasUsernameLikeIdentity; +exports.getUsernameLikeIdentity = getUsernameLikeIdentity; exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = void 0; exports.isFormLikelyToBeUsedAsPageWrapper = isFormLikelyToBeUsedAsPageWrapper; exports.isLikelyASubmitButton = exports.isIncontextSignupEnabledFromProcessedConfig = void 0; @@ -13569,12 +13570,22 @@ function queryElementsWithShadow(element, selector) { } /** - * Checks if there is a single username-like identity, i.e. email or phone + * Checks if there is a single username-like identity, i.e. email or phone or credit card number + * If there is then returns that, otherwise returns undefined * @param {InternalIdentityObject} identities - * @returns {boolean} + * @param {InternalCreditCardObject} creditCards + * @returns {string | undefined} */ -function hasUsernameLikeIdentity(identities) { - return Object.keys(identities ?? {}).length === 1 && Boolean(identities?.emailAddress || identities.phone); +function getUsernameLikeIdentity(identities, creditCards) { + if (identities?.emailAddress) { + return identities.emailAddress; + } + if (Object.keys(identities ?? {}).length === 1 && Boolean(identities.phone)) { + return identities.phone; + } + if (Object.keys(creditCards ?? {}).length === 1 && Boolean(creditCards.cardNumber)) { + return creditCards.cardNumber; + } } },{"./Form/matching.js":34,"./constants.js":57,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],55:[function(require,module,exports){ diff --git a/package-lock.json b/package-lock.json index c731bb8f4571..aef0e24c0163 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "dependencies": { "@duckduckgo/autoconsent": "^12.11.0", - "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.2.1", + "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.2.2", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#7.20.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#8.4.0", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1739774089" @@ -58,7 +58,7 @@ } }, "node_modules/@duckduckgo/autofill": { - "resolved": "git+ssh://git@github.com/duckduckgo/duckduckgo-autofill.git#3a9606fd26e9a54bf369cc241e6fa3b2571eb13a", + "resolved": "git+ssh://git@github.com/duckduckgo/duckduckgo-autofill.git#b5976277a68e18f93edb0d853889e461e06557fa", "hasInstallScript": true, "license": "Apache-2.0" }, diff --git a/package.json b/package.json index f2b16389d1f7..e0f8ea7fbcb5 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@duckduckgo/autoconsent": "^12.11.0", - "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.2.1", + "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.2.2", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#7.20.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#8.4.0", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1739774089"