From 8462e3b2d03015246e06ca5b6cfe9e381f626095 Mon Sep 17 00:00:00 2001 From: Deepankar Bajpeyi Date: Mon, 16 Sep 2024 16:38:06 +0200 Subject: [PATCH] feat: re-introduce autofill in iframe (#652) Co-authored-by: Emanuele Feliziani --- dist/autofill-debug.js | 647 ++++++++++-------- dist/autofill.js | 598 ++++++++-------- docs/playwright-tests.md | 6 + docs/runtime.android.md | 178 +++-- docs/runtime.ios.md | 102 ++- integration-test/helpers/harness.js | 16 +- integration-test/helpers/harness.types.d.ts | 1 + integration-test/helpers/mocks.android.js | 156 ++--- integration-test/helpers/mocks.webkit.js | 6 +- integration-test/helpers/mocks.windows.js | 3 + .../tests/email-autofill.android.spec.js | 78 +-- .../tests/incontext-signup.android.spec.js | 21 +- .../tests/login-form.android.spec.js | 78 ++- .../tests/save-prompts.android.spec.js | 51 +- packages/messaging/android.js | 111 +++ packages/messaging/messaging.js | 8 +- src/DeviceInterface/AndroidInterface.js | 79 +-- src/DeviceInterface/InterfacePrototype.js | 14 +- src/DeviceInterface/WindowsInterface.js | 4 +- src/Form/Form.js | 2 +- src/Settings.js | 11 + src/ThirdPartyProvider.js | 4 +- src/UI/controllers/NativeUIController.js | 4 + src/config.js | 4 + .../__generated__/deviceApiCalls.js | 11 + .../__generated__/validators-ts.ts | 121 ++-- .../__generated__/validators.zod.js | 69 +- src/deviceApiCalls/api.json | 9 + .../emailProtectionGetAlias.params.json | 21 + .../emailProtectionGetAlias.result.json | 23 + .../schemas/runtime-configuration.json | 3 + .../transports/android.transport.js | 165 +---- .../Resources/assets/autofill-debug.js | 647 ++++++++++-------- swift-package/Resources/assets/autofill.js | 598 ++++++++-------- types.d.ts | 8 + 35 files changed, 2127 insertions(+), 1730 deletions(-) create mode 100644 packages/messaging/android.js create mode 100644 src/deviceApiCalls/schemas/emailProtectionGetAlias.params.json create mode 100644 src/deviceApiCalls/schemas/emailProtectionGetAlias.result.json diff --git a/dist/autofill-debug.js b/dist/autofill-debug.js index 31e570e2f..0734be99a 100644 --- a/dist/autofill-debug.js +++ b/dist/autofill-debug.js @@ -4591,6 +4591,130 @@ exports.DeviceApi = DeviceApi; },{}],15:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidMessagingTransport = exports.AndroidMessagingConfig = void 0; +var _messaging = require("./messaging.js"); +/** + * @module Android Messaging + * + * @description A wrapper for messaging on Android. See example usage in android.transport.js + */ + +/** + * @typedef {import("./messaging").MessagingTransport} MessagingTransport + */ + +/** + * On Android, handlers are added to the window object and are prefixed with `ddg`. The object looks like this: + * + * ```typescript + * { + * onMessage: undefined, + * postMessage: (message) => void, + * addEventListener: (eventType: string, Function) => void, + * removeEventListener: (eventType: string, Function) => void + * } + * ``` + * + * You send messages to `postMessage` and listen with `addEventListener`. Once the event is received, + * we also remove the listener with `removeEventListener`. + * + * @link https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener) + * @implements {MessagingTransport} + */ +class AndroidMessagingTransport { + /** @type {AndroidMessagingConfig} */ + config; + globals = { + capturedHandlers: {} + }; + /** + * @param {AndroidMessagingConfig} config + */ + constructor(config) { + this.config = config; + } + + /** + * Given the method name, returns the related Android handler + * @param {string} methodName + * @returns {AndroidHandler} + * @private + */ + _getHandler(methodName) { + const androidSpecificName = this._getHandlerName(methodName); + if (!(androidSpecificName in window)) { + throw new _messaging.MissingHandler(`Missing android handler: '${methodName}'`, methodName); + } + return window[androidSpecificName]; + } + + /** + * Given the autofill method name, it returns the Android-specific handler name + * @param {string} internalName + * @returns {string} + * @private + */ + _getHandlerName(internalName) { + return 'ddg' + internalName[0].toUpperCase() + internalName.slice(1); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + notify(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const handler = this._getHandler(name); + const message = data ? JSON.stringify(data) : ''; + handler.postMessage(message); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + async request(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + // Set up the listener first + const handler = this._getHandler(name); + const responseOnce = new Promise(resolve => { + const responseHandler = e => { + handler.removeEventListener('message', responseHandler); + resolve(e.data); + }; + handler.addEventListener('message', responseHandler); + }); + + // Then send the message + this.notify(name, data); + + // And return once the promise resolves + const responseJSON = await responseOnce; + return JSON.parse(responseJSON); + } +} + +/** + * Use this configuration to create an instance of {@link Messaging} for Android + */ +exports.AndroidMessagingTransport = AndroidMessagingTransport; +class AndroidMessagingConfig { + /** + * All the expected Android handler names + * @param {{messageHandlerNames: string[]}} config + */ + constructor(config) { + this.messageHandlerNames = config.messageHandlerNames; + } +} +exports.AndroidMessagingConfig = AndroidMessagingConfig; + +},{"./messaging.js":16}],16:[function(require,module,exports){ +"use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); @@ -4602,6 +4726,7 @@ Object.defineProperty(exports, "WebkitMessagingConfig", { } }); var _webkit = require("./webkit.js"); +var _android = require("./android.js"); /** * @module Messaging * @@ -4660,7 +4785,7 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config */ constructor(config) { this.transport = getTransport(config); @@ -4732,7 +4857,7 @@ class MessagingTransport { } /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config * @returns {MessagingTransport} */ exports.MessagingTransport = MessagingTransport; @@ -4740,6 +4865,9 @@ function getTransport(config) { if (config instanceof _webkit.WebkitMessagingConfig) { return new _webkit.WebkitMessagingTransport(config); } + if (config instanceof _android.AndroidMessagingConfig) { + return new _android.AndroidMessagingTransport(config); + } throw new Error('unreachable'); } @@ -4762,7 +4890,7 @@ class MissingHandler extends Error { */ exports.MissingHandler = MissingHandler; -},{"./webkit.js":16}],16:[function(require,module,exports){ +},{"./android.js":15,"./webkit.js":17}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5157,7 +5285,7 @@ function captureGlobals() { }; } -},{"./messaging.js":15}],17:[function(require,module,exports){ +},{"./messaging.js":16}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5288,7 +5416,7 @@ function _safeHostname(inputHostname) { } } -},{"./lib/apple.password.js":18,"./lib/constants.js":19,"./lib/rules-parser.js":20}],18:[function(require,module,exports){ +},{"./lib/apple.password.js":19,"./lib/constants.js":20,"./lib/rules-parser.js":21}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5817,7 +5945,7 @@ class Password { } exports.Password = Password; -},{"./constants.js":19,"./rules-parser.js":20}],19:[function(require,module,exports){ +},{"./constants.js":20,"./rules-parser.js":21}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5837,7 +5965,7 @@ const constants = exports.constants = { DEFAULT_UNAMBIGUOUS_CHARS }; -},{}],20:[function(require,module,exports){ +},{}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -6433,7 +6561,7 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return newPasswordRules; } -},{}],21:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ module.exports={ "163.com": { "password-rules": "minlength: 6; maxlength: 16;" @@ -7465,7 +7593,7 @@ module.exports={ "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 6; required: lower; required: upper; required: digit;" } } -},{}],22:[function(require,module,exports){ +},{}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7529,7 +7657,7 @@ class CredentialsImport { } exports.CredentialsImport = CredentialsImport; -},{"./deviceApiCalls/__generated__/deviceApiCalls.js":68}],23:[function(require,module,exports){ +},{"./deviceApiCalls/__generated__/deviceApiCalls.js":69}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7585,7 +7713,7 @@ function createDevice() { return new _ExtensionInterface.ExtensionInterface(globalConfig, deviceApi, settings); } -},{"../packages/device-api/index.js":12,"./DeviceInterface/AndroidInterface.js":24,"./DeviceInterface/AppleDeviceInterface.js":25,"./DeviceInterface/AppleOverlayDeviceInterface.js":26,"./DeviceInterface/ExtensionInterface.js":27,"./DeviceInterface/WindowsInterface.js":29,"./DeviceInterface/WindowsOverlayDeviceInterface.js":30,"./Settings.js":51,"./config.js":66,"./deviceApiCalls/transports/transports.js":74}],24:[function(require,module,exports){ +},{"../packages/device-api/index.js":12,"./DeviceInterface/AndroidInterface.js":25,"./DeviceInterface/AppleDeviceInterface.js":26,"./DeviceInterface/AppleOverlayDeviceInterface.js":27,"./DeviceInterface/ExtensionInterface.js":28,"./DeviceInterface/WindowsInterface.js":30,"./DeviceInterface/WindowsOverlayDeviceInterface.js":31,"./Settings.js":52,"./config.js":67,"./deviceApiCalls/transports/transports.js":75}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7605,25 +7733,35 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {Promise} */ async getAlias() { - const { - alias - } = await (0, _autofillUtils.sendAndWaitForAnswer)(async () => { - if (this.inContextSignup.isAvailable()) { - const { - isSignedIn - } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + // If in-context signup is available, do that first + if (this.inContextSignup.isAvailable()) { + const { + isSignedIn + } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + if (isSignedIn) { // On Android we can't get the input type data again without // refreshing the page, so instead we can mutate it now that we // know the user has Email Protection available. - if (this.globalConfig.availableInputTypes) { - this.globalConfig.availableInputTypes.email = isSignedIn; + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: isSignedIn + }); } this.updateForStateChange(); this.onFinishedAutofill(); } - return window.EmailInterface.showTooltip(); - }, 'getAliasResponse'); - return alias; + } + // Then, if successful actually prompt to fill + if (this.settings.availableInputTypes.email) { + const { + alias + } = await this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetAliasCall({ + requiresUserPermission: !this.globalConfig.isApp, + shouldConsumeAliasIfProvided: !this.globalConfig.isApp, + isIncontextSignupAvailable: this.inContextSignup.isAvailable() + })); + return alias ? (0, _autofillUtils.formatDuckAddress)(alias) : undefined; + } } /** @@ -7638,14 +7776,9 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {boolean} */ isDeviceSignedIn() { - // on DDG domains, always check via `window.EmailInterface.isSignedIn()` - if (this.globalConfig.isDDGDomain) { - return window.EmailInterface.isSignedIn() === 'true'; - } - // on non-DDG domains, where `availableInputTypes.email` is present, use it - if (typeof this.globalConfig.availableInputTypes?.email === 'boolean') { - return this.globalConfig.availableInputTypes.email; + if (typeof this.settings.availableInputTypes?.email === 'boolean') { + return this.settings.availableInputTypes.email; } // ...on other domains we assume true because the script wouldn't exist otherwise @@ -7660,15 +7793,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Settings page displays data of the logged in user data */ getUserData() { - let userData = null; - try { - userData = JSON.parse(window.EmailInterface.getUserData()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(userData); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetUserDataCall({})); } /** @@ -7676,25 +7801,13 @@ class AndroidInterface extends _InterfacePrototype.default { * Device capabilities determine which functionality is available to the user */ getEmailProtectionCapabilities() { - let deviceCapabilities = null; - try { - deviceCapabilities = JSON.parse(window.EmailInterface.getDeviceCapabilities()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(deviceCapabilities); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetCapabilitiesCall({})); } storeUserData(_ref) { let { - addUserData: { - token, - userName, - cohort - } + addUserData } = _ref; - return window.EmailInterface.storeCredentials(token, userName, cohort); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionStoreUserDataCall(addUserData)); } /** @@ -7702,13 +7815,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Provides functionality to log the user out */ removeUserData() { - try { - return window.EmailInterface.removeCredentials(); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionRemoveUserDataCall({})); } /** @@ -7733,7 +7840,7 @@ class AndroidInterface extends _InterfacePrototype.default { } exports.AndroidInterface = AndroidInterface; -},{"../InContextSignup.js":45,"../UI/controllers/NativeUIController.js":59,"../autofill-utils.js":64,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./InterfacePrototype.js":28}],25:[function(require,module,exports){ +},{"../InContextSignup.js":46,"../UI/controllers/NativeUIController.js":60,"../autofill-utils.js":65,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./InterfacePrototype.js":29}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8089,7 +8196,7 @@ class AppleDeviceInterface extends _InterfacePrototype.default { } exports.AppleDeviceInterface = AppleDeviceInterface; -},{"../../packages/device-api/index.js":12,"../Form/matching.js":44,"../InContextSignup.js":45,"../ThirdPartyProvider.js":52,"../UI/HTMLTooltip.js":57,"../UI/controllers/HTMLTooltipUIController.js":58,"../UI/controllers/NativeUIController.js":59,"../UI/controllers/OverlayUIController.js":60,"../autofill-utils.js":64,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"../deviceApiCalls/additionalDeviceApiCalls.js":70,"./InterfacePrototype.js":28}],26:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"../Form/matching.js":45,"../InContextSignup.js":46,"../ThirdPartyProvider.js":53,"../UI/HTMLTooltip.js":58,"../UI/controllers/HTMLTooltipUIController.js":59,"../UI/controllers/NativeUIController.js":60,"../UI/controllers/OverlayUIController.js":61,"../autofill-utils.js":65,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"../deviceApiCalls/additionalDeviceApiCalls.js":71,"./InterfacePrototype.js":29}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8208,7 +8315,7 @@ class AppleOverlayDeviceInterface extends _AppleDeviceInterface.AppleDeviceInter } exports.AppleOverlayDeviceInterface = AppleOverlayDeviceInterface; -},{"../../packages/device-api/index.js":12,"../UI/controllers/HTMLTooltipUIController.js":58,"./AppleDeviceInterface.js":25,"./overlayApi.js":32}],27:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"../UI/controllers/HTMLTooltipUIController.js":59,"./AppleDeviceInterface.js":26,"./overlayApi.js":33}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8427,7 +8534,7 @@ class ExtensionInterface extends _InterfacePrototype.default { } exports.ExtensionInterface = ExtensionInterface; -},{"../Form/matching.js":44,"../InContextSignup.js":45,"../UI/HTMLTooltip.js":57,"../UI/controllers/HTMLTooltipUIController.js":58,"../autofill-utils.js":64,"./InterfacePrototype.js":28}],28:[function(require,module,exports){ +},{"../Form/matching.js":45,"../InContextSignup.js":46,"../UI/HTMLTooltip.js":58,"../UI/controllers/HTMLTooltipUIController.js":59,"../autofill-utils.js":65,"./InterfacePrototype.js":29}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9030,11 +9137,19 @@ class InterfacePrototype { let userData; try { userData = await this.getUserData(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('getUserData failed with', e); + } + } let capabilities; try { capabilities = await this.getEmailProtectionCapabilities(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('capabilities fetching failed with', e); + } + } // Set up listener for web app actions if (this.globalConfig.isDDGDomain) { @@ -9090,6 +9205,13 @@ class InterfacePrototype { const data = await (0, _autofillUtils.sendAndWaitForAnswer)(_autofillUtils.SIGN_IN_MSG, 'addUserData'); // This call doesn't send a response, so we can't know if it succeeded this.storeUserData(data); + + // Assuming the previous call succeeded, let's update availableInputTypes + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: true + }); + } await this.setupAutofill(); await this.settings.refresh(); await this.setupSettingsPage({ @@ -9258,7 +9380,7 @@ class InterfacePrototype { } var _default = exports.default = InterfacePrototype; -},{"../../packages/device-api/index.js":12,"../CredentialsImport.js":22,"../EmailProtection.js":33,"../Form/formatters.js":37,"../Form/matching.js":44,"../InputTypes/Credentials.js":46,"../PasswordGenerator.js":49,"../Scanner.js":50,"../Settings.js":51,"../UI/controllers/NativeUIController.js":59,"../autofill-utils.js":64,"../config.js":66,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"../deviceApiCalls/transports/transports.js":74,"../locales/strings.js":99,"./initFormSubmissionsApi.js":31}],29:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"../CredentialsImport.js":23,"../EmailProtection.js":34,"../Form/formatters.js":38,"../Form/matching.js":45,"../InputTypes/Credentials.js":47,"../PasswordGenerator.js":50,"../Scanner.js":51,"../Settings.js":52,"../UI/controllers/NativeUIController.js":60,"../autofill-utils.js":65,"../config.js":67,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"../deviceApiCalls/transports/transports.js":75,"../locales/strings.js":100,"./initFormSubmissionsApi.js":32}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9343,13 +9465,13 @@ class WindowsInterface extends _InterfacePrototype.default { return await this.credentialsImport.refresh(); } default: - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { console.warn('unhandled response', resp); } return this._closeAutofillParent(); } } catch (e) { - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { if (e instanceof DOMException && e.name === 'AbortError') { console.log('Promise Aborted'); } else { @@ -9424,7 +9546,7 @@ class WindowsInterface extends _InterfacePrototype.default { } exports.WindowsInterface = WindowsInterface; -},{"../UI/controllers/OverlayUIController.js":60,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./InterfacePrototype.js":28}],30:[function(require,module,exports){ +},{"../UI/controllers/OverlayUIController.js":61,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./InterfacePrototype.js":29}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9603,7 +9725,7 @@ class WindowsOverlayDeviceInterface extends _InterfacePrototype.default { } exports.WindowsOverlayDeviceInterface = WindowsOverlayDeviceInterface; -},{"../UI/controllers/HTMLTooltipUIController.js":58,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./InterfacePrototype.js":28,"./overlayApi.js":32}],31:[function(require,module,exports){ +},{"../UI/controllers/HTMLTooltipUIController.js":59,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./InterfacePrototype.js":29,"./overlayApi.js":33}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9702,7 +9824,7 @@ function initFormSubmissionsApi(forms, matching) { }); } -},{"../Form/label-util.js":40,"../autofill-utils.js":64}],32:[function(require,module,exports){ +},{"../Form/label-util.js":41,"../autofill-utils.js":65}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9760,7 +9882,7 @@ function overlayApi(device) { }; } -},{"../deviceApiCalls/__generated__/deviceApiCalls.js":68}],33:[function(require,module,exports){ +},{"../deviceApiCalls/__generated__/deviceApiCalls.js":69}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9795,7 +9917,7 @@ class EmailProtection { } exports.EmailProtection = EmailProtection; -},{}],34:[function(require,module,exports){ +},{}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9935,7 +10057,7 @@ class Form { } submitHandler() { let via = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown'; - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('Form.submitHandler via:', via, this); } if (this.submitHandlerExecuted) return; @@ -10702,7 +10824,7 @@ class Form { } exports.Form = Form; -},{"../InputTypes/Credentials.js":46,"../autofill-utils.js":64,"../constants.js":67,"./FormAnalyzer.js":35,"./formatters.js":37,"./inputStyles.js":38,"./inputTypeConfig.js":39,"./matching.js":44}],35:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":47,"../autofill-utils.js":65,"../constants.js":68,"./FormAnalyzer.js":36,"./formatters.js":38,"./inputStyles.js":39,"./inputTypeConfig.js":40,"./matching.js":45}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11072,7 +11194,7 @@ class FormAnalyzer { } var _default = exports.default = FormAnalyzer; -},{"../autofill-utils.js":64,"../constants.js":67,"./matching-config/__generated__/compiled-matching-config.js":42,"./matching.js":44}],36:[function(require,module,exports){ +},{"../autofill-utils.js":65,"../constants.js":68,"./matching-config/__generated__/compiled-matching-config.js":43,"./matching.js":45}],37:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11637,7 +11759,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { 'Unknown Region': 'ZZ' }; -},{}],37:[function(require,module,exports){ +},{}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11942,7 +12064,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":36,"./matching.js":44}],38:[function(require,module,exports){ +},{"./countryNames.js":37,"./matching.js":45}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12033,7 +12155,7 @@ const getIconStylesAutofilled = (input, form) => { }; exports.getIconStylesAutofilled = getIconStylesAutofilled; -},{"./inputTypeConfig.js":39}],39:[function(require,module,exports){ +},{"./inputTypeConfig.js":40}],40:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12287,7 +12409,7 @@ const isFieldDecorated = input => { }; exports.isFieldDecorated = isFieldDecorated; -},{"../InputTypes/Credentials.js":46,"../InputTypes/CreditCard.js":47,"../InputTypes/Identity.js":48,"../UI/img/ddgPasswordIcon.js":62,"../constants.js":67,"./logo-svg.js":41,"./matching.js":44}],40:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":47,"../InputTypes/CreditCard.js":48,"../InputTypes/Identity.js":49,"../UI/img/ddgPasswordIcon.js":63,"../constants.js":68,"./logo-svg.js":42,"./matching.js":45}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12335,7 +12457,7 @@ const extractElementStrings = element => { }; exports.extractElementStrings = extractElementStrings; -},{"./matching.js":44}],41:[function(require,module,exports){ +},{"./matching.js":45}],42:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12368,7 +12490,7 @@ const daxGrayscaleSvg = ` `.trim(); const daxGrayscaleBase64 = exports.daxGrayscaleBase64 = `data:image/svg+xml;base64,${window.btoa(daxGrayscaleSvg)}`; -},{}],42:[function(require,module,exports){ +},{}],43:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12821,7 +12943,7 @@ const matchingConfiguration = exports.matchingConfiguration = { } }; -},{}],43:[function(require,module,exports){ +},{}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12896,7 +13018,7 @@ function logUnmatched(el, allStrings) { console.groupEnd(); } -},{"../autofill-utils.js":64,"./matching.js":44}],44:[function(require,module,exports){ +},{"../autofill-utils.js":65,"./matching.js":45}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13888,7 +14010,7 @@ function createMatching() { return new Matching(_compiledMatchingConfig.matchingConfiguration); } -},{"../autofill-utils.js":64,"../constants.js":67,"./label-util.js":40,"./matching-config/__generated__/compiled-matching-config.js":42,"./matching-utils.js":43}],45:[function(require,module,exports){ +},{"../autofill-utils.js":65,"../constants.js":68,"./label-util.js":41,"./matching-config/__generated__/compiled-matching-config.js":43,"./matching-utils.js":44}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14020,7 +14142,7 @@ class InContextSignup { } exports.InContextSignup = InContextSignup; -},{"./autofill-utils.js":64,"./deviceApiCalls/__generated__/deviceApiCalls.js":68}],46:[function(require,module,exports){ +},{"./autofill-utils.js":65,"./deviceApiCalls/__generated__/deviceApiCalls.js":69}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14176,7 +14298,7 @@ function createCredentialsTooltipItem(data) { return new CredentialsTooltipItem(data); } -},{"../autofill-utils.js":64}],47:[function(require,module,exports){ +},{"../autofill-utils.js":65}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14201,7 +14323,7 @@ class CreditCardTooltipItem { } exports.CreditCardTooltipItem = CreditCardTooltipItem; -},{}],48:[function(require,module,exports){ +},{}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14247,7 +14369,7 @@ class IdentityTooltipItem { } exports.IdentityTooltipItem = IdentityTooltipItem; -},{"../Form/formatters.js":37}],49:[function(require,module,exports){ +},{"../Form/formatters.js":38}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14289,7 +14411,7 @@ class PasswordGenerator { } exports.PasswordGenerator = PasswordGenerator; -},{"../packages/password/index.js":17,"../packages/password/rules.json":21}],50:[function(require,module,exports){ +},{"../packages/password/index.js":18,"../packages/password/rules.json":22}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14750,7 +14872,7 @@ function createScanner(device, scannerOptions) { }); } -},{"./Form/Form.js":34,"./Form/matching.js":44,"./autofill-utils.js":64,"./constants.js":67,"./deviceApiCalls/__generated__/deviceApiCalls.js":68}],51:[function(require,module,exports){ +},{"./Form/Form.js":35,"./Form/matching.js":45,"./autofill-utils.js":65,"./constants.js":68,"./deviceApiCalls/__generated__/deviceApiCalls.js":69}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14896,6 +15018,11 @@ class Settings { if (this._runtimeConfiguration) return this._runtimeConfiguration; const runtimeConfig = await this.deviceApi.request(new _deviceApiCalls.GetRuntimeConfigurationCall(null)); this._runtimeConfiguration = runtimeConfig; + + // If the platform sends availableInputTypes here, store them + if (runtimeConfig.availableInputTypes) { + this.setAvailableInputTypes(runtimeConfig.availableInputTypes); + } return this._runtimeConfiguration; } @@ -14911,6 +15038,9 @@ class Settings { if (this.globalConfig.isTopFrame) { return Settings.defaults.availableInputTypes; } + if (this._availableInputTypes) { + return this.availableInputTypes; + } return await this.deviceApi.request(new _deviceApiCalls.GetAvailableInputTypesCall(null)); } catch (e) { if (this.globalConfig.isDDGTestMode) { @@ -15163,7 +15293,7 @@ class Settings { } exports.Settings = Settings; -},{"../packages/device-api/index.js":12,"./autofill-utils.js":64,"./deviceApiCalls/__generated__/deviceApiCalls.js":68,"./deviceApiCalls/__generated__/validators.zod.js":69}],52:[function(require,module,exports){ +},{"../packages/device-api/index.js":12,"./autofill-utils.js":65,"./deviceApiCalls/__generated__/deviceApiCalls.js":69,"./deviceApiCalls/__generated__/validators.zod.js":70}],53:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15230,7 +15360,7 @@ class ThirdPartyProvider { this.device.scanner.forms.forEach(form => form.recategorizeAllInputs()); } } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: providerStatusUpdated error: ❌', e); } } @@ -15245,7 +15375,7 @@ class ThirdPartyProvider { } setTimeout(() => this._pollForUpdatesToCredentialsProvider(), 2000); } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: _pollForUpdatesToCredentialsProvider: ❌', e); } } @@ -15253,7 +15383,7 @@ class ThirdPartyProvider { } exports.ThirdPartyProvider = ThirdPartyProvider; -},{"../packages/device-api/index.js":12,"./Form/matching.js":44,"./deviceApiCalls/__generated__/deviceApiCalls.js":68,"./deviceApiCalls/__generated__/validators.zod.js":69}],53:[function(require,module,exports){ +},{"../packages/device-api/index.js":12,"./Form/matching.js":45,"./deviceApiCalls/__generated__/deviceApiCalls.js":69,"./deviceApiCalls/__generated__/validators.zod.js":70}],54:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15294,7 +15424,7 @@ ${this.options.css} } var _default = exports.default = CredentialsImportTooltip; -},{"./HTMLTooltip.js":57}],54:[function(require,module,exports){ +},{"./HTMLTooltip.js":58}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15445,7 +15575,7 @@ ${css} } var _default = exports.default = DataHTMLTooltip; -},{"../InputTypes/Credentials.js":46,"../autofill-utils.js":64,"./HTMLTooltip.js":57}],55:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":47,"../autofill-utils.js":65,"./HTMLTooltip.js":58}],56:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15527,7 +15657,7 @@ ${this.options.css} } var _default = exports.default = EmailHTMLTooltip; -},{"../autofill-utils.js":64,"./HTMLTooltip.js":57}],56:[function(require,module,exports){ +},{"../autofill-utils.js":65,"./HTMLTooltip.js":58}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15580,7 +15710,7 @@ ${this.options.css} } var _default = exports.default = EmailSignupHTMLTooltip; -},{"./HTMLTooltip.js":57}],57:[function(require,module,exports){ +},{"./HTMLTooltip.js":58}],58:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15968,7 +16098,7 @@ class HTMLTooltip { exports.HTMLTooltip = HTMLTooltip; var _default = exports.default = HTMLTooltip; -},{"../Form/matching.js":44,"../autofill-utils.js":64,"./styles/styles.js":63}],58:[function(require,module,exports){ +},{"../Form/matching.js":45,"../autofill-utils.js":65,"./styles/styles.js":64}],59:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16336,7 +16466,7 @@ class HTMLTooltipUIController extends _UIController.UIController { } exports.HTMLTooltipUIController = HTMLTooltipUIController; -},{"../../Form/inputTypeConfig.js":39,"../../Form/matching.js":44,"../../autofill-utils.js":64,"../CredentialsImportTooltip.js":53,"../DataHTMLTooltip.js":54,"../EmailHTMLTooltip.js":55,"../EmailSignupHTMLTooltip.js":56,"../HTMLTooltip.js":57,"./UIController.js":61}],59:[function(require,module,exports){ +},{"../../Form/inputTypeConfig.js":40,"../../Form/matching.js":45,"../../autofill-utils.js":65,"../CredentialsImportTooltip.js":54,"../DataHTMLTooltip.js":55,"../EmailHTMLTooltip.js":56,"../EmailSignupHTMLTooltip.js":57,"../HTMLTooltip.js":58,"./UIController.js":62}],60:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16438,6 +16568,11 @@ class NativeUIController extends _UIController.UIController { form.activeInput?.focus(); break; } + case 'none': + { + // do nothing + break; + } default: { if (args.device.isTestMode()) { @@ -16498,7 +16633,7 @@ class NativeUIController extends _UIController.UIController { } exports.NativeUIController = NativeUIController; -},{"../../Form/matching.js":44,"../../InputTypes/Credentials.js":46,"../../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./UIController.js":61}],60:[function(require,module,exports){ +},{"../../Form/matching.js":45,"../../InputTypes/Credentials.js":47,"../../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./UIController.js":62}],61:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16735,7 +16870,7 @@ class OverlayUIController extends _UIController.UIController { } exports.OverlayUIController = OverlayUIController; -},{"../../Form/matching.js":44,"./UIController.js":61}],61:[function(require,module,exports){ +},{"../../Form/matching.js":45,"./UIController.js":62}],62:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16819,7 +16954,7 @@ class UIController { } exports.UIController = UIController; -},{}],62:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16836,7 +16971,7 @@ const ddgCcIconBase = exports.ddgCcIconBase = 'data:image/svg+xml;base64,PD94bWw const ddgCcIconFilled = exports.ddgCcIconFilled = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzc2NDMxMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjNzY0MzEwIi8+Cjwvc3ZnPgo='; const ddgIdentityIconBase = exports.ddgIdentityIconBase = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4KPHBhdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJub25lIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyMWMyLjE0MyAwIDQuMTExLS43NSA1LjY1Ny0yLS42MjYtLjUwNi0xLjMxOC0uOTI3LTIuMDYtMS4yNS0xLjEtLjQ4LTIuMjg1LS43MzUtMy40ODYtLjc1LTEuMi0uMDE0LTIuMzkyLjIxMS0zLjUwNC42NjQtLjgxNy4zMzMtMS41OC43ODMtMi4yNjQgMS4zMzYgMS41NDYgMS4yNSAzLjUxNCAyIDUuNjU3IDJ6bTQuMzk3LTUuMDgzYy45NjcuNDIyIDEuODY2Ljk4IDIuNjcyIDEuNjU1QzIwLjI3OSAxNi4wMzkgMjEgMTQuMTA0IDIxIDEyYzAtNC45Ny00LjAzLTktOS05cy05IDQuMDMtOSA5YzAgMi4xMDQuNzIyIDQuMDQgMS45MzIgNS41NzIuODc0LS43MzQgMS44Ni0xLjMyOCAyLjkyMS0xLjc2IDEuMzYtLjU1NCAyLjgxNi0uODMgNC4yODMtLjgxMSAxLjQ2Ny4wMTggMi45MTYuMzMgNC4yNi45MTZ6TTEyIDIzYzYuMDc1IDAgMTEtNC45MjUgMTEtMTFTMTguMDc1IDEgMTIgMSAxIDUuOTI1IDEgMTJzNC45MjUgMTEgMTEgMTF6bTMtMTNjMCAxLjY1Ny0xLjM0MyAzLTMgM3MtMy0xLjM0My0zLTMgMS4zNDMtMyAzLTMgMyAxLjM0MyAzIDN6bTIgMGMwIDIuNzYxLTIuMjM5IDUtNSA1cy01LTIuMjM5LTUtNSAyLjIzOS01IDUtNSA1IDIuMjM5IDUgNXoiIGZpbGw9IiMwMDAiLz4KPC9zdmc+Cg==`; -},{}],63:[function(require,module,exports){ +},{}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16845,7 +16980,7 @@ Object.defineProperty(exports, "__esModule", { exports.CSS_STYLES = void 0; const CSS_STYLES = exports.CSS_STYLES = ":root {\n color-scheme: light dark;\n}\n\n.wrapper *, .wrapper *::before, .wrapper *::after {\n box-sizing: border-box;\n}\n.wrapper {\n position: fixed;\n top: 0;\n left: 0;\n padding: 0;\n font-family: 'DDG_ProximaNova', 'Proxima Nova', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n z-index: 2147483647;\n}\n.wrapper--data {\n font-family: 'SF Pro Text', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n}\n.wrapper:not(.top-autofill) .tooltip {\n position: absolute;\n width: 300px;\n max-width: calc(100vw - 25px);\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--data, #topAutofill {\n background-color: rgba(242, 240, 240, 1);\n -webkit-backdrop-filter: blur(40px);\n backdrop-filter: blur(40px);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data, #topAutofill {\n background: rgb(100, 98, 102, .9);\n }\n}\n.tooltip--data {\n padding: 6px;\n font-size: 13px;\n line-height: 14px;\n width: 315px;\n max-height: 290px;\n overflow-y: auto;\n}\n.top-autofill .tooltip--data {\n min-height: 100vh;\n}\n.tooltip--data.tooltip--incontext-signup {\n width: 360px;\n}\n.wrapper:not(.top-autofill) .tooltip--data {\n top: 100%;\n left: 100%;\n border: 0.5px solid rgba(255, 255, 255, 0.2);\n border-radius: 6px;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.32);\n}\n@media (prefers-color-scheme: dark) {\n .wrapper:not(.top-autofill) .tooltip--data {\n border: 1px solid rgba(255, 255, 255, 0.2);\n }\n}\n.wrapper:not(.top-autofill) .tooltip--email {\n top: calc(100% + 6px);\n right: calc(100% - 48px);\n padding: 8px;\n border: 1px solid #D0D0D0;\n border-radius: 10px;\n background-color: #FFFFFF;\n font-size: 14px;\n line-height: 1.3;\n color: #333333;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);\n}\n.tooltip--email__caret {\n position: absolute;\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--email__caret::before,\n.tooltip--email__caret::after {\n content: \"\";\n width: 0;\n height: 0;\n border-left: 10px solid transparent;\n border-right: 10px solid transparent;\n display: block;\n border-bottom: 8px solid #D0D0D0;\n position: absolute;\n right: -28px;\n}\n.tooltip--email__caret::before {\n border-bottom-color: #D0D0D0;\n top: -1px;\n}\n.tooltip--email__caret::after {\n border-bottom-color: #FFFFFF;\n top: 0px;\n}\n\n/* Buttons */\n.tooltip__button {\n display: flex;\n width: 100%;\n padding: 8px 8px 8px 0px;\n font-family: inherit;\n color: inherit;\n background: transparent;\n border: none;\n border-radius: 6px;\n text-align: left;\n}\n.tooltip__button.currentFocus,\n.wrapper:not(.top-autofill) .tooltip__button:hover {\n background-color: #3969EF;\n color: #FFFFFF;\n}\n\n/* Data autofill tooltip specific */\n.tooltip__button--data {\n position: relative;\n min-height: 48px;\n flex-direction: row;\n justify-content: flex-start;\n font-size: inherit;\n font-weight: 500;\n line-height: 16px;\n text-align: left;\n border-radius: 3px;\n}\n.tooltip--data__item-container {\n max-height: 220px;\n overflow: auto;\n}\n.tooltip__button--data:first-child {\n margin-top: 0;\n}\n.tooltip__button--data:last-child {\n margin-bottom: 0;\n}\n.tooltip__button--data::before {\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 20px 20px;\n background-repeat: no-repeat;\n background-position: center center;\n}\n#provider_locked::after {\n position: absolute;\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 11px 13px;\n background-repeat: no-repeat;\n background-position: right bottom;\n}\n.tooltip__button--data.currentFocus:not(.tooltip__button--data--bitwarden)::before,\n.wrapper:not(.top-autofill) .tooltip__button--data:not(.tooltip__button--data--bitwarden):hover::before {\n filter: invert(100%);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before,\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before {\n filter: invert(100%);\n opacity: .9;\n }\n}\n.tooltip__button__text-container {\n margin: auto 0;\n}\n.label {\n display: block;\n font-weight: 400;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.8);\n font-size: 13px;\n line-height: 1;\n}\n.label + .label {\n margin-top: 2px;\n}\n.label.label--medium {\n font-weight: 500;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.9);\n}\n.label.label--small {\n font-size: 11px;\n font-weight: 400;\n letter-spacing: 0.06px;\n color: rgba(0,0,0,0.6);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data .label {\n color: #ffffff;\n }\n .tooltip--data .label--medium {\n color: #ffffff;\n }\n .tooltip--data .label--small {\n color: #cdcdcd;\n }\n}\n.tooltip__button.currentFocus .label,\n.wrapper:not(.top-autofill) .tooltip__button:hover .label {\n color: #FFFFFF;\n}\n\n.tooltip__button--manage {\n font-size: 13px;\n padding: 5px 9px;\n border-radius: 3px;\n margin: 0;\n}\n\n/* Icons */\n.tooltip__button--data--credentials::before,\n.tooltip__button--data--credentials__current::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS4zMzQgNi42NjdhMiAyIDAgMSAwIDAgNCAyIDIgMCAwIDAgMC00Wm0tLjY2NyAyYS42NjcuNjY3IDAgMSAxIDEuMzMzIDAgLjY2Ny42NjcgMCAwIDEtMS4zMzMgMFoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTQuNjY3IDRhNS4zMzMgNS4zMzMgMCAwIDAtNS4xODggNi41NzhsLTUuMjg0IDUuMjg0YS42NjcuNjY3IDAgMCAwLS4xOTUuNDcxdjNjMCAuMzY5LjI5OC42NjcuNjY3LjY2N2gyLjY2NmMuNzM3IDAgMS4zMzQtLjU5NyAxLjMzNC0xLjMzM1YxOGguNjY2Yy43MzcgMCAxLjMzNC0uNTk3IDEuMzM0LTEuMzMzdi0xLjMzNEgxMmMuMTc3IDAgLjM0Ni0uMDcuNDcxLS4xOTVsLjY4OC0uNjg4QTUuMzMzIDUuMzMzIDAgMSAwIDE0LjY2NyA0Wm0tNCA1LjMzM2E0IDQgMCAxIDEgMi41NTUgMy43MzIuNjY3LjY2NyAwIDAgMC0uNzEzLjE1bC0uNzg1Ljc4NUgxMGEuNjY3LjY2NyAwIDAgMC0uNjY3LjY2N3YySDhhLjY2Ny42NjcgMCAwIDAtLjY2Ny42NjZ2MS4zMzRoLTJ2LTIuMDU4bDUuMzY1LTUuMzY0YS42NjcuNjY3IDAgMCAwIC4xNjMtLjY3NyAzLjk5NiAzLjk5NiAwIDAgMS0uMTk0LTEuMjM1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--credentials__new::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBkPSJNOC4wNDcgNC42MjVDNy45MzcgNC4xMjUgNy44NjIgNCA3LjUgNGMtLjM2MiAwLS40MzguMTI1LS41NDcuNjI1LS4wNjguMzEtLjE3NyAxLjMzOC0uMjUxIDIuMDc3LS43MzguMDc0LTEuNzY3LjE4My0yLjA3Ny4yNTEtLjUuMTEtLjYyNS4xODQtLjYyNS41NDcgMCAuMzYyLjEyNS40MzcuNjI1LjU0Ny4zMS4wNjcgMS4zMzYuMTc3IDIuMDc0LjI1LjA3My43NjcuMTg1IDEuODQyLjI1NCAyLjA3OC4xMS4zNzUuMTg1LjYyNS41NDcuNjI1LjM2MiAwIC40MzgtLjEyNS41NDctLjYyNS4wNjgtLjMxLjE3Ny0xLjMzNi4yNS0yLjA3NC43NjctLjA3MyAxLjg0Mi0uMTg1IDIuMDc4LS4yNTQuMzc1LS4xMS42MjUtLjE4NS42MjUtLjU0NyAwLS4zNjMtLjEyNS0uNDM4LS42MjUtLjU0Ny0uMzEtLjA2OC0xLjMzOS0uMTc3LTIuMDc3LS4yNTEtLjA3NC0uNzM5LS4xODMtMS43NjctLjI1MS0yLjA3N1oiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0xNC42ODEgNS4xOTljLS43NjYgMC0xLjQ4Mi4yMS0yLjA5My41NzhhLjYzNi42MzYgMCAwIDEtLjY1NS0xLjA5IDUuMzQgNS4zNCAwIDEgMSAxLjMwMiA5LjcyMmwtLjc3NS43NzZhLjYzNi42MzYgMCAwIDEtLjQ1LjE4NmgtMS4zOTh2MS42NWMwIC40OTMtLjQuODkzLS44OTMuODkzSDguNTc4djEuMTQxYzAgLjQ5NC0uNC44OTMtLjg5NC44OTNINC42MzZBLjYzNi42MzYgMCAwIDEgNCAxOS4zMTNWMTYuMjZjMC0uMTY5LjA2Ny0uMzMuMTg2LS40NWw1LjU2Mi01LjU2MmEuNjM2LjYzNiAwIDEgMSAuOS45bC01LjM3NiA1LjM3NXYyLjE1M2gyLjAzNHYtMS4zOTljMC0uMzUuMjg1LS42MzYuNjM2LS42MzZIOS4zNHYtMS45MDdjMC0uMzUxLjI4NC0uNjM2LjYzNS0uNjM2aDEuNzcxbC44NjQtLjg2M2EuNjM2LjYzNiAwIDAgMSAuNjY4LS4xNDcgNC4wNjkgNC4wNjkgMCAxIDAgMS40MDItNy44OVoiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTEzLjYyNSA4LjQ5OWExLjg3NSAxLjg3NSAwIDEgMSAzLjc1IDAgMS44NzUgMS44NzUgMCAwIDEtMy43NSAwWm0xLjg3NS0uNjI1YS42MjUuNjI1IDAgMSAwIDAgMS4yNS42MjUuNjI1IDAgMCAwIDAtMS4yNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZD0iTTQuNjI1IDEyLjEyNWEuNjI1LjYyNSAwIDEgMCAwLTEuMjUuNjI1LjYyNSAwIDAgMCAwIDEuMjVaIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--creditCards::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--identities::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4=');\n}\n.tooltip__button--data--credentials.tooltip__button--data--bitwarden::before,\n.tooltip__button--data--credentials__current.tooltip__button--data--bitwarden::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iOCIgZmlsbD0iIzE3NUREQyIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE4LjU2OTYgNS40MzM1NUMxOC41MDg0IDUuMzc0NDIgMTguNDM0NyA1LjMyNzYzIDE4LjM1MzEgNS4yOTYxMUMxOC4yNzE1IDUuMjY0NiAxOC4xODM3IDUuMjQ5MDQgMTguMDk1MyA1LjI1MDQxSDUuOTIxOTFDNS44MzMyNiA1LjI0NzI5IDUuNzQ0OTMgNS4yNjIwNSA1LjY2MzA0IDUuMjkzNjdDNS41ODExNSA1LjMyNTI5IDUuNTA3NjUgNS4zNzMwMiA1LjQ0NzYyIDUuNDMzNTVDNS4zMjE3IDUuNTUwMTMgNS4yNTA2NSA1LjcwODE1IDUuMjUgNS44NzMxVjEzLjM4MjFDNS4yNTMzNiAxMy45NTM1IDUuMzc0MDggMTQuNTE5MSA1LjYwNTcyIDE1LjA0ODdDNS44MTkzMSAxNS41NzI4IDYuMTEyMDcgMTYuMDY2MSA2LjQ3NTI0IDE2LjUxMzlDNi44NDIgMTYuOTY4MyA3LjI1OTI5IDE3LjM4NTcgNy43MjAyNSAxNy43NTkzQzguMTQwNTMgMTguMTI1NiA4LjU4OTcxIDE4LjQ2MjMgOS4wNjQwNyAxOC43NjY2QzkuNDU5MzEgMTkuMDIzIDkuOTEzODMgMTkuMjc5NCAxMC4zNDg2IDE5LjUxNzVDMTAuNzgzNCAxOS43NTU2IDExLjA5OTYgMTkuOTIwNCAxMS4yNzc0IDE5Ljk5MzdDMTEuNDU1MyAyMC4wNjY5IDExLjYxMzQgMjAuMTQwMiAxMS43MTIyIDIwLjE5NTFDMTEuNzk5MiAyMC4yMzEzIDExLjg5MzUgMjAuMjUgMTEuOTg4OCAyMC4yNUMxMi4wODQyIDIwLjI1IDEyLjE3ODUgMjAuMjMxMyAxMi4yNjU1IDIwLjE5NTFDMTIuNDIxMiAyMC4xMzYzIDEyLjU3MjkgMjAuMDY5IDEyLjcyIDE5Ljk5MzdDMTIuNzcxMSAxOS45Njc0IDEyLjgzMzUgMTkuOTM2NiAxMi45MDY5IDE5LjkwMDRDMTMuMDg5MSAxOS44MTA1IDEzLjMzODggMTkuNjg3MiAxMy42NDg5IDE5LjUxNzVDMTQuMDgzNiAxOS4yNzk0IDE0LjUxODQgMTkuMDIzIDE0LjkzMzQgMTguNzY2NkMxNS40MDQgMTguNDU3NyAxNS44NTI4IDE4LjEyMTIgMTYuMjc3MiAxNy43NTkzQzE2LjczMzEgMTcuMzgwOSAxNy4xNDk5IDE2Ljk2NCAxNy41MjIyIDE2LjUxMzlDMTcuODc4IDE2LjA2MTcgMTguMTcwMiAxNS41NjkzIDE4LjM5MTcgMTUuMDQ4N0MxOC42MjM0IDE0LjUxOTEgMTguNzQ0MSAxMy45NTM1IDE4Ljc0NzQgMTMuMzgyMVY1Ljg3MzFDMTguNzU1NyA1Ljc5MjE0IDE4Ljc0MzkgNS43MTA1IDE4LjcxMzEgNS42MzQzNUMxOC42ODIzIDUuNTU4MiAxOC42MzMyIDUuNDg5NTQgMTguNTY5NiA1LjQzMzU1Wk0xNy4wMDg0IDEzLjQ1NTNDMTcuMDA4NCAxNi4xODQyIDEyLjAwODYgMTguNTI4NSAxMi4wMDg2IDE4LjUyODVWNi44NjIwOUgxNy4wMDg0VjEzLjQ1NTNaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');\n}\n#provider_locked:after {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMSAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEgNy42MDA1N1Y3LjYwMjVWOS41MjI1QzEgMTAuMDgwMSAxLjIyMTUxIDEwLjYxNDkgMS42MTU4MSAxMS4wMDkyQzIuMDEwMSAxMS40MDM1IDIuNTQ0ODggMTEuNjI1IDMuMTAyNSAxMS42MjVINy4yNzI1QzcuNTQ4NjEgMTEuNjI1IDcuODIyMDEgMTEuNTcwNiA4LjA3NzA5IDExLjQ2NUM4LjMzMjE4IDExLjM1OTMgOC41NjM5NiAxMS4yMDQ0IDguNzU5MTkgMTEuMDA5MkM4Ljk1NDQzIDEwLjgxNCA5LjEwOTMgMTAuNTgyMiA5LjIxNDk2IDEwLjMyNzFDOS4zMjA2MiAxMC4wNzIgOS4zNzUgOS43OTg2MSA5LjM3NSA5LjUyMjVMOS4zNzUgNy42MDI1TDkuMzc1IDcuNjAwNTdDOS4zNzQxNSA3LjE2MTMxIDkuMjM1NzQgNi43MzMzNSA4Ljk3OTIyIDYuMzc2NzhDOC44NzY4MyA2LjIzNDQ2IDguNzU3NjggNi4xMDYzNyA4LjYyNSA1Ljk5NDg5VjUuMTg3NUM4LjYyNSA0LjI3NTgyIDguMjYyODQgMy40MDE0OCA3LjYxODE4IDIuNzU2ODJDNi45NzM1MiAyLjExMjE2IDYuMDk5MTggMS43NSA1LjE4NzUgMS43NUM0LjI3NTgyIDEuNzUgMy40MDE0OCAyLjExMjE2IDIuNzU2ODIgMi43NTY4MkMyLjExMjE2IDMuNDAxNDggMS43NSA0LjI3NTgyIDEuNzUgNS4xODc1VjUuOTk0ODlDMS42MTczMiA2LjEwNjM3IDEuNDk4MTcgNi4yMzQ0NiAxLjM5NTc4IDYuMzc2NzhDMS4xMzkyNiA2LjczMzM1IDEuMDAwODUgNy4xNjEzMSAxIDcuNjAwNTdaTTQuOTY4NyA0Ljk2ODdDNS4wMjY5NCA0LjkxMDQ3IDUuMTA1MzIgNC44NzY5OSA1LjE4NzUgNC44NzUwN0M1LjI2OTY4IDQuODc2OTkgNS4zNDgwNiA0LjkxMDQ3IDUuNDA2MyA0Ljk2ODdDNS40NjU0MiA1LjAyNzgzIDUuNDk5MDQgNS4xMDc3NCA1LjUgNS4xOTEzVjUuNUg0Ljg3NVY1LjE5MTNDNC44NzU5NiA1LjEwNzc0IDQuOTA5NTggNS4wMjc4MyA0Ljk2ODcgNC45Njg3WiIgZmlsbD0iIzIyMjIyMiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIi8+Cjwvc3ZnPgo=');\n}\n\nhr {\n display: block;\n margin: 5px 9px;\n border: none; /* reset the border */\n border-top: 1px solid rgba(0,0,0,.1);\n}\n\nhr:first-child {\n display: none;\n}\n\n@media (prefers-color-scheme: dark) {\n hr {\n border-top: 1px solid rgba(255,255,255,.2);\n }\n}\n\n#privateAddress {\n align-items: flex-start;\n}\n#personalAddress::before,\n#privateAddress::before,\n#incontextSignup::before,\n#personalAddress.currentFocus::before,\n#personalAddress:hover::before,\n#privateAddress.currentFocus::before,\n#privateAddress:hover::before {\n filter: none;\n /* This is the same icon as `daxBase64` in `src/Form/logo-svg.js` */\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTY0IDEyOGMzNS4zNDYgMCA2NC0yOC42NTQgNjQtNjRzLTI4LjY1NC02NC02NC02NC02NCAyOC42NTQtNjQgNjQgMjguNjU0IDY0IDY0IDY0eiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im03MyAxMTEuNzVjMC0uNS4xMjMtLjYxNC0xLjQ2Ni0zLjc4Mi00LjIyNC04LjQ1OS04LjQ3LTIwLjM4NC02LjU0LTI4LjA3NS4zNTMtMS4zOTctMy45NzgtNTEuNzQ0LTcuMDQtNTMuMzY1LTMuNDAyLTEuODEzLTcuNTg4LTQuNjktMTEuNDE4LTUuMzMtMS45NDMtLjMxLTQuNDktLjE2NC02LjQ4Mi4xMDUtLjM1My4wNDctLjM2OC42ODMtLjAzLjc5OCAxLjMwOC40NDMgMi44OTUgMS4yMTIgMy44MyAyLjM3NS4xNzguMjItLjA2LjU2Ni0uMzQyLjU3Ny0uODgyLjAzMi0yLjQ4Mi40MDItNC41OTMgMi4xOTUtLjI0NC4yMDctLjA0MS41OTIuMjczLjUzIDQuNTM2LS44OTcgOS4xNy0uNDU1IDExLjkgMi4wMjcuMTc3LjE2LjA4NC40NS0uMTQ3LjUxMi0yMy42OTQgNi40NC0xOS4wMDMgMjcuMDUtMTIuNjk2IDUyLjM0NCA1LjYxOSAyMi41MyA3LjczMyAyOS43OTIgOC40IDMyLjAwNGEuNzE4LjcxOCAwIDAgMCAuNDIzLjQ2N2M4LjE1NiAzLjI0OCAyNS45MjggMy4zOTIgMjUuOTI4LTIuMTMyeiIgZmlsbD0iI2RkZCIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBkPSJtNzYuMjUgMTE2LjVjLTIuODc1IDEuMTI1LTguNSAxLjYyNS0xMS43NSAxLjYyNS00Ljc2NCAwLTExLjYyNS0uNzUtMTQuMTI1LTEuODc1LTEuNTQ0LTQuNzUxLTYuMTY0LTE5LjQ4LTEwLjcyNy0zOC4xODVsLS40NDctMS44MjctLjAwNC0uMDE1Yy01LjQyNC0yMi4xNTctOS44NTUtNDAuMjUzIDE0LjQyNy00NS45MzguMjIyLS4wNTIuMzMtLjMxNy4xODQtLjQ5Mi0yLjc4Ni0zLjMwNS04LjAwNS00LjM4OC0xNC42MDUtMi4xMTEtLjI3LjA5My0uNTA2LS4xOC0uMzM3LS40MTIgMS4yOTQtMS43ODMgMy44MjMtMy4xNTUgNS4wNzEtMy43NTYuMjU4LS4xMjQuMjQyLS41MDItLjAzLS41ODhhMjcuODc3IDI3Ljg3NyAwIDAgMCAtMy43NzItLjljLS4zNy0uMDU5LS40MDMtLjY5My0uMDMyLS43NDMgOS4zNTYtMS4yNTkgMTkuMTI1IDEuNTUgMjQuMDI4IDcuNzI2YS4zMjYuMzI2IDAgMCAwIC4xODYuMTE0YzE3Ljk1MiAzLjg1NiAxOS4yMzggMzIuMjM1IDE3LjE3IDMzLjUyOC0uNDA4LjI1NS0xLjcxNS4xMDgtMy40MzgtLjA4NS02Ljk4Ni0uNzgxLTIwLjgxOC0yLjMyOS05LjQwMiAxOC45NDguMTEzLjIxLS4wMzYuNDg4LS4yNzIuNTI1LTYuNDM4IDEgMS44MTIgMjEuMTczIDcuODc1IDM0LjQ2MXoiIGZpbGw9IiNmZmYiLz4KICAgIDxwYXRoIGQ9Im04NC4yOCA5MC42OThjLTEuMzY3LS42MzMtNi42MjEgMy4xMzUtMTAuMTEgNi4wMjgtLjcyOC0xLjAzMS0yLjEwMy0xLjc4LTUuMjAzLTEuMjQyLTIuNzEzLjQ3Mi00LjIxMSAxLjEyNi00Ljg4IDIuMjU0LTQuMjgzLTEuNjIzLTExLjQ4OC00LjEzLTEzLjIyOS0xLjcxLTEuOTAyIDIuNjQ2LjQ3NiAxNS4xNjEgMy4wMDMgMTYuNzg2IDEuMzIuODQ5IDcuNjMtMy4yMDggMTAuOTI2LTYuMDA1LjUzMi43NDkgMS4zODggMS4xNzggMy4xNDggMS4xMzcgMi42NjItLjA2MiA2Ljk3OS0uNjgxIDcuNjQ5LTEuOTIxLjA0LS4wNzUuMDc1LS4xNjQuMTA1LS4yNjYgMy4zODggMS4yNjYgOS4zNSAyLjYwNiAxMC42ODIgMi40MDYgMy40Ny0uNTIxLS40ODQtMTYuNzIzLTIuMDktMTcuNDY3eiIgZmlsbD0iIzNjYTgyYiIvPgogICAgPHBhdGggZD0ibTc0LjQ5IDk3LjA5N2MuMTQ0LjI1Ni4yNi41MjYuMzU4LjguNDgzIDEuMzUyIDEuMjcgNS42NDguNjc0IDYuNzA5LS41OTUgMS4wNjItNC40NTkgMS41NzQtNi44NDMgMS42MTVzLTIuOTItLjgzMS0zLjQwMy0yLjE4MWMtLjM4Ny0xLjA4MS0uNTc3LTMuNjIxLS41NzItNS4wNzUtLjA5OC0yLjE1OC42OS0yLjkxNiA0LjMzNC0zLjUwNiAyLjY5Ni0uNDM2IDQuMTIxLjA3MSA0Ljk0NC45NCAzLjgyOC0yLjg1NyAxMC4yMTUtNi44ODkgMTAuODM4LTYuMTUyIDMuMTA2IDMuNjc0IDMuNDk5IDEyLjQyIDIuODI2IDE1LjkzOS0uMjIgMS4xNTEtMTAuNTA1LTEuMTM5LTEwLjUwNS0yLjM4IDAtNS4xNTItMS4zMzctNi41NjUtMi42NS02Ljcxem0tMjIuNTMtMS42MDljLjg0My0xLjMzMyA3LjY3NC4zMjUgMTEuNDI0IDEuOTkzIDAgMC0uNzcgMy40OTEuNDU2IDcuNjA0LjM1OSAxLjIwMy04LjYyNyA2LjU1OC05LjggNS42MzctMS4zNTUtMS4wNjUtMy44NS0xMi40MzItMi4wOC0xNS4yMzR6IiBmaWxsPSIjNGNiYTNjIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im01NS4yNjkgNjguNDA2Yy41NTMtMi40MDMgMy4xMjctNi45MzIgMTIuMzIxLTYuODIyIDQuNjQ4LS4wMTkgMTAuNDIyLS4wMDIgMTQuMjUtLjQzNmE1MS4zMTIgNTEuMzEyIDAgMCAwIDEyLjcyNi0zLjA5NWMzLjk4LTEuNTE5IDUuMzkyLTEuMTggNS44ODctLjI3Mi41NDQuOTk5LS4wOTcgMi43MjItMS40ODggNC4zMDktMi42NTYgMy4wMy03LjQzMSA1LjM4LTE1Ljg2NSA2LjA3Ni04LjQzMy42OTgtMTQuMDItMS41NjUtMTYuNDI1IDIuMTE4LTEuMDM4IDEuNTg5LS4yMzYgNS4zMzMgNy45MiA2LjUxMiAxMS4wMiAxLjU5IDIwLjA3Mi0xLjkxNyAyMS4xOS4yMDEgMS4xMTkgMi4xMTgtNS4zMjMgNi40MjgtMTYuMzYyIDYuNTE4cy0xNy45MzQtMy44NjUtMjAuMzc5LTUuODNjLTMuMTAyLTIuNDk1LTQuNDktNi4xMzMtMy43NzUtOS4yNzl6IiBmaWxsPSIjZmMzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KICAgIDxnIGZpbGw9IiMxNDMwN2UiIG9wYWNpdHk9Ii44Ij4KICAgICAgPHBhdGggZD0ibTY5LjMyNyA0Mi4xMjdjLjYxNi0xLjAwOCAxLjk4MS0xLjc4NiA0LjIxNi0xLjc4NiAyLjIzNCAwIDMuMjg1Ljg4OSA0LjAxMyAxLjg4LjE0OC4yMDItLjA3Ni40NC0uMzA2LjM0YTU5Ljg2OSA1OS44NjkgMCAwIDEgLS4xNjgtLjA3M2MtLjgxNy0uMzU3LTEuODItLjc5NS0zLjU0LS44Mi0xLjgzOC0uMDI2LTIuOTk3LjQzNS0zLjcyNy44MzEtLjI0Ni4xMzQtLjYzNC0uMTMzLS40ODgtLjM3MnptLTI1LjE1NyAxLjI5YzIuMTctLjkwNyAzLjg3Ni0uNzkgNS4wODEtLjUwNC4yNTQuMDYuNDMtLjIxMy4yMjctLjM3Ny0uOTM1LS43NTUtMy4wMy0xLjY5Mi01Ljc2LS42NzQtMi40MzcuOTA5LTMuNTg1IDIuNzk2LTMuNTkyIDQuMDM4LS4wMDIuMjkyLjYuMzE3Ljc1Ni4wNy40Mi0uNjcgMS4xMi0xLjY0NiAzLjI4OS0yLjU1M3oiLz4KICAgICAgPHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtNzUuNDQgNTUuOTJhMy40NyAzLjQ3IDAgMCAxIC0zLjQ3NC0zLjQ2MiAzLjQ3IDMuNDcgMCAwIDEgMy40NzUtMy40NiAzLjQ3IDMuNDcgMCAwIDEgMy40NzQgMy40NiAzLjQ3IDMuNDcgMCAwIDEgLTMuNDc1IDMuNDYyem0yLjQ0Ny00LjYwOGEuODk5Ljg5OSAwIDAgMCAtMS43OTkgMGMwIC40OTQuNDA1Ljg5NS45Ljg5NS40OTkgMCAuOS0uNC45LS44OTV6bS0yNS40NjQgMy41NDJhNC4wNDIgNC4wNDIgMCAwIDEgLTQuMDQ5IDQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIC00LjA1LTQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIDQuMDUtNC4wMzcgNC4wNDUgNC4wNDUgMCAwIDEgNC4wNSA0LjAzN3ptLTEuMTkzLTEuMzM4YTEuMDUgMS4wNSAwIDAgMCAtMi4wOTcgMCAxLjA0OCAxLjA0OCAwIDAgMCAyLjA5NyAweiIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8L2c+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im02NCAxMTcuNzVjMjkuNjg1IDAgNTMuNzUtMjQuMDY1IDUzLjc1LTUzLjc1cy0yNC4wNjUtNTMuNzUtNTMuNzUtNTMuNzUtNTMuNzUgMjQuMDY1LTUzLjc1IDUzLjc1IDI0LjA2NSA1My43NSA1My43NSA1My43NXptMCA1YzMyLjQ0NyAwIDU4Ljc1LTI2LjMwMyA1OC43NS01OC43NXMtMjYuMzAzLTU4Ljc1LTU4Ljc1LTU4Ljc1LTU4Ljc1IDI2LjMwMy01OC43NSA1OC43NSAyNi4zMDMgNTguNzUgNTguNzUgNTguNzV6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KPC9zdmc+');\n}\n\n/* Email tooltip specific */\n.tooltip__button--email {\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n font-size: 14px;\n padding: 4px 8px;\n}\n.tooltip__button--email__primary-text {\n font-weight: bold;\n}\n.tooltip__button--email__secondary-text {\n font-size: 12px;\n}\n\n/* Email Protection signup notice */\n:not(.top-autofill) .tooltip--email-signup {\n text-align: left;\n color: #222222;\n padding: 16px 20px;\n width: 380px;\n}\n\n.tooltip--email-signup h1 {\n font-weight: 700;\n font-size: 16px;\n line-height: 1.5;\n margin: 0;\n}\n\n.tooltip--email-signup p {\n font-weight: 400;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.notice-controls {\n display: flex;\n}\n\n.tooltip--email-signup .notice-controls > * {\n border-radius: 8px;\n border: 0;\n cursor: pointer;\n display: inline-block;\n font-family: inherit;\n font-style: normal;\n font-weight: bold;\n padding: 8px 12px;\n text-decoration: none;\n}\n\n.notice-controls .ghost {\n margin-left: 1rem;\n}\n\n.tooltip--email-signup a.primary {\n background: #3969EF;\n color: #fff;\n}\n\n.tooltip--email-signup a.primary:hover,\n.tooltip--email-signup a.primary:focus {\n background: #2b55ca;\n}\n\n.tooltip--email-signup a.primary:active {\n background: #1e42a4;\n}\n\n.tooltip--email-signup button.ghost {\n background: transparent;\n color: #3969EF;\n}\n\n.tooltip--email-signup button.ghost:hover,\n.tooltip--email-signup button.ghost:focus {\n background-color: rgba(0, 0, 0, 0.06);\n color: #2b55ca;\n}\n\n.tooltip--email-signup button.ghost:active {\n background-color: rgba(0, 0, 0, 0.12);\n color: #1e42a4;\n}\n\n.tooltip--email-signup button.close-tooltip {\n background-color: transparent;\n background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMiAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjI5Mjg5NCAwLjY1NjkwN0MwLjY4MzQxOCAwLjI2NjM4MyAxLjMxNjU4IDAuMjY2MzgzIDEuNzA3MTEgMC42NTY5MDdMNiA0Ljk0OThMMTAuMjkyOSAwLjY1NjkwN0MxMC42ODM0IDAuMjY2MzgzIDExLjMxNjYgMC4yNjYzODMgMTEuNzA3MSAwLjY1NjkwN0MxMi4wOTc2IDEuMDQ3NDMgMTIuMDk3NiAxLjY4MDYgMTEuNzA3MSAyLjA3MTEyTDcuNDE0MjEgNi4zNjQwMUwxMS43MDcxIDEwLjY1NjlDMTIuMDk3NiAxMS4wNDc0IDEyLjA5NzYgMTEuNjgwNiAxMS43MDcxIDEyLjA3MTFDMTEuMzE2NiAxMi40NjE2IDEwLjY4MzQgMTIuNDYxNiAxMC4yOTI5IDEyLjA3MTFMNiA3Ljc3ODIzTDEuNzA3MTEgMTIuMDcxMUMxLjMxNjU4IDEyLjQ2MTYgMC42ODM0MTcgMTIuNDYxNiAwLjI5Mjg5MyAxMi4wNzExQy0wLjA5NzYzMTEgMTEuNjgwNiAtMC4wOTc2MzExIDExLjA0NzQgMC4yOTI4OTMgMTAuNjU2OUw0LjU4NTc5IDYuMzY0MDFMMC4yOTI4OTQgMi4wNzExMkMtMC4wOTc2MzA2IDEuNjgwNiAtMC4wOTc2MzA2IDEuMDQ3NDMgMC4yOTI4OTQgMC42NTY5MDdaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjg0Ii8+Cjwvc3ZnPgo=);\n background-position: center center;\n background-repeat: no-repeat;\n border: 0;\n cursor: pointer;\n padding: 16px;\n position: absolute;\n right: 12px;\n top: 12px;\n}\n\n/* Import promotion prompt icon style */\n\n.tooltip__button--credentials-import::before {\n content: \"\";\n background-image: url(data:image/svg+xml;base64,Cjxzdmcgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik03Ljk3MjY5IDkuMDEzN0M3Ljk3MjY5IDUuMTQwMTQgMTEuMTEyOCAyIDE0Ljk4NjQgMkMxOC44NTk5IDIgMjIuMDAwMSA1LjE0MDE0IDIyLjAwMDEgOS4wMTM3QzIyLjAwMDEgOS44MDM5NyAyMS44Njk0IDEwLjU2MzcgMjEuNjI4NCAxMS4yNzI1QzIxLjQ2MDEgMTEuNzY3NiAyMC44NjU2IDExLjkxMzUgMjAuMzk3NyAxMS42OEMxOS45MjIxIDExLjQ0MjggMTkuNjc3OSAxMC44NjQ0IDE5LjgxOTUgMTAuMzUyQzE5LjkzNzIgOS45MjU5OSAyMC4wMDAxIDkuNDc3MTkgMjAuMDAwMSA5LjAxMzdDMjAuMDAwMSA2LjI0NDcxIDE3Ljc1NTQgNCAxNC45ODY0IDRDMTIuMjE3NCA0IDkuOTcyNjkgNi4yNDQ3MSA5Ljk3MjY5IDkuMDEzN0M5Ljk3MjY5IDkuNTU1NCAxMC4wNTgyIDEwLjA3NTIgMTAuMjE1OCAxMC41NjEzQzEwLjMzMTcgMTAuOTE4OCAxMC4yMzc0IDExLjMxMTEgOS45NzE2NSAxMS41NzY4TDMuOTk5OTQgMTcuNTQ4NVYyMC4wMDAyTDYuNDk5OTggMjAuMDAwMlYxOC4zMDAyQzYuNDk5OTggMTcuNzQ3OSA2Ljk0NzcgMTcuMzAwMiA3LjQ5OTk4IDE3LjMwMDJIOS4yMDAwMVYxNS42MDAxQzkuMjAwMDEgMTUuMDQ3OCA5LjY0NzczIDE0LjYwMDEgMTAuMiAxNC42MDAxSDEwLjVDMTEuMjEwNiAxNC41ODcgMTEuNDI1MiAxNS4zMzY5IDExLjMxNTYgMTUuNzMzMUMxMS4xNTY1IDE2LjMwODUgMTEgMTcuMDAxIDExIDE3LjVDMTEgMTcuNzI4NCAxMS4wMTE4IDE3Ljk1NCAxMS4wMzQ4IDE4LjE3NjNDMTAuNzM3OSAxOC44Mzg3IDEwLjA3MjkgMTkuMzAwMiA5LjMgMTkuMzAwMkg4LjQ5OTk4VjIwLjEwMDJDOC40OTk5OCAyMS4xNDk1IDcuNjQ5MzMgMjIuMDAwMiA2LjU5OTk5IDIyLjAwMDJMMi45OTk5NSAyMi4wMDAyQzIuNzM0NzMgMjIuMDAwMiAyLjQ4MDM3IDIxLjg5NDkgMi4yOTI4NCAyMS43MDczQzIuMTA1MyAyMS41MTk4IDEuOTk5OTQgMjEuMjY1NCAxLjk5OTk0IDIxLjAwMDJWMTcuMTM0M0MxLjk5OTk0IDE2Ljg2OTEgMi4xMDUzIDE2LjYxNDcgMi4yOTI4MyAxNi40MjcyTDguMTQ2ODkgMTAuNTczMUM4LjAzMjc5IDEwLjA3MDkgNy45NzI2OSA5LjU0ODgxIDcuOTcyNjkgOS4wMTM3WiIgZmlsbD0iYmxhY2siIC8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTMgOC40OTk4OUMxMyA3LjExOTE4IDE0LjExOTMgNS45OTk4OSAxNS41IDUuOTk5ODlDMTYuODgwNyA1Ljk5OTg5IDE4IDcuMTE5MTggMTggOC40OTk4OUMxOCA5Ljg4MDYgMTYuODgwNyAxMC45OTk5IDE1LjUgMTAuOTk5OUMxNC4xMTkzIDEwLjk5OTkgMTMgOS44ODA2IDEzIDguNDk5ODlaTTE1LjUgNy45OTk4OUMxNS4yMjM5IDcuOTk5ODkgMTUgOC4yMjM3NSAxNSA4LjQ5OTg5QzE1IDguNzc2MDQgMTUuMjIzOSA4Ljk5OTg5IDE1LjUgOC45OTk4OUMxNS43NzYyIDguOTk5ODkgMTYgOC43NzYwNCAxNiA4LjQ5OTg5QzE2IDguMjIzNzUgMTUuNzc2MiA3Ljk5OTg5IDE1LjUgNy45OTk4OVoiIGZpbGw9ImJsYWNrIiAvPgo8cGF0aCBkPSJNMTcgMTVMMTQuNSAxNy41TDE3IDIwIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMjEuNSAxNy41TDE2IDE3LjUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=);\n background-repeat: no-repeat;\n}\n"; -},{}],64:[function(require,module,exports){ +},{}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17491,7 +17626,7 @@ function findEnclosedElements(root, selector) { return shadowElements; } -},{"./Form/matching.js":44,"./constants.js":67,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],65:[function(require,module,exports){ +},{"./Form/matching.js":45,"./constants.js":68,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],66:[function(require,module,exports){ "use strict"; require("./requestIdleCallback.js"); @@ -17522,7 +17657,7 @@ var _autofillUtils = require("./autofill-utils.js"); } })(); -},{"./DeviceInterface.js":23,"./autofill-utils.js":64,"./requestIdleCallback.js":104}],66:[function(require,module,exports){ +},{"./DeviceInterface.js":24,"./autofill-utils.js":65,"./requestIdleCallback.js":105}],67:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17539,6 +17674,10 @@ const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a- * @returns {GlobalConfig} */ function createGlobalConfig(overrides) { + /** + * Defines whether it's one of our desktop apps + * @type {boolean} + */ let isApp = false; let isTopFrame = false; let supportsTopFrame = false; @@ -17608,7 +17747,7 @@ function createGlobalConfig(overrides) { return config; } -},{}],67:[function(require,module,exports){ +},{}],68:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17625,13 +17764,13 @@ const constants = exports.constants = { MAX_FORM_RESCANS: 50 }; -},{}],68:[function(require,module,exports){ +},{}],69:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; +exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAliasCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; var _validatorsZod = require("./validators.zod.js"); var _deviceApi = require("../../../packages/device-api"); /* DO NOT EDIT, this file was generated by scripts/api-call-generator.js */ @@ -17793,9 +17932,19 @@ class StartCredentialsImportFlowCall extends _deviceApi.DeviceApiCall { method = "startCredentialsImportFlow"; } /** - * @extends {DeviceApiCall} + * @extends {DeviceApiCall} */ exports.StartCredentialsImportFlowCall = StartCredentialsImportFlowCall; +class EmailProtectionGetAliasCall extends _deviceApi.DeviceApiCall { + method = "emailProtectionGetAlias"; + id = "emailProtectionGetAliasResponse"; + paramsValidator = _validatorsZod.emailProtectionGetAliasParamsSchema; + resultValidator = _validatorsZod.emailProtectionGetAliasResultSchema; +} +/** + * @extends {DeviceApiCall} + */ +exports.EmailProtectionGetAliasCall = EmailProtectionGetAliasCall; class EmailProtectionStoreUserDataCall extends _deviceApi.DeviceApiCall { method = "emailProtectionStoreUserData"; id = "emailProtectionStoreUserDataResponse"; @@ -17878,13 +18027,13 @@ class ShowInContextEmailProtectionSignupPromptCall extends _deviceApi.DeviceApiC } exports.ShowInContextEmailProtectionSignupPromptCall = ShowInContextEmailProtectionSignupPromptCall; -},{"../../../packages/device-api":12,"./validators.zod.js":69}],69:[function(require,module,exports){ +},{"../../../packages/device-api":12,"./validators.zod.js":70}],70:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; +exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; var _zod = require("zod"); /* DO NOT EDIT, this file was generated by scripts/api-call-generator.js */ // Generated by ts-to-zod @@ -17944,6 +18093,11 @@ const getAliasResultSchema = exports.getAliasResultSchema = _zod.z.object({ alias: _zod.z.string().optional() }) }); +const emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAliasParamsSchema = _zod.z.object({ + requiresUserPermission: _zod.z.boolean(), + shouldConsumeAliasIfProvided: _zod.z.boolean(), + isIncontextSignupAvailable: _zod.z.boolean().optional() +}); const emailProtectionStoreUserDataParamsSchema = exports.emailProtectionStoreUserDataParamsSchema = _zod.z.object({ token: _zod.z.string(), userName: _zod.z.string(), @@ -17998,10 +18152,6 @@ const userPreferencesSchema = exports.userPreferencesSchema = _zod.z.object({ settings: _zod.z.record(_zod.z.unknown()) })) }); -const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = _zod.z.object({ - username: _zod.z.string().optional(), - password: _zod.z.string().optional() -}); const availableInputTypesSchema = exports.availableInputTypesSchema = _zod.z.object({ credentials: _zod.z.object({ username: _zod.z.boolean().optional(), @@ -18034,6 +18184,10 @@ const availableInputTypesSchema = exports.availableInputTypesSchema = _zod.z.obj credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = _zod.z.object({ + username: _zod.z.string().optional(), + password: _zod.z.string().optional() +}); const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.object({ credentials: _zod.z.object({ username: _zod.z.boolean().optional(), @@ -18066,6 +18220,11 @@ const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.o credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ + status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), + credentials: _zod.z.array(credentialsSchema), + availableInputTypes: availableInputTypesSchema +}); const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = _zod.z.object({ inputType_credentials: _zod.z.boolean().optional(), inputType_identities: _zod.z.boolean().optional(), @@ -18101,7 +18260,7 @@ const storeFormDataSchema = exports.storeFormDataSchema = _zod.z.object({ }); const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = _zod.z.object({ type: _zod.z.literal("getAvailableInputTypesResponse").optional(), - success: availableInputTypesSchema, + success: availableInputTypes1Schema, error: genericErrorSchema.optional() }); const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = _zod.z.object({ @@ -18124,9 +18283,25 @@ const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultS }).optional(), error: genericErrorSchema.optional() }); +const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = _zod.z.object({ + type: _zod.z.literal("askToUnlockProviderResponse").optional(), + success: providerStatusUpdatedSchema, + error: genericErrorSchema.optional() +}); +const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = _zod.z.object({ + type: _zod.z.literal("checkCredentialsProviderStatusResponse").optional(), + success: providerStatusUpdatedSchema, + error: genericErrorSchema.optional() +}); const autofillSettingsSchema = exports.autofillSettingsSchema = _zod.z.object({ featureToggles: autofillFeatureTogglesSchema }); +const emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasResultSchema = _zod.z.object({ + success: _zod.z.object({ + alias: _zod.z.string() + }).optional(), + error: genericErrorSchema.optional() +}); const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = _zod.z.object({ success: _zod.z.boolean().optional(), error: genericErrorSchema.optional() @@ -18164,28 +18339,14 @@ const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtection const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = _zod.z.object({ contentScope: contentScopeSchema, userUnprotectedDomains: _zod.z.array(_zod.z.string()), - userPreferences: userPreferencesSchema -}); -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ - status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), - credentials: _zod.z.array(credentialsSchema), - availableInputTypes: availableInputTypes1Schema + userPreferences: userPreferencesSchema, + availableInputTypes: availableInputTypesSchema.optional() }); const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = _zod.z.object({ type: _zod.z.literal("getRuntimeConfigurationResponse").optional(), success: runtimeConfigurationSchema.optional(), error: genericErrorSchema.optional() }); -const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = _zod.z.object({ - type: _zod.z.literal("askToUnlockProviderResponse").optional(), - success: providerStatusUpdatedSchema, - error: genericErrorSchema.optional() -}); -const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = _zod.z.object({ - type: _zod.z.literal("checkCredentialsProviderStatusResponse").optional(), - success: providerStatusUpdatedSchema, - error: genericErrorSchema.optional() -}); const apiSchema = exports.apiSchema = _zod.z.object({ addDebugFlag: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ paramsValidator: addDebugFlagParamsSchema.optional() @@ -18253,6 +18414,11 @@ const apiSchema = exports.apiSchema = _zod.z.object({ openManageCreditCards: _zod.z.record(_zod.z.unknown()).optional(), openManageIdentities: _zod.z.record(_zod.z.unknown()).optional(), startCredentialsImportFlow: _zod.z.record(_zod.z.unknown()).optional(), + emailProtectionGetAlias: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ + id: _zod.z.literal("emailProtectionGetAliasResponse").optional(), + paramsValidator: emailProtectionGetAliasParamsSchema.optional(), + resultValidator: emailProtectionGetAliasResultSchema.optional() + })).optional(), emailProtectionStoreUserData: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ id: _zod.z.literal("emailProtectionStoreUserDataResponse").optional(), paramsValidator: emailProtectionStoreUserDataParamsSchema.optional() @@ -18286,7 +18452,7 @@ const apiSchema = exports.apiSchema = _zod.z.object({ })).optional() }); -},{"zod":9}],70:[function(require,module,exports){ +},{"zod":9}],71:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18312,7 +18478,7 @@ class GetAlias extends _index.DeviceApiCall { } exports.GetAlias = GetAlias; -},{"../../packages/device-api/index.js":12,"./__generated__/validators.zod.js":69}],71:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"./__generated__/validators.zod.js":70}],72:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18320,7 +18486,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.AndroidTransport = void 0; var _index = require("../../../packages/device-api/index.js"); -var _deviceApiCalls = require("../__generated__/deviceApiCalls.js"); +var _messaging = require("../../../packages/messaging/messaging.js"); +var _android = require("../../../packages/messaging/android.js"); class AndroidTransport extends _index.DeviceApiTransport { /** @type {GlobalConfig} */ config; @@ -18329,133 +18496,39 @@ class AndroidTransport extends _index.DeviceApiTransport { constructor(globalConfig) { super(); this.config = globalConfig; - if (this.config.isDDGTestMode) { - if (typeof window.BrowserAutofill?.getAutofillData !== 'function') { - console.warn('window.BrowserAutofill.getAutofillData missing'); - } - if (typeof window.BrowserAutofill?.storeFormData !== 'function') { - console.warn('window.BrowserAutofill.storeFormData missing'); - } - } + const messageHandlerNames = ['EmailProtectionStoreUserData', 'EmailProtectionRemoveUserData', 'EmailProtectionGetUserData', 'EmailProtectionGetCapabilities', 'EmailProtectionGetAlias', 'SetIncontextSignupPermanentlyDismissedAt', 'StartEmailProtectionSignup', 'CloseEmailProtectionTab', 'ShowInContextEmailProtectionSignupPrompt', 'StoreFormData', 'GetIncontextSignupDismissedAt', 'GetRuntimeConfiguration', 'GetAutofillData']; + const androidMessagingConfig = new _android.AndroidMessagingConfig({ + messageHandlerNames + }); + this.messaging = new _messaging.Messaging(androidMessagingConfig); } /** * @param {import("../../../packages/device-api").DeviceApiCall} deviceApiCall * @returns {Promise} */ async send(deviceApiCall) { - if (deviceApiCall instanceof _deviceApiCalls.GetRuntimeConfigurationCall) { - return androidSpecificRuntimeConfiguration(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAvailableInputTypesCall) { - return androidSpecificAvailableInputTypes(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetIncontextSignupDismissedAtCall) { - window.BrowserAutofill.getIncontextSignupDismissedAt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.SetIncontextSignupPermanentlyDismissedAtCall) { - return window.BrowserAutofill.setIncontextSignupPermanentlyDismissedAt(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.StartEmailProtectionSignupCall) { - return window.BrowserAutofill.startEmailProtectionSignup(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.CloseEmailProtectionTabCall) { - return window.BrowserAutofill.closeEmailProtectionTab(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall) { - window.BrowserAutofill.showInContextEmailProtectionSignupPrompt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAutofillDataCall) { - window.BrowserAutofill.getAutofillData(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.StoreFormDataCall) { - return window.BrowserAutofill.storeFormData(JSON.stringify(deviceApiCall.params)); - } - throw new Error('android: not implemented: ' + deviceApiCall.method); - } -} - -/** - * @param {string} expectedResponse - the name/id of the response - * @param {GlobalConfig} config - * @returns {Promise<*>} - */ -exports.AndroidTransport = AndroidTransport; -function waitForResponse(expectedResponse, config) { - return new Promise(resolve => { - const handler = e => { - if (!config.isDDGTestMode) { - if (e.origin !== '') { - return; - } - } - if (!e.data) { - return; - } - if (typeof e.data !== 'string') { - if (config.isDDGTestMode) { - console.log('❌ event.data was not a string. Expected a string so that it can be JSON parsed'); - } - return; + try { + // if the call has an `id`, it means that it expects a response + if (deviceApiCall.id) { + return await this.messaging.request(deviceApiCall.method, deviceApiCall.params || undefined); + } else { + return this.messaging.notify(deviceApiCall.method, deviceApiCall.params || undefined); } - try { - let data = JSON.parse(e.data); - if (data.type === expectedResponse) { - window.removeEventListener('message', handler); - return resolve(data); - } - if (config.isDDGTestMode) { - console.log(`❌ event.data.type was '${data.type}', which didnt match '${expectedResponse}'`, JSON.stringify(data)); - } - } catch (e) { - window.removeEventListener('message', handler); - if (config.isDDGTestMode) { - console.log('❌ Could not JSON.parse the response'); + } catch (e) { + if (e instanceof _messaging.MissingHandler) { + if (this.config.isDDGTestMode) { + console.log('MissingAndroidHandler error for:', deviceApiCall.method); } + throw new Error('unimplemented handler: ' + deviceApiCall.method); + } else { + throw e; } - }; - window.addEventListener('message', handler); - }); -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').RuntimeConfiguration}} - */ -function androidSpecificRuntimeConfiguration(globalConfig) { - if (!globalConfig.userPreferences) { - throw new Error('globalConfig.userPreferences not supported yet on Android'); - } - return { - success: { - // @ts-ignore - contentScope: globalConfig.contentScope, - // @ts-ignore - userPreferences: globalConfig.userPreferences, - // @ts-ignore - userUnprotectedDomains: globalConfig.userUnprotectedDomains, - // @ts-ignore - availableInputTypes: globalConfig.availableInputTypes } - }; -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').AvailableInputTypes}} - */ -function androidSpecificAvailableInputTypes(globalConfig) { - if (!globalConfig.availableInputTypes) { - throw new Error('globalConfig.availableInputTypes not supported yet on Android'); } - return { - success: globalConfig.availableInputTypes - }; } +exports.AndroidTransport = AndroidTransport; -},{"../../../packages/device-api/index.js":12,"../__generated__/deviceApiCalls.js":68}],72:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12,"../../../packages/messaging/android.js":15,"../../../packages/messaging/messaging.js":16}],73:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18498,7 +18571,7 @@ class AppleTransport extends _index.DeviceApiTransport { } exports.AppleTransport = AppleTransport; -},{"../../../packages/device-api/index.js":12,"../../../packages/messaging/messaging.js":15}],73:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12,"../../../packages/messaging/messaging.js":16}],74:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18652,7 +18725,7 @@ async function extensionSpecificSetIncontextSignupPermanentlyDismissedAtCall(par }); } -},{"../../../packages/device-api/index.js":12,"../../Settings.js":51,"../../autofill-utils.js":64,"../__generated__/deviceApiCalls.js":68}],74:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12,"../../Settings.js":52,"../../autofill-utils.js":65,"../__generated__/deviceApiCalls.js":69}],75:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18696,7 +18769,7 @@ function createTransport(globalConfig) { return new _extensionTransport.ExtensionTransport(globalConfig); } -},{"./android.transport.js":71,"./apple.transport.js":72,"./extension.transport.js":73,"./windows.transport.js":75}],75:[function(require,module,exports){ +},{"./android.transport.js":72,"./apple.transport.js":73,"./extension.transport.js":74,"./windows.transport.js":76}],76:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18781,7 +18854,7 @@ function waitForWindowsResponse(responseId, options) { }); } -},{"../../../packages/device-api/index.js":12}],76:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12}],77:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -18882,7 +18955,7 @@ module.exports={ } } -},{}],77:[function(require,module,exports){ +},{}],78:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -18983,7 +19056,7 @@ module.exports={ } } -},{}],78:[function(require,module,exports){ +},{}],79:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19084,7 +19157,7 @@ module.exports={ } } -},{}],79:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19185,7 +19258,7 @@ module.exports={ } } -},{}],80:[function(require,module,exports){ +},{}],81:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19286,7 +19359,7 @@ module.exports={ } } -},{}],81:[function(require,module,exports){ +},{}],82:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -19388,7 +19461,7 @@ module.exports={ } } -},{}],82:[function(require,module,exports){ +},{}],83:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19489,7 +19562,7 @@ module.exports={ } } -},{}],83:[function(require,module,exports){ +},{}],84:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19590,7 +19663,7 @@ module.exports={ } } -},{}],84:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19691,7 +19764,7 @@ module.exports={ } } -},{}],85:[function(require,module,exports){ +},{}],86:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19792,7 +19865,7 @@ module.exports={ } } -},{}],86:[function(require,module,exports){ +},{}],87:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19893,7 +19966,7 @@ module.exports={ } } -},{}],87:[function(require,module,exports){ +},{}],88:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19994,7 +20067,7 @@ module.exports={ } } -},{}],88:[function(require,module,exports){ +},{}],89:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20095,7 +20168,7 @@ module.exports={ } } -},{}],89:[function(require,module,exports){ +},{}],90:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20196,7 +20269,7 @@ module.exports={ } } -},{}],90:[function(require,module,exports){ +},{}],91:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20297,7 +20370,7 @@ module.exports={ } } -},{}],91:[function(require,module,exports){ +},{}],92:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20398,7 +20471,7 @@ module.exports={ } } -},{}],92:[function(require,module,exports){ +},{}],93:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20499,7 +20572,7 @@ module.exports={ } } -},{}],93:[function(require,module,exports){ +},{}],94:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20600,7 +20673,7 @@ module.exports={ } } -},{}],94:[function(require,module,exports){ +},{}],95:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20701,7 +20774,7 @@ module.exports={ } } -},{}],95:[function(require,module,exports){ +},{}],96:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20802,7 +20875,7 @@ module.exports={ } } -},{}],96:[function(require,module,exports){ +},{}],97:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20903,7 +20976,7 @@ module.exports={ } } -},{}],97:[function(require,module,exports){ +},{}],98:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21004,7 +21077,7 @@ module.exports={ } } -},{}],98:[function(require,module,exports){ +},{}],99:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21105,7 +21178,7 @@ module.exports={ } } -},{}],99:[function(require,module,exports){ +},{}],100:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -21193,7 +21266,7 @@ function translateImpl(library, namespacedId, opts) { return out; } -},{"./translations.js":102}],100:[function(require,module,exports){ +},{"./translations.js":103}],101:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21294,7 +21367,7 @@ module.exports={ } } -},{}],101:[function(require,module,exports){ +},{}],102:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21395,7 +21468,7 @@ module.exports={ } } -},{}],102:[function(require,module,exports){ +},{}],103:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -21514,7 +21587,7 @@ var _default = exports.default = { } }; -},{"./bg/autofill.json":76,"./cs/autofill.json":77,"./da/autofill.json":78,"./de/autofill.json":79,"./el/autofill.json":80,"./en/autofill.json":81,"./es/autofill.json":82,"./et/autofill.json":83,"./fi/autofill.json":84,"./fr/autofill.json":85,"./hr/autofill.json":86,"./hu/autofill.json":87,"./it/autofill.json":88,"./lt/autofill.json":89,"./lv/autofill.json":90,"./nb/autofill.json":91,"./nl/autofill.json":92,"./pl/autofill.json":93,"./pt/autofill.json":94,"./ro/autofill.json":95,"./ru/autofill.json":96,"./sk/autofill.json":97,"./sl/autofill.json":98,"./sv/autofill.json":100,"./tr/autofill.json":101,"./xa/autofill.json":103}],103:[function(require,module,exports){ +},{"./bg/autofill.json":77,"./cs/autofill.json":78,"./da/autofill.json":79,"./de/autofill.json":80,"./el/autofill.json":81,"./en/autofill.json":82,"./es/autofill.json":83,"./et/autofill.json":84,"./fi/autofill.json":85,"./fr/autofill.json":86,"./hr/autofill.json":87,"./hu/autofill.json":88,"./it/autofill.json":89,"./lt/autofill.json":90,"./lv/autofill.json":91,"./nb/autofill.json":92,"./nl/autofill.json":93,"./pl/autofill.json":94,"./pt/autofill.json":95,"./ro/autofill.json":96,"./ru/autofill.json":97,"./sk/autofill.json":98,"./sl/autofill.json":99,"./sv/autofill.json":101,"./tr/autofill.json":102,"./xa/autofill.json":104}],104:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -21607,7 +21680,7 @@ module.exports={ "note": "Button that prevents the DuckDuckGo email protection signup prompt from appearing again." } } -},{}],104:[function(require,module,exports){ +},{}],105:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -21650,4 +21723,4 @@ window.cancelIdleCallback = window.cancelIdleCallback || function (id) { }; var _default = exports.default = {}; -},{}]},{},[65]); +},{}]},{},[66]); diff --git a/dist/autofill.js b/dist/autofill.js index 7b2e5f08e..e07247a53 100644 --- a/dist/autofill.js +++ b/dist/autofill.js @@ -425,6 +425,130 @@ exports.DeviceApi = DeviceApi; },{}],5:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidMessagingTransport = exports.AndroidMessagingConfig = void 0; +var _messaging = require("./messaging.js"); +/** + * @module Android Messaging + * + * @description A wrapper for messaging on Android. See example usage in android.transport.js + */ + +/** + * @typedef {import("./messaging").MessagingTransport} MessagingTransport + */ + +/** + * On Android, handlers are added to the window object and are prefixed with `ddg`. The object looks like this: + * + * ```typescript + * { + * onMessage: undefined, + * postMessage: (message) => void, + * addEventListener: (eventType: string, Function) => void, + * removeEventListener: (eventType: string, Function) => void + * } + * ``` + * + * You send messages to `postMessage` and listen with `addEventListener`. Once the event is received, + * we also remove the listener with `removeEventListener`. + * + * @link https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener) + * @implements {MessagingTransport} + */ +class AndroidMessagingTransport { + /** @type {AndroidMessagingConfig} */ + config; + globals = { + capturedHandlers: {} + }; + /** + * @param {AndroidMessagingConfig} config + */ + constructor(config) { + this.config = config; + } + + /** + * Given the method name, returns the related Android handler + * @param {string} methodName + * @returns {AndroidHandler} + * @private + */ + _getHandler(methodName) { + const androidSpecificName = this._getHandlerName(methodName); + if (!(androidSpecificName in window)) { + throw new _messaging.MissingHandler(`Missing android handler: '${methodName}'`, methodName); + } + return window[androidSpecificName]; + } + + /** + * Given the autofill method name, it returns the Android-specific handler name + * @param {string} internalName + * @returns {string} + * @private + */ + _getHandlerName(internalName) { + return 'ddg' + internalName[0].toUpperCase() + internalName.slice(1); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + notify(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const handler = this._getHandler(name); + const message = data ? JSON.stringify(data) : ''; + handler.postMessage(message); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + async request(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + // Set up the listener first + const handler = this._getHandler(name); + const responseOnce = new Promise(resolve => { + const responseHandler = e => { + handler.removeEventListener('message', responseHandler); + resolve(e.data); + }; + handler.addEventListener('message', responseHandler); + }); + + // Then send the message + this.notify(name, data); + + // And return once the promise resolves + const responseJSON = await responseOnce; + return JSON.parse(responseJSON); + } +} + +/** + * Use this configuration to create an instance of {@link Messaging} for Android + */ +exports.AndroidMessagingTransport = AndroidMessagingTransport; +class AndroidMessagingConfig { + /** + * All the expected Android handler names + * @param {{messageHandlerNames: string[]}} config + */ + constructor(config) { + this.messageHandlerNames = config.messageHandlerNames; + } +} +exports.AndroidMessagingConfig = AndroidMessagingConfig; + +},{"./messaging.js":6}],6:[function(require,module,exports){ +"use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); @@ -436,6 +560,7 @@ Object.defineProperty(exports, "WebkitMessagingConfig", { } }); var _webkit = require("./webkit.js"); +var _android = require("./android.js"); /** * @module Messaging * @@ -494,7 +619,7 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config */ constructor(config) { this.transport = getTransport(config); @@ -566,7 +691,7 @@ class MessagingTransport { } /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config * @returns {MessagingTransport} */ exports.MessagingTransport = MessagingTransport; @@ -574,6 +699,9 @@ function getTransport(config) { if (config instanceof _webkit.WebkitMessagingConfig) { return new _webkit.WebkitMessagingTransport(config); } + if (config instanceof _android.AndroidMessagingConfig) { + return new _android.AndroidMessagingTransport(config); + } throw new Error('unreachable'); } @@ -596,7 +724,7 @@ class MissingHandler extends Error { */ exports.MissingHandler = MissingHandler; -},{"./webkit.js":6}],6:[function(require,module,exports){ +},{"./android.js":5,"./webkit.js":7}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -991,7 +1119,7 @@ function captureGlobals() { }; } -},{"./messaging.js":5}],7:[function(require,module,exports){ +},{"./messaging.js":6}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1122,7 +1250,7 @@ function _safeHostname(inputHostname) { } } -},{"./lib/apple.password.js":8,"./lib/constants.js":9,"./lib/rules-parser.js":10}],8:[function(require,module,exports){ +},{"./lib/apple.password.js":9,"./lib/constants.js":10,"./lib/rules-parser.js":11}],9:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1651,7 +1779,7 @@ class Password { } exports.Password = Password; -},{"./constants.js":9,"./rules-parser.js":10}],9:[function(require,module,exports){ +},{"./constants.js":10,"./rules-parser.js":11}],10:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1671,7 +1799,7 @@ const constants = exports.constants = { DEFAULT_UNAMBIGUOUS_CHARS }; -},{}],10:[function(require,module,exports){ +},{}],11:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -2267,7 +2395,7 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return newPasswordRules; } -},{}],11:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ module.exports={ "163.com": { "password-rules": "minlength: 6; maxlength: 16;" @@ -3299,7 +3427,7 @@ module.exports={ "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 6; required: lower; required: upper; required: digit;" } } -},{}],12:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3363,7 +3491,7 @@ class CredentialsImport { } exports.CredentialsImport = CredentialsImport; -},{"./deviceApiCalls/__generated__/deviceApiCalls.js":58}],13:[function(require,module,exports){ +},{"./deviceApiCalls/__generated__/deviceApiCalls.js":59}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3419,7 +3547,7 @@ function createDevice() { return new _ExtensionInterface.ExtensionInterface(globalConfig, deviceApi, settings); } -},{"../packages/device-api/index.js":2,"./DeviceInterface/AndroidInterface.js":14,"./DeviceInterface/AppleDeviceInterface.js":15,"./DeviceInterface/AppleOverlayDeviceInterface.js":16,"./DeviceInterface/ExtensionInterface.js":17,"./DeviceInterface/WindowsInterface.js":19,"./DeviceInterface/WindowsOverlayDeviceInterface.js":20,"./Settings.js":41,"./config.js":56,"./deviceApiCalls/transports/transports.js":64}],14:[function(require,module,exports){ +},{"../packages/device-api/index.js":2,"./DeviceInterface/AndroidInterface.js":15,"./DeviceInterface/AppleDeviceInterface.js":16,"./DeviceInterface/AppleOverlayDeviceInterface.js":17,"./DeviceInterface/ExtensionInterface.js":18,"./DeviceInterface/WindowsInterface.js":20,"./DeviceInterface/WindowsOverlayDeviceInterface.js":21,"./Settings.js":42,"./config.js":57,"./deviceApiCalls/transports/transports.js":65}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3439,25 +3567,35 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {Promise} */ async getAlias() { - const { - alias - } = await (0, _autofillUtils.sendAndWaitForAnswer)(async () => { - if (this.inContextSignup.isAvailable()) { - const { - isSignedIn - } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + // If in-context signup is available, do that first + if (this.inContextSignup.isAvailable()) { + const { + isSignedIn + } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + if (isSignedIn) { // On Android we can't get the input type data again without // refreshing the page, so instead we can mutate it now that we // know the user has Email Protection available. - if (this.globalConfig.availableInputTypes) { - this.globalConfig.availableInputTypes.email = isSignedIn; + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: isSignedIn + }); } this.updateForStateChange(); this.onFinishedAutofill(); } - return window.EmailInterface.showTooltip(); - }, 'getAliasResponse'); - return alias; + } + // Then, if successful actually prompt to fill + if (this.settings.availableInputTypes.email) { + const { + alias + } = await this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetAliasCall({ + requiresUserPermission: !this.globalConfig.isApp, + shouldConsumeAliasIfProvided: !this.globalConfig.isApp, + isIncontextSignupAvailable: this.inContextSignup.isAvailable() + })); + return alias ? (0, _autofillUtils.formatDuckAddress)(alias) : undefined; + } } /** @@ -3472,14 +3610,9 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {boolean} */ isDeviceSignedIn() { - // on DDG domains, always check via `window.EmailInterface.isSignedIn()` - if (this.globalConfig.isDDGDomain) { - return window.EmailInterface.isSignedIn() === 'true'; - } - // on non-DDG domains, where `availableInputTypes.email` is present, use it - if (typeof this.globalConfig.availableInputTypes?.email === 'boolean') { - return this.globalConfig.availableInputTypes.email; + if (typeof this.settings.availableInputTypes?.email === 'boolean') { + return this.settings.availableInputTypes.email; } // ...on other domains we assume true because the script wouldn't exist otherwise @@ -3494,15 +3627,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Settings page displays data of the logged in user data */ getUserData() { - let userData = null; - try { - userData = JSON.parse(window.EmailInterface.getUserData()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(userData); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetUserDataCall({})); } /** @@ -3510,25 +3635,13 @@ class AndroidInterface extends _InterfacePrototype.default { * Device capabilities determine which functionality is available to the user */ getEmailProtectionCapabilities() { - let deviceCapabilities = null; - try { - deviceCapabilities = JSON.parse(window.EmailInterface.getDeviceCapabilities()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(deviceCapabilities); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetCapabilitiesCall({})); } storeUserData(_ref) { let { - addUserData: { - token, - userName, - cohort - } + addUserData } = _ref; - return window.EmailInterface.storeCredentials(token, userName, cohort); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionStoreUserDataCall(addUserData)); } /** @@ -3536,13 +3649,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Provides functionality to log the user out */ removeUserData() { - try { - return window.EmailInterface.removeCredentials(); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionRemoveUserDataCall({})); } /** @@ -3567,7 +3674,7 @@ class AndroidInterface extends _InterfacePrototype.default { } exports.AndroidInterface = AndroidInterface; -},{"../InContextSignup.js":35,"../UI/controllers/NativeUIController.js":49,"../autofill-utils.js":54,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./InterfacePrototype.js":18}],15:[function(require,module,exports){ +},{"../InContextSignup.js":36,"../UI/controllers/NativeUIController.js":50,"../autofill-utils.js":55,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./InterfacePrototype.js":19}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3923,7 +4030,7 @@ class AppleDeviceInterface extends _InterfacePrototype.default { } exports.AppleDeviceInterface = AppleDeviceInterface; -},{"../../packages/device-api/index.js":2,"../Form/matching.js":34,"../InContextSignup.js":35,"../ThirdPartyProvider.js":42,"../UI/HTMLTooltip.js":47,"../UI/controllers/HTMLTooltipUIController.js":48,"../UI/controllers/NativeUIController.js":49,"../UI/controllers/OverlayUIController.js":50,"../autofill-utils.js":54,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"../deviceApiCalls/additionalDeviceApiCalls.js":60,"./InterfacePrototype.js":18}],16:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"../Form/matching.js":35,"../InContextSignup.js":36,"../ThirdPartyProvider.js":43,"../UI/HTMLTooltip.js":48,"../UI/controllers/HTMLTooltipUIController.js":49,"../UI/controllers/NativeUIController.js":50,"../UI/controllers/OverlayUIController.js":51,"../autofill-utils.js":55,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"../deviceApiCalls/additionalDeviceApiCalls.js":61,"./InterfacePrototype.js":19}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4042,7 +4149,7 @@ class AppleOverlayDeviceInterface extends _AppleDeviceInterface.AppleDeviceInter } exports.AppleOverlayDeviceInterface = AppleOverlayDeviceInterface; -},{"../../packages/device-api/index.js":2,"../UI/controllers/HTMLTooltipUIController.js":48,"./AppleDeviceInterface.js":15,"./overlayApi.js":22}],17:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"../UI/controllers/HTMLTooltipUIController.js":49,"./AppleDeviceInterface.js":16,"./overlayApi.js":23}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4261,7 +4368,7 @@ class ExtensionInterface extends _InterfacePrototype.default { } exports.ExtensionInterface = ExtensionInterface; -},{"../Form/matching.js":34,"../InContextSignup.js":35,"../UI/HTMLTooltip.js":47,"../UI/controllers/HTMLTooltipUIController.js":48,"../autofill-utils.js":54,"./InterfacePrototype.js":18}],18:[function(require,module,exports){ +},{"../Form/matching.js":35,"../InContextSignup.js":36,"../UI/HTMLTooltip.js":48,"../UI/controllers/HTMLTooltipUIController.js":49,"../autofill-utils.js":55,"./InterfacePrototype.js":19}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4864,11 +4971,19 @@ class InterfacePrototype { let userData; try { userData = await this.getUserData(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('getUserData failed with', e); + } + } let capabilities; try { capabilities = await this.getEmailProtectionCapabilities(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('capabilities fetching failed with', e); + } + } // Set up listener for web app actions if (this.globalConfig.isDDGDomain) { @@ -4924,6 +5039,13 @@ class InterfacePrototype { const data = await (0, _autofillUtils.sendAndWaitForAnswer)(_autofillUtils.SIGN_IN_MSG, 'addUserData'); // This call doesn't send a response, so we can't know if it succeeded this.storeUserData(data); + + // Assuming the previous call succeeded, let's update availableInputTypes + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: true + }); + } await this.setupAutofill(); await this.settings.refresh(); await this.setupSettingsPage({ @@ -5092,7 +5214,7 @@ class InterfacePrototype { } var _default = exports.default = InterfacePrototype; -},{"../../packages/device-api/index.js":2,"../CredentialsImport.js":12,"../EmailProtection.js":23,"../Form/formatters.js":27,"../Form/matching.js":34,"../InputTypes/Credentials.js":36,"../PasswordGenerator.js":39,"../Scanner.js":40,"../Settings.js":41,"../UI/controllers/NativeUIController.js":49,"../autofill-utils.js":54,"../config.js":56,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"../deviceApiCalls/transports/transports.js":64,"../locales/strings.js":89,"./initFormSubmissionsApi.js":21}],19:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"../CredentialsImport.js":13,"../EmailProtection.js":24,"../Form/formatters.js":28,"../Form/matching.js":35,"../InputTypes/Credentials.js":37,"../PasswordGenerator.js":40,"../Scanner.js":41,"../Settings.js":42,"../UI/controllers/NativeUIController.js":50,"../autofill-utils.js":55,"../config.js":57,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"../deviceApiCalls/transports/transports.js":65,"../locales/strings.js":90,"./initFormSubmissionsApi.js":22}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5177,13 +5299,13 @@ class WindowsInterface extends _InterfacePrototype.default { return await this.credentialsImport.refresh(); } default: - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { console.warn('unhandled response', resp); } return this._closeAutofillParent(); } } catch (e) { - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { if (e instanceof DOMException && e.name === 'AbortError') { console.log('Promise Aborted'); } else { @@ -5258,7 +5380,7 @@ class WindowsInterface extends _InterfacePrototype.default { } exports.WindowsInterface = WindowsInterface; -},{"../UI/controllers/OverlayUIController.js":50,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./InterfacePrototype.js":18}],20:[function(require,module,exports){ +},{"../UI/controllers/OverlayUIController.js":51,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./InterfacePrototype.js":19}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5437,7 +5559,7 @@ class WindowsOverlayDeviceInterface extends _InterfacePrototype.default { } exports.WindowsOverlayDeviceInterface = WindowsOverlayDeviceInterface; -},{"../UI/controllers/HTMLTooltipUIController.js":48,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./InterfacePrototype.js":18,"./overlayApi.js":22}],21:[function(require,module,exports){ +},{"../UI/controllers/HTMLTooltipUIController.js":49,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./InterfacePrototype.js":19,"./overlayApi.js":23}],22:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5536,7 +5658,7 @@ function initFormSubmissionsApi(forms, matching) { }); } -},{"../Form/label-util.js":30,"../autofill-utils.js":54}],22:[function(require,module,exports){ +},{"../Form/label-util.js":31,"../autofill-utils.js":55}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5594,7 +5716,7 @@ function overlayApi(device) { }; } -},{"../deviceApiCalls/__generated__/deviceApiCalls.js":58}],23:[function(require,module,exports){ +},{"../deviceApiCalls/__generated__/deviceApiCalls.js":59}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5629,7 +5751,7 @@ class EmailProtection { } exports.EmailProtection = EmailProtection; -},{}],24:[function(require,module,exports){ +},{}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5769,7 +5891,7 @@ class Form { } submitHandler() { let via = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown'; - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('Form.submitHandler via:', via, this); } if (this.submitHandlerExecuted) return; @@ -6536,7 +6658,7 @@ class Form { } exports.Form = Form; -},{"../InputTypes/Credentials.js":36,"../autofill-utils.js":54,"../constants.js":57,"./FormAnalyzer.js":25,"./formatters.js":27,"./inputStyles.js":28,"./inputTypeConfig.js":29,"./matching.js":34}],25:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":37,"../autofill-utils.js":55,"../constants.js":58,"./FormAnalyzer.js":26,"./formatters.js":28,"./inputStyles.js":29,"./inputTypeConfig.js":30,"./matching.js":35}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -6906,7 +7028,7 @@ class FormAnalyzer { } var _default = exports.default = FormAnalyzer; -},{"../autofill-utils.js":54,"../constants.js":57,"./matching-config/__generated__/compiled-matching-config.js":32,"./matching.js":34}],26:[function(require,module,exports){ +},{"../autofill-utils.js":55,"../constants.js":58,"./matching-config/__generated__/compiled-matching-config.js":33,"./matching.js":35}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7471,7 +7593,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { 'Unknown Region': 'ZZ' }; -},{}],27:[function(require,module,exports){ +},{}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7776,7 +7898,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":26,"./matching.js":34}],28:[function(require,module,exports){ +},{"./countryNames.js":27,"./matching.js":35}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7867,7 +7989,7 @@ const getIconStylesAutofilled = (input, form) => { }; exports.getIconStylesAutofilled = getIconStylesAutofilled; -},{"./inputTypeConfig.js":29}],29:[function(require,module,exports){ +},{"./inputTypeConfig.js":30}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8121,7 +8243,7 @@ const isFieldDecorated = input => { }; exports.isFieldDecorated = isFieldDecorated; -},{"../InputTypes/Credentials.js":36,"../InputTypes/CreditCard.js":37,"../InputTypes/Identity.js":38,"../UI/img/ddgPasswordIcon.js":52,"../constants.js":57,"./logo-svg.js":31,"./matching.js":34}],30:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":37,"../InputTypes/CreditCard.js":38,"../InputTypes/Identity.js":39,"../UI/img/ddgPasswordIcon.js":53,"../constants.js":58,"./logo-svg.js":32,"./matching.js":35}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8169,7 +8291,7 @@ const extractElementStrings = element => { }; exports.extractElementStrings = extractElementStrings; -},{"./matching.js":34}],31:[function(require,module,exports){ +},{"./matching.js":35}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8202,7 +8324,7 @@ const daxGrayscaleSvg = ` `.trim(); const daxGrayscaleBase64 = exports.daxGrayscaleBase64 = `data:image/svg+xml;base64,${window.btoa(daxGrayscaleSvg)}`; -},{}],32:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8655,7 +8777,7 @@ const matchingConfiguration = exports.matchingConfiguration = { } }; -},{}],33:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8730,7 +8852,7 @@ function logUnmatched(el, allStrings) { console.groupEnd(); } -},{"../autofill-utils.js":54,"./matching.js":34}],34:[function(require,module,exports){ +},{"../autofill-utils.js":55,"./matching.js":35}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9722,7 +9844,7 @@ function createMatching() { return new Matching(_compiledMatchingConfig.matchingConfiguration); } -},{"../autofill-utils.js":54,"../constants.js":57,"./label-util.js":30,"./matching-config/__generated__/compiled-matching-config.js":32,"./matching-utils.js":33}],35:[function(require,module,exports){ +},{"../autofill-utils.js":55,"../constants.js":58,"./label-util.js":31,"./matching-config/__generated__/compiled-matching-config.js":33,"./matching-utils.js":34}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9854,7 +9976,7 @@ class InContextSignup { } exports.InContextSignup = InContextSignup; -},{"./autofill-utils.js":54,"./deviceApiCalls/__generated__/deviceApiCalls.js":58}],36:[function(require,module,exports){ +},{"./autofill-utils.js":55,"./deviceApiCalls/__generated__/deviceApiCalls.js":59}],37:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10010,7 +10132,7 @@ function createCredentialsTooltipItem(data) { return new CredentialsTooltipItem(data); } -},{"../autofill-utils.js":54}],37:[function(require,module,exports){ +},{"../autofill-utils.js":55}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10035,7 +10157,7 @@ class CreditCardTooltipItem { } exports.CreditCardTooltipItem = CreditCardTooltipItem; -},{}],38:[function(require,module,exports){ +},{}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10081,7 +10203,7 @@ class IdentityTooltipItem { } exports.IdentityTooltipItem = IdentityTooltipItem; -},{"../Form/formatters.js":27}],39:[function(require,module,exports){ +},{"../Form/formatters.js":28}],40:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10123,7 +10245,7 @@ class PasswordGenerator { } exports.PasswordGenerator = PasswordGenerator; -},{"../packages/password/index.js":7,"../packages/password/rules.json":11}],40:[function(require,module,exports){ +},{"../packages/password/index.js":8,"../packages/password/rules.json":12}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10584,7 +10706,7 @@ function createScanner(device, scannerOptions) { }); } -},{"./Form/Form.js":24,"./Form/matching.js":34,"./autofill-utils.js":54,"./constants.js":57,"./deviceApiCalls/__generated__/deviceApiCalls.js":58}],41:[function(require,module,exports){ +},{"./Form/Form.js":25,"./Form/matching.js":35,"./autofill-utils.js":55,"./constants.js":58,"./deviceApiCalls/__generated__/deviceApiCalls.js":59}],42:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10730,6 +10852,11 @@ class Settings { if (this._runtimeConfiguration) return this._runtimeConfiguration; const runtimeConfig = await this.deviceApi.request(new _deviceApiCalls.GetRuntimeConfigurationCall(null)); this._runtimeConfiguration = runtimeConfig; + + // If the platform sends availableInputTypes here, store them + if (runtimeConfig.availableInputTypes) { + this.setAvailableInputTypes(runtimeConfig.availableInputTypes); + } return this._runtimeConfiguration; } @@ -10745,6 +10872,9 @@ class Settings { if (this.globalConfig.isTopFrame) { return Settings.defaults.availableInputTypes; } + if (this._availableInputTypes) { + return this.availableInputTypes; + } return await this.deviceApi.request(new _deviceApiCalls.GetAvailableInputTypesCall(null)); } catch (e) { if (this.globalConfig.isDDGTestMode) { @@ -10997,7 +11127,7 @@ class Settings { } exports.Settings = Settings; -},{"../packages/device-api/index.js":2,"./autofill-utils.js":54,"./deviceApiCalls/__generated__/deviceApiCalls.js":58,"./deviceApiCalls/__generated__/validators.zod.js":59}],42:[function(require,module,exports){ +},{"../packages/device-api/index.js":2,"./autofill-utils.js":55,"./deviceApiCalls/__generated__/deviceApiCalls.js":59,"./deviceApiCalls/__generated__/validators.zod.js":60}],43:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11064,7 +11194,7 @@ class ThirdPartyProvider { this.device.scanner.forms.forEach(form => form.recategorizeAllInputs()); } } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: providerStatusUpdated error: ❌', e); } } @@ -11079,7 +11209,7 @@ class ThirdPartyProvider { } setTimeout(() => this._pollForUpdatesToCredentialsProvider(), 2000); } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: _pollForUpdatesToCredentialsProvider: ❌', e); } } @@ -11087,7 +11217,7 @@ class ThirdPartyProvider { } exports.ThirdPartyProvider = ThirdPartyProvider; -},{"../packages/device-api/index.js":2,"./Form/matching.js":34,"./deviceApiCalls/__generated__/deviceApiCalls.js":58,"./deviceApiCalls/__generated__/validators.zod.js":59}],43:[function(require,module,exports){ +},{"../packages/device-api/index.js":2,"./Form/matching.js":35,"./deviceApiCalls/__generated__/deviceApiCalls.js":59,"./deviceApiCalls/__generated__/validators.zod.js":60}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11128,7 +11258,7 @@ ${this.options.css} } var _default = exports.default = CredentialsImportTooltip; -},{"./HTMLTooltip.js":47}],44:[function(require,module,exports){ +},{"./HTMLTooltip.js":48}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11279,7 +11409,7 @@ ${css} } var _default = exports.default = DataHTMLTooltip; -},{"../InputTypes/Credentials.js":36,"../autofill-utils.js":54,"./HTMLTooltip.js":47}],45:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":37,"../autofill-utils.js":55,"./HTMLTooltip.js":48}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11361,7 +11491,7 @@ ${this.options.css} } var _default = exports.default = EmailHTMLTooltip; -},{"../autofill-utils.js":54,"./HTMLTooltip.js":47}],46:[function(require,module,exports){ +},{"../autofill-utils.js":55,"./HTMLTooltip.js":48}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11414,7 +11544,7 @@ ${this.options.css} } var _default = exports.default = EmailSignupHTMLTooltip; -},{"./HTMLTooltip.js":47}],47:[function(require,module,exports){ +},{"./HTMLTooltip.js":48}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11802,7 +11932,7 @@ class HTMLTooltip { exports.HTMLTooltip = HTMLTooltip; var _default = exports.default = HTMLTooltip; -},{"../Form/matching.js":34,"../autofill-utils.js":54,"./styles/styles.js":53}],48:[function(require,module,exports){ +},{"../Form/matching.js":35,"../autofill-utils.js":55,"./styles/styles.js":54}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12170,7 +12300,7 @@ class HTMLTooltipUIController extends _UIController.UIController { } exports.HTMLTooltipUIController = HTMLTooltipUIController; -},{"../../Form/inputTypeConfig.js":29,"../../Form/matching.js":34,"../../autofill-utils.js":54,"../CredentialsImportTooltip.js":43,"../DataHTMLTooltip.js":44,"../EmailHTMLTooltip.js":45,"../EmailSignupHTMLTooltip.js":46,"../HTMLTooltip.js":47,"./UIController.js":51}],49:[function(require,module,exports){ +},{"../../Form/inputTypeConfig.js":30,"../../Form/matching.js":35,"../../autofill-utils.js":55,"../CredentialsImportTooltip.js":44,"../DataHTMLTooltip.js":45,"../EmailHTMLTooltip.js":46,"../EmailSignupHTMLTooltip.js":47,"../HTMLTooltip.js":48,"./UIController.js":52}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12272,6 +12402,11 @@ class NativeUIController extends _UIController.UIController { form.activeInput?.focus(); break; } + case 'none': + { + // do nothing + break; + } default: { if (args.device.isTestMode()) { @@ -12332,7 +12467,7 @@ class NativeUIController extends _UIController.UIController { } exports.NativeUIController = NativeUIController; -},{"../../Form/matching.js":34,"../../InputTypes/Credentials.js":36,"../../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./UIController.js":51}],50:[function(require,module,exports){ +},{"../../Form/matching.js":35,"../../InputTypes/Credentials.js":37,"../../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./UIController.js":52}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12569,7 +12704,7 @@ class OverlayUIController extends _UIController.UIController { } exports.OverlayUIController = OverlayUIController; -},{"../../Form/matching.js":34,"./UIController.js":51}],51:[function(require,module,exports){ +},{"../../Form/matching.js":35,"./UIController.js":52}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12653,7 +12788,7 @@ class UIController { } exports.UIController = UIController; -},{}],52:[function(require,module,exports){ +},{}],53:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12670,7 +12805,7 @@ const ddgCcIconBase = exports.ddgCcIconBase = 'data:image/svg+xml;base64,PD94bWw const ddgCcIconFilled = exports.ddgCcIconFilled = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzc2NDMxMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjNzY0MzEwIi8+Cjwvc3ZnPgo='; const ddgIdentityIconBase = exports.ddgIdentityIconBase = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4KPHBhdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJub25lIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyMWMyLjE0MyAwIDQuMTExLS43NSA1LjY1Ny0yLS42MjYtLjUwNi0xLjMxOC0uOTI3LTIuMDYtMS4yNS0xLjEtLjQ4LTIuMjg1LS43MzUtMy40ODYtLjc1LTEuMi0uMDE0LTIuMzkyLjIxMS0zLjUwNC42NjQtLjgxNy4zMzMtMS41OC43ODMtMi4yNjQgMS4zMzYgMS41NDYgMS4yNSAzLjUxNCAyIDUuNjU3IDJ6bTQuMzk3LTUuMDgzYy45NjcuNDIyIDEuODY2Ljk4IDIuNjcyIDEuNjU1QzIwLjI3OSAxNi4wMzkgMjEgMTQuMTA0IDIxIDEyYzAtNC45Ny00LjAzLTktOS05cy05IDQuMDMtOSA5YzAgMi4xMDQuNzIyIDQuMDQgMS45MzIgNS41NzIuODc0LS43MzQgMS44Ni0xLjMyOCAyLjkyMS0xLjc2IDEuMzYtLjU1NCAyLjgxNi0uODMgNC4yODMtLjgxMSAxLjQ2Ny4wMTggMi45MTYuMzMgNC4yNi45MTZ6TTEyIDIzYzYuMDc1IDAgMTEtNC45MjUgMTEtMTFTMTguMDc1IDEgMTIgMSAxIDUuOTI1IDEgMTJzNC45MjUgMTEgMTEgMTF6bTMtMTNjMCAxLjY1Ny0xLjM0MyAzLTMgM3MtMy0xLjM0My0zLTMgMS4zNDMtMyAzLTMgMyAxLjM0MyAzIDN6bTIgMGMwIDIuNzYxLTIuMjM5IDUtNSA1cy01LTIuMjM5LTUtNSAyLjIzOS01IDUtNSA1IDIuMjM5IDUgNXoiIGZpbGw9IiMwMDAiLz4KPC9zdmc+Cg==`; -},{}],53:[function(require,module,exports){ +},{}],54:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12679,7 +12814,7 @@ Object.defineProperty(exports, "__esModule", { exports.CSS_STYLES = void 0; const CSS_STYLES = exports.CSS_STYLES = ":root {\n color-scheme: light dark;\n}\n\n.wrapper *, .wrapper *::before, .wrapper *::after {\n box-sizing: border-box;\n}\n.wrapper {\n position: fixed;\n top: 0;\n left: 0;\n padding: 0;\n font-family: 'DDG_ProximaNova', 'Proxima Nova', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n z-index: 2147483647;\n}\n.wrapper--data {\n font-family: 'SF Pro Text', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n}\n.wrapper:not(.top-autofill) .tooltip {\n position: absolute;\n width: 300px;\n max-width: calc(100vw - 25px);\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--data, #topAutofill {\n background-color: rgba(242, 240, 240, 1);\n -webkit-backdrop-filter: blur(40px);\n backdrop-filter: blur(40px);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data, #topAutofill {\n background: rgb(100, 98, 102, .9);\n }\n}\n.tooltip--data {\n padding: 6px;\n font-size: 13px;\n line-height: 14px;\n width: 315px;\n max-height: 290px;\n overflow-y: auto;\n}\n.top-autofill .tooltip--data {\n min-height: 100vh;\n}\n.tooltip--data.tooltip--incontext-signup {\n width: 360px;\n}\n.wrapper:not(.top-autofill) .tooltip--data {\n top: 100%;\n left: 100%;\n border: 0.5px solid rgba(255, 255, 255, 0.2);\n border-radius: 6px;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.32);\n}\n@media (prefers-color-scheme: dark) {\n .wrapper:not(.top-autofill) .tooltip--data {\n border: 1px solid rgba(255, 255, 255, 0.2);\n }\n}\n.wrapper:not(.top-autofill) .tooltip--email {\n top: calc(100% + 6px);\n right: calc(100% - 48px);\n padding: 8px;\n border: 1px solid #D0D0D0;\n border-radius: 10px;\n background-color: #FFFFFF;\n font-size: 14px;\n line-height: 1.3;\n color: #333333;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);\n}\n.tooltip--email__caret {\n position: absolute;\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--email__caret::before,\n.tooltip--email__caret::after {\n content: \"\";\n width: 0;\n height: 0;\n border-left: 10px solid transparent;\n border-right: 10px solid transparent;\n display: block;\n border-bottom: 8px solid #D0D0D0;\n position: absolute;\n right: -28px;\n}\n.tooltip--email__caret::before {\n border-bottom-color: #D0D0D0;\n top: -1px;\n}\n.tooltip--email__caret::after {\n border-bottom-color: #FFFFFF;\n top: 0px;\n}\n\n/* Buttons */\n.tooltip__button {\n display: flex;\n width: 100%;\n padding: 8px 8px 8px 0px;\n font-family: inherit;\n color: inherit;\n background: transparent;\n border: none;\n border-radius: 6px;\n text-align: left;\n}\n.tooltip__button.currentFocus,\n.wrapper:not(.top-autofill) .tooltip__button:hover {\n background-color: #3969EF;\n color: #FFFFFF;\n}\n\n/* Data autofill tooltip specific */\n.tooltip__button--data {\n position: relative;\n min-height: 48px;\n flex-direction: row;\n justify-content: flex-start;\n font-size: inherit;\n font-weight: 500;\n line-height: 16px;\n text-align: left;\n border-radius: 3px;\n}\n.tooltip--data__item-container {\n max-height: 220px;\n overflow: auto;\n}\n.tooltip__button--data:first-child {\n margin-top: 0;\n}\n.tooltip__button--data:last-child {\n margin-bottom: 0;\n}\n.tooltip__button--data::before {\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 20px 20px;\n background-repeat: no-repeat;\n background-position: center center;\n}\n#provider_locked::after {\n position: absolute;\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 11px 13px;\n background-repeat: no-repeat;\n background-position: right bottom;\n}\n.tooltip__button--data.currentFocus:not(.tooltip__button--data--bitwarden)::before,\n.wrapper:not(.top-autofill) .tooltip__button--data:not(.tooltip__button--data--bitwarden):hover::before {\n filter: invert(100%);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before,\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before {\n filter: invert(100%);\n opacity: .9;\n }\n}\n.tooltip__button__text-container {\n margin: auto 0;\n}\n.label {\n display: block;\n font-weight: 400;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.8);\n font-size: 13px;\n line-height: 1;\n}\n.label + .label {\n margin-top: 2px;\n}\n.label.label--medium {\n font-weight: 500;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.9);\n}\n.label.label--small {\n font-size: 11px;\n font-weight: 400;\n letter-spacing: 0.06px;\n color: rgba(0,0,0,0.6);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data .label {\n color: #ffffff;\n }\n .tooltip--data .label--medium {\n color: #ffffff;\n }\n .tooltip--data .label--small {\n color: #cdcdcd;\n }\n}\n.tooltip__button.currentFocus .label,\n.wrapper:not(.top-autofill) .tooltip__button:hover .label {\n color: #FFFFFF;\n}\n\n.tooltip__button--manage {\n font-size: 13px;\n padding: 5px 9px;\n border-radius: 3px;\n margin: 0;\n}\n\n/* Icons */\n.tooltip__button--data--credentials::before,\n.tooltip__button--data--credentials__current::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS4zMzQgNi42NjdhMiAyIDAgMSAwIDAgNCAyIDIgMCAwIDAgMC00Wm0tLjY2NyAyYS42NjcuNjY3IDAgMSAxIDEuMzMzIDAgLjY2Ny42NjcgMCAwIDEtMS4zMzMgMFoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTQuNjY3IDRhNS4zMzMgNS4zMzMgMCAwIDAtNS4xODggNi41NzhsLTUuMjg0IDUuMjg0YS42NjcuNjY3IDAgMCAwLS4xOTUuNDcxdjNjMCAuMzY5LjI5OC42NjcuNjY3LjY2N2gyLjY2NmMuNzM3IDAgMS4zMzQtLjU5NyAxLjMzNC0xLjMzM1YxOGguNjY2Yy43MzcgMCAxLjMzNC0uNTk3IDEuMzM0LTEuMzMzdi0xLjMzNEgxMmMuMTc3IDAgLjM0Ni0uMDcuNDcxLS4xOTVsLjY4OC0uNjg4QTUuMzMzIDUuMzMzIDAgMSAwIDE0LjY2NyA0Wm0tNCA1LjMzM2E0IDQgMCAxIDEgMi41NTUgMy43MzIuNjY3LjY2NyAwIDAgMC0uNzEzLjE1bC0uNzg1Ljc4NUgxMGEuNjY3LjY2NyAwIDAgMC0uNjY3LjY2N3YySDhhLjY2Ny42NjcgMCAwIDAtLjY2Ny42NjZ2MS4zMzRoLTJ2LTIuMDU4bDUuMzY1LTUuMzY0YS42NjcuNjY3IDAgMCAwIC4xNjMtLjY3NyAzLjk5NiAzLjk5NiAwIDAgMS0uMTk0LTEuMjM1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--credentials__new::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBkPSJNOC4wNDcgNC42MjVDNy45MzcgNC4xMjUgNy44NjIgNCA3LjUgNGMtLjM2MiAwLS40MzguMTI1LS41NDcuNjI1LS4wNjguMzEtLjE3NyAxLjMzOC0uMjUxIDIuMDc3LS43MzguMDc0LTEuNzY3LjE4My0yLjA3Ny4yNTEtLjUuMTEtLjYyNS4xODQtLjYyNS41NDcgMCAuMzYyLjEyNS40MzcuNjI1LjU0Ny4zMS4wNjcgMS4zMzYuMTc3IDIuMDc0LjI1LjA3My43NjcuMTg1IDEuODQyLjI1NCAyLjA3OC4xMS4zNzUuMTg1LjYyNS41NDcuNjI1LjM2MiAwIC40MzgtLjEyNS41NDctLjYyNS4wNjgtLjMxLjE3Ny0xLjMzNi4yNS0yLjA3NC43NjctLjA3MyAxLjg0Mi0uMTg1IDIuMDc4LS4yNTQuMzc1LS4xMS42MjUtLjE4NS42MjUtLjU0NyAwLS4zNjMtLjEyNS0uNDM4LS42MjUtLjU0Ny0uMzEtLjA2OC0xLjMzOS0uMTc3LTIuMDc3LS4yNTEtLjA3NC0uNzM5LS4xODMtMS43NjctLjI1MS0yLjA3N1oiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0xNC42ODEgNS4xOTljLS43NjYgMC0xLjQ4Mi4yMS0yLjA5My41NzhhLjYzNi42MzYgMCAwIDEtLjY1NS0xLjA5IDUuMzQgNS4zNCAwIDEgMSAxLjMwMiA5LjcyMmwtLjc3NS43NzZhLjYzNi42MzYgMCAwIDEtLjQ1LjE4NmgtMS4zOTh2MS42NWMwIC40OTMtLjQuODkzLS44OTMuODkzSDguNTc4djEuMTQxYzAgLjQ5NC0uNC44OTMtLjg5NC44OTNINC42MzZBLjYzNi42MzYgMCAwIDEgNCAxOS4zMTNWMTYuMjZjMC0uMTY5LjA2Ny0uMzMuMTg2LS40NWw1LjU2Mi01LjU2MmEuNjM2LjYzNiAwIDEgMSAuOS45bC01LjM3NiA1LjM3NXYyLjE1M2gyLjAzNHYtMS4zOTljMC0uMzUuMjg1LS42MzYuNjM2LS42MzZIOS4zNHYtMS45MDdjMC0uMzUxLjI4NC0uNjM2LjYzNS0uNjM2aDEuNzcxbC44NjQtLjg2M2EuNjM2LjYzNiAwIDAgMSAuNjY4LS4xNDcgNC4wNjkgNC4wNjkgMCAxIDAgMS40MDItNy44OVoiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTEzLjYyNSA4LjQ5OWExLjg3NSAxLjg3NSAwIDEgMSAzLjc1IDAgMS44NzUgMS44NzUgMCAwIDEtMy43NSAwWm0xLjg3NS0uNjI1YS42MjUuNjI1IDAgMSAwIDAgMS4yNS42MjUuNjI1IDAgMCAwIDAtMS4yNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZD0iTTQuNjI1IDEyLjEyNWEuNjI1LjYyNSAwIDEgMCAwLTEuMjUuNjI1LjYyNSAwIDAgMCAwIDEuMjVaIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--creditCards::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--identities::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4=');\n}\n.tooltip__button--data--credentials.tooltip__button--data--bitwarden::before,\n.tooltip__button--data--credentials__current.tooltip__button--data--bitwarden::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iOCIgZmlsbD0iIzE3NUREQyIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE4LjU2OTYgNS40MzM1NUMxOC41MDg0IDUuMzc0NDIgMTguNDM0NyA1LjMyNzYzIDE4LjM1MzEgNS4yOTYxMUMxOC4yNzE1IDUuMjY0NiAxOC4xODM3IDUuMjQ5MDQgMTguMDk1MyA1LjI1MDQxSDUuOTIxOTFDNS44MzMyNiA1LjI0NzI5IDUuNzQ0OTMgNS4yNjIwNSA1LjY2MzA0IDUuMjkzNjdDNS41ODExNSA1LjMyNTI5IDUuNTA3NjUgNS4zNzMwMiA1LjQ0NzYyIDUuNDMzNTVDNS4zMjE3IDUuNTUwMTMgNS4yNTA2NSA1LjcwODE1IDUuMjUgNS44NzMxVjEzLjM4MjFDNS4yNTMzNiAxMy45NTM1IDUuMzc0MDggMTQuNTE5MSA1LjYwNTcyIDE1LjA0ODdDNS44MTkzMSAxNS41NzI4IDYuMTEyMDcgMTYuMDY2MSA2LjQ3NTI0IDE2LjUxMzlDNi44NDIgMTYuOTY4MyA3LjI1OTI5IDE3LjM4NTcgNy43MjAyNSAxNy43NTkzQzguMTQwNTMgMTguMTI1NiA4LjU4OTcxIDE4LjQ2MjMgOS4wNjQwNyAxOC43NjY2QzkuNDU5MzEgMTkuMDIzIDkuOTEzODMgMTkuMjc5NCAxMC4zNDg2IDE5LjUxNzVDMTAuNzgzNCAxOS43NTU2IDExLjA5OTYgMTkuOTIwNCAxMS4yNzc0IDE5Ljk5MzdDMTEuNDU1MyAyMC4wNjY5IDExLjYxMzQgMjAuMTQwMiAxMS43MTIyIDIwLjE5NTFDMTEuNzk5MiAyMC4yMzEzIDExLjg5MzUgMjAuMjUgMTEuOTg4OCAyMC4yNUMxMi4wODQyIDIwLjI1IDEyLjE3ODUgMjAuMjMxMyAxMi4yNjU1IDIwLjE5NTFDMTIuNDIxMiAyMC4xMzYzIDEyLjU3MjkgMjAuMDY5IDEyLjcyIDE5Ljk5MzdDMTIuNzcxMSAxOS45Njc0IDEyLjgzMzUgMTkuOTM2NiAxMi45MDY5IDE5LjkwMDRDMTMuMDg5MSAxOS44MTA1IDEzLjMzODggMTkuNjg3MiAxMy42NDg5IDE5LjUxNzVDMTQuMDgzNiAxOS4yNzk0IDE0LjUxODQgMTkuMDIzIDE0LjkzMzQgMTguNzY2NkMxNS40MDQgMTguNDU3NyAxNS44NTI4IDE4LjEyMTIgMTYuMjc3MiAxNy43NTkzQzE2LjczMzEgMTcuMzgwOSAxNy4xNDk5IDE2Ljk2NCAxNy41MjIyIDE2LjUxMzlDMTcuODc4IDE2LjA2MTcgMTguMTcwMiAxNS41NjkzIDE4LjM5MTcgMTUuMDQ4N0MxOC42MjM0IDE0LjUxOTEgMTguNzQ0MSAxMy45NTM1IDE4Ljc0NzQgMTMuMzgyMVY1Ljg3MzFDMTguNzU1NyA1Ljc5MjE0IDE4Ljc0MzkgNS43MTA1IDE4LjcxMzEgNS42MzQzNUMxOC42ODIzIDUuNTU4MiAxOC42MzMyIDUuNDg5NTQgMTguNTY5NiA1LjQzMzU1Wk0xNy4wMDg0IDEzLjQ1NTNDMTcuMDA4NCAxNi4xODQyIDEyLjAwODYgMTguNTI4NSAxMi4wMDg2IDE4LjUyODVWNi44NjIwOUgxNy4wMDg0VjEzLjQ1NTNaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');\n}\n#provider_locked:after {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMSAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEgNy42MDA1N1Y3LjYwMjVWOS41MjI1QzEgMTAuMDgwMSAxLjIyMTUxIDEwLjYxNDkgMS42MTU4MSAxMS4wMDkyQzIuMDEwMSAxMS40MDM1IDIuNTQ0ODggMTEuNjI1IDMuMTAyNSAxMS42MjVINy4yNzI1QzcuNTQ4NjEgMTEuNjI1IDcuODIyMDEgMTEuNTcwNiA4LjA3NzA5IDExLjQ2NUM4LjMzMjE4IDExLjM1OTMgOC41NjM5NiAxMS4yMDQ0IDguNzU5MTkgMTEuMDA5MkM4Ljk1NDQzIDEwLjgxNCA5LjEwOTMgMTAuNTgyMiA5LjIxNDk2IDEwLjMyNzFDOS4zMjA2MiAxMC4wNzIgOS4zNzUgOS43OTg2MSA5LjM3NSA5LjUyMjVMOS4zNzUgNy42MDI1TDkuMzc1IDcuNjAwNTdDOS4zNzQxNSA3LjE2MTMxIDkuMjM1NzQgNi43MzMzNSA4Ljk3OTIyIDYuMzc2NzhDOC44NzY4MyA2LjIzNDQ2IDguNzU3NjggNi4xMDYzNyA4LjYyNSA1Ljk5NDg5VjUuMTg3NUM4LjYyNSA0LjI3NTgyIDguMjYyODQgMy40MDE0OCA3LjYxODE4IDIuNzU2ODJDNi45NzM1MiAyLjExMjE2IDYuMDk5MTggMS43NSA1LjE4NzUgMS43NUM0LjI3NTgyIDEuNzUgMy40MDE0OCAyLjExMjE2IDIuNzU2ODIgMi43NTY4MkMyLjExMjE2IDMuNDAxNDggMS43NSA0LjI3NTgyIDEuNzUgNS4xODc1VjUuOTk0ODlDMS42MTczMiA2LjEwNjM3IDEuNDk4MTcgNi4yMzQ0NiAxLjM5NTc4IDYuMzc2NzhDMS4xMzkyNiA2LjczMzM1IDEuMDAwODUgNy4xNjEzMSAxIDcuNjAwNTdaTTQuOTY4NyA0Ljk2ODdDNS4wMjY5NCA0LjkxMDQ3IDUuMTA1MzIgNC44NzY5OSA1LjE4NzUgNC44NzUwN0M1LjI2OTY4IDQuODc2OTkgNS4zNDgwNiA0LjkxMDQ3IDUuNDA2MyA0Ljk2ODdDNS40NjU0MiA1LjAyNzgzIDUuNDk5MDQgNS4xMDc3NCA1LjUgNS4xOTEzVjUuNUg0Ljg3NVY1LjE5MTNDNC44NzU5NiA1LjEwNzc0IDQuOTA5NTggNS4wMjc4MyA0Ljk2ODcgNC45Njg3WiIgZmlsbD0iIzIyMjIyMiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIi8+Cjwvc3ZnPgo=');\n}\n\nhr {\n display: block;\n margin: 5px 9px;\n border: none; /* reset the border */\n border-top: 1px solid rgba(0,0,0,.1);\n}\n\nhr:first-child {\n display: none;\n}\n\n@media (prefers-color-scheme: dark) {\n hr {\n border-top: 1px solid rgba(255,255,255,.2);\n }\n}\n\n#privateAddress {\n align-items: flex-start;\n}\n#personalAddress::before,\n#privateAddress::before,\n#incontextSignup::before,\n#personalAddress.currentFocus::before,\n#personalAddress:hover::before,\n#privateAddress.currentFocus::before,\n#privateAddress:hover::before {\n filter: none;\n /* This is the same icon as `daxBase64` in `src/Form/logo-svg.js` */\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTY0IDEyOGMzNS4zNDYgMCA2NC0yOC42NTQgNjQtNjRzLTI4LjY1NC02NC02NC02NC02NCAyOC42NTQtNjQgNjQgMjguNjU0IDY0IDY0IDY0eiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im03MyAxMTEuNzVjMC0uNS4xMjMtLjYxNC0xLjQ2Ni0zLjc4Mi00LjIyNC04LjQ1OS04LjQ3LTIwLjM4NC02LjU0LTI4LjA3NS4zNTMtMS4zOTctMy45NzgtNTEuNzQ0LTcuMDQtNTMuMzY1LTMuNDAyLTEuODEzLTcuNTg4LTQuNjktMTEuNDE4LTUuMzMtMS45NDMtLjMxLTQuNDktLjE2NC02LjQ4Mi4xMDUtLjM1My4wNDctLjM2OC42ODMtLjAzLjc5OCAxLjMwOC40NDMgMi44OTUgMS4yMTIgMy44MyAyLjM3NS4xNzguMjItLjA2LjU2Ni0uMzQyLjU3Ny0uODgyLjAzMi0yLjQ4Mi40MDItNC41OTMgMi4xOTUtLjI0NC4yMDctLjA0MS41OTIuMjczLjUzIDQuNTM2LS44OTcgOS4xNy0uNDU1IDExLjkgMi4wMjcuMTc3LjE2LjA4NC40NS0uMTQ3LjUxMi0yMy42OTQgNi40NC0xOS4wMDMgMjcuMDUtMTIuNjk2IDUyLjM0NCA1LjYxOSAyMi41MyA3LjczMyAyOS43OTIgOC40IDMyLjAwNGEuNzE4LjcxOCAwIDAgMCAuNDIzLjQ2N2M4LjE1NiAzLjI0OCAyNS45MjggMy4zOTIgMjUuOTI4LTIuMTMyeiIgZmlsbD0iI2RkZCIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBkPSJtNzYuMjUgMTE2LjVjLTIuODc1IDEuMTI1LTguNSAxLjYyNS0xMS43NSAxLjYyNS00Ljc2NCAwLTExLjYyNS0uNzUtMTQuMTI1LTEuODc1LTEuNTQ0LTQuNzUxLTYuMTY0LTE5LjQ4LTEwLjcyNy0zOC4xODVsLS40NDctMS44MjctLjAwNC0uMDE1Yy01LjQyNC0yMi4xNTctOS44NTUtNDAuMjUzIDE0LjQyNy00NS45MzguMjIyLS4wNTIuMzMtLjMxNy4xODQtLjQ5Mi0yLjc4Ni0zLjMwNS04LjAwNS00LjM4OC0xNC42MDUtMi4xMTEtLjI3LjA5My0uNTA2LS4xOC0uMzM3LS40MTIgMS4yOTQtMS43ODMgMy44MjMtMy4xNTUgNS4wNzEtMy43NTYuMjU4LS4xMjQuMjQyLS41MDItLjAzLS41ODhhMjcuODc3IDI3Ljg3NyAwIDAgMCAtMy43NzItLjljLS4zNy0uMDU5LS40MDMtLjY5My0uMDMyLS43NDMgOS4zNTYtMS4yNTkgMTkuMTI1IDEuNTUgMjQuMDI4IDcuNzI2YS4zMjYuMzI2IDAgMCAwIC4xODYuMTE0YzE3Ljk1MiAzLjg1NiAxOS4yMzggMzIuMjM1IDE3LjE3IDMzLjUyOC0uNDA4LjI1NS0xLjcxNS4xMDgtMy40MzgtLjA4NS02Ljk4Ni0uNzgxLTIwLjgxOC0yLjMyOS05LjQwMiAxOC45NDguMTEzLjIxLS4wMzYuNDg4LS4yNzIuNTI1LTYuNDM4IDEgMS44MTIgMjEuMTczIDcuODc1IDM0LjQ2MXoiIGZpbGw9IiNmZmYiLz4KICAgIDxwYXRoIGQ9Im04NC4yOCA5MC42OThjLTEuMzY3LS42MzMtNi42MjEgMy4xMzUtMTAuMTEgNi4wMjgtLjcyOC0xLjAzMS0yLjEwMy0xLjc4LTUuMjAzLTEuMjQyLTIuNzEzLjQ3Mi00LjIxMSAxLjEyNi00Ljg4IDIuMjU0LTQuMjgzLTEuNjIzLTExLjQ4OC00LjEzLTEzLjIyOS0xLjcxLTEuOTAyIDIuNjQ2LjQ3NiAxNS4xNjEgMy4wMDMgMTYuNzg2IDEuMzIuODQ5IDcuNjMtMy4yMDggMTAuOTI2LTYuMDA1LjUzMi43NDkgMS4zODggMS4xNzggMy4xNDggMS4xMzcgMi42NjItLjA2MiA2Ljk3OS0uNjgxIDcuNjQ5LTEuOTIxLjA0LS4wNzUuMDc1LS4xNjQuMTA1LS4yNjYgMy4zODggMS4yNjYgOS4zNSAyLjYwNiAxMC42ODIgMi40MDYgMy40Ny0uNTIxLS40ODQtMTYuNzIzLTIuMDktMTcuNDY3eiIgZmlsbD0iIzNjYTgyYiIvPgogICAgPHBhdGggZD0ibTc0LjQ5IDk3LjA5N2MuMTQ0LjI1Ni4yNi41MjYuMzU4LjguNDgzIDEuMzUyIDEuMjcgNS42NDguNjc0IDYuNzA5LS41OTUgMS4wNjItNC40NTkgMS41NzQtNi44NDMgMS42MTVzLTIuOTItLjgzMS0zLjQwMy0yLjE4MWMtLjM4Ny0xLjA4MS0uNTc3LTMuNjIxLS41NzItNS4wNzUtLjA5OC0yLjE1OC42OS0yLjkxNiA0LjMzNC0zLjUwNiAyLjY5Ni0uNDM2IDQuMTIxLjA3MSA0Ljk0NC45NCAzLjgyOC0yLjg1NyAxMC4yMTUtNi44ODkgMTAuODM4LTYuMTUyIDMuMTA2IDMuNjc0IDMuNDk5IDEyLjQyIDIuODI2IDE1LjkzOS0uMjIgMS4xNTEtMTAuNTA1LTEuMTM5LTEwLjUwNS0yLjM4IDAtNS4xNTItMS4zMzctNi41NjUtMi42NS02Ljcxem0tMjIuNTMtMS42MDljLjg0My0xLjMzMyA3LjY3NC4zMjUgMTEuNDI0IDEuOTkzIDAgMC0uNzcgMy40OTEuNDU2IDcuNjA0LjM1OSAxLjIwMy04LjYyNyA2LjU1OC05LjggNS42MzctMS4zNTUtMS4wNjUtMy44NS0xMi40MzItMi4wOC0xNS4yMzR6IiBmaWxsPSIjNGNiYTNjIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im01NS4yNjkgNjguNDA2Yy41NTMtMi40MDMgMy4xMjctNi45MzIgMTIuMzIxLTYuODIyIDQuNjQ4LS4wMTkgMTAuNDIyLS4wMDIgMTQuMjUtLjQzNmE1MS4zMTIgNTEuMzEyIDAgMCAwIDEyLjcyNi0zLjA5NWMzLjk4LTEuNTE5IDUuMzkyLTEuMTggNS44ODctLjI3Mi41NDQuOTk5LS4wOTcgMi43MjItMS40ODggNC4zMDktMi42NTYgMy4wMy03LjQzMSA1LjM4LTE1Ljg2NSA2LjA3Ni04LjQzMy42OTgtMTQuMDItMS41NjUtMTYuNDI1IDIuMTE4LTEuMDM4IDEuNTg5LS4yMzYgNS4zMzMgNy45MiA2LjUxMiAxMS4wMiAxLjU5IDIwLjA3Mi0xLjkxNyAyMS4xOS4yMDEgMS4xMTkgMi4xMTgtNS4zMjMgNi40MjgtMTYuMzYyIDYuNTE4cy0xNy45MzQtMy44NjUtMjAuMzc5LTUuODNjLTMuMTAyLTIuNDk1LTQuNDktNi4xMzMtMy43NzUtOS4yNzl6IiBmaWxsPSIjZmMzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KICAgIDxnIGZpbGw9IiMxNDMwN2UiIG9wYWNpdHk9Ii44Ij4KICAgICAgPHBhdGggZD0ibTY5LjMyNyA0Mi4xMjdjLjYxNi0xLjAwOCAxLjk4MS0xLjc4NiA0LjIxNi0xLjc4NiAyLjIzNCAwIDMuMjg1Ljg4OSA0LjAxMyAxLjg4LjE0OC4yMDItLjA3Ni40NC0uMzA2LjM0YTU5Ljg2OSA1OS44NjkgMCAwIDEgLS4xNjgtLjA3M2MtLjgxNy0uMzU3LTEuODItLjc5NS0zLjU0LS44Mi0xLjgzOC0uMDI2LTIuOTk3LjQzNS0zLjcyNy44MzEtLjI0Ni4xMzQtLjYzNC0uMTMzLS40ODgtLjM3MnptLTI1LjE1NyAxLjI5YzIuMTctLjkwNyAzLjg3Ni0uNzkgNS4wODEtLjUwNC4yNTQuMDYuNDMtLjIxMy4yMjctLjM3Ny0uOTM1LS43NTUtMy4wMy0xLjY5Mi01Ljc2LS42NzQtMi40MzcuOTA5LTMuNTg1IDIuNzk2LTMuNTkyIDQuMDM4LS4wMDIuMjkyLjYuMzE3Ljc1Ni4wNy40Mi0uNjcgMS4xMi0xLjY0NiAzLjI4OS0yLjU1M3oiLz4KICAgICAgPHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtNzUuNDQgNTUuOTJhMy40NyAzLjQ3IDAgMCAxIC0zLjQ3NC0zLjQ2MiAzLjQ3IDMuNDcgMCAwIDEgMy40NzUtMy40NiAzLjQ3IDMuNDcgMCAwIDEgMy40NzQgMy40NiAzLjQ3IDMuNDcgMCAwIDEgLTMuNDc1IDMuNDYyem0yLjQ0Ny00LjYwOGEuODk5Ljg5OSAwIDAgMCAtMS43OTkgMGMwIC40OTQuNDA1Ljg5NS45Ljg5NS40OTkgMCAuOS0uNC45LS44OTV6bS0yNS40NjQgMy41NDJhNC4wNDIgNC4wNDIgMCAwIDEgLTQuMDQ5IDQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIC00LjA1LTQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIDQuMDUtNC4wMzcgNC4wNDUgNC4wNDUgMCAwIDEgNC4wNSA0LjAzN3ptLTEuMTkzLTEuMzM4YTEuMDUgMS4wNSAwIDAgMCAtMi4wOTcgMCAxLjA0OCAxLjA0OCAwIDAgMCAyLjA5NyAweiIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8L2c+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im02NCAxMTcuNzVjMjkuNjg1IDAgNTMuNzUtMjQuMDY1IDUzLjc1LTUzLjc1cy0yNC4wNjUtNTMuNzUtNTMuNzUtNTMuNzUtNTMuNzUgMjQuMDY1LTUzLjc1IDUzLjc1IDI0LjA2NSA1My43NSA1My43NSA1My43NXptMCA1YzMyLjQ0NyAwIDU4Ljc1LTI2LjMwMyA1OC43NS01OC43NXMtMjYuMzAzLTU4Ljc1LTU4Ljc1LTU4Ljc1LTU4Ljc1IDI2LjMwMy01OC43NSA1OC43NSAyNi4zMDMgNTguNzUgNTguNzUgNTguNzV6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KPC9zdmc+');\n}\n\n/* Email tooltip specific */\n.tooltip__button--email {\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n font-size: 14px;\n padding: 4px 8px;\n}\n.tooltip__button--email__primary-text {\n font-weight: bold;\n}\n.tooltip__button--email__secondary-text {\n font-size: 12px;\n}\n\n/* Email Protection signup notice */\n:not(.top-autofill) .tooltip--email-signup {\n text-align: left;\n color: #222222;\n padding: 16px 20px;\n width: 380px;\n}\n\n.tooltip--email-signup h1 {\n font-weight: 700;\n font-size: 16px;\n line-height: 1.5;\n margin: 0;\n}\n\n.tooltip--email-signup p {\n font-weight: 400;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.notice-controls {\n display: flex;\n}\n\n.tooltip--email-signup .notice-controls > * {\n border-radius: 8px;\n border: 0;\n cursor: pointer;\n display: inline-block;\n font-family: inherit;\n font-style: normal;\n font-weight: bold;\n padding: 8px 12px;\n text-decoration: none;\n}\n\n.notice-controls .ghost {\n margin-left: 1rem;\n}\n\n.tooltip--email-signup a.primary {\n background: #3969EF;\n color: #fff;\n}\n\n.tooltip--email-signup a.primary:hover,\n.tooltip--email-signup a.primary:focus {\n background: #2b55ca;\n}\n\n.tooltip--email-signup a.primary:active {\n background: #1e42a4;\n}\n\n.tooltip--email-signup button.ghost {\n background: transparent;\n color: #3969EF;\n}\n\n.tooltip--email-signup button.ghost:hover,\n.tooltip--email-signup button.ghost:focus {\n background-color: rgba(0, 0, 0, 0.06);\n color: #2b55ca;\n}\n\n.tooltip--email-signup button.ghost:active {\n background-color: rgba(0, 0, 0, 0.12);\n color: #1e42a4;\n}\n\n.tooltip--email-signup button.close-tooltip {\n background-color: transparent;\n background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMiAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjI5Mjg5NCAwLjY1NjkwN0MwLjY4MzQxOCAwLjI2NjM4MyAxLjMxNjU4IDAuMjY2MzgzIDEuNzA3MTEgMC42NTY5MDdMNiA0Ljk0OThMMTAuMjkyOSAwLjY1NjkwN0MxMC42ODM0IDAuMjY2MzgzIDExLjMxNjYgMC4yNjYzODMgMTEuNzA3MSAwLjY1NjkwN0MxMi4wOTc2IDEuMDQ3NDMgMTIuMDk3NiAxLjY4MDYgMTEuNzA3MSAyLjA3MTEyTDcuNDE0MjEgNi4zNjQwMUwxMS43MDcxIDEwLjY1NjlDMTIuMDk3NiAxMS4wNDc0IDEyLjA5NzYgMTEuNjgwNiAxMS43MDcxIDEyLjA3MTFDMTEuMzE2NiAxMi40NjE2IDEwLjY4MzQgMTIuNDYxNiAxMC4yOTI5IDEyLjA3MTFMNiA3Ljc3ODIzTDEuNzA3MTEgMTIuMDcxMUMxLjMxNjU4IDEyLjQ2MTYgMC42ODM0MTcgMTIuNDYxNiAwLjI5Mjg5MyAxMi4wNzExQy0wLjA5NzYzMTEgMTEuNjgwNiAtMC4wOTc2MzExIDExLjA0NzQgMC4yOTI4OTMgMTAuNjU2OUw0LjU4NTc5IDYuMzY0MDFMMC4yOTI4OTQgMi4wNzExMkMtMC4wOTc2MzA2IDEuNjgwNiAtMC4wOTc2MzA2IDEuMDQ3NDMgMC4yOTI4OTQgMC42NTY5MDdaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjg0Ii8+Cjwvc3ZnPgo=);\n background-position: center center;\n background-repeat: no-repeat;\n border: 0;\n cursor: pointer;\n padding: 16px;\n position: absolute;\n right: 12px;\n top: 12px;\n}\n\n/* Import promotion prompt icon style */\n\n.tooltip__button--credentials-import::before {\n content: \"\";\n background-image: url(data:image/svg+xml;base64,Cjxzdmcgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik03Ljk3MjY5IDkuMDEzN0M3Ljk3MjY5IDUuMTQwMTQgMTEuMTEyOCAyIDE0Ljk4NjQgMkMxOC44NTk5IDIgMjIuMDAwMSA1LjE0MDE0IDIyLjAwMDEgOS4wMTM3QzIyLjAwMDEgOS44MDM5NyAyMS44Njk0IDEwLjU2MzcgMjEuNjI4NCAxMS4yNzI1QzIxLjQ2MDEgMTEuNzY3NiAyMC44NjU2IDExLjkxMzUgMjAuMzk3NyAxMS42OEMxOS45MjIxIDExLjQ0MjggMTkuNjc3OSAxMC44NjQ0IDE5LjgxOTUgMTAuMzUyQzE5LjkzNzIgOS45MjU5OSAyMC4wMDAxIDkuNDc3MTkgMjAuMDAwMSA5LjAxMzdDMjAuMDAwMSA2LjI0NDcxIDE3Ljc1NTQgNCAxNC45ODY0IDRDMTIuMjE3NCA0IDkuOTcyNjkgNi4yNDQ3MSA5Ljk3MjY5IDkuMDEzN0M5Ljk3MjY5IDkuNTU1NCAxMC4wNTgyIDEwLjA3NTIgMTAuMjE1OCAxMC41NjEzQzEwLjMzMTcgMTAuOTE4OCAxMC4yMzc0IDExLjMxMTEgOS45NzE2NSAxMS41NzY4TDMuOTk5OTQgMTcuNTQ4NVYyMC4wMDAyTDYuNDk5OTggMjAuMDAwMlYxOC4zMDAyQzYuNDk5OTggMTcuNzQ3OSA2Ljk0NzcgMTcuMzAwMiA3LjQ5OTk4IDE3LjMwMDJIOS4yMDAwMVYxNS42MDAxQzkuMjAwMDEgMTUuMDQ3OCA5LjY0NzczIDE0LjYwMDEgMTAuMiAxNC42MDAxSDEwLjVDMTEuMjEwNiAxNC41ODcgMTEuNDI1MiAxNS4zMzY5IDExLjMxNTYgMTUuNzMzMUMxMS4xNTY1IDE2LjMwODUgMTEgMTcuMDAxIDExIDE3LjVDMTEgMTcuNzI4NCAxMS4wMTE4IDE3Ljk1NCAxMS4wMzQ4IDE4LjE3NjNDMTAuNzM3OSAxOC44Mzg3IDEwLjA3MjkgMTkuMzAwMiA5LjMgMTkuMzAwMkg4LjQ5OTk4VjIwLjEwMDJDOC40OTk5OCAyMS4xNDk1IDcuNjQ5MzMgMjIuMDAwMiA2LjU5OTk5IDIyLjAwMDJMMi45OTk5NSAyMi4wMDAyQzIuNzM0NzMgMjIuMDAwMiAyLjQ4MDM3IDIxLjg5NDkgMi4yOTI4NCAyMS43MDczQzIuMTA1MyAyMS41MTk4IDEuOTk5OTQgMjEuMjY1NCAxLjk5OTk0IDIxLjAwMDJWMTcuMTM0M0MxLjk5OTk0IDE2Ljg2OTEgMi4xMDUzIDE2LjYxNDcgMi4yOTI4MyAxNi40MjcyTDguMTQ2ODkgMTAuNTczMUM4LjAzMjc5IDEwLjA3MDkgNy45NzI2OSA5LjU0ODgxIDcuOTcyNjkgOS4wMTM3WiIgZmlsbD0iYmxhY2siIC8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTMgOC40OTk4OUMxMyA3LjExOTE4IDE0LjExOTMgNS45OTk4OSAxNS41IDUuOTk5ODlDMTYuODgwNyA1Ljk5OTg5IDE4IDcuMTE5MTggMTggOC40OTk4OUMxOCA5Ljg4MDYgMTYuODgwNyAxMC45OTk5IDE1LjUgMTAuOTk5OUMxNC4xMTkzIDEwLjk5OTkgMTMgOS44ODA2IDEzIDguNDk5ODlaTTE1LjUgNy45OTk4OUMxNS4yMjM5IDcuOTk5ODkgMTUgOC4yMjM3NSAxNSA4LjQ5OTg5QzE1IDguNzc2MDQgMTUuMjIzOSA4Ljk5OTg5IDE1LjUgOC45OTk4OUMxNS43NzYyIDguOTk5ODkgMTYgOC43NzYwNCAxNiA4LjQ5OTg5QzE2IDguMjIzNzUgMTUuNzc2MiA3Ljk5OTg5IDE1LjUgNy45OTk4OVoiIGZpbGw9ImJsYWNrIiAvPgo8cGF0aCBkPSJNMTcgMTVMMTQuNSAxNy41TDE3IDIwIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMjEuNSAxNy41TDE2IDE3LjUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=);\n background-repeat: no-repeat;\n}\n"; -},{}],54:[function(require,module,exports){ +},{}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13325,7 +13460,7 @@ function findEnclosedElements(root, selector) { return shadowElements; } -},{"./Form/matching.js":34,"./constants.js":57,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],55:[function(require,module,exports){ +},{"./Form/matching.js":35,"./constants.js":58,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],56:[function(require,module,exports){ "use strict"; require("./requestIdleCallback.js"); @@ -13356,7 +13491,7 @@ var _autofillUtils = require("./autofill-utils.js"); } })(); -},{"./DeviceInterface.js":13,"./autofill-utils.js":54,"./requestIdleCallback.js":94}],56:[function(require,module,exports){ +},{"./DeviceInterface.js":14,"./autofill-utils.js":55,"./requestIdleCallback.js":95}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13373,6 +13508,10 @@ const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a- * @returns {GlobalConfig} */ function createGlobalConfig(overrides) { + /** + * Defines whether it's one of our desktop apps + * @type {boolean} + */ let isApp = false; let isTopFrame = false; let supportsTopFrame = false; @@ -13442,7 +13581,7 @@ function createGlobalConfig(overrides) { return config; } -},{}],57:[function(require,module,exports){ +},{}],58:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13459,13 +13598,13 @@ const constants = exports.constants = { MAX_FORM_RESCANS: 50 }; -},{}],58:[function(require,module,exports){ +},{}],59:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; +exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAliasCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; var _validatorsZod = require("./validators.zod.js"); var _deviceApi = require("../../../packages/device-api"); /* DO NOT EDIT, this file was generated by scripts/api-call-generator.js */ @@ -13627,9 +13766,19 @@ class StartCredentialsImportFlowCall extends _deviceApi.DeviceApiCall { method = "startCredentialsImportFlow"; } /** - * @extends {DeviceApiCall} + * @extends {DeviceApiCall} */ exports.StartCredentialsImportFlowCall = StartCredentialsImportFlowCall; +class EmailProtectionGetAliasCall extends _deviceApi.DeviceApiCall { + method = "emailProtectionGetAlias"; + id = "emailProtectionGetAliasResponse"; + paramsValidator = _validatorsZod.emailProtectionGetAliasParamsSchema; + resultValidator = _validatorsZod.emailProtectionGetAliasResultSchema; +} +/** + * @extends {DeviceApiCall} + */ +exports.EmailProtectionGetAliasCall = EmailProtectionGetAliasCall; class EmailProtectionStoreUserDataCall extends _deviceApi.DeviceApiCall { method = "emailProtectionStoreUserData"; id = "emailProtectionStoreUserDataResponse"; @@ -13712,13 +13861,13 @@ class ShowInContextEmailProtectionSignupPromptCall extends _deviceApi.DeviceApiC } exports.ShowInContextEmailProtectionSignupPromptCall = ShowInContextEmailProtectionSignupPromptCall; -},{"../../../packages/device-api":2,"./validators.zod.js":59}],59:[function(require,module,exports){ +},{"../../../packages/device-api":2,"./validators.zod.js":60}],60:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; +exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; const sendJSPixelParamsSchema = exports.sendJSPixelParamsSchema = null; const addDebugFlagParamsSchema = exports.addDebugFlagParamsSchema = null; const getAutofillCredentialsParamsSchema = exports.getAutofillCredentialsParamsSchema = null; @@ -13728,6 +13877,7 @@ const setIncontextSignupPermanentlyDismissedAtSchema = exports.setIncontextSignu const getIncontextSignupDismissedAtSchema = exports.getIncontextSignupDismissedAtSchema = null; const getAliasParamsSchema = exports.getAliasParamsSchema = null; const getAliasResultSchema = exports.getAliasResultSchema = null; +const emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAliasParamsSchema = null; const emailProtectionStoreUserDataParamsSchema = exports.emailProtectionStoreUserDataParamsSchema = null; const showInContextEmailProtectionSignupPromptSchema = exports.showInContextEmailProtectionSignupPromptSchema = null; const generatedPasswordSchema = exports.generatedPasswordSchema = null; @@ -13736,9 +13886,10 @@ const credentialsSchema = exports.credentialsSchema = null; const genericErrorSchema = exports.genericErrorSchema = null; const contentScopeSchema = exports.contentScopeSchema = null; const userPreferencesSchema = exports.userPreferencesSchema = null; -const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = null; const availableInputTypesSchema = exports.availableInputTypesSchema = null; +const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = null; const availableInputTypes1Schema = exports.availableInputTypes1Schema = null; +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = null; const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = null; const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = null; @@ -13746,20 +13897,20 @@ const storeFormDataSchema = exports.storeFormDataSchema = null; const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = null; const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = null; const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = null; +const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = null; +const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = null; const autofillSettingsSchema = exports.autofillSettingsSchema = null; +const emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasResultSchema = null; const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = null; const emailProtectionGetUserDataResultSchema = exports.emailProtectionGetUserDataResultSchema = null; const emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = null; const emailProtectionGetAddressesResultSchema = exports.emailProtectionGetAddressesResultSchema = null; const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = null; const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = null; -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = null; -const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = null; -const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = null; const apiSchema = exports.apiSchema = null; -},{}],60:[function(require,module,exports){ +},{}],61:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13785,7 +13936,7 @@ class GetAlias extends _index.DeviceApiCall { } exports.GetAlias = GetAlias; -},{"../../packages/device-api/index.js":2,"./__generated__/validators.zod.js":59}],61:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"./__generated__/validators.zod.js":60}],62:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13793,7 +13944,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.AndroidTransport = void 0; var _index = require("../../../packages/device-api/index.js"); -var _deviceApiCalls = require("../__generated__/deviceApiCalls.js"); +var _messaging = require("../../../packages/messaging/messaging.js"); +var _android = require("../../../packages/messaging/android.js"); class AndroidTransport extends _index.DeviceApiTransport { /** @type {GlobalConfig} */ config; @@ -13802,133 +13954,39 @@ class AndroidTransport extends _index.DeviceApiTransport { constructor(globalConfig) { super(); this.config = globalConfig; - if (this.config.isDDGTestMode) { - if (typeof window.BrowserAutofill?.getAutofillData !== 'function') { - console.warn('window.BrowserAutofill.getAutofillData missing'); - } - if (typeof window.BrowserAutofill?.storeFormData !== 'function') { - console.warn('window.BrowserAutofill.storeFormData missing'); - } - } + const messageHandlerNames = ['EmailProtectionStoreUserData', 'EmailProtectionRemoveUserData', 'EmailProtectionGetUserData', 'EmailProtectionGetCapabilities', 'EmailProtectionGetAlias', 'SetIncontextSignupPermanentlyDismissedAt', 'StartEmailProtectionSignup', 'CloseEmailProtectionTab', 'ShowInContextEmailProtectionSignupPrompt', 'StoreFormData', 'GetIncontextSignupDismissedAt', 'GetRuntimeConfiguration', 'GetAutofillData']; + const androidMessagingConfig = new _android.AndroidMessagingConfig({ + messageHandlerNames + }); + this.messaging = new _messaging.Messaging(androidMessagingConfig); } /** * @param {import("../../../packages/device-api").DeviceApiCall} deviceApiCall * @returns {Promise} */ async send(deviceApiCall) { - if (deviceApiCall instanceof _deviceApiCalls.GetRuntimeConfigurationCall) { - return androidSpecificRuntimeConfiguration(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAvailableInputTypesCall) { - return androidSpecificAvailableInputTypes(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetIncontextSignupDismissedAtCall) { - window.BrowserAutofill.getIncontextSignupDismissedAt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.SetIncontextSignupPermanentlyDismissedAtCall) { - return window.BrowserAutofill.setIncontextSignupPermanentlyDismissedAt(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.StartEmailProtectionSignupCall) { - return window.BrowserAutofill.startEmailProtectionSignup(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.CloseEmailProtectionTabCall) { - return window.BrowserAutofill.closeEmailProtectionTab(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall) { - window.BrowserAutofill.showInContextEmailProtectionSignupPrompt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAutofillDataCall) { - window.BrowserAutofill.getAutofillData(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.StoreFormDataCall) { - return window.BrowserAutofill.storeFormData(JSON.stringify(deviceApiCall.params)); - } - throw new Error('android: not implemented: ' + deviceApiCall.method); - } -} - -/** - * @param {string} expectedResponse - the name/id of the response - * @param {GlobalConfig} config - * @returns {Promise<*>} - */ -exports.AndroidTransport = AndroidTransport; -function waitForResponse(expectedResponse, config) { - return new Promise(resolve => { - const handler = e => { - if (!config.isDDGTestMode) { - if (e.origin !== '') { - return; - } - } - if (!e.data) { - return; - } - if (typeof e.data !== 'string') { - if (config.isDDGTestMode) { - console.log('❌ event.data was not a string. Expected a string so that it can be JSON parsed'); - } - return; + try { + // if the call has an `id`, it means that it expects a response + if (deviceApiCall.id) { + return await this.messaging.request(deviceApiCall.method, deviceApiCall.params || undefined); + } else { + return this.messaging.notify(deviceApiCall.method, deviceApiCall.params || undefined); } - try { - let data = JSON.parse(e.data); - if (data.type === expectedResponse) { - window.removeEventListener('message', handler); - return resolve(data); - } - if (config.isDDGTestMode) { - console.log(`❌ event.data.type was '${data.type}', which didnt match '${expectedResponse}'`, JSON.stringify(data)); - } - } catch (e) { - window.removeEventListener('message', handler); - if (config.isDDGTestMode) { - console.log('❌ Could not JSON.parse the response'); + } catch (e) { + if (e instanceof _messaging.MissingHandler) { + if (this.config.isDDGTestMode) { + console.log('MissingAndroidHandler error for:', deviceApiCall.method); } + throw new Error('unimplemented handler: ' + deviceApiCall.method); + } else { + throw e; } - }; - window.addEventListener('message', handler); - }); -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').RuntimeConfiguration}} - */ -function androidSpecificRuntimeConfiguration(globalConfig) { - if (!globalConfig.userPreferences) { - throw new Error('globalConfig.userPreferences not supported yet on Android'); - } - return { - success: { - // @ts-ignore - contentScope: globalConfig.contentScope, - // @ts-ignore - userPreferences: globalConfig.userPreferences, - // @ts-ignore - userUnprotectedDomains: globalConfig.userUnprotectedDomains, - // @ts-ignore - availableInputTypes: globalConfig.availableInputTypes } - }; -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').AvailableInputTypes}} - */ -function androidSpecificAvailableInputTypes(globalConfig) { - if (!globalConfig.availableInputTypes) { - throw new Error('globalConfig.availableInputTypes not supported yet on Android'); } - return { - success: globalConfig.availableInputTypes - }; } +exports.AndroidTransport = AndroidTransport; -},{"../../../packages/device-api/index.js":2,"../__generated__/deviceApiCalls.js":58}],62:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2,"../../../packages/messaging/android.js":5,"../../../packages/messaging/messaging.js":6}],63:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13971,7 +14029,7 @@ class AppleTransport extends _index.DeviceApiTransport { } exports.AppleTransport = AppleTransport; -},{"../../../packages/device-api/index.js":2,"../../../packages/messaging/messaging.js":5}],63:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2,"../../../packages/messaging/messaging.js":6}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14125,7 +14183,7 @@ async function extensionSpecificSetIncontextSignupPermanentlyDismissedAtCall(par }); } -},{"../../../packages/device-api/index.js":2,"../../Settings.js":41,"../../autofill-utils.js":54,"../__generated__/deviceApiCalls.js":58}],64:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2,"../../Settings.js":42,"../../autofill-utils.js":55,"../__generated__/deviceApiCalls.js":59}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14169,7 +14227,7 @@ function createTransport(globalConfig) { return new _extensionTransport.ExtensionTransport(globalConfig); } -},{"./android.transport.js":61,"./apple.transport.js":62,"./extension.transport.js":63,"./windows.transport.js":65}],65:[function(require,module,exports){ +},{"./android.transport.js":62,"./apple.transport.js":63,"./extension.transport.js":64,"./windows.transport.js":66}],66:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14254,7 +14312,7 @@ function waitForWindowsResponse(responseId, options) { }); } -},{"../../../packages/device-api/index.js":2}],66:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2}],67:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14355,7 +14413,7 @@ module.exports={ } } -},{}],67:[function(require,module,exports){ +},{}],68:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14456,7 +14514,7 @@ module.exports={ } } -},{}],68:[function(require,module,exports){ +},{}],69:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14557,7 +14615,7 @@ module.exports={ } } -},{}],69:[function(require,module,exports){ +},{}],70:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14658,7 +14716,7 @@ module.exports={ } } -},{}],70:[function(require,module,exports){ +},{}],71:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14759,7 +14817,7 @@ module.exports={ } } -},{}],71:[function(require,module,exports){ +},{}],72:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -14861,7 +14919,7 @@ module.exports={ } } -},{}],72:[function(require,module,exports){ +},{}],73:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14962,7 +15020,7 @@ module.exports={ } } -},{}],73:[function(require,module,exports){ +},{}],74:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15063,7 +15121,7 @@ module.exports={ } } -},{}],74:[function(require,module,exports){ +},{}],75:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15164,7 +15222,7 @@ module.exports={ } } -},{}],75:[function(require,module,exports){ +},{}],76:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15265,7 +15323,7 @@ module.exports={ } } -},{}],76:[function(require,module,exports){ +},{}],77:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15366,7 +15424,7 @@ module.exports={ } } -},{}],77:[function(require,module,exports){ +},{}],78:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15467,7 +15525,7 @@ module.exports={ } } -},{}],78:[function(require,module,exports){ +},{}],79:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15568,7 +15626,7 @@ module.exports={ } } -},{}],79:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15669,7 +15727,7 @@ module.exports={ } } -},{}],80:[function(require,module,exports){ +},{}],81:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15770,7 +15828,7 @@ module.exports={ } } -},{}],81:[function(require,module,exports){ +},{}],82:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15871,7 +15929,7 @@ module.exports={ } } -},{}],82:[function(require,module,exports){ +},{}],83:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15972,7 +16030,7 @@ module.exports={ } } -},{}],83:[function(require,module,exports){ +},{}],84:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16073,7 +16131,7 @@ module.exports={ } } -},{}],84:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16174,7 +16232,7 @@ module.exports={ } } -},{}],85:[function(require,module,exports){ +},{}],86:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16275,7 +16333,7 @@ module.exports={ } } -},{}],86:[function(require,module,exports){ +},{}],87:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16376,7 +16434,7 @@ module.exports={ } } -},{}],87:[function(require,module,exports){ +},{}],88:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16477,7 +16535,7 @@ module.exports={ } } -},{}],88:[function(require,module,exports){ +},{}],89:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16578,7 +16636,7 @@ module.exports={ } } -},{}],89:[function(require,module,exports){ +},{}],90:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16666,7 +16724,7 @@ function translateImpl(library, namespacedId, opts) { return out; } -},{"./translations.js":92}],90:[function(require,module,exports){ +},{"./translations.js":93}],91:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16767,7 +16825,7 @@ module.exports={ } } -},{}],91:[function(require,module,exports){ +},{}],92:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16868,7 +16926,7 @@ module.exports={ } } -},{}],92:[function(require,module,exports){ +},{}],93:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16987,7 +17045,7 @@ var _default = exports.default = { } }; -},{"./bg/autofill.json":66,"./cs/autofill.json":67,"./da/autofill.json":68,"./de/autofill.json":69,"./el/autofill.json":70,"./en/autofill.json":71,"./es/autofill.json":72,"./et/autofill.json":73,"./fi/autofill.json":74,"./fr/autofill.json":75,"./hr/autofill.json":76,"./hu/autofill.json":77,"./it/autofill.json":78,"./lt/autofill.json":79,"./lv/autofill.json":80,"./nb/autofill.json":81,"./nl/autofill.json":82,"./pl/autofill.json":83,"./pt/autofill.json":84,"./ro/autofill.json":85,"./ru/autofill.json":86,"./sk/autofill.json":87,"./sl/autofill.json":88,"./sv/autofill.json":90,"./tr/autofill.json":91,"./xa/autofill.json":93}],93:[function(require,module,exports){ +},{"./bg/autofill.json":67,"./cs/autofill.json":68,"./da/autofill.json":69,"./de/autofill.json":70,"./el/autofill.json":71,"./en/autofill.json":72,"./es/autofill.json":73,"./et/autofill.json":74,"./fi/autofill.json":75,"./fr/autofill.json":76,"./hr/autofill.json":77,"./hu/autofill.json":78,"./it/autofill.json":79,"./lt/autofill.json":80,"./lv/autofill.json":81,"./nb/autofill.json":82,"./nl/autofill.json":83,"./pl/autofill.json":84,"./pt/autofill.json":85,"./ro/autofill.json":86,"./ru/autofill.json":87,"./sk/autofill.json":88,"./sl/autofill.json":89,"./sv/autofill.json":91,"./tr/autofill.json":92,"./xa/autofill.json":94}],94:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -17080,7 +17138,7 @@ module.exports={ "note": "Button that prevents the DuckDuckGo email protection signup prompt from appearing again." } } -},{}],94:[function(require,module,exports){ +},{}],95:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17123,4 +17181,4 @@ window.cancelIdleCallback = window.cancelIdleCallback || function (id) { }; var _default = exports.default = {}; -},{}]},{},[55]); +},{}]},{},[56]); diff --git a/docs/playwright-tests.md b/docs/playwright-tests.md index 7789c5f4f..d3dd89125 100644 --- a/docs/playwright-tests.md +++ b/docs/playwright-tests.md @@ -71,6 +71,12 @@ await emailPage.clickIntoInput() ```shell npm run test:integration +# Shows the UI, thus allowing await page.pause() +npm run test:integration:showui +# Skips file compilation and uses higher concurrency +npm run test:integration:fast +# Skips file compilation and uses higher concurrency, and shows the UI +npm run test:integration:fast:showui ``` ## Running only flaky tests diff --git a/docs/runtime.android.md b/docs/runtime.android.md index f389b1db2..0da73bd30 100644 --- a/docs/runtime.android.md +++ b/docs/runtime.android.md @@ -1,121 +1,111 @@ -## ~`getRuntimeConfiguration()`~ +## String replacement +On Android, the only string replacement needed is the platform name. We substitute this: -on android devices, this data is retrieved from the following string-replacements: +```js +// INJECT userPreferences HERE +``` -Internally, we force it into the following shape in order to conform to the following schema definition: -- [Runtime Configuration Schema](https://github.com/duckduckgo/content-scope-scripts/blob/shane/unify-config/src/schema/runtime-configuration.schema.json) +with this -**strings to replace** -``` -// INJECT contentScope HERE -// INJECT userUnprotectedDomains HERE -// INJECT userPreferences HERE +```js +userPreferences = { + "debug": false, + "platform": { + "name": "android" + } +} ``` -Directly replace the lines above in the following way: +## `getRuntimeConfiguration()` -`str.replace('// INJECT contentScope HERE', 'contentScope = {JSON_HERE}') + ';'` +See: [../src/schema/runtimeConfiguration.json](../src/deviceApiCalls/schemas/runtimeConfiguration.json). -For example, the 3 variables should look like this (don't forget the semicolon at the end of each!) +This includes the configurations needed for autofill to know what options are available on the specific page we're on, for example whether the domain is blocklisted by remote config, or whether a specific feature is turned on/off either remotely or by the user. -```javascript -// INJECT contentScope HERE -contentScope = { - "features": { - "autofill": { - "state": "enabled", - "exceptions": [] - } - }, - "unprotectedTemporary": [] -}; -``` +Compared to other platforms, on Android we include `availableInputTypes` in the initial runtime configuration. We plan to adopt this to all platforms to reduce message passing. -```javascript -// INJECT userUnprotectedDomains HERE -userUnprotectedDomains = []; -``` +**Example:** -```javascript -// INJECT userPreferences HERE -userPreferences = { - "debug": false, - "platform": { - "name": "android" - }, - "features": { - "autofill": { - "settings": { - "featureToggles": { - "inputType_credentials": true, - "inputType_identities": false, - "inputType_creditCards": false, - "emailProtection": true, - "password_generation": false, - "credentials_saving": true +```json +{ + "success": { + "availableInputTypes": { + "email": false, + "credentials": { + "username": true, + "password": true + }, + "identities": { + "firstName": false, + "middleName": false, + "lastName": false, + "birthdayDay": false, + "birthdayMonth": false, + "birthdayYear": false, + "addressStreet": false, + "addressStreet2": false, + "addressCity": false, + "addressProvince": false, + "addressPostalCode": false, + "addressCountryCode": false, + "phone": false, + "emailAddress": false + }, + "creditCards": { + "cardName": false, + "cardSecurityCode": false, + "expirationMonth": false, + "expirationYear": false, + "cardNumber": false + } + }, + "contentScope": { + "features": { + "autofill": { + "state": "enabled", + "exceptions": [] + } + }, + "unprotectedTemporary": [] + }, + "userUnprotectedDomains": [], + "userPreferences": { + "debug": false, + "platform": { + "name": "android" + }, + "features": { + "autofill": { + "settings": { + "featureToggles": { + "inputType_credentials": true, + "inputType_identities": false, + "inputType_creditCards": false, + "emailProtection": true, + "password_generation": true, + "unknown_username_categorization": true, + "credentials_saving": true + } + } } } } } -}; +} ``` --- ## `getAvailableInputTypes()` -This represents which input types we can autofill for the current user. - - -**strings to replace** -``` -// INJECT availableInputTypes HERE -``` - -Directly replace the line above in the following way: - -`str.replace('// INJECT availableInputTypes HERE', 'contentScope = {JSON_HERE}') + ';'` - See: [../src/schema/availableInputTypes.json](../src/deviceApiCalls/schemas/availableInputTypes.json). This represents which input types we can autofill for the current user. Values are `true` if we can autofill the field type with at least one item. For example, if we have two credential items and the first only has a username -and the second only has a password, both fields will be `true`. The email value is the same as returned by the +and the second only has a password, both fields will be `true`. The email value is the same as returned by the `isSignedIn()` method. At this time `identities` and `creditCards` are optional as they are not supported on Android. -```javascript -// INJECT availableInputTypes HERE -availableInputTypes = { - "email": true, - "credentials": { - "username": true, - "password": true - }, - "identities": { - "firstName": false, - "middleName": false, - "lastName": false, - "birthdayDay": false, - "birthdayMonth": false, - "birthdayYear": false, - "addressStreet": false, - "addressStreet2": false, - "addressCity": false, - "addressProvince": false, - "addressPostalCode": false, - "addressCountryCode": false, - "phone": false, - "emailAddress": false - }, - "creditCards": { - "cardName": false, - "cardSecurityCode": false, - "expirationMonth": false, - "expirationYear": false, - "cardNumber": false - } -} -``` +On Android, this data is passed with the initial runtime configurations, so the call just returns the data we already received. --- @@ -165,11 +155,11 @@ window.BrowserAutofill.storeFormData(JSON.stringify(data)) --- -## `window.BrowserAutofill.getAutofillData(request)` +## `window.ddgGetAutofillData(request)` - Autofill will send `request` as a string of JSON - See: [../src/schema/request.getAutofillData.schema.json](../src/deviceApiCalls/schemas/getAutofillData.params.json) -- Response Message via: `window.postMessage(response)` +- Response Message via the listener to: `window.ddgGetAutofillData` - See: [../src/schema/response.getAutofillData.schema.json](../src/deviceApiCalls/schemas/getAutofillData.result.json) **`request`** example diff --git a/docs/runtime.ios.md b/docs/runtime.ios.md index 5e46f405a..ed9ae8aef 100644 --- a/docs/runtime.ios.md +++ b/docs/runtime.ios.md @@ -1,74 +1,72 @@ -## ~`getRuntimeConfiguration()`~ - -on Apple devices, this data is retrieved from the following string-replacements - -- [BrowserServices Kit String replacements](https://github.com/duckduckgo/BrowserServicesKit/blob/main/Sources/BrowserServicesKit/Autofill/AutofillUserScript+SourceProvider.swift#L54-L56) +## String replacement +On iOS and macOS, we string-replace these variables: -Internally, we force it into the following shape in order to conform to the following schema definition: -- [Runtime Configuration Schema](https://github.com/duckduckgo/content-scope-scripts/blob/shane/unify-config/src/schema/runtime-configuration.schema.json) - -**strings to replace** -``` -// INJECT contentScope HERE -// INJECT userUnprotectedDomains HERE +```js // INJECT userPreferences HERE +// INJECT isApp HERE +// INJECT isTopFrame HERE +// INJECT supportsTopFrame HERE +// INJECT hasModernWebkitAPI HERE +// INJECT webkitMessageHandlerNames HERE ``` -Directly replace the lines above in the following way: +- `userPreferences`: sets the platform name +- `isApp`: true when is macOS +- `isTopFrame`: true when the script is being rendered in the overlay webview +- `supportsTopFrame`: true on macOS when the overlay webview is supported (now on all versions) +- `hasModernWebkitAPI`: now true on all versions, since we've dropped macOS Catalina +- `webkitMessageHandlerNames`: an array of all the expected call names, if we attempt a call that's not in the list, the script will error -`str.replace('// INJECT contentScope HERE', 'contentScope = {JSON_HERE}') + ';'` +## ~`getRuntimeConfiguration()`~ -For example, the 3 variables should look like this (don't forget the semicolon at the end of each!) +See: [../src/schema/runtimeConfiguration.json](../src/deviceApiCalls/schemas/runtimeConfiguration.json). -```javascript -// INJECT contentScope HERE -contentScope = { - "features": { - "autofill": { - "state": "enabled", - "exceptions": [] - } - }, - "unprotectedTemporary": [] -}; -``` +This includes the configurations needed for autofill to know what options are available on the specific page we're on, for example whether the domain is blocklisted by remote config, or whether a specific feature is turned on/off either remotely or by the user. -```javascript -// INJECT userUnprotectedDomains HERE -userUnprotectedDomains = []; -``` +**Example:** -```javascript -// INJECT userPreferences HERE -userPreferences = { - "debug": false, - "platform": { - "name": "android" - }, - "features": { - "autofill": { - "settings": { - "featureToggles": { - "inputType_credentials": true, - "inputType_identities": false, - "inputType_creditCards": false, - "emailProtection": true, - "password_generation": false, - "credentials_saving": true +```json +{ + "success": { + "contentScope": { + "features": { + "autofill": { + "state": "enabled", + "exceptions": [] + } + }, + "unprotectedTemporary": [] + }, + "userUnprotectedDomains": [], + "userPreferences": { + "debug": false, + "platform": { + "name": "ios" + }, + "features": { + "autofill": { + "settings": { + "featureToggles": { + "inputType_credentials": true, + "inputType_identities": false, + "inputType_creditCards": false, + "emailProtection": true, + "password_generation": true, + "credentials_saving": true + } + } } } } } -}; +} ``` --- ## `getAvailableInputTypes()` -see: - -- [../src/deviceApiCalls/schemas/getAvailableInputTypes.result.json](../src/deviceApiCalls/schemas/getAvailableInputTypes.result.json) +see: [../src/deviceApiCalls/schemas/getAvailableInputTypes.result.json](../src/deviceApiCalls/schemas/getAvailableInputTypes.result.json) This represents which input types we can autofill for the current user. Values are `true` if we can autofill the field type with at least one item. For example, if we have two credential items and the first only has a username diff --git a/integration-test/helpers/harness.js b/integration-test/helpers/harness.js index 92eb24b7d..ba6a20a52 100644 --- a/integration-test/helpers/harness.js +++ b/integration-test/helpers/harness.js @@ -171,6 +171,20 @@ export async function defaultIOSScript (page) { .applyTo(page) } +/** + * @param {import("@playwright/test").Page} page + */ +export async function defaultAndroidScript (page) { + return createAutofillScript() + .replaceAll({ + userPreferences: { + platform: {name: 'android'} + } + }) + .platform('android') + .applyTo(page) +} + /** * @param {import("@playwright/test").Page} page */ @@ -313,7 +327,7 @@ export async function addMocksAsAttachments (page, test, testInfo) { const lines = [`name: ${name}`] if (platform === 'android') { lines.push('sent as json string: \n\n' + JSON.stringify(params)) - params = JSON.parse(/** @type {any} */(params)) + params = typeof params === 'string' ? JSON.parse(/** @type {any} */(params)) : params } lines.push(`\n\nparams: \n\n` + JSON.stringify(params, null, 2)) lines.push(`\n\nresponse: \n\n` + JSON.stringify(response, null, 2)) diff --git a/integration-test/helpers/harness.types.d.ts b/integration-test/helpers/harness.types.d.ts index 06391c48f..c5bab41a0 100644 --- a/integration-test/helpers/harness.types.d.ts +++ b/integration-test/helpers/harness.types.d.ts @@ -28,6 +28,7 @@ interface CredentialsMock { * ``` */ interface MockBuilder> { + withRuntimeConfigOverrides(overrides: RuntimeConfiguration): MockBuilder // Set the private email address withPrivateEmail(email: string): MockBuilder // Set the personal email address diff --git a/integration-test/helpers/mocks.android.js b/integration-test/helpers/mocks.android.js index 6490b9ec4..cafa6cf28 100644 --- a/integration-test/helpers/mocks.android.js +++ b/integration-test/helpers/mocks.android.js @@ -1,4 +1,5 @@ /** + * @typedef {import('../../src/deviceApiCalls/__generated__/validators-ts').RuntimeConfiguration} RuntimeConfiguration * @typedef {import('../../src/deviceApiCalls/__generated__/validators-ts').GetAutofillDataResponse} GetAutofillDataResponse * @typedef {import('../../src/deviceApiCalls/__generated__/validators-ts').AutofillFeatureToggles} AutofillFeatureToggles * @typedef {import('../../src/deviceApiCalls/__generated__/validators-ts').AvailableInputTypes} AvailableInputTypes @@ -9,8 +10,9 @@ import {createAvailableInputTypes, withDataType} from './utils.js' * @param {object} [overrides] * @param {Partial} [overrides.featureToggles] * @param {Partial} [overrides.availableInputTypes] + * @return {RuntimeConfiguration} */ -export function androidStringReplacements (overrides = {}) { +export function createRuntimeConfiguration (overrides = {}) { return { /** @type {AvailableInputTypes} */ availableInputTypes: { @@ -60,13 +62,12 @@ export function androidStringReplacements (overrides = {}) { /** * Use this to mock android message handlers. * - * For example, the following would mock interactions with window.postMessage + * For example, the following would mock interactions with Android handlers * to ensure that it returns { alias: "x" } * * ```js * await createWebkitMocks() * .withPrivateEmail("x") - * .withPersonalEmail("y") * .applyTo(page) * ``` * @public @@ -74,23 +75,30 @@ export function androidStringReplacements (overrides = {}) { */ export function createAndroidMocks () { const mocks = { + getRuntimeConfiguration: createRuntimeConfiguration(), /** @type {GetAutofillDataResponse['success']|null} */ getAutofillData: null, showInContextEmailProtectionSignupPrompt: { isSignedIn: true }, incontextSignupDismissedAt: {}, - /** @type {string|null} */ + /** @type {{alias: string}|null} */ address: null, isSignedIn: '' } /** @type {MockBuilder} */ const builder = { + withRuntimeConfigOverrides (overrides) { + mocks.getRuntimeConfiguration = createRuntimeConfiguration(overrides) + return this + }, withPrivateEmail (email) { - mocks.address = email + email = email.replace('@duck.com', '') + mocks.address = {alias: email} mocks.isSignedIn = 'true' return this }, withPersonalEmail (email) { - mocks.address = email + email = email.replace('@duck.com', '') + mocks.address = {alias: email} mocks.isSignedIn = 'true' return this }, @@ -154,92 +162,72 @@ export function createAndroidMocks () { async applyTo (page) { return page.evaluate(mocks => { window.__playwright_autofill = {mocks: {calls: []}} - window.EmailInterface = { - showTooltip () { - window.postMessage({ - type: 'getAliasResponse', - alias: mocks.address - }, window.origin) - }, - getUserData () { - return '' - }, - storeCredentials () { - return '' - }, - isSignedIn () { - return mocks.isSignedIn - }, - getDeviceCapabilities () { - return '' - }, - removeCredentials () { - window.postMessage({ - emailProtectionSignedOut: true - }, window.origin) - } - } - /** - * @param {string} name - * @param {any} request - * @param {any} response - */ - function respond (name, request, response) { - const call = [name, request, response] - window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) - window.postMessage(JSON.stringify({ - type: name + 'Response', - success: response - }), window.origin) + class AndroidHandlerMock { + constructor (name, response) { + this.name = name + this.request = null + this.response = response + this._eventHandlers = new Set() + } + postMessage (passedRequest) { + this.request = passedRequest + const call = [this.name, JSON.parse(passedRequest), this.response] + if (this.response) { + this.onMessage() + } else { + // If we're not waiting for a response, add the call here, otherwise it's added in onMessage + window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) + } + } + onMessage () { + this._eventHandlers.forEach((fn) => { + const call = [this.name, this.request, this.response] + window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) + fn({data: JSON.stringify({success: this.response})}) + }) + } + addEventListener (_eventName, fn) { + this._eventHandlers.add(fn) + } + removeEventListener (_eventName, fn) { + this._eventHandlers.delete(fn) + } } - window.BrowserAutofill = { - getAutofillData (request) { - return respond('getAutofillData', request, mocks.getAutofillData) + /** @type {{ callName: string, response?: any }[]} */ + const androidHandlersMocksConfig = [ + { + callName: 'getRuntimeConfiguration', + response: mocks.getRuntimeConfiguration }, - storeFormData (request) { - /** @type {MockCall} */ - const call = ['storeFormData', request, mocks.getAutofillData] - window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) + {callName: 'emailProtectionStoreUserData'}, + {callName: 'emailProtectionGetUserData'}, + {callName: 'emailProtectionGetCapabilities'}, + { + callName: 'emailProtectionGetAlias', + response: mocks.address }, - showInContextEmailProtectionSignupPrompt (request) { - return respond('ShowInContextEmailProtectionSignupPrompt', request, mocks.showInContextEmailProtectionSignupPrompt) + { + callName: 'getAutofillData', + response: mocks.getAutofillData }, - getIncontextSignupDismissedAt (request) { - const call = ['getIncontextSignupDismissedAt', request, mocks.incontextSignupDismissedAt] - window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) - window.postMessage(JSON.stringify({ - type: 'getIncontextSignupDismissedAt', - success: mocks.incontextSignupDismissedAt - }), window.origin) + {callName: 'storeFormData'}, + { + callName: 'getIncontextSignupDismissedAt', + response: mocks.incontextSignupDismissedAt }, - setIncontextSignupPermanentlyDismissedAt (request) { - const call = ['setIncontextSignupPermanentlyDismissedAt', request] - window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) - }, - startEmailProtectionSignup (request) { - const call = ['startEmailProtectionSignup', request] - window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) - }, - closeEmailProtectionTab (request) { - const call = ['closeEmailProtectionTab', request] - window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call))) - } - } + {callName: 'setIncontextSignupPermanentlyDismissedAt'}, + {callName: 'ShowInContextEmailProtectionSignupPrompt'}, + {callName: 'closeEmailProtectionTab'} + ] + + // Attach the mocks to the window object + androidHandlersMocksConfig.forEach((call) => { + const androidSpecificName = 'ddg' + call.callName[0].toUpperCase() + call.callName.slice(1) + window[androidSpecificName] = new AndroidHandlerMock(call.callName, call.response) + }) }, mocks) - }, - removeHandlers: function (handlers) { - const keys = Object.keys(mocks) - for (let handler of handlers) { - // @ts-ignore - if (!keys.includes(handler)) { - // @ts-ignore - throw new Error('android mock did not exist for ' + handler) - } - delete mocks[handler] - } - return this } } return builder diff --git a/integration-test/helpers/mocks.webkit.js b/integration-test/helpers/mocks.webkit.js index c039c2630..eafd1378e 100644 --- a/integration-test/helpers/mocks.webkit.js +++ b/integration-test/helpers/mocks.webkit.js @@ -248,8 +248,7 @@ export function createWebkitMocks (platform = 'macos') { } } } - }, - availableInputTypes: constants.availableInputTypes + } } }, storeFormData: null, @@ -271,6 +270,9 @@ export function createWebkitMocks (platform = 'macos') { /** @type {MockBuilder} */ const builder = { + withRuntimeConfigOverrides: function () { + throw new Error('Function not implemented.') + }, withPrivateEmail (email) { webkitBase.emailHandlerCheckAppSignedInStatus.isAppSignedIn = true if (platform === 'ios') { diff --git a/integration-test/helpers/mocks.windows.js b/integration-test/helpers/mocks.windows.js index 1c8537d61..885e809e3 100644 --- a/integration-test/helpers/mocks.windows.js +++ b/integration-test/helpers/mocks.windows.js @@ -75,6 +75,9 @@ export function createWindowsMocks () { } /** @type {MockBuilder} */ const builder = { + withRuntimeConfigOverrides: function () { + throw new Error('Function not implemented.') + }, withPrivateEmail (_email) { mocks.emailProtectionGetIsLoggedIn = true return this diff --git a/integration-test/tests/email-autofill.android.spec.js b/integration-test/tests/email-autofill.android.spec.js index be2867628..8769a641c 100644 --- a/integration-test/tests/email-autofill.android.spec.js +++ b/integration-test/tests/email-autofill.android.spec.js @@ -1,10 +1,7 @@ -import { - createAutofillScript, - forwardConsoleMessages -} from '../helpers/harness.js' +import {defaultAndroidScript, forwardConsoleMessages} from '../helpers/harness.js' import {test as base} from '@playwright/test' import {constants} from '../helpers/mocks.js' -import {androidStringReplacements, createAndroidMocks} from '../helpers/mocks.android.js' +import {createAndroidMocks} from '../helpers/mocks.android.js' import {testContext} from '../helpers/test-context.js' import {signupPage} from '../helpers/pages/signupPage.js' import {emailAutofillPage} from '../helpers/pages/emailAutofillPage.js' @@ -30,10 +27,7 @@ test.describe('android', () => { .applyTo(page) // create + inject the script - await createAutofillScript() - .replaceAll(androidStringReplacements()) - .platform('android') - .applyTo(page) + await defaultAndroidScript(page) // if this works, the tooltipHandler must have loaded and added the field decorations await emailPage.clickIntoInput() @@ -48,19 +42,17 @@ test.describe('android', () => { const {personalAddress, privateAddress0} = constants.fields.email await createAndroidMocks() - .withPersonalEmail(personalAddress) - .withPrivateEmail(privateAddress0) - .applyTo(page) - - await createAutofillScript() - .replaceAll(androidStringReplacements({ + .withRuntimeConfigOverrides({ featureToggles: { credentials_saving: true } - })) - .platform('android') + }) + .withPersonalEmail(personalAddress) + .withPrivateEmail(privateAddress0) .applyTo(page) + await defaultAndroidScript(page) + await signup.clickIntoEmailField() await signup.enterPassword('abcd') await signup.submit() @@ -78,19 +70,17 @@ test.describe('android', () => { await emailPage.navigate() const {personalAddress} = constants.fields.email await createAndroidMocks() + .withRuntimeConfigOverrides({ + availableInputTypes: { + email: true + } + }) .withPersonalEmail(personalAddress) .withPrivateEmail(personalAddress) .applyTo(page) // create + inject the script - await createAutofillScript() - .replaceAll(androidStringReplacements({ - availableInputTypes: { - email: true - } - })) - .platform('android') - .applyTo(page) + await defaultAndroidScript(page) await emailPage.clickIntoInput() await emailPage.assertEmailValue(personalAddress) @@ -107,33 +97,29 @@ test.describe('android', () => { // android specific mocks await createAndroidMocks() - .applyTo(page) - - // create + inject the script - await createAutofillScript() - .replaceAll(androidStringReplacements({ + .withRuntimeConfigOverrides({ availableInputTypes: { email: false } - })) - .platform('android') + }) .applyTo(page) + // create + inject the script + await defaultAndroidScript(page) + await signup.assertEmailHasNoDaxIcon() }) }) test.describe('password generation', () => { - const script = createAutofillScript() - .replaceAll(androidStringReplacements({ - availableInputTypes: {}, - featureToggles: { - password_generation: true, - inputType_credentials: true, - inlineIcon_credentials: true, - credentials_saving: true - } - })) - .platform('android') + const overrides = { + availableInputTypes: {}, + featureToggles: { + password_generation: true, + inputType_credentials: true, + inlineIcon_credentials: true, + credentials_saving: true + } + } test('should autofill with generated password + private email', async ({page}) => { // enable in-terminal exceptions @@ -143,12 +129,13 @@ test.describe('android', () => { const {personalAddress, privateAddress0} = constants.fields.email await createAndroidMocks() + .withRuntimeConfigOverrides(overrides) .withPersonalEmail(personalAddress) .withPrivateEmail(privateAddress0) .withPasswordDecision?.('accept') .applyTo(page) - await script.applyTo(page) + await defaultAndroidScript(page) // simulate the email modal await signup.clickIntoEmailField() @@ -171,11 +158,12 @@ test.describe('android', () => { // android specific mocks await createAndroidMocks() + .withRuntimeConfigOverrides(overrides) .withPasswordDecision?.('reject') .applyTo(page) // create + inject the script - await script.applyTo(page) + await defaultAndroidScript(page) await signup.clickIntoPasswordField() await signup.assertPasswordWasNotAutofilled() diff --git a/integration-test/tests/incontext-signup.android.spec.js b/integration-test/tests/incontext-signup.android.spec.js index f6b06eba9..bb1c7fd69 100644 --- a/integration-test/tests/incontext-signup.android.spec.js +++ b/integration-test/tests/incontext-signup.android.spec.js @@ -1,6 +1,11 @@ -import {createAutofillScript, forwardConsoleMessages, mockedCalls, setupMockedDomain} from '../helpers/harness.js' +import { + defaultAndroidScript, + forwardConsoleMessages, + mockedCalls, + setupMockedDomain +} from '../helpers/harness.js' import {expect, test as base} from '@playwright/test' -import {androidStringReplacements, createAndroidMocks} from '../helpers/mocks.android.js' +import {createAndroidMocks} from '../helpers/mocks.android.js' import {testContext} from '../helpers/test-context.js' import {emailAutofillPage} from '../helpers/pages/emailAutofillPage.js' @@ -18,18 +23,16 @@ test.describe('android', () => { await emailPage.navigate('https://example.com') await createAndroidMocks() - .applyTo(page) - - // create + inject the script - await createAutofillScript() - .replaceAll(androidStringReplacements({ + .withRuntimeConfigOverrides({ availableInputTypes: { email: false } - })) - .platform('android') + }) .applyTo(page) + // create + inject the script + await defaultAndroidScript(page) + // Checks if in-context signup has already been dismissed const checkCall = await mockedCalls(page, {names: ['getIncontextSignupDismissedAt']}) expect(checkCall.length).toBe(1) diff --git a/integration-test/tests/login-form.android.spec.js b/integration-test/tests/login-form.android.spec.js index 97e44e96e..b55e54ee7 100644 --- a/integration-test/tests/login-form.android.spec.js +++ b/integration-test/tests/login-form.android.spec.js @@ -1,6 +1,6 @@ import {constants} from '../helpers/mocks.js' -import {createAutofillScript, forwardConsoleMessages} from '../helpers/harness.js' -import {androidStringReplacements, createAndroidMocks} from '../helpers/mocks.android.js' +import {defaultAndroidScript, forwardConsoleMessages} from '../helpers/harness.js' +import {createAndroidMocks} from '../helpers/mocks.android.js' import {test as base} from '@playwright/test' import {testContext} from '../helpers/test-context.js' import {loginPage} from '../helpers/pages/loginPage.js' @@ -19,8 +19,10 @@ const test = testContext(base) /** * @param {import("@playwright/test").Page} page * @param {object} opts - * @param {Partial} opts.featureToggles - * @param {Partial} [opts.availableInputTypes] + * @param {{ + * featureToggles: Partial, + * availableInputTypes?: Partial + * }} opts.configOverrides * @param {CredentialsMock} [opts.credentials] * @param {keyof typeof constants.pages} [opts.pageType] */ @@ -34,6 +36,8 @@ async function testLoginPage (page, opts) { // android specific mocks const mocks = createAndroidMocks() + mocks.withRuntimeConfigOverrides(opts.configOverrides) + if (opts.credentials) { mocks.withCredentials(opts.credentials) } @@ -41,13 +45,7 @@ async function testLoginPage (page, opts) { await mocks.applyTo(page) // create + inject the script - await createAutofillScript() - .replaceAll(androidStringReplacements({ - featureToggles: opts.featureToggles, - availableInputTypes: opts.availableInputTypes - })) - .platform('android') - .applyTo(page) + await defaultAndroidScript(page) return {login} } @@ -64,8 +62,10 @@ test.describe('Feature: auto-filling a login form on Android', () => { test.describe('and I have saved credentials', () => { test('I should be prompted to use my saved credentials with autoprompt', async ({page}) => { const {login} = await testLoginPage(page, { - featureToggles: { - inputType_credentials: true + configOverrides: { + featureToggles: { + inputType_credentials: true + } }, credentials }) @@ -75,8 +75,10 @@ test.describe('Feature: auto-filling a login form on Android', () => { }) test('I should be prompted to use my saved credentials when clicking the field even if the form was below the fold', async ({page}) => { const {login} = await testLoginPage(page, { - featureToggles: { - inputType_credentials: true + configOverrides: { + featureToggles: { + inputType_credentials: true + } }, credentials, pageType: 'loginWithText' @@ -88,8 +90,10 @@ test.describe('Feature: auto-filling a login form on Android', () => { }) test('I should not be prompted automatically to use my saved credentials if the form is below the fold', async ({page}) => { const {login} = await testLoginPage(page, { - featureToggles: { - inputType_credentials: true + configOverrides: { + featureToggles: { + inputType_credentials: true + } }, credentials, pageType: 'loginWithText' @@ -101,8 +105,10 @@ test.describe('Feature: auto-filling a login form on Android', () => { }) test('the form should be submitted after autofill', async ({page}) => { const {login} = await testLoginPage(page, { - featureToggles: { - inputType_credentials: true + configOverrides: { + featureToggles: { + inputType_credentials: true + } }, credentials, pageType: 'loginWithFormInModal' @@ -117,12 +123,14 @@ test.describe('Feature: auto-filling a login form on Android', () => { }) test('should prompt to store and not autosubmit when the form completes a partial credential stored', async ({page}) => { const {login} = await testLoginPage(page, { - featureToggles: { - inputType_credentials: true, - inlineIcon_credentials: true, - credentials_saving: true + configOverrides: { + featureToggles: { + inputType_credentials: true, + inlineIcon_credentials: true, + credentials_saving: true + }, + availableInputTypes: {credentials: {password: true, username: false}} }, - availableInputTypes: {credentials: {password: true, username: false}}, credentials: { ...credentials, username: '' @@ -145,10 +153,12 @@ test.describe('Feature: auto-filling a login form on Android', () => { test.describe('but I dont have saved credentials', () => { test('I should not be prompted', async ({page}) => { const {login} = await testLoginPage(page, { - featureToggles: { - inputType_credentials: true - }, - availableInputTypes: {} + configOverrides: { + featureToggles: { + inputType_credentials: true + }, + availableInputTypes: {} + } }) await login.promptWasNotShown() }) @@ -157,11 +167,13 @@ test.describe('Feature: auto-filling a login form on Android', () => { test.describe('when `inputType_credentials` is false', () => { test('I should not be prompted at all', async ({page}) => { const {login} = await testLoginPage(page, { - featureToggles: { - inputType_credentials: false - }, - availableInputTypes: { - credentials: {username: true, password: true} + configOverrides: { + featureToggles: { + inputType_credentials: false + }, + availableInputTypes: { + credentials: {username: true, password: true} + } }, credentials }) diff --git a/integration-test/tests/save-prompts.android.spec.js b/integration-test/tests/save-prompts.android.spec.js index e8082e044..7dff39c3d 100644 --- a/integration-test/tests/save-prompts.android.spec.js +++ b/integration-test/tests/save-prompts.android.spec.js @@ -1,9 +1,9 @@ import { - createAutofillScript, + createAutofillScript, defaultAndroidScript, forwardConsoleMessages } from '../helpers/harness.js' import {test as base} from '@playwright/test' -import {androidStringReplacements, createAndroidMocks} from '../helpers/mocks.android.js' +import {createAndroidMocks} from '../helpers/mocks.android.js' import {constants} from '../helpers/mocks.js' import {testContext} from '../helpers/test-context.js' import {signupPage} from '../helpers/pages/signupPage.js' @@ -30,17 +30,11 @@ test.describe('Android Save prompts', () => { const signup = signupPage(page) await signup.navigate() - await createAndroidMocks().applyTo(page) - - await createAutofillScript() - .replaceAll(androidStringReplacements({ - featureToggles: { - credentials_saving: true - } - })) - .platform('android') + await createAndroidMocks() .applyTo(page) + await defaultAndroidScript(page) + await signup.enterCredentials(credentials) await signup.assertWasPromptedToSave(credentials) }) @@ -52,18 +46,16 @@ test.describe('Android Save prompts', () => { await login.navigate() await createAndroidMocks() - .applyTo(page) - await createAutofillScript() - .replaceAll(androidStringReplacements({ + .withRuntimeConfigOverrides({ featureToggles: { credentials_saving: true }, availableInputTypes: { credentials: {username: false, password: false} } - })) - .platform('android') + }) .applyTo(page) + await defaultAndroidScript(page) return { login } } test('with username+password (should prompt)', async ({page}) => { @@ -96,22 +88,19 @@ test.describe('Android Save prompts', () => { const login = loginPage(page) await login.navigate() - /** @type {Partial} */ - const toggles = { - credentials_saving: false - } - await createAndroidMocks() + .withRuntimeConfigOverrides({ + featureToggles: { + credentials_saving: false + }, + availableInputTypes: { + credentials: {username: false, password: false} + } + }) .applyTo(page) // create + inject the script await createAutofillScript() - .replaceAll(androidStringReplacements({ - featureToggles: toggles, - availableInputTypes: { - credentials: {username: false, password: false} - } - })) .platform('android') .applyTo(page) @@ -139,18 +128,16 @@ test.describe('Android Save prompts', () => { await login.navigate('loginWithPoorForm') await createAndroidMocks() - .applyTo(page) - await createAutofillScript() - .replaceAll(androidStringReplacements({ + .withRuntimeConfigOverrides({ featureToggles: { credentials_saving: true }, availableInputTypes: { credentials: {username: false, password: false} } - })) - .platform('android') + }) .applyTo(page) + await defaultAndroidScript(page) await page.type('#password', credentials.password) await page.type('#email', credentials.username) diff --git a/packages/messaging/android.js b/packages/messaging/android.js new file mode 100644 index 000000000..dd99e8b73 --- /dev/null +++ b/packages/messaging/android.js @@ -0,0 +1,111 @@ +/** + * @module Android Messaging + * + * @description A wrapper for messaging on Android. See example usage in android.transport.js + */ +import { MissingHandler } from './messaging.js' + +/** + * @typedef {import("./messaging").MessagingTransport} MessagingTransport + */ + +/** + * On Android, handlers are added to the window object and are prefixed with `ddg`. The object looks like this: + * + * ```typescript + * { + * onMessage: undefined, + * postMessage: (message) => void, + * addEventListener: (eventType: string, Function) => void, + * removeEventListener: (eventType: string, Function) => void + * } + * ``` + * + * You send messages to `postMessage` and listen with `addEventListener`. Once the event is received, + * we also remove the listener with `removeEventListener`. + * + * @link https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener) + * @implements {MessagingTransport} + */ +export class AndroidMessagingTransport { + /** @type {AndroidMessagingConfig} */ + config + globals = {capturedHandlers: {}} + /** + * @param {AndroidMessagingConfig} config + */ + constructor (config) { + this.config = config + } + + /** + * Given the method name, returns the related Android handler + * @param {string} methodName + * @returns {AndroidHandler} + * @private + */ + _getHandler (methodName) { + const androidSpecificName = this._getHandlerName(methodName) + if (!(androidSpecificName in window)) { + throw new MissingHandler(`Missing android handler: '${methodName}'`, methodName) + } + return window[androidSpecificName] + } + + /** + * Given the autofill method name, it returns the Android-specific handler name + * @param {string} internalName + * @returns {string} + * @private + */ + _getHandlerName (internalName) { + return 'ddg' + internalName[0].toUpperCase() + internalName.slice(1) + } + + /** + * @param {string} name + * @param {Record} [data] + */ + notify (name, data = {}) { + const handler = this._getHandler(name) + const message = data ? JSON.stringify(data) : '' + handler.postMessage(message) + } + + /** + * @param {string} name + * @param {Record} [data] + */ + async request (name, data = {}) { + // Set up the listener first + const handler = this._getHandler(name) + + const responseOnce = new Promise((resolve) => { + const responseHandler = (e) => { + handler.removeEventListener('message', responseHandler) + resolve(e.data) + } + handler.addEventListener('message', responseHandler) + }) + + // Then send the message + this.notify(name, data) + + // And return once the promise resolves + const responseJSON = await responseOnce + return JSON.parse(responseJSON) + } +} + +/** + * Use this configuration to create an instance of {@link Messaging} for Android + */ +export class AndroidMessagingConfig { + /** + * All the expected Android handler names + * @param {{messageHandlerNames: string[]}} config + */ + constructor (config) { + this.messageHandlerNames = config.messageHandlerNames + } +} diff --git a/packages/messaging/messaging.js b/packages/messaging/messaging.js index ec940670e..6d4364271 100644 --- a/packages/messaging/messaging.js +++ b/packages/messaging/messaging.js @@ -51,13 +51,14 @@ * ``` */ import { WebkitMessagingConfig, WebkitMessagingTransport } from './webkit.js' +import { AndroidMessagingConfig, AndroidMessagingTransport } from './android.js' /** * @implements {MessagingTransport} */ export class Messaging { /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config */ constructor (config) { this.transport = getTransport(config) @@ -124,13 +125,16 @@ export class MessagingTransport { } /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config * @returns {MessagingTransport} */ function getTransport (config) { if (config instanceof WebkitMessagingConfig) { return new WebkitMessagingTransport(config) } + if (config instanceof AndroidMessagingConfig) { + return new AndroidMessagingTransport(config) + } throw new Error('unreachable') } diff --git a/src/DeviceInterface/AndroidInterface.js b/src/DeviceInterface/AndroidInterface.js index a8d7be924..25a1574a4 100644 --- a/src/DeviceInterface/AndroidInterface.js +++ b/src/DeviceInterface/AndroidInterface.js @@ -1,8 +1,14 @@ import InterfacePrototype from './InterfacePrototype.js' -import {sendAndWaitForAnswer} from '../autofill-utils.js' +import {formatDuckAddress} from '../autofill-utils.js' import { NativeUIController } from '../UI/controllers/NativeUIController.js' import { InContextSignup } from '../InContextSignup.js' -import { CloseEmailProtectionTabCall, ShowInContextEmailProtectionSignupPromptCall } from '../deviceApiCalls/__generated__/deviceApiCalls.js' +import { + CloseEmailProtectionTabCall, EmailProtectionGetAliasCall, + EmailProtectionGetCapabilitiesCall, + EmailProtectionGetUserDataCall, EmailProtectionRemoveUserDataCall, + EmailProtectionStoreUserDataCall, + ShowInContextEmailProtectionSignupPromptCall +} from '../deviceApiCalls/__generated__/deviceApiCalls.js' class AndroidInterface extends InterfacePrototype { inContextSignup = new InContextSignup(this) @@ -11,21 +17,29 @@ class AndroidInterface extends InterfacePrototype { * @returns {Promise} */ async getAlias () { - const { alias } = await sendAndWaitForAnswer(async () => { - if (this.inContextSignup.isAvailable()) { - const { isSignedIn } = await this.deviceApi.request(new ShowInContextEmailProtectionSignupPromptCall(null)) + // If in-context signup is available, do that first + if (this.inContextSignup.isAvailable()) { + const { isSignedIn } = await this.deviceApi.request(new ShowInContextEmailProtectionSignupPromptCall(null)) + if (isSignedIn) { // On Android we can't get the input type data again without // refreshing the page, so instead we can mutate it now that we // know the user has Email Protection available. - if (this.globalConfig.availableInputTypes) { - this.globalConfig.availableInputTypes.email = isSignedIn + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({email: isSignedIn}) } this.updateForStateChange() this.onFinishedAutofill() } - return window.EmailInterface.showTooltip() - }, 'getAliasResponse') - return alias + } + // Then, if successful actually prompt to fill + if (this.settings.availableInputTypes.email) { + const {alias} = await this.deviceApi.request(new EmailProtectionGetAliasCall({ + requiresUserPermission: !this.globalConfig.isApp, + shouldConsumeAliasIfProvided: !this.globalConfig.isApp, + isIncontextSignupAvailable: this.inContextSignup.isAvailable() + })) + return alias ? formatDuckAddress(alias) : undefined + } } /** @@ -40,14 +54,9 @@ class AndroidInterface extends InterfacePrototype { * @returns {boolean} */ isDeviceSignedIn () { - // on DDG domains, always check via `window.EmailInterface.isSignedIn()` - if (this.globalConfig.isDDGDomain) { - return window.EmailInterface.isSignedIn() === 'true' - } - // on non-DDG domains, where `availableInputTypes.email` is present, use it - if (typeof this.globalConfig.availableInputTypes?.email === 'boolean') { - return this.globalConfig.availableInputTypes.email + if (typeof this.settings.availableInputTypes?.email === 'boolean') { + return this.settings.availableInputTypes.email } // ...on other domains we assume true because the script wouldn't exist otherwise @@ -63,17 +72,7 @@ class AndroidInterface extends InterfacePrototype { * Settings page displays data of the logged in user data */ getUserData () { - let userData = null - - try { - userData = JSON.parse(window.EmailInterface.getUserData()) - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e) - } - } - - return Promise.resolve(userData) + return this.deviceApi.request(new EmailProtectionGetUserDataCall({})) } /** @@ -81,21 +80,11 @@ class AndroidInterface extends InterfacePrototype { * Device capabilities determine which functionality is available to the user */ getEmailProtectionCapabilities () { - let deviceCapabilities = null - - try { - deviceCapabilities = JSON.parse(window.EmailInterface.getDeviceCapabilities()) - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e) - } - } - - return Promise.resolve(deviceCapabilities) + return this.deviceApi.request(new EmailProtectionGetCapabilitiesCall({})) } - storeUserData ({addUserData: {token, userName, cohort}}) { - return window.EmailInterface.storeCredentials(token, userName, cohort) + storeUserData ({addUserData}) { + return this.deviceApi.request(new EmailProtectionStoreUserDataCall(addUserData)) } /** @@ -103,13 +92,7 @@ class AndroidInterface extends InterfacePrototype { * Provides functionality to log the user out */ removeUserData () { - try { - return window.EmailInterface.removeCredentials() - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e) - } - } + return this.deviceApi.request(new EmailProtectionRemoveUserDataCall({})) } /** diff --git a/src/DeviceInterface/InterfacePrototype.js b/src/DeviceInterface/InterfacePrototype.js index 0f4e3a1e5..92f4ab970 100644 --- a/src/DeviceInterface/InterfacePrototype.js +++ b/src/DeviceInterface/InterfacePrototype.js @@ -602,12 +602,19 @@ class InterfacePrototype { try { userData = await this.getUserData() } catch (e) { + if (this.isTestMode()) { + console.log('getUserData failed with', e) + } } let capabilities try { capabilities = await this.getEmailProtectionCapabilities() - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('capabilities fetching failed with', e) + } + } // Set up listener for web app actions if (this.globalConfig.isDDGDomain) { @@ -662,6 +669,11 @@ class InterfacePrototype { // This call doesn't send a response, so we can't know if it succeeded this.storeUserData(data) + // Assuming the previous call succeeded, let's update availableInputTypes + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({email: true}) + } + await this.setupAutofill() await this.settings.refresh() await this.setupSettingsPage({shouldLog: true}) diff --git a/src/DeviceInterface/WindowsInterface.js b/src/DeviceInterface/WindowsInterface.js index 6b1f39ffe..eb5a76ce5 100644 --- a/src/DeviceInterface/WindowsInterface.js +++ b/src/DeviceInterface/WindowsInterface.js @@ -85,13 +85,13 @@ export class WindowsInterface extends InterfacePrototype { } default: - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { console.warn('unhandled response', resp) } return this._closeAutofillParent() } } catch (e) { - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { if (e instanceof DOMException && e.name === 'AbortError') { console.log('Promise Aborted') } else { diff --git a/src/Form/Form.js b/src/Form/Form.js index 51982fa4f..9463030c2 100644 --- a/src/Form/Form.js +++ b/src/Form/Form.js @@ -163,7 +163,7 @@ class Form { } submitHandler (via = 'unknown') { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('Form.submitHandler via:', via, this) } diff --git a/src/Settings.js b/src/Settings.js index b271c1f89..ef0a2ba6d 100644 --- a/src/Settings.js +++ b/src/Settings.js @@ -138,6 +138,12 @@ export class Settings { if (this._runtimeConfiguration) return this._runtimeConfiguration const runtimeConfig = await this.deviceApi.request(new GetRuntimeConfigurationCall(null)) this._runtimeConfiguration = runtimeConfig + + // If the platform sends availableInputTypes here, store them + if (runtimeConfig.availableInputTypes) { + this.setAvailableInputTypes(runtimeConfig.availableInputTypes) + } + return this._runtimeConfiguration } @@ -153,6 +159,11 @@ export class Settings { if (this.globalConfig.isTopFrame) { return Settings.defaults.availableInputTypes } + + if (this._availableInputTypes) { + return this.availableInputTypes + } + return await this.deviceApi.request(new GetAvailableInputTypesCall(null)) } catch (e) { if (this.globalConfig.isDDGTestMode) { diff --git a/src/ThirdPartyProvider.js b/src/ThirdPartyProvider.js index c7d6f6e05..86fe804fd 100644 --- a/src/ThirdPartyProvider.js +++ b/src/ThirdPartyProvider.js @@ -61,7 +61,7 @@ export class ThirdPartyProvider { this.device.scanner.forms.forEach(form => form.recategorizeAllInputs()) } } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: providerStatusUpdated error: ❌', e) } } @@ -76,7 +76,7 @@ export class ThirdPartyProvider { } setTimeout(() => this._pollForUpdatesToCredentialsProvider(), 2000) } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: _pollForUpdatesToCredentialsProvider: ❌', e) } } diff --git a/src/UI/controllers/NativeUIController.js b/src/UI/controllers/NativeUIController.js index 186353e73..a890a0bcf 100644 --- a/src/UI/controllers/NativeUIController.js +++ b/src/UI/controllers/NativeUIController.js @@ -87,6 +87,10 @@ export class NativeUIController extends UIController { form.activeInput?.focus() break } + case 'none': { + // do nothing + break + } default: { if (args.device.isTestMode()) { console.warn('response not handled', resp) diff --git a/src/config.js b/src/config.js index 7930ac9b8..dd06af6d7 100644 --- a/src/config.js +++ b/src/config.js @@ -7,6 +7,10 @@ const DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.c * @returns {GlobalConfig} */ function createGlobalConfig (overrides) { + /** + * Defines whether it's one of our desktop apps + * @type {boolean} + */ let isApp = false let isTopFrame = false let supportsTopFrame = false diff --git a/src/deviceApiCalls/__generated__/deviceApiCalls.js b/src/deviceApiCalls/__generated__/deviceApiCalls.js index 55e51a5cc..cb31cf679 100644 --- a/src/deviceApiCalls/__generated__/deviceApiCalls.js +++ b/src/deviceApiCalls/__generated__/deviceApiCalls.js @@ -16,6 +16,8 @@ import { sendJSPixelParamsSchema, setIncontextSignupPermanentlyDismissedAtSchema, getIncontextSignupDismissedAtSchema, + emailProtectionGetAliasParamsSchema, + emailProtectionGetAliasResultSchema, emailProtectionStoreUserDataParamsSchema, emailProtectionGetIsLoggedInResultSchema, emailProtectionGetUserDataResultSchema, @@ -164,6 +166,15 @@ export class OpenManageIdentitiesCall extends DeviceApiCall { export class StartCredentialsImportFlowCall extends DeviceApiCall { method = "startCredentialsImportFlow" } +/** + * @extends {DeviceApiCall} + */ +export class EmailProtectionGetAliasCall extends DeviceApiCall { + method = "emailProtectionGetAlias" + id = "emailProtectionGetAliasResponse" + paramsValidator = emailProtectionGetAliasParamsSchema + resultValidator = emailProtectionGetAliasResultSchema +} /** * @extends {DeviceApiCall} */ diff --git a/src/deviceApiCalls/__generated__/validators-ts.ts b/src/deviceApiCalls/__generated__/validators-ts.ts index 691f094f2..4fdbd32b8 100644 --- a/src/deviceApiCalls/__generated__/validators-ts.ts +++ b/src/deviceApiCalls/__generated__/validators-ts.ts @@ -168,6 +168,15 @@ export interface API { startCredentialsImportFlow?: { [k: string]: unknown; }; + /** + * Used to prompt email protection autofill on mobile. + */ + emailProtectionGetAlias?: { + id?: "emailProtectionGetAliasResponse"; + paramsValidator?: EmailProtectionGetAliasParams; + resultValidator?: EmailProtectionGetAliasResult; + [k: string]: unknown; + }; /** * Used to store Email Protection auth credentials (logging in) */ @@ -347,6 +356,7 @@ export interface RuntimeConfiguration { contentScope: ContentScope; userUnprotectedDomains: string[]; userPreferences: UserPreferences; + availableInputTypes?: AvailableInputTypes; } export interface ContentScope { features: { @@ -376,6 +386,53 @@ export interface UserPreferences { }; }; } +/** + * For each main autofill types, it maps specific fields to their availability + */ +export interface AvailableInputTypes { + /** + * maps field types and the availability of data for the current site + */ + credentials?: { + username?: boolean; + password?: boolean; + }; + /** + * maps field types and the availability of data saved by the user + */ + identities?: { + firstName?: boolean; + middleName?: boolean; + lastName?: boolean; + birthdayDay?: boolean; + birthdayMonth?: boolean; + birthdayYear?: boolean; + addressStreet?: boolean; + addressStreet2?: boolean; + addressCity?: boolean; + addressProvince?: boolean; + addressPostalCode?: boolean; + addressCountryCode?: boolean; + phone?: boolean; + emailAddress?: boolean; + }; + /** + * maps field types and the availability of data saved by the user + */ + creditCards?: { + cardName?: boolean; + cardSecurityCode?: boolean; + expirationMonth?: boolean; + expirationYear?: boolean; + cardNumber?: boolean; + }; + /** + * true if signed in for Email Protection + */ + email?: boolean; + credentialsProviderStatus?: "locked" | "unlocked"; + credentialsImport?: boolean; +} /** * Autofill could send this data at any point. * @@ -400,13 +457,13 @@ export interface GetAvailableInputTypesResult { * A string used to identify this result. It's optional */ type?: "getAvailableInputTypesResponse"; - success: AvailableInputTypes; + success: AvailableInputTypes1; error?: GenericError; } /** * For each main autofill types, it maps specific fields to their availability */ -export interface AvailableInputTypes { +export interface AvailableInputTypes1 { /** * maps field types and the availability of data for the current site */ @@ -525,54 +582,7 @@ export interface AskToUnlockProviderResult { export interface ProviderStatusUpdated { status: "locked" | "unlocked"; credentials: Credentials[]; - availableInputTypes: AvailableInputTypes1; -} -/** - * For each main autofill types, it maps specific fields to their availability - */ -export interface AvailableInputTypes1 { - /** - * maps field types and the availability of data for the current site - */ - credentials?: { - username?: boolean; - password?: boolean; - }; - /** - * maps field types and the availability of data saved by the user - */ - identities?: { - firstName?: boolean; - middleName?: boolean; - lastName?: boolean; - birthdayDay?: boolean; - birthdayMonth?: boolean; - birthdayYear?: boolean; - addressStreet?: boolean; - addressStreet2?: boolean; - addressCity?: boolean; - addressProvince?: boolean; - addressPostalCode?: boolean; - addressCountryCode?: boolean; - phone?: boolean; - emailAddress?: boolean; - }; - /** - * maps field types and the availability of data saved by the user - */ - creditCards?: { - cardName?: boolean; - cardSecurityCode?: boolean; - expirationMonth?: boolean; - expirationYear?: boolean; - cardNumber?: boolean; - }; - /** - * true if signed in for Email Protection - */ - email?: boolean; - credentialsProviderStatus?: "locked" | "unlocked"; - credentialsImport?: boolean; + availableInputTypes: AvailableInputTypes; } /** * This is only used in macOS 10.15 Catalina @@ -634,6 +644,17 @@ export interface GetAliasResult { alias?: string; }; } +export interface EmailProtectionGetAliasParams { + requiresUserPermission: boolean; + shouldConsumeAliasIfProvided: boolean; + isIncontextSignupAvailable?: boolean; +} +export interface EmailProtectionGetAliasResult { + success?: { + alias: string; + }; + error?: GenericError; +} /** * Used to store Email Protection auth credentials. */ diff --git a/src/deviceApiCalls/__generated__/validators.zod.js b/src/deviceApiCalls/__generated__/validators.zod.js index 409cd6370..6241aa67a 100644 --- a/src/deviceApiCalls/__generated__/validators.zod.js +++ b/src/deviceApiCalls/__generated__/validators.zod.js @@ -66,6 +66,12 @@ export const getAliasResultSchema = z.object({ }) }); +export const emailProtectionGetAliasParamsSchema = z.object({ + requiresUserPermission: z.boolean(), + shouldConsumeAliasIfProvided: z.boolean(), + isIncontextSignupAvailable: z.boolean().optional() +}); + export const emailProtectionStoreUserDataParamsSchema = z.object({ token: z.string(), userName: z.string(), @@ -128,11 +134,6 @@ export const userPreferencesSchema = z.object({ })) }); -export const outgoingCredentialsSchema = z.object({ - username: z.string().optional(), - password: z.string().optional() -}); - export const availableInputTypesSchema = z.object({ credentials: z.object({ username: z.boolean().optional(), @@ -166,6 +167,11 @@ export const availableInputTypesSchema = z.object({ credentialsImport: z.boolean().optional() }); +export const outgoingCredentialsSchema = z.object({ + username: z.string().optional(), + password: z.string().optional() +}); + export const availableInputTypes1Schema = z.object({ credentials: z.object({ username: z.boolean().optional(), @@ -199,6 +205,12 @@ export const availableInputTypes1Schema = z.object({ credentialsImport: z.boolean().optional() }); +export const providerStatusUpdatedSchema = z.object({ + status: z.union([z.literal("locked"), z.literal("unlocked")]), + credentials: z.array(credentialsSchema), + availableInputTypes: availableInputTypesSchema +}); + export const autofillFeatureTogglesSchema = z.object({ inputType_credentials: z.boolean().optional(), inputType_identities: z.boolean().optional(), @@ -238,7 +250,7 @@ export const storeFormDataSchema = z.object({ export const getAvailableInputTypesResultSchema = z.object({ type: z.literal("getAvailableInputTypesResponse").optional(), - success: availableInputTypesSchema, + success: availableInputTypes1Schema, error: genericErrorSchema.optional() }); @@ -264,10 +276,29 @@ export const getAutofillCredentialsResultSchema = z.object({ error: genericErrorSchema.optional() }); +export const askToUnlockProviderResultSchema = z.object({ + type: z.literal("askToUnlockProviderResponse").optional(), + success: providerStatusUpdatedSchema, + error: genericErrorSchema.optional() +}); + +export const checkCredentialsProviderStatusResultSchema = z.object({ + type: z.literal("checkCredentialsProviderStatusResponse").optional(), + success: providerStatusUpdatedSchema, + error: genericErrorSchema.optional() +}); + export const autofillSettingsSchema = z.object({ featureToggles: autofillFeatureTogglesSchema }); +export const emailProtectionGetAliasResultSchema = z.object({ + success: z.object({ + alias: z.string() + }).optional(), + error: genericErrorSchema.optional() +}); + export const emailProtectionGetIsLoggedInResultSchema = z.object({ success: z.boolean().optional(), error: genericErrorSchema.optional() @@ -310,13 +341,8 @@ export const emailProtectionRefreshPrivateAddressResultSchema = z.object({ export const runtimeConfigurationSchema = z.object({ contentScope: contentScopeSchema, userUnprotectedDomains: z.array(z.string()), - userPreferences: userPreferencesSchema -}); - -export const providerStatusUpdatedSchema = z.object({ - status: z.union([z.literal("locked"), z.literal("unlocked")]), - credentials: z.array(credentialsSchema), - availableInputTypes: availableInputTypes1Schema + userPreferences: userPreferencesSchema, + availableInputTypes: availableInputTypesSchema.optional() }); export const getRuntimeConfigurationResponseSchema = z.object({ @@ -325,18 +351,6 @@ export const getRuntimeConfigurationResponseSchema = z.object({ error: genericErrorSchema.optional() }); -export const askToUnlockProviderResultSchema = z.object({ - type: z.literal("askToUnlockProviderResponse").optional(), - success: providerStatusUpdatedSchema, - error: genericErrorSchema.optional() -}); - -export const checkCredentialsProviderStatusResultSchema = z.object({ - type: z.literal("checkCredentialsProviderStatusResponse").optional(), - success: providerStatusUpdatedSchema, - error: genericErrorSchema.optional() -}); - export const apiSchema = z.object({ addDebugFlag: z.record(z.unknown()).and(z.object({ paramsValidator: addDebugFlagParamsSchema.optional() @@ -404,6 +418,11 @@ export const apiSchema = z.object({ openManageCreditCards: z.record(z.unknown()).optional(), openManageIdentities: z.record(z.unknown()).optional(), startCredentialsImportFlow: z.record(z.unknown()).optional(), + emailProtectionGetAlias: z.record(z.unknown()).and(z.object({ + id: z.literal("emailProtectionGetAliasResponse").optional(), + paramsValidator: emailProtectionGetAliasParamsSchema.optional(), + resultValidator: emailProtectionGetAliasResultSchema.optional() + })).optional(), emailProtectionStoreUserData: z.record(z.unknown()).and(z.object({ id: z.literal("emailProtectionStoreUserDataResponse").optional(), paramsValidator: emailProtectionStoreUserDataParamsSchema.optional() diff --git a/src/deviceApiCalls/api.json b/src/deviceApiCalls/api.json index 255a2b997..6093ec1e5 100644 --- a/src/deviceApiCalls/api.json +++ b/src/deviceApiCalls/api.json @@ -148,6 +148,15 @@ "type": "object", "description": "(macOS/Windows) Opens the native password import flow UI" }, + "emailProtectionGetAlias": { + "type": "object", + "description": "Used to prompt email protection autofill on mobile.", + "properties": { + "id": { "type": "string", "const": "emailProtectionGetAliasResponse"}, + "paramsValidator": { "$ref": "./schemas/emailProtectionGetAlias.params.json" }, + "resultValidator": { "$ref": "./schemas/emailProtectionGetAlias.result.json" } + } + }, "emailProtectionStoreUserData": { "type": "object", "description": "Used to store Email Protection auth credentials (logging in)", diff --git a/src/deviceApiCalls/schemas/emailProtectionGetAlias.params.json b/src/deviceApiCalls/schemas/emailProtectionGetAlias.params.json new file mode 100644 index 000000000..8d0957688 --- /dev/null +++ b/src/deviceApiCalls/schemas/emailProtectionGetAlias.params.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EmailProtectionGetAliasParams", + "type": "object", + "additionalProperties": false, + "properties": { + "requiresUserPermission": { + "type": "boolean" + }, + "shouldConsumeAliasIfProvided": { + "type": "boolean" + }, + "isIncontextSignupAvailable": { + "type": "boolean" + } + }, + "required": [ + "requiresUserPermission", + "shouldConsumeAliasIfProvided" + ] +} diff --git a/src/deviceApiCalls/schemas/emailProtectionGetAlias.result.json b/src/deviceApiCalls/schemas/emailProtectionGetAlias.result.json new file mode 100644 index 000000000..f2a38636b --- /dev/null +++ b/src/deviceApiCalls/schemas/emailProtectionGetAlias.result.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EmailProtectionGetAliasResult", + "type": "object", + "additionalProperties": false, + "properties": { + "success": { + "type": "object", + "additionalProperties": false, + "properties": { + "alias": { + "type": "string" + } + }, + "required": [ + "alias" + ] + }, + "error": { + "$ref": "./error.json" + } + } +} diff --git a/src/deviceApiCalls/schemas/runtime-configuration.json b/src/deviceApiCalls/schemas/runtime-configuration.json index d5299f0eb..b36c9f957 100644 --- a/src/deviceApiCalls/schemas/runtime-configuration.json +++ b/src/deviceApiCalls/schemas/runtime-configuration.json @@ -109,6 +109,9 @@ "features", "platform" ] + }, + "availableInputTypes": { + "$ref": "availableInputTypes.json" } }, "required": [ diff --git a/src/deviceApiCalls/transports/android.transport.js b/src/deviceApiCalls/transports/android.transport.js index d3464bb21..13300b8e3 100644 --- a/src/deviceApiCalls/transports/android.transport.js +++ b/src/deviceApiCalls/transports/android.transport.js @@ -1,15 +1,6 @@ import {DeviceApiTransport} from '../../../packages/device-api/index.js' -import { - CloseEmailProtectionTabCall, - GetAutofillDataCall, - GetAvailableInputTypesCall, - GetIncontextSignupDismissedAtCall, - GetRuntimeConfigurationCall, - SetIncontextSignupPermanentlyDismissedAtCall, - ShowInContextEmailProtectionSignupPromptCall, - StartEmailProtectionSignupCall, - StoreFormDataCall -} from '../__generated__/deviceApiCalls.js' +import {Messaging, MissingHandler} from '../../../packages/messaging/messaging.js' +import {AndroidMessagingConfig} from '../../../packages/messaging/android.js' export class AndroidTransport extends DeviceApiTransport { /** @type {GlobalConfig} */ @@ -19,137 +10,45 @@ export class AndroidTransport extends DeviceApiTransport { constructor (globalConfig) { super() this.config = globalConfig - - if (this.config.isDDGTestMode) { - if (typeof window.BrowserAutofill?.getAutofillData !== 'function') { - console.warn('window.BrowserAutofill.getAutofillData missing') - } - if (typeof window.BrowserAutofill?.storeFormData !== 'function') { - console.warn('window.BrowserAutofill.storeFormData missing') - } - } + const messageHandlerNames = [ + 'EmailProtectionStoreUserData', + 'EmailProtectionRemoveUserData', + 'EmailProtectionGetUserData', + 'EmailProtectionGetCapabilities', + 'EmailProtectionGetAlias', + 'SetIncontextSignupPermanentlyDismissedAt', + 'StartEmailProtectionSignup', + 'CloseEmailProtectionTab', + 'ShowInContextEmailProtectionSignupPrompt', + 'StoreFormData', + 'GetIncontextSignupDismissedAt', + 'GetRuntimeConfiguration', + 'GetAutofillData' + ] + const androidMessagingConfig = new AndroidMessagingConfig({messageHandlerNames}) + this.messaging = new Messaging(androidMessagingConfig) } /** * @param {import("../../../packages/device-api").DeviceApiCall} deviceApiCall * @returns {Promise} */ async send (deviceApiCall) { - if (deviceApiCall instanceof GetRuntimeConfigurationCall) { - return androidSpecificRuntimeConfiguration(this.config) - } - - if (deviceApiCall instanceof GetAvailableInputTypesCall) { - return androidSpecificAvailableInputTypes(this.config) - } - - if (deviceApiCall instanceof GetIncontextSignupDismissedAtCall) { - window.BrowserAutofill.getIncontextSignupDismissedAt(JSON.stringify(deviceApiCall.params)) - return waitForResponse(deviceApiCall.id, this.config) - } - - if (deviceApiCall instanceof SetIncontextSignupPermanentlyDismissedAtCall) { - return window.BrowserAutofill.setIncontextSignupPermanentlyDismissedAt(JSON.stringify(deviceApiCall.params)) - } - - if (deviceApiCall instanceof StartEmailProtectionSignupCall) { - return window.BrowserAutofill.startEmailProtectionSignup(JSON.stringify(deviceApiCall.params)) - } - - if (deviceApiCall instanceof CloseEmailProtectionTabCall) { - return window.BrowserAutofill.closeEmailProtectionTab(JSON.stringify(deviceApiCall.params)) - } - - if (deviceApiCall instanceof ShowInContextEmailProtectionSignupPromptCall) { - window.BrowserAutofill.showInContextEmailProtectionSignupPrompt(JSON.stringify(deviceApiCall.params)) - return waitForResponse(deviceApiCall.id, this.config) - } - - if (deviceApiCall instanceof GetAutofillDataCall) { - window.BrowserAutofill.getAutofillData(JSON.stringify(deviceApiCall.params)) - return waitForResponse(deviceApiCall.id, this.config) - } - - if (deviceApiCall instanceof StoreFormDataCall) { - return window.BrowserAutofill.storeFormData(JSON.stringify(deviceApiCall.params)) - } - - throw new Error('android: not implemented: ' + deviceApiCall.method) - } -} - -/** - * @param {string} expectedResponse - the name/id of the response - * @param {GlobalConfig} config - * @returns {Promise<*>} - */ -function waitForResponse (expectedResponse, config) { - return new Promise((resolve) => { - const handler = e => { - if (!config.isDDGTestMode) { - if (e.origin !== '') { - return - } - } - if (!e.data) { - return + try { + // if the call has an `id`, it means that it expects a response + if (deviceApiCall.id) { + return await this.messaging.request(deviceApiCall.method, deviceApiCall.params || undefined) + } else { + return this.messaging.notify(deviceApiCall.method, deviceApiCall.params || undefined) } - if (typeof e.data !== 'string') { - if (config.isDDGTestMode) { - console.log('❌ event.data was not a string. Expected a string so that it can be JSON parsed') + } catch (e) { + if (e instanceof MissingHandler) { + if (this.config.isDDGTestMode) { + console.log('MissingAndroidHandler error for:', deviceApiCall.method) } - return + throw new Error('unimplemented handler: ' + deviceApiCall.method) + } else { + throw e } - try { - let data = JSON.parse(e.data) - if (data.type === expectedResponse) { - window.removeEventListener('message', handler) - return resolve(data) - } - if (config.isDDGTestMode) { - console.log(`❌ event.data.type was '${data.type}', which didnt match '${expectedResponse}'`, JSON.stringify(data)) - } - } catch (e) { - window.removeEventListener('message', handler) - if (config.isDDGTestMode) { - console.log('❌ Could not JSON.parse the response') - } - } - } - window.addEventListener('message', handler) - }) -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').RuntimeConfiguration}} - */ -function androidSpecificRuntimeConfiguration (globalConfig) { - if (!globalConfig.userPreferences) { - throw new Error('globalConfig.userPreferences not supported yet on Android') - } - return { - success: { - // @ts-ignore - contentScope: globalConfig.contentScope, - // @ts-ignore - userPreferences: globalConfig.userPreferences, - // @ts-ignore - userUnprotectedDomains: globalConfig.userUnprotectedDomains, - // @ts-ignore - availableInputTypes: globalConfig.availableInputTypes } } } - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').AvailableInputTypes}} - */ -function androidSpecificAvailableInputTypes (globalConfig) { - if (!globalConfig.availableInputTypes) { - throw new Error('globalConfig.availableInputTypes not supported yet on Android') - } - return { - success: globalConfig.availableInputTypes - } -} diff --git a/swift-package/Resources/assets/autofill-debug.js b/swift-package/Resources/assets/autofill-debug.js index 31e570e2f..0734be99a 100644 --- a/swift-package/Resources/assets/autofill-debug.js +++ b/swift-package/Resources/assets/autofill-debug.js @@ -4591,6 +4591,130 @@ exports.DeviceApi = DeviceApi; },{}],15:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidMessagingTransport = exports.AndroidMessagingConfig = void 0; +var _messaging = require("./messaging.js"); +/** + * @module Android Messaging + * + * @description A wrapper for messaging on Android. See example usage in android.transport.js + */ + +/** + * @typedef {import("./messaging").MessagingTransport} MessagingTransport + */ + +/** + * On Android, handlers are added to the window object and are prefixed with `ddg`. The object looks like this: + * + * ```typescript + * { + * onMessage: undefined, + * postMessage: (message) => void, + * addEventListener: (eventType: string, Function) => void, + * removeEventListener: (eventType: string, Function) => void + * } + * ``` + * + * You send messages to `postMessage` and listen with `addEventListener`. Once the event is received, + * we also remove the listener with `removeEventListener`. + * + * @link https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener) + * @implements {MessagingTransport} + */ +class AndroidMessagingTransport { + /** @type {AndroidMessagingConfig} */ + config; + globals = { + capturedHandlers: {} + }; + /** + * @param {AndroidMessagingConfig} config + */ + constructor(config) { + this.config = config; + } + + /** + * Given the method name, returns the related Android handler + * @param {string} methodName + * @returns {AndroidHandler} + * @private + */ + _getHandler(methodName) { + const androidSpecificName = this._getHandlerName(methodName); + if (!(androidSpecificName in window)) { + throw new _messaging.MissingHandler(`Missing android handler: '${methodName}'`, methodName); + } + return window[androidSpecificName]; + } + + /** + * Given the autofill method name, it returns the Android-specific handler name + * @param {string} internalName + * @returns {string} + * @private + */ + _getHandlerName(internalName) { + return 'ddg' + internalName[0].toUpperCase() + internalName.slice(1); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + notify(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const handler = this._getHandler(name); + const message = data ? JSON.stringify(data) : ''; + handler.postMessage(message); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + async request(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + // Set up the listener first + const handler = this._getHandler(name); + const responseOnce = new Promise(resolve => { + const responseHandler = e => { + handler.removeEventListener('message', responseHandler); + resolve(e.data); + }; + handler.addEventListener('message', responseHandler); + }); + + // Then send the message + this.notify(name, data); + + // And return once the promise resolves + const responseJSON = await responseOnce; + return JSON.parse(responseJSON); + } +} + +/** + * Use this configuration to create an instance of {@link Messaging} for Android + */ +exports.AndroidMessagingTransport = AndroidMessagingTransport; +class AndroidMessagingConfig { + /** + * All the expected Android handler names + * @param {{messageHandlerNames: string[]}} config + */ + constructor(config) { + this.messageHandlerNames = config.messageHandlerNames; + } +} +exports.AndroidMessagingConfig = AndroidMessagingConfig; + +},{"./messaging.js":16}],16:[function(require,module,exports){ +"use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); @@ -4602,6 +4726,7 @@ Object.defineProperty(exports, "WebkitMessagingConfig", { } }); var _webkit = require("./webkit.js"); +var _android = require("./android.js"); /** * @module Messaging * @@ -4660,7 +4785,7 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config */ constructor(config) { this.transport = getTransport(config); @@ -4732,7 +4857,7 @@ class MessagingTransport { } /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config * @returns {MessagingTransport} */ exports.MessagingTransport = MessagingTransport; @@ -4740,6 +4865,9 @@ function getTransport(config) { if (config instanceof _webkit.WebkitMessagingConfig) { return new _webkit.WebkitMessagingTransport(config); } + if (config instanceof _android.AndroidMessagingConfig) { + return new _android.AndroidMessagingTransport(config); + } throw new Error('unreachable'); } @@ -4762,7 +4890,7 @@ class MissingHandler extends Error { */ exports.MissingHandler = MissingHandler; -},{"./webkit.js":16}],16:[function(require,module,exports){ +},{"./android.js":15,"./webkit.js":17}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5157,7 +5285,7 @@ function captureGlobals() { }; } -},{"./messaging.js":15}],17:[function(require,module,exports){ +},{"./messaging.js":16}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5288,7 +5416,7 @@ function _safeHostname(inputHostname) { } } -},{"./lib/apple.password.js":18,"./lib/constants.js":19,"./lib/rules-parser.js":20}],18:[function(require,module,exports){ +},{"./lib/apple.password.js":19,"./lib/constants.js":20,"./lib/rules-parser.js":21}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5817,7 +5945,7 @@ class Password { } exports.Password = Password; -},{"./constants.js":19,"./rules-parser.js":20}],19:[function(require,module,exports){ +},{"./constants.js":20,"./rules-parser.js":21}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5837,7 +5965,7 @@ const constants = exports.constants = { DEFAULT_UNAMBIGUOUS_CHARS }; -},{}],20:[function(require,module,exports){ +},{}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -6433,7 +6561,7 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return newPasswordRules; } -},{}],21:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ module.exports={ "163.com": { "password-rules": "minlength: 6; maxlength: 16;" @@ -7465,7 +7593,7 @@ module.exports={ "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 6; required: lower; required: upper; required: digit;" } } -},{}],22:[function(require,module,exports){ +},{}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7529,7 +7657,7 @@ class CredentialsImport { } exports.CredentialsImport = CredentialsImport; -},{"./deviceApiCalls/__generated__/deviceApiCalls.js":68}],23:[function(require,module,exports){ +},{"./deviceApiCalls/__generated__/deviceApiCalls.js":69}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7585,7 +7713,7 @@ function createDevice() { return new _ExtensionInterface.ExtensionInterface(globalConfig, deviceApi, settings); } -},{"../packages/device-api/index.js":12,"./DeviceInterface/AndroidInterface.js":24,"./DeviceInterface/AppleDeviceInterface.js":25,"./DeviceInterface/AppleOverlayDeviceInterface.js":26,"./DeviceInterface/ExtensionInterface.js":27,"./DeviceInterface/WindowsInterface.js":29,"./DeviceInterface/WindowsOverlayDeviceInterface.js":30,"./Settings.js":51,"./config.js":66,"./deviceApiCalls/transports/transports.js":74}],24:[function(require,module,exports){ +},{"../packages/device-api/index.js":12,"./DeviceInterface/AndroidInterface.js":25,"./DeviceInterface/AppleDeviceInterface.js":26,"./DeviceInterface/AppleOverlayDeviceInterface.js":27,"./DeviceInterface/ExtensionInterface.js":28,"./DeviceInterface/WindowsInterface.js":30,"./DeviceInterface/WindowsOverlayDeviceInterface.js":31,"./Settings.js":52,"./config.js":67,"./deviceApiCalls/transports/transports.js":75}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7605,25 +7733,35 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {Promise} */ async getAlias() { - const { - alias - } = await (0, _autofillUtils.sendAndWaitForAnswer)(async () => { - if (this.inContextSignup.isAvailable()) { - const { - isSignedIn - } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + // If in-context signup is available, do that first + if (this.inContextSignup.isAvailable()) { + const { + isSignedIn + } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + if (isSignedIn) { // On Android we can't get the input type data again without // refreshing the page, so instead we can mutate it now that we // know the user has Email Protection available. - if (this.globalConfig.availableInputTypes) { - this.globalConfig.availableInputTypes.email = isSignedIn; + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: isSignedIn + }); } this.updateForStateChange(); this.onFinishedAutofill(); } - return window.EmailInterface.showTooltip(); - }, 'getAliasResponse'); - return alias; + } + // Then, if successful actually prompt to fill + if (this.settings.availableInputTypes.email) { + const { + alias + } = await this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetAliasCall({ + requiresUserPermission: !this.globalConfig.isApp, + shouldConsumeAliasIfProvided: !this.globalConfig.isApp, + isIncontextSignupAvailable: this.inContextSignup.isAvailable() + })); + return alias ? (0, _autofillUtils.formatDuckAddress)(alias) : undefined; + } } /** @@ -7638,14 +7776,9 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {boolean} */ isDeviceSignedIn() { - // on DDG domains, always check via `window.EmailInterface.isSignedIn()` - if (this.globalConfig.isDDGDomain) { - return window.EmailInterface.isSignedIn() === 'true'; - } - // on non-DDG domains, where `availableInputTypes.email` is present, use it - if (typeof this.globalConfig.availableInputTypes?.email === 'boolean') { - return this.globalConfig.availableInputTypes.email; + if (typeof this.settings.availableInputTypes?.email === 'boolean') { + return this.settings.availableInputTypes.email; } // ...on other domains we assume true because the script wouldn't exist otherwise @@ -7660,15 +7793,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Settings page displays data of the logged in user data */ getUserData() { - let userData = null; - try { - userData = JSON.parse(window.EmailInterface.getUserData()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(userData); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetUserDataCall({})); } /** @@ -7676,25 +7801,13 @@ class AndroidInterface extends _InterfacePrototype.default { * Device capabilities determine which functionality is available to the user */ getEmailProtectionCapabilities() { - let deviceCapabilities = null; - try { - deviceCapabilities = JSON.parse(window.EmailInterface.getDeviceCapabilities()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(deviceCapabilities); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetCapabilitiesCall({})); } storeUserData(_ref) { let { - addUserData: { - token, - userName, - cohort - } + addUserData } = _ref; - return window.EmailInterface.storeCredentials(token, userName, cohort); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionStoreUserDataCall(addUserData)); } /** @@ -7702,13 +7815,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Provides functionality to log the user out */ removeUserData() { - try { - return window.EmailInterface.removeCredentials(); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionRemoveUserDataCall({})); } /** @@ -7733,7 +7840,7 @@ class AndroidInterface extends _InterfacePrototype.default { } exports.AndroidInterface = AndroidInterface; -},{"../InContextSignup.js":45,"../UI/controllers/NativeUIController.js":59,"../autofill-utils.js":64,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./InterfacePrototype.js":28}],25:[function(require,module,exports){ +},{"../InContextSignup.js":46,"../UI/controllers/NativeUIController.js":60,"../autofill-utils.js":65,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./InterfacePrototype.js":29}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8089,7 +8196,7 @@ class AppleDeviceInterface extends _InterfacePrototype.default { } exports.AppleDeviceInterface = AppleDeviceInterface; -},{"../../packages/device-api/index.js":12,"../Form/matching.js":44,"../InContextSignup.js":45,"../ThirdPartyProvider.js":52,"../UI/HTMLTooltip.js":57,"../UI/controllers/HTMLTooltipUIController.js":58,"../UI/controllers/NativeUIController.js":59,"../UI/controllers/OverlayUIController.js":60,"../autofill-utils.js":64,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"../deviceApiCalls/additionalDeviceApiCalls.js":70,"./InterfacePrototype.js":28}],26:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"../Form/matching.js":45,"../InContextSignup.js":46,"../ThirdPartyProvider.js":53,"../UI/HTMLTooltip.js":58,"../UI/controllers/HTMLTooltipUIController.js":59,"../UI/controllers/NativeUIController.js":60,"../UI/controllers/OverlayUIController.js":61,"../autofill-utils.js":65,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"../deviceApiCalls/additionalDeviceApiCalls.js":71,"./InterfacePrototype.js":29}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8208,7 +8315,7 @@ class AppleOverlayDeviceInterface extends _AppleDeviceInterface.AppleDeviceInter } exports.AppleOverlayDeviceInterface = AppleOverlayDeviceInterface; -},{"../../packages/device-api/index.js":12,"../UI/controllers/HTMLTooltipUIController.js":58,"./AppleDeviceInterface.js":25,"./overlayApi.js":32}],27:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"../UI/controllers/HTMLTooltipUIController.js":59,"./AppleDeviceInterface.js":26,"./overlayApi.js":33}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8427,7 +8534,7 @@ class ExtensionInterface extends _InterfacePrototype.default { } exports.ExtensionInterface = ExtensionInterface; -},{"../Form/matching.js":44,"../InContextSignup.js":45,"../UI/HTMLTooltip.js":57,"../UI/controllers/HTMLTooltipUIController.js":58,"../autofill-utils.js":64,"./InterfacePrototype.js":28}],28:[function(require,module,exports){ +},{"../Form/matching.js":45,"../InContextSignup.js":46,"../UI/HTMLTooltip.js":58,"../UI/controllers/HTMLTooltipUIController.js":59,"../autofill-utils.js":65,"./InterfacePrototype.js":29}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9030,11 +9137,19 @@ class InterfacePrototype { let userData; try { userData = await this.getUserData(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('getUserData failed with', e); + } + } let capabilities; try { capabilities = await this.getEmailProtectionCapabilities(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('capabilities fetching failed with', e); + } + } // Set up listener for web app actions if (this.globalConfig.isDDGDomain) { @@ -9090,6 +9205,13 @@ class InterfacePrototype { const data = await (0, _autofillUtils.sendAndWaitForAnswer)(_autofillUtils.SIGN_IN_MSG, 'addUserData'); // This call doesn't send a response, so we can't know if it succeeded this.storeUserData(data); + + // Assuming the previous call succeeded, let's update availableInputTypes + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: true + }); + } await this.setupAutofill(); await this.settings.refresh(); await this.setupSettingsPage({ @@ -9258,7 +9380,7 @@ class InterfacePrototype { } var _default = exports.default = InterfacePrototype; -},{"../../packages/device-api/index.js":12,"../CredentialsImport.js":22,"../EmailProtection.js":33,"../Form/formatters.js":37,"../Form/matching.js":44,"../InputTypes/Credentials.js":46,"../PasswordGenerator.js":49,"../Scanner.js":50,"../Settings.js":51,"../UI/controllers/NativeUIController.js":59,"../autofill-utils.js":64,"../config.js":66,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"../deviceApiCalls/transports/transports.js":74,"../locales/strings.js":99,"./initFormSubmissionsApi.js":31}],29:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"../CredentialsImport.js":23,"../EmailProtection.js":34,"../Form/formatters.js":38,"../Form/matching.js":45,"../InputTypes/Credentials.js":47,"../PasswordGenerator.js":50,"../Scanner.js":51,"../Settings.js":52,"../UI/controllers/NativeUIController.js":60,"../autofill-utils.js":65,"../config.js":67,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"../deviceApiCalls/transports/transports.js":75,"../locales/strings.js":100,"./initFormSubmissionsApi.js":32}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9343,13 +9465,13 @@ class WindowsInterface extends _InterfacePrototype.default { return await this.credentialsImport.refresh(); } default: - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { console.warn('unhandled response', resp); } return this._closeAutofillParent(); } } catch (e) { - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { if (e instanceof DOMException && e.name === 'AbortError') { console.log('Promise Aborted'); } else { @@ -9424,7 +9546,7 @@ class WindowsInterface extends _InterfacePrototype.default { } exports.WindowsInterface = WindowsInterface; -},{"../UI/controllers/OverlayUIController.js":60,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./InterfacePrototype.js":28}],30:[function(require,module,exports){ +},{"../UI/controllers/OverlayUIController.js":61,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./InterfacePrototype.js":29}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9603,7 +9725,7 @@ class WindowsOverlayDeviceInterface extends _InterfacePrototype.default { } exports.WindowsOverlayDeviceInterface = WindowsOverlayDeviceInterface; -},{"../UI/controllers/HTMLTooltipUIController.js":58,"../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./InterfacePrototype.js":28,"./overlayApi.js":32}],31:[function(require,module,exports){ +},{"../UI/controllers/HTMLTooltipUIController.js":59,"../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./InterfacePrototype.js":29,"./overlayApi.js":33}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9702,7 +9824,7 @@ function initFormSubmissionsApi(forms, matching) { }); } -},{"../Form/label-util.js":40,"../autofill-utils.js":64}],32:[function(require,module,exports){ +},{"../Form/label-util.js":41,"../autofill-utils.js":65}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9760,7 +9882,7 @@ function overlayApi(device) { }; } -},{"../deviceApiCalls/__generated__/deviceApiCalls.js":68}],33:[function(require,module,exports){ +},{"../deviceApiCalls/__generated__/deviceApiCalls.js":69}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9795,7 +9917,7 @@ class EmailProtection { } exports.EmailProtection = EmailProtection; -},{}],34:[function(require,module,exports){ +},{}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9935,7 +10057,7 @@ class Form { } submitHandler() { let via = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown'; - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('Form.submitHandler via:', via, this); } if (this.submitHandlerExecuted) return; @@ -10702,7 +10824,7 @@ class Form { } exports.Form = Form; -},{"../InputTypes/Credentials.js":46,"../autofill-utils.js":64,"../constants.js":67,"./FormAnalyzer.js":35,"./formatters.js":37,"./inputStyles.js":38,"./inputTypeConfig.js":39,"./matching.js":44}],35:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":47,"../autofill-utils.js":65,"../constants.js":68,"./FormAnalyzer.js":36,"./formatters.js":38,"./inputStyles.js":39,"./inputTypeConfig.js":40,"./matching.js":45}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11072,7 +11194,7 @@ class FormAnalyzer { } var _default = exports.default = FormAnalyzer; -},{"../autofill-utils.js":64,"../constants.js":67,"./matching-config/__generated__/compiled-matching-config.js":42,"./matching.js":44}],36:[function(require,module,exports){ +},{"../autofill-utils.js":65,"../constants.js":68,"./matching-config/__generated__/compiled-matching-config.js":43,"./matching.js":45}],37:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11637,7 +11759,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { 'Unknown Region': 'ZZ' }; -},{}],37:[function(require,module,exports){ +},{}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11942,7 +12064,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":36,"./matching.js":44}],38:[function(require,module,exports){ +},{"./countryNames.js":37,"./matching.js":45}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12033,7 +12155,7 @@ const getIconStylesAutofilled = (input, form) => { }; exports.getIconStylesAutofilled = getIconStylesAutofilled; -},{"./inputTypeConfig.js":39}],39:[function(require,module,exports){ +},{"./inputTypeConfig.js":40}],40:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12287,7 +12409,7 @@ const isFieldDecorated = input => { }; exports.isFieldDecorated = isFieldDecorated; -},{"../InputTypes/Credentials.js":46,"../InputTypes/CreditCard.js":47,"../InputTypes/Identity.js":48,"../UI/img/ddgPasswordIcon.js":62,"../constants.js":67,"./logo-svg.js":41,"./matching.js":44}],40:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":47,"../InputTypes/CreditCard.js":48,"../InputTypes/Identity.js":49,"../UI/img/ddgPasswordIcon.js":63,"../constants.js":68,"./logo-svg.js":42,"./matching.js":45}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12335,7 +12457,7 @@ const extractElementStrings = element => { }; exports.extractElementStrings = extractElementStrings; -},{"./matching.js":44}],41:[function(require,module,exports){ +},{"./matching.js":45}],42:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12368,7 +12490,7 @@ const daxGrayscaleSvg = ` `.trim(); const daxGrayscaleBase64 = exports.daxGrayscaleBase64 = `data:image/svg+xml;base64,${window.btoa(daxGrayscaleSvg)}`; -},{}],42:[function(require,module,exports){ +},{}],43:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12821,7 +12943,7 @@ const matchingConfiguration = exports.matchingConfiguration = { } }; -},{}],43:[function(require,module,exports){ +},{}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12896,7 +13018,7 @@ function logUnmatched(el, allStrings) { console.groupEnd(); } -},{"../autofill-utils.js":64,"./matching.js":44}],44:[function(require,module,exports){ +},{"../autofill-utils.js":65,"./matching.js":45}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13888,7 +14010,7 @@ function createMatching() { return new Matching(_compiledMatchingConfig.matchingConfiguration); } -},{"../autofill-utils.js":64,"../constants.js":67,"./label-util.js":40,"./matching-config/__generated__/compiled-matching-config.js":42,"./matching-utils.js":43}],45:[function(require,module,exports){ +},{"../autofill-utils.js":65,"../constants.js":68,"./label-util.js":41,"./matching-config/__generated__/compiled-matching-config.js":43,"./matching-utils.js":44}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14020,7 +14142,7 @@ class InContextSignup { } exports.InContextSignup = InContextSignup; -},{"./autofill-utils.js":64,"./deviceApiCalls/__generated__/deviceApiCalls.js":68}],46:[function(require,module,exports){ +},{"./autofill-utils.js":65,"./deviceApiCalls/__generated__/deviceApiCalls.js":69}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14176,7 +14298,7 @@ function createCredentialsTooltipItem(data) { return new CredentialsTooltipItem(data); } -},{"../autofill-utils.js":64}],47:[function(require,module,exports){ +},{"../autofill-utils.js":65}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14201,7 +14323,7 @@ class CreditCardTooltipItem { } exports.CreditCardTooltipItem = CreditCardTooltipItem; -},{}],48:[function(require,module,exports){ +},{}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14247,7 +14369,7 @@ class IdentityTooltipItem { } exports.IdentityTooltipItem = IdentityTooltipItem; -},{"../Form/formatters.js":37}],49:[function(require,module,exports){ +},{"../Form/formatters.js":38}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14289,7 +14411,7 @@ class PasswordGenerator { } exports.PasswordGenerator = PasswordGenerator; -},{"../packages/password/index.js":17,"../packages/password/rules.json":21}],50:[function(require,module,exports){ +},{"../packages/password/index.js":18,"../packages/password/rules.json":22}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14750,7 +14872,7 @@ function createScanner(device, scannerOptions) { }); } -},{"./Form/Form.js":34,"./Form/matching.js":44,"./autofill-utils.js":64,"./constants.js":67,"./deviceApiCalls/__generated__/deviceApiCalls.js":68}],51:[function(require,module,exports){ +},{"./Form/Form.js":35,"./Form/matching.js":45,"./autofill-utils.js":65,"./constants.js":68,"./deviceApiCalls/__generated__/deviceApiCalls.js":69}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14896,6 +15018,11 @@ class Settings { if (this._runtimeConfiguration) return this._runtimeConfiguration; const runtimeConfig = await this.deviceApi.request(new _deviceApiCalls.GetRuntimeConfigurationCall(null)); this._runtimeConfiguration = runtimeConfig; + + // If the platform sends availableInputTypes here, store them + if (runtimeConfig.availableInputTypes) { + this.setAvailableInputTypes(runtimeConfig.availableInputTypes); + } return this._runtimeConfiguration; } @@ -14911,6 +15038,9 @@ class Settings { if (this.globalConfig.isTopFrame) { return Settings.defaults.availableInputTypes; } + if (this._availableInputTypes) { + return this.availableInputTypes; + } return await this.deviceApi.request(new _deviceApiCalls.GetAvailableInputTypesCall(null)); } catch (e) { if (this.globalConfig.isDDGTestMode) { @@ -15163,7 +15293,7 @@ class Settings { } exports.Settings = Settings; -},{"../packages/device-api/index.js":12,"./autofill-utils.js":64,"./deviceApiCalls/__generated__/deviceApiCalls.js":68,"./deviceApiCalls/__generated__/validators.zod.js":69}],52:[function(require,module,exports){ +},{"../packages/device-api/index.js":12,"./autofill-utils.js":65,"./deviceApiCalls/__generated__/deviceApiCalls.js":69,"./deviceApiCalls/__generated__/validators.zod.js":70}],53:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15230,7 +15360,7 @@ class ThirdPartyProvider { this.device.scanner.forms.forEach(form => form.recategorizeAllInputs()); } } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: providerStatusUpdated error: ❌', e); } } @@ -15245,7 +15375,7 @@ class ThirdPartyProvider { } setTimeout(() => this._pollForUpdatesToCredentialsProvider(), 2000); } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: _pollForUpdatesToCredentialsProvider: ❌', e); } } @@ -15253,7 +15383,7 @@ class ThirdPartyProvider { } exports.ThirdPartyProvider = ThirdPartyProvider; -},{"../packages/device-api/index.js":12,"./Form/matching.js":44,"./deviceApiCalls/__generated__/deviceApiCalls.js":68,"./deviceApiCalls/__generated__/validators.zod.js":69}],53:[function(require,module,exports){ +},{"../packages/device-api/index.js":12,"./Form/matching.js":45,"./deviceApiCalls/__generated__/deviceApiCalls.js":69,"./deviceApiCalls/__generated__/validators.zod.js":70}],54:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15294,7 +15424,7 @@ ${this.options.css} } var _default = exports.default = CredentialsImportTooltip; -},{"./HTMLTooltip.js":57}],54:[function(require,module,exports){ +},{"./HTMLTooltip.js":58}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15445,7 +15575,7 @@ ${css} } var _default = exports.default = DataHTMLTooltip; -},{"../InputTypes/Credentials.js":46,"../autofill-utils.js":64,"./HTMLTooltip.js":57}],55:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":47,"../autofill-utils.js":65,"./HTMLTooltip.js":58}],56:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15527,7 +15657,7 @@ ${this.options.css} } var _default = exports.default = EmailHTMLTooltip; -},{"../autofill-utils.js":64,"./HTMLTooltip.js":57}],56:[function(require,module,exports){ +},{"../autofill-utils.js":65,"./HTMLTooltip.js":58}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15580,7 +15710,7 @@ ${this.options.css} } var _default = exports.default = EmailSignupHTMLTooltip; -},{"./HTMLTooltip.js":57}],57:[function(require,module,exports){ +},{"./HTMLTooltip.js":58}],58:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -15968,7 +16098,7 @@ class HTMLTooltip { exports.HTMLTooltip = HTMLTooltip; var _default = exports.default = HTMLTooltip; -},{"../Form/matching.js":44,"../autofill-utils.js":64,"./styles/styles.js":63}],58:[function(require,module,exports){ +},{"../Form/matching.js":45,"../autofill-utils.js":65,"./styles/styles.js":64}],59:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16336,7 +16466,7 @@ class HTMLTooltipUIController extends _UIController.UIController { } exports.HTMLTooltipUIController = HTMLTooltipUIController; -},{"../../Form/inputTypeConfig.js":39,"../../Form/matching.js":44,"../../autofill-utils.js":64,"../CredentialsImportTooltip.js":53,"../DataHTMLTooltip.js":54,"../EmailHTMLTooltip.js":55,"../EmailSignupHTMLTooltip.js":56,"../HTMLTooltip.js":57,"./UIController.js":61}],59:[function(require,module,exports){ +},{"../../Form/inputTypeConfig.js":40,"../../Form/matching.js":45,"../../autofill-utils.js":65,"../CredentialsImportTooltip.js":54,"../DataHTMLTooltip.js":55,"../EmailHTMLTooltip.js":56,"../EmailSignupHTMLTooltip.js":57,"../HTMLTooltip.js":58,"./UIController.js":62}],60:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16438,6 +16568,11 @@ class NativeUIController extends _UIController.UIController { form.activeInput?.focus(); break; } + case 'none': + { + // do nothing + break; + } default: { if (args.device.isTestMode()) { @@ -16498,7 +16633,7 @@ class NativeUIController extends _UIController.UIController { } exports.NativeUIController = NativeUIController; -},{"../../Form/matching.js":44,"../../InputTypes/Credentials.js":46,"../../deviceApiCalls/__generated__/deviceApiCalls.js":68,"./UIController.js":61}],60:[function(require,module,exports){ +},{"../../Form/matching.js":45,"../../InputTypes/Credentials.js":47,"../../deviceApiCalls/__generated__/deviceApiCalls.js":69,"./UIController.js":62}],61:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16735,7 +16870,7 @@ class OverlayUIController extends _UIController.UIController { } exports.OverlayUIController = OverlayUIController; -},{"../../Form/matching.js":44,"./UIController.js":61}],61:[function(require,module,exports){ +},{"../../Form/matching.js":45,"./UIController.js":62}],62:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16819,7 +16954,7 @@ class UIController { } exports.UIController = UIController; -},{}],62:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16836,7 +16971,7 @@ const ddgCcIconBase = exports.ddgCcIconBase = 'data:image/svg+xml;base64,PD94bWw const ddgCcIconFilled = exports.ddgCcIconFilled = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzc2NDMxMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjNzY0MzEwIi8+Cjwvc3ZnPgo='; const ddgIdentityIconBase = exports.ddgIdentityIconBase = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4KPHBhdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJub25lIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyMWMyLjE0MyAwIDQuMTExLS43NSA1LjY1Ny0yLS42MjYtLjUwNi0xLjMxOC0uOTI3LTIuMDYtMS4yNS0xLjEtLjQ4LTIuMjg1LS43MzUtMy40ODYtLjc1LTEuMi0uMDE0LTIuMzkyLjIxMS0zLjUwNC42NjQtLjgxNy4zMzMtMS41OC43ODMtMi4yNjQgMS4zMzYgMS41NDYgMS4yNSAzLjUxNCAyIDUuNjU3IDJ6bTQuMzk3LTUuMDgzYy45NjcuNDIyIDEuODY2Ljk4IDIuNjcyIDEuNjU1QzIwLjI3OSAxNi4wMzkgMjEgMTQuMTA0IDIxIDEyYzAtNC45Ny00LjAzLTktOS05cy05IDQuMDMtOSA5YzAgMi4xMDQuNzIyIDQuMDQgMS45MzIgNS41NzIuODc0LS43MzQgMS44Ni0xLjMyOCAyLjkyMS0xLjc2IDEuMzYtLjU1NCAyLjgxNi0uODMgNC4yODMtLjgxMSAxLjQ2Ny4wMTggMi45MTYuMzMgNC4yNi45MTZ6TTEyIDIzYzYuMDc1IDAgMTEtNC45MjUgMTEtMTFTMTguMDc1IDEgMTIgMSAxIDUuOTI1IDEgMTJzNC45MjUgMTEgMTEgMTF6bTMtMTNjMCAxLjY1Ny0xLjM0MyAzLTMgM3MtMy0xLjM0My0zLTMgMS4zNDMtMyAzLTMgMyAxLjM0MyAzIDN6bTIgMGMwIDIuNzYxLTIuMjM5IDUtNSA1cy01LTIuMjM5LTUtNSAyLjIzOS01IDUtNSA1IDIuMjM5IDUgNXoiIGZpbGw9IiMwMDAiLz4KPC9zdmc+Cg==`; -},{}],63:[function(require,module,exports){ +},{}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16845,7 +16980,7 @@ Object.defineProperty(exports, "__esModule", { exports.CSS_STYLES = void 0; const CSS_STYLES = exports.CSS_STYLES = ":root {\n color-scheme: light dark;\n}\n\n.wrapper *, .wrapper *::before, .wrapper *::after {\n box-sizing: border-box;\n}\n.wrapper {\n position: fixed;\n top: 0;\n left: 0;\n padding: 0;\n font-family: 'DDG_ProximaNova', 'Proxima Nova', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n z-index: 2147483647;\n}\n.wrapper--data {\n font-family: 'SF Pro Text', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n}\n.wrapper:not(.top-autofill) .tooltip {\n position: absolute;\n width: 300px;\n max-width: calc(100vw - 25px);\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--data, #topAutofill {\n background-color: rgba(242, 240, 240, 1);\n -webkit-backdrop-filter: blur(40px);\n backdrop-filter: blur(40px);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data, #topAutofill {\n background: rgb(100, 98, 102, .9);\n }\n}\n.tooltip--data {\n padding: 6px;\n font-size: 13px;\n line-height: 14px;\n width: 315px;\n max-height: 290px;\n overflow-y: auto;\n}\n.top-autofill .tooltip--data {\n min-height: 100vh;\n}\n.tooltip--data.tooltip--incontext-signup {\n width: 360px;\n}\n.wrapper:not(.top-autofill) .tooltip--data {\n top: 100%;\n left: 100%;\n border: 0.5px solid rgba(255, 255, 255, 0.2);\n border-radius: 6px;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.32);\n}\n@media (prefers-color-scheme: dark) {\n .wrapper:not(.top-autofill) .tooltip--data {\n border: 1px solid rgba(255, 255, 255, 0.2);\n }\n}\n.wrapper:not(.top-autofill) .tooltip--email {\n top: calc(100% + 6px);\n right: calc(100% - 48px);\n padding: 8px;\n border: 1px solid #D0D0D0;\n border-radius: 10px;\n background-color: #FFFFFF;\n font-size: 14px;\n line-height: 1.3;\n color: #333333;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);\n}\n.tooltip--email__caret {\n position: absolute;\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--email__caret::before,\n.tooltip--email__caret::after {\n content: \"\";\n width: 0;\n height: 0;\n border-left: 10px solid transparent;\n border-right: 10px solid transparent;\n display: block;\n border-bottom: 8px solid #D0D0D0;\n position: absolute;\n right: -28px;\n}\n.tooltip--email__caret::before {\n border-bottom-color: #D0D0D0;\n top: -1px;\n}\n.tooltip--email__caret::after {\n border-bottom-color: #FFFFFF;\n top: 0px;\n}\n\n/* Buttons */\n.tooltip__button {\n display: flex;\n width: 100%;\n padding: 8px 8px 8px 0px;\n font-family: inherit;\n color: inherit;\n background: transparent;\n border: none;\n border-radius: 6px;\n text-align: left;\n}\n.tooltip__button.currentFocus,\n.wrapper:not(.top-autofill) .tooltip__button:hover {\n background-color: #3969EF;\n color: #FFFFFF;\n}\n\n/* Data autofill tooltip specific */\n.tooltip__button--data {\n position: relative;\n min-height: 48px;\n flex-direction: row;\n justify-content: flex-start;\n font-size: inherit;\n font-weight: 500;\n line-height: 16px;\n text-align: left;\n border-radius: 3px;\n}\n.tooltip--data__item-container {\n max-height: 220px;\n overflow: auto;\n}\n.tooltip__button--data:first-child {\n margin-top: 0;\n}\n.tooltip__button--data:last-child {\n margin-bottom: 0;\n}\n.tooltip__button--data::before {\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 20px 20px;\n background-repeat: no-repeat;\n background-position: center center;\n}\n#provider_locked::after {\n position: absolute;\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 11px 13px;\n background-repeat: no-repeat;\n background-position: right bottom;\n}\n.tooltip__button--data.currentFocus:not(.tooltip__button--data--bitwarden)::before,\n.wrapper:not(.top-autofill) .tooltip__button--data:not(.tooltip__button--data--bitwarden):hover::before {\n filter: invert(100%);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before,\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before {\n filter: invert(100%);\n opacity: .9;\n }\n}\n.tooltip__button__text-container {\n margin: auto 0;\n}\n.label {\n display: block;\n font-weight: 400;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.8);\n font-size: 13px;\n line-height: 1;\n}\n.label + .label {\n margin-top: 2px;\n}\n.label.label--medium {\n font-weight: 500;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.9);\n}\n.label.label--small {\n font-size: 11px;\n font-weight: 400;\n letter-spacing: 0.06px;\n color: rgba(0,0,0,0.6);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data .label {\n color: #ffffff;\n }\n .tooltip--data .label--medium {\n color: #ffffff;\n }\n .tooltip--data .label--small {\n color: #cdcdcd;\n }\n}\n.tooltip__button.currentFocus .label,\n.wrapper:not(.top-autofill) .tooltip__button:hover .label {\n color: #FFFFFF;\n}\n\n.tooltip__button--manage {\n font-size: 13px;\n padding: 5px 9px;\n border-radius: 3px;\n margin: 0;\n}\n\n/* Icons */\n.tooltip__button--data--credentials::before,\n.tooltip__button--data--credentials__current::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS4zMzQgNi42NjdhMiAyIDAgMSAwIDAgNCAyIDIgMCAwIDAgMC00Wm0tLjY2NyAyYS42NjcuNjY3IDAgMSAxIDEuMzMzIDAgLjY2Ny42NjcgMCAwIDEtMS4zMzMgMFoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTQuNjY3IDRhNS4zMzMgNS4zMzMgMCAwIDAtNS4xODggNi41NzhsLTUuMjg0IDUuMjg0YS42NjcuNjY3IDAgMCAwLS4xOTUuNDcxdjNjMCAuMzY5LjI5OC42NjcuNjY3LjY2N2gyLjY2NmMuNzM3IDAgMS4zMzQtLjU5NyAxLjMzNC0xLjMzM1YxOGguNjY2Yy43MzcgMCAxLjMzNC0uNTk3IDEuMzM0LTEuMzMzdi0xLjMzNEgxMmMuMTc3IDAgLjM0Ni0uMDcuNDcxLS4xOTVsLjY4OC0uNjg4QTUuMzMzIDUuMzMzIDAgMSAwIDE0LjY2NyA0Wm0tNCA1LjMzM2E0IDQgMCAxIDEgMi41NTUgMy43MzIuNjY3LjY2NyAwIDAgMC0uNzEzLjE1bC0uNzg1Ljc4NUgxMGEuNjY3LjY2NyAwIDAgMC0uNjY3LjY2N3YySDhhLjY2Ny42NjcgMCAwIDAtLjY2Ny42NjZ2MS4zMzRoLTJ2LTIuMDU4bDUuMzY1LTUuMzY0YS42NjcuNjY3IDAgMCAwIC4xNjMtLjY3NyAzLjk5NiAzLjk5NiAwIDAgMS0uMTk0LTEuMjM1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--credentials__new::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBkPSJNOC4wNDcgNC42MjVDNy45MzcgNC4xMjUgNy44NjIgNCA3LjUgNGMtLjM2MiAwLS40MzguMTI1LS41NDcuNjI1LS4wNjguMzEtLjE3NyAxLjMzOC0uMjUxIDIuMDc3LS43MzguMDc0LTEuNzY3LjE4My0yLjA3Ny4yNTEtLjUuMTEtLjYyNS4xODQtLjYyNS41NDcgMCAuMzYyLjEyNS40MzcuNjI1LjU0Ny4zMS4wNjcgMS4zMzYuMTc3IDIuMDc0LjI1LjA3My43NjcuMTg1IDEuODQyLjI1NCAyLjA3OC4xMS4zNzUuMTg1LjYyNS41NDcuNjI1LjM2MiAwIC40MzgtLjEyNS41NDctLjYyNS4wNjgtLjMxLjE3Ny0xLjMzNi4yNS0yLjA3NC43NjctLjA3MyAxLjg0Mi0uMTg1IDIuMDc4LS4yNTQuMzc1LS4xMS42MjUtLjE4NS42MjUtLjU0NyAwLS4zNjMtLjEyNS0uNDM4LS42MjUtLjU0Ny0uMzEtLjA2OC0xLjMzOS0uMTc3LTIuMDc3LS4yNTEtLjA3NC0uNzM5LS4xODMtMS43NjctLjI1MS0yLjA3N1oiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0xNC42ODEgNS4xOTljLS43NjYgMC0xLjQ4Mi4yMS0yLjA5My41NzhhLjYzNi42MzYgMCAwIDEtLjY1NS0xLjA5IDUuMzQgNS4zNCAwIDEgMSAxLjMwMiA5LjcyMmwtLjc3NS43NzZhLjYzNi42MzYgMCAwIDEtLjQ1LjE4NmgtMS4zOTh2MS42NWMwIC40OTMtLjQuODkzLS44OTMuODkzSDguNTc4djEuMTQxYzAgLjQ5NC0uNC44OTMtLjg5NC44OTNINC42MzZBLjYzNi42MzYgMCAwIDEgNCAxOS4zMTNWMTYuMjZjMC0uMTY5LjA2Ny0uMzMuMTg2LS40NWw1LjU2Mi01LjU2MmEuNjM2LjYzNiAwIDEgMSAuOS45bC01LjM3NiA1LjM3NXYyLjE1M2gyLjAzNHYtMS4zOTljMC0uMzUuMjg1LS42MzYuNjM2LS42MzZIOS4zNHYtMS45MDdjMC0uMzUxLjI4NC0uNjM2LjYzNS0uNjM2aDEuNzcxbC44NjQtLjg2M2EuNjM2LjYzNiAwIDAgMSAuNjY4LS4xNDcgNC4wNjkgNC4wNjkgMCAxIDAgMS40MDItNy44OVoiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTEzLjYyNSA4LjQ5OWExLjg3NSAxLjg3NSAwIDEgMSAzLjc1IDAgMS44NzUgMS44NzUgMCAwIDEtMy43NSAwWm0xLjg3NS0uNjI1YS42MjUuNjI1IDAgMSAwIDAgMS4yNS42MjUuNjI1IDAgMCAwIDAtMS4yNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZD0iTTQuNjI1IDEyLjEyNWEuNjI1LjYyNSAwIDEgMCAwLTEuMjUuNjI1LjYyNSAwIDAgMCAwIDEuMjVaIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--creditCards::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--identities::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4=');\n}\n.tooltip__button--data--credentials.tooltip__button--data--bitwarden::before,\n.tooltip__button--data--credentials__current.tooltip__button--data--bitwarden::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iOCIgZmlsbD0iIzE3NUREQyIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE4LjU2OTYgNS40MzM1NUMxOC41MDg0IDUuMzc0NDIgMTguNDM0NyA1LjMyNzYzIDE4LjM1MzEgNS4yOTYxMUMxOC4yNzE1IDUuMjY0NiAxOC4xODM3IDUuMjQ5MDQgMTguMDk1MyA1LjI1MDQxSDUuOTIxOTFDNS44MzMyNiA1LjI0NzI5IDUuNzQ0OTMgNS4yNjIwNSA1LjY2MzA0IDUuMjkzNjdDNS41ODExNSA1LjMyNTI5IDUuNTA3NjUgNS4zNzMwMiA1LjQ0NzYyIDUuNDMzNTVDNS4zMjE3IDUuNTUwMTMgNS4yNTA2NSA1LjcwODE1IDUuMjUgNS44NzMxVjEzLjM4MjFDNS4yNTMzNiAxMy45NTM1IDUuMzc0MDggMTQuNTE5MSA1LjYwNTcyIDE1LjA0ODdDNS44MTkzMSAxNS41NzI4IDYuMTEyMDcgMTYuMDY2MSA2LjQ3NTI0IDE2LjUxMzlDNi44NDIgMTYuOTY4MyA3LjI1OTI5IDE3LjM4NTcgNy43MjAyNSAxNy43NTkzQzguMTQwNTMgMTguMTI1NiA4LjU4OTcxIDE4LjQ2MjMgOS4wNjQwNyAxOC43NjY2QzkuNDU5MzEgMTkuMDIzIDkuOTEzODMgMTkuMjc5NCAxMC4zNDg2IDE5LjUxNzVDMTAuNzgzNCAxOS43NTU2IDExLjA5OTYgMTkuOTIwNCAxMS4yNzc0IDE5Ljk5MzdDMTEuNDU1MyAyMC4wNjY5IDExLjYxMzQgMjAuMTQwMiAxMS43MTIyIDIwLjE5NTFDMTEuNzk5MiAyMC4yMzEzIDExLjg5MzUgMjAuMjUgMTEuOTg4OCAyMC4yNUMxMi4wODQyIDIwLjI1IDEyLjE3ODUgMjAuMjMxMyAxMi4yNjU1IDIwLjE5NTFDMTIuNDIxMiAyMC4xMzYzIDEyLjU3MjkgMjAuMDY5IDEyLjcyIDE5Ljk5MzdDMTIuNzcxMSAxOS45Njc0IDEyLjgzMzUgMTkuOTM2NiAxMi45MDY5IDE5LjkwMDRDMTMuMDg5MSAxOS44MTA1IDEzLjMzODggMTkuNjg3MiAxMy42NDg5IDE5LjUxNzVDMTQuMDgzNiAxOS4yNzk0IDE0LjUxODQgMTkuMDIzIDE0LjkzMzQgMTguNzY2NkMxNS40MDQgMTguNDU3NyAxNS44NTI4IDE4LjEyMTIgMTYuMjc3MiAxNy43NTkzQzE2LjczMzEgMTcuMzgwOSAxNy4xNDk5IDE2Ljk2NCAxNy41MjIyIDE2LjUxMzlDMTcuODc4IDE2LjA2MTcgMTguMTcwMiAxNS41NjkzIDE4LjM5MTcgMTUuMDQ4N0MxOC42MjM0IDE0LjUxOTEgMTguNzQ0MSAxMy45NTM1IDE4Ljc0NzQgMTMuMzgyMVY1Ljg3MzFDMTguNzU1NyA1Ljc5MjE0IDE4Ljc0MzkgNS43MTA1IDE4LjcxMzEgNS42MzQzNUMxOC42ODIzIDUuNTU4MiAxOC42MzMyIDUuNDg5NTQgMTguNTY5NiA1LjQzMzU1Wk0xNy4wMDg0IDEzLjQ1NTNDMTcuMDA4NCAxNi4xODQyIDEyLjAwODYgMTguNTI4NSAxMi4wMDg2IDE4LjUyODVWNi44NjIwOUgxNy4wMDg0VjEzLjQ1NTNaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');\n}\n#provider_locked:after {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMSAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEgNy42MDA1N1Y3LjYwMjVWOS41MjI1QzEgMTAuMDgwMSAxLjIyMTUxIDEwLjYxNDkgMS42MTU4MSAxMS4wMDkyQzIuMDEwMSAxMS40MDM1IDIuNTQ0ODggMTEuNjI1IDMuMTAyNSAxMS42MjVINy4yNzI1QzcuNTQ4NjEgMTEuNjI1IDcuODIyMDEgMTEuNTcwNiA4LjA3NzA5IDExLjQ2NUM4LjMzMjE4IDExLjM1OTMgOC41NjM5NiAxMS4yMDQ0IDguNzU5MTkgMTEuMDA5MkM4Ljk1NDQzIDEwLjgxNCA5LjEwOTMgMTAuNTgyMiA5LjIxNDk2IDEwLjMyNzFDOS4zMjA2MiAxMC4wNzIgOS4zNzUgOS43OTg2MSA5LjM3NSA5LjUyMjVMOS4zNzUgNy42MDI1TDkuMzc1IDcuNjAwNTdDOS4zNzQxNSA3LjE2MTMxIDkuMjM1NzQgNi43MzMzNSA4Ljk3OTIyIDYuMzc2NzhDOC44NzY4MyA2LjIzNDQ2IDguNzU3NjggNi4xMDYzNyA4LjYyNSA1Ljk5NDg5VjUuMTg3NUM4LjYyNSA0LjI3NTgyIDguMjYyODQgMy40MDE0OCA3LjYxODE4IDIuNzU2ODJDNi45NzM1MiAyLjExMjE2IDYuMDk5MTggMS43NSA1LjE4NzUgMS43NUM0LjI3NTgyIDEuNzUgMy40MDE0OCAyLjExMjE2IDIuNzU2ODIgMi43NTY4MkMyLjExMjE2IDMuNDAxNDggMS43NSA0LjI3NTgyIDEuNzUgNS4xODc1VjUuOTk0ODlDMS42MTczMiA2LjEwNjM3IDEuNDk4MTcgNi4yMzQ0NiAxLjM5NTc4IDYuMzc2NzhDMS4xMzkyNiA2LjczMzM1IDEuMDAwODUgNy4xNjEzMSAxIDcuNjAwNTdaTTQuOTY4NyA0Ljk2ODdDNS4wMjY5NCA0LjkxMDQ3IDUuMTA1MzIgNC44NzY5OSA1LjE4NzUgNC44NzUwN0M1LjI2OTY4IDQuODc2OTkgNS4zNDgwNiA0LjkxMDQ3IDUuNDA2MyA0Ljk2ODdDNS40NjU0MiA1LjAyNzgzIDUuNDk5MDQgNS4xMDc3NCA1LjUgNS4xOTEzVjUuNUg0Ljg3NVY1LjE5MTNDNC44NzU5NiA1LjEwNzc0IDQuOTA5NTggNS4wMjc4MyA0Ljk2ODcgNC45Njg3WiIgZmlsbD0iIzIyMjIyMiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIi8+Cjwvc3ZnPgo=');\n}\n\nhr {\n display: block;\n margin: 5px 9px;\n border: none; /* reset the border */\n border-top: 1px solid rgba(0,0,0,.1);\n}\n\nhr:first-child {\n display: none;\n}\n\n@media (prefers-color-scheme: dark) {\n hr {\n border-top: 1px solid rgba(255,255,255,.2);\n }\n}\n\n#privateAddress {\n align-items: flex-start;\n}\n#personalAddress::before,\n#privateAddress::before,\n#incontextSignup::before,\n#personalAddress.currentFocus::before,\n#personalAddress:hover::before,\n#privateAddress.currentFocus::before,\n#privateAddress:hover::before {\n filter: none;\n /* This is the same icon as `daxBase64` in `src/Form/logo-svg.js` */\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTY0IDEyOGMzNS4zNDYgMCA2NC0yOC42NTQgNjQtNjRzLTI4LjY1NC02NC02NC02NC02NCAyOC42NTQtNjQgNjQgMjguNjU0IDY0IDY0IDY0eiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im03MyAxMTEuNzVjMC0uNS4xMjMtLjYxNC0xLjQ2Ni0zLjc4Mi00LjIyNC04LjQ1OS04LjQ3LTIwLjM4NC02LjU0LTI4LjA3NS4zNTMtMS4zOTctMy45NzgtNTEuNzQ0LTcuMDQtNTMuMzY1LTMuNDAyLTEuODEzLTcuNTg4LTQuNjktMTEuNDE4LTUuMzMtMS45NDMtLjMxLTQuNDktLjE2NC02LjQ4Mi4xMDUtLjM1My4wNDctLjM2OC42ODMtLjAzLjc5OCAxLjMwOC40NDMgMi44OTUgMS4yMTIgMy44MyAyLjM3NS4xNzguMjItLjA2LjU2Ni0uMzQyLjU3Ny0uODgyLjAzMi0yLjQ4Mi40MDItNC41OTMgMi4xOTUtLjI0NC4yMDctLjA0MS41OTIuMjczLjUzIDQuNTM2LS44OTcgOS4xNy0uNDU1IDExLjkgMi4wMjcuMTc3LjE2LjA4NC40NS0uMTQ3LjUxMi0yMy42OTQgNi40NC0xOS4wMDMgMjcuMDUtMTIuNjk2IDUyLjM0NCA1LjYxOSAyMi41MyA3LjczMyAyOS43OTIgOC40IDMyLjAwNGEuNzE4LjcxOCAwIDAgMCAuNDIzLjQ2N2M4LjE1NiAzLjI0OCAyNS45MjggMy4zOTIgMjUuOTI4LTIuMTMyeiIgZmlsbD0iI2RkZCIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBkPSJtNzYuMjUgMTE2LjVjLTIuODc1IDEuMTI1LTguNSAxLjYyNS0xMS43NSAxLjYyNS00Ljc2NCAwLTExLjYyNS0uNzUtMTQuMTI1LTEuODc1LTEuNTQ0LTQuNzUxLTYuMTY0LTE5LjQ4LTEwLjcyNy0zOC4xODVsLS40NDctMS44MjctLjAwNC0uMDE1Yy01LjQyNC0yMi4xNTctOS44NTUtNDAuMjUzIDE0LjQyNy00NS45MzguMjIyLS4wNTIuMzMtLjMxNy4xODQtLjQ5Mi0yLjc4Ni0zLjMwNS04LjAwNS00LjM4OC0xNC42MDUtMi4xMTEtLjI3LjA5My0uNTA2LS4xOC0uMzM3LS40MTIgMS4yOTQtMS43ODMgMy44MjMtMy4xNTUgNS4wNzEtMy43NTYuMjU4LS4xMjQuMjQyLS41MDItLjAzLS41ODhhMjcuODc3IDI3Ljg3NyAwIDAgMCAtMy43NzItLjljLS4zNy0uMDU5LS40MDMtLjY5My0uMDMyLS43NDMgOS4zNTYtMS4yNTkgMTkuMTI1IDEuNTUgMjQuMDI4IDcuNzI2YS4zMjYuMzI2IDAgMCAwIC4xODYuMTE0YzE3Ljk1MiAzLjg1NiAxOS4yMzggMzIuMjM1IDE3LjE3IDMzLjUyOC0uNDA4LjI1NS0xLjcxNS4xMDgtMy40MzgtLjA4NS02Ljk4Ni0uNzgxLTIwLjgxOC0yLjMyOS05LjQwMiAxOC45NDguMTEzLjIxLS4wMzYuNDg4LS4yNzIuNTI1LTYuNDM4IDEgMS44MTIgMjEuMTczIDcuODc1IDM0LjQ2MXoiIGZpbGw9IiNmZmYiLz4KICAgIDxwYXRoIGQ9Im04NC4yOCA5MC42OThjLTEuMzY3LS42MzMtNi42MjEgMy4xMzUtMTAuMTEgNi4wMjgtLjcyOC0xLjAzMS0yLjEwMy0xLjc4LTUuMjAzLTEuMjQyLTIuNzEzLjQ3Mi00LjIxMSAxLjEyNi00Ljg4IDIuMjU0LTQuMjgzLTEuNjIzLTExLjQ4OC00LjEzLTEzLjIyOS0xLjcxLTEuOTAyIDIuNjQ2LjQ3NiAxNS4xNjEgMy4wMDMgMTYuNzg2IDEuMzIuODQ5IDcuNjMtMy4yMDggMTAuOTI2LTYuMDA1LjUzMi43NDkgMS4zODggMS4xNzggMy4xNDggMS4xMzcgMi42NjItLjA2MiA2Ljk3OS0uNjgxIDcuNjQ5LTEuOTIxLjA0LS4wNzUuMDc1LS4xNjQuMTA1LS4yNjYgMy4zODggMS4yNjYgOS4zNSAyLjYwNiAxMC42ODIgMi40MDYgMy40Ny0uNTIxLS40ODQtMTYuNzIzLTIuMDktMTcuNDY3eiIgZmlsbD0iIzNjYTgyYiIvPgogICAgPHBhdGggZD0ibTc0LjQ5IDk3LjA5N2MuMTQ0LjI1Ni4yNi41MjYuMzU4LjguNDgzIDEuMzUyIDEuMjcgNS42NDguNjc0IDYuNzA5LS41OTUgMS4wNjItNC40NTkgMS41NzQtNi44NDMgMS42MTVzLTIuOTItLjgzMS0zLjQwMy0yLjE4MWMtLjM4Ny0xLjA4MS0uNTc3LTMuNjIxLS41NzItNS4wNzUtLjA5OC0yLjE1OC42OS0yLjkxNiA0LjMzNC0zLjUwNiAyLjY5Ni0uNDM2IDQuMTIxLjA3MSA0Ljk0NC45NCAzLjgyOC0yLjg1NyAxMC4yMTUtNi44ODkgMTAuODM4LTYuMTUyIDMuMTA2IDMuNjc0IDMuNDk5IDEyLjQyIDIuODI2IDE1LjkzOS0uMjIgMS4xNTEtMTAuNTA1LTEuMTM5LTEwLjUwNS0yLjM4IDAtNS4xNTItMS4zMzctNi41NjUtMi42NS02Ljcxem0tMjIuNTMtMS42MDljLjg0My0xLjMzMyA3LjY3NC4zMjUgMTEuNDI0IDEuOTkzIDAgMC0uNzcgMy40OTEuNDU2IDcuNjA0LjM1OSAxLjIwMy04LjYyNyA2LjU1OC05LjggNS42MzctMS4zNTUtMS4wNjUtMy44NS0xMi40MzItMi4wOC0xNS4yMzR6IiBmaWxsPSIjNGNiYTNjIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im01NS4yNjkgNjguNDA2Yy41NTMtMi40MDMgMy4xMjctNi45MzIgMTIuMzIxLTYuODIyIDQuNjQ4LS4wMTkgMTAuNDIyLS4wMDIgMTQuMjUtLjQzNmE1MS4zMTIgNTEuMzEyIDAgMCAwIDEyLjcyNi0zLjA5NWMzLjk4LTEuNTE5IDUuMzkyLTEuMTggNS44ODctLjI3Mi41NDQuOTk5LS4wOTcgMi43MjItMS40ODggNC4zMDktMi42NTYgMy4wMy03LjQzMSA1LjM4LTE1Ljg2NSA2LjA3Ni04LjQzMy42OTgtMTQuMDItMS41NjUtMTYuNDI1IDIuMTE4LTEuMDM4IDEuNTg5LS4yMzYgNS4zMzMgNy45MiA2LjUxMiAxMS4wMiAxLjU5IDIwLjA3Mi0xLjkxNyAyMS4xOS4yMDEgMS4xMTkgMi4xMTgtNS4zMjMgNi40MjgtMTYuMzYyIDYuNTE4cy0xNy45MzQtMy44NjUtMjAuMzc5LTUuODNjLTMuMTAyLTIuNDk1LTQuNDktNi4xMzMtMy43NzUtOS4yNzl6IiBmaWxsPSIjZmMzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KICAgIDxnIGZpbGw9IiMxNDMwN2UiIG9wYWNpdHk9Ii44Ij4KICAgICAgPHBhdGggZD0ibTY5LjMyNyA0Mi4xMjdjLjYxNi0xLjAwOCAxLjk4MS0xLjc4NiA0LjIxNi0xLjc4NiAyLjIzNCAwIDMuMjg1Ljg4OSA0LjAxMyAxLjg4LjE0OC4yMDItLjA3Ni40NC0uMzA2LjM0YTU5Ljg2OSA1OS44NjkgMCAwIDEgLS4xNjgtLjA3M2MtLjgxNy0uMzU3LTEuODItLjc5NS0zLjU0LS44Mi0xLjgzOC0uMDI2LTIuOTk3LjQzNS0zLjcyNy44MzEtLjI0Ni4xMzQtLjYzNC0uMTMzLS40ODgtLjM3MnptLTI1LjE1NyAxLjI5YzIuMTctLjkwNyAzLjg3Ni0uNzkgNS4wODEtLjUwNC4yNTQuMDYuNDMtLjIxMy4yMjctLjM3Ny0uOTM1LS43NTUtMy4wMy0xLjY5Mi01Ljc2LS42NzQtMi40MzcuOTA5LTMuNTg1IDIuNzk2LTMuNTkyIDQuMDM4LS4wMDIuMjkyLjYuMzE3Ljc1Ni4wNy40Mi0uNjcgMS4xMi0xLjY0NiAzLjI4OS0yLjU1M3oiLz4KICAgICAgPHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtNzUuNDQgNTUuOTJhMy40NyAzLjQ3IDAgMCAxIC0zLjQ3NC0zLjQ2MiAzLjQ3IDMuNDcgMCAwIDEgMy40NzUtMy40NiAzLjQ3IDMuNDcgMCAwIDEgMy40NzQgMy40NiAzLjQ3IDMuNDcgMCAwIDEgLTMuNDc1IDMuNDYyem0yLjQ0Ny00LjYwOGEuODk5Ljg5OSAwIDAgMCAtMS43OTkgMGMwIC40OTQuNDA1Ljg5NS45Ljg5NS40OTkgMCAuOS0uNC45LS44OTV6bS0yNS40NjQgMy41NDJhNC4wNDIgNC4wNDIgMCAwIDEgLTQuMDQ5IDQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIC00LjA1LTQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIDQuMDUtNC4wMzcgNC4wNDUgNC4wNDUgMCAwIDEgNC4wNSA0LjAzN3ptLTEuMTkzLTEuMzM4YTEuMDUgMS4wNSAwIDAgMCAtMi4wOTcgMCAxLjA0OCAxLjA0OCAwIDAgMCAyLjA5NyAweiIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8L2c+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im02NCAxMTcuNzVjMjkuNjg1IDAgNTMuNzUtMjQuMDY1IDUzLjc1LTUzLjc1cy0yNC4wNjUtNTMuNzUtNTMuNzUtNTMuNzUtNTMuNzUgMjQuMDY1LTUzLjc1IDUzLjc1IDI0LjA2NSA1My43NSA1My43NSA1My43NXptMCA1YzMyLjQ0NyAwIDU4Ljc1LTI2LjMwMyA1OC43NS01OC43NXMtMjYuMzAzLTU4Ljc1LTU4Ljc1LTU4Ljc1LTU4Ljc1IDI2LjMwMy01OC43NSA1OC43NSAyNi4zMDMgNTguNzUgNTguNzUgNTguNzV6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KPC9zdmc+');\n}\n\n/* Email tooltip specific */\n.tooltip__button--email {\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n font-size: 14px;\n padding: 4px 8px;\n}\n.tooltip__button--email__primary-text {\n font-weight: bold;\n}\n.tooltip__button--email__secondary-text {\n font-size: 12px;\n}\n\n/* Email Protection signup notice */\n:not(.top-autofill) .tooltip--email-signup {\n text-align: left;\n color: #222222;\n padding: 16px 20px;\n width: 380px;\n}\n\n.tooltip--email-signup h1 {\n font-weight: 700;\n font-size: 16px;\n line-height: 1.5;\n margin: 0;\n}\n\n.tooltip--email-signup p {\n font-weight: 400;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.notice-controls {\n display: flex;\n}\n\n.tooltip--email-signup .notice-controls > * {\n border-radius: 8px;\n border: 0;\n cursor: pointer;\n display: inline-block;\n font-family: inherit;\n font-style: normal;\n font-weight: bold;\n padding: 8px 12px;\n text-decoration: none;\n}\n\n.notice-controls .ghost {\n margin-left: 1rem;\n}\n\n.tooltip--email-signup a.primary {\n background: #3969EF;\n color: #fff;\n}\n\n.tooltip--email-signup a.primary:hover,\n.tooltip--email-signup a.primary:focus {\n background: #2b55ca;\n}\n\n.tooltip--email-signup a.primary:active {\n background: #1e42a4;\n}\n\n.tooltip--email-signup button.ghost {\n background: transparent;\n color: #3969EF;\n}\n\n.tooltip--email-signup button.ghost:hover,\n.tooltip--email-signup button.ghost:focus {\n background-color: rgba(0, 0, 0, 0.06);\n color: #2b55ca;\n}\n\n.tooltip--email-signup button.ghost:active {\n background-color: rgba(0, 0, 0, 0.12);\n color: #1e42a4;\n}\n\n.tooltip--email-signup button.close-tooltip {\n background-color: transparent;\n background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMiAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjI5Mjg5NCAwLjY1NjkwN0MwLjY4MzQxOCAwLjI2NjM4MyAxLjMxNjU4IDAuMjY2MzgzIDEuNzA3MTEgMC42NTY5MDdMNiA0Ljk0OThMMTAuMjkyOSAwLjY1NjkwN0MxMC42ODM0IDAuMjY2MzgzIDExLjMxNjYgMC4yNjYzODMgMTEuNzA3MSAwLjY1NjkwN0MxMi4wOTc2IDEuMDQ3NDMgMTIuMDk3NiAxLjY4MDYgMTEuNzA3MSAyLjA3MTEyTDcuNDE0MjEgNi4zNjQwMUwxMS43MDcxIDEwLjY1NjlDMTIuMDk3NiAxMS4wNDc0IDEyLjA5NzYgMTEuNjgwNiAxMS43MDcxIDEyLjA3MTFDMTEuMzE2NiAxMi40NjE2IDEwLjY4MzQgMTIuNDYxNiAxMC4yOTI5IDEyLjA3MTFMNiA3Ljc3ODIzTDEuNzA3MTEgMTIuMDcxMUMxLjMxNjU4IDEyLjQ2MTYgMC42ODM0MTcgMTIuNDYxNiAwLjI5Mjg5MyAxMi4wNzExQy0wLjA5NzYzMTEgMTEuNjgwNiAtMC4wOTc2MzExIDExLjA0NzQgMC4yOTI4OTMgMTAuNjU2OUw0LjU4NTc5IDYuMzY0MDFMMC4yOTI4OTQgMi4wNzExMkMtMC4wOTc2MzA2IDEuNjgwNiAtMC4wOTc2MzA2IDEuMDQ3NDMgMC4yOTI4OTQgMC42NTY5MDdaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjg0Ii8+Cjwvc3ZnPgo=);\n background-position: center center;\n background-repeat: no-repeat;\n border: 0;\n cursor: pointer;\n padding: 16px;\n position: absolute;\n right: 12px;\n top: 12px;\n}\n\n/* Import promotion prompt icon style */\n\n.tooltip__button--credentials-import::before {\n content: \"\";\n background-image: url(data:image/svg+xml;base64,Cjxzdmcgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik03Ljk3MjY5IDkuMDEzN0M3Ljk3MjY5IDUuMTQwMTQgMTEuMTEyOCAyIDE0Ljk4NjQgMkMxOC44NTk5IDIgMjIuMDAwMSA1LjE0MDE0IDIyLjAwMDEgOS4wMTM3QzIyLjAwMDEgOS44MDM5NyAyMS44Njk0IDEwLjU2MzcgMjEuNjI4NCAxMS4yNzI1QzIxLjQ2MDEgMTEuNzY3NiAyMC44NjU2IDExLjkxMzUgMjAuMzk3NyAxMS42OEMxOS45MjIxIDExLjQ0MjggMTkuNjc3OSAxMC44NjQ0IDE5LjgxOTUgMTAuMzUyQzE5LjkzNzIgOS45MjU5OSAyMC4wMDAxIDkuNDc3MTkgMjAuMDAwMSA5LjAxMzdDMjAuMDAwMSA2LjI0NDcxIDE3Ljc1NTQgNCAxNC45ODY0IDRDMTIuMjE3NCA0IDkuOTcyNjkgNi4yNDQ3MSA5Ljk3MjY5IDkuMDEzN0M5Ljk3MjY5IDkuNTU1NCAxMC4wNTgyIDEwLjA3NTIgMTAuMjE1OCAxMC41NjEzQzEwLjMzMTcgMTAuOTE4OCAxMC4yMzc0IDExLjMxMTEgOS45NzE2NSAxMS41NzY4TDMuOTk5OTQgMTcuNTQ4NVYyMC4wMDAyTDYuNDk5OTggMjAuMDAwMlYxOC4zMDAyQzYuNDk5OTggMTcuNzQ3OSA2Ljk0NzcgMTcuMzAwMiA3LjQ5OTk4IDE3LjMwMDJIOS4yMDAwMVYxNS42MDAxQzkuMjAwMDEgMTUuMDQ3OCA5LjY0NzczIDE0LjYwMDEgMTAuMiAxNC42MDAxSDEwLjVDMTEuMjEwNiAxNC41ODcgMTEuNDI1MiAxNS4zMzY5IDExLjMxNTYgMTUuNzMzMUMxMS4xNTY1IDE2LjMwODUgMTEgMTcuMDAxIDExIDE3LjVDMTEgMTcuNzI4NCAxMS4wMTE4IDE3Ljk1NCAxMS4wMzQ4IDE4LjE3NjNDMTAuNzM3OSAxOC44Mzg3IDEwLjA3MjkgMTkuMzAwMiA5LjMgMTkuMzAwMkg4LjQ5OTk4VjIwLjEwMDJDOC40OTk5OCAyMS4xNDk1IDcuNjQ5MzMgMjIuMDAwMiA2LjU5OTk5IDIyLjAwMDJMMi45OTk5NSAyMi4wMDAyQzIuNzM0NzMgMjIuMDAwMiAyLjQ4MDM3IDIxLjg5NDkgMi4yOTI4NCAyMS43MDczQzIuMTA1MyAyMS41MTk4IDEuOTk5OTQgMjEuMjY1NCAxLjk5OTk0IDIxLjAwMDJWMTcuMTM0M0MxLjk5OTk0IDE2Ljg2OTEgMi4xMDUzIDE2LjYxNDcgMi4yOTI4MyAxNi40MjcyTDguMTQ2ODkgMTAuNTczMUM4LjAzMjc5IDEwLjA3MDkgNy45NzI2OSA5LjU0ODgxIDcuOTcyNjkgOS4wMTM3WiIgZmlsbD0iYmxhY2siIC8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTMgOC40OTk4OUMxMyA3LjExOTE4IDE0LjExOTMgNS45OTk4OSAxNS41IDUuOTk5ODlDMTYuODgwNyA1Ljk5OTg5IDE4IDcuMTE5MTggMTggOC40OTk4OUMxOCA5Ljg4MDYgMTYuODgwNyAxMC45OTk5IDE1LjUgMTAuOTk5OUMxNC4xMTkzIDEwLjk5OTkgMTMgOS44ODA2IDEzIDguNDk5ODlaTTE1LjUgNy45OTk4OUMxNS4yMjM5IDcuOTk5ODkgMTUgOC4yMjM3NSAxNSA4LjQ5OTg5QzE1IDguNzc2MDQgMTUuMjIzOSA4Ljk5OTg5IDE1LjUgOC45OTk4OUMxNS43NzYyIDguOTk5ODkgMTYgOC43NzYwNCAxNiA4LjQ5OTg5QzE2IDguMjIzNzUgMTUuNzc2MiA3Ljk5OTg5IDE1LjUgNy45OTk4OVoiIGZpbGw9ImJsYWNrIiAvPgo8cGF0aCBkPSJNMTcgMTVMMTQuNSAxNy41TDE3IDIwIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMjEuNSAxNy41TDE2IDE3LjUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=);\n background-repeat: no-repeat;\n}\n"; -},{}],64:[function(require,module,exports){ +},{}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17491,7 +17626,7 @@ function findEnclosedElements(root, selector) { return shadowElements; } -},{"./Form/matching.js":44,"./constants.js":67,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],65:[function(require,module,exports){ +},{"./Form/matching.js":45,"./constants.js":68,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],66:[function(require,module,exports){ "use strict"; require("./requestIdleCallback.js"); @@ -17522,7 +17657,7 @@ var _autofillUtils = require("./autofill-utils.js"); } })(); -},{"./DeviceInterface.js":23,"./autofill-utils.js":64,"./requestIdleCallback.js":104}],66:[function(require,module,exports){ +},{"./DeviceInterface.js":24,"./autofill-utils.js":65,"./requestIdleCallback.js":105}],67:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17539,6 +17674,10 @@ const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a- * @returns {GlobalConfig} */ function createGlobalConfig(overrides) { + /** + * Defines whether it's one of our desktop apps + * @type {boolean} + */ let isApp = false; let isTopFrame = false; let supportsTopFrame = false; @@ -17608,7 +17747,7 @@ function createGlobalConfig(overrides) { return config; } -},{}],67:[function(require,module,exports){ +},{}],68:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17625,13 +17764,13 @@ const constants = exports.constants = { MAX_FORM_RESCANS: 50 }; -},{}],68:[function(require,module,exports){ +},{}],69:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; +exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAliasCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; var _validatorsZod = require("./validators.zod.js"); var _deviceApi = require("../../../packages/device-api"); /* DO NOT EDIT, this file was generated by scripts/api-call-generator.js */ @@ -17793,9 +17932,19 @@ class StartCredentialsImportFlowCall extends _deviceApi.DeviceApiCall { method = "startCredentialsImportFlow"; } /** - * @extends {DeviceApiCall} + * @extends {DeviceApiCall} */ exports.StartCredentialsImportFlowCall = StartCredentialsImportFlowCall; +class EmailProtectionGetAliasCall extends _deviceApi.DeviceApiCall { + method = "emailProtectionGetAlias"; + id = "emailProtectionGetAliasResponse"; + paramsValidator = _validatorsZod.emailProtectionGetAliasParamsSchema; + resultValidator = _validatorsZod.emailProtectionGetAliasResultSchema; +} +/** + * @extends {DeviceApiCall} + */ +exports.EmailProtectionGetAliasCall = EmailProtectionGetAliasCall; class EmailProtectionStoreUserDataCall extends _deviceApi.DeviceApiCall { method = "emailProtectionStoreUserData"; id = "emailProtectionStoreUserDataResponse"; @@ -17878,13 +18027,13 @@ class ShowInContextEmailProtectionSignupPromptCall extends _deviceApi.DeviceApiC } exports.ShowInContextEmailProtectionSignupPromptCall = ShowInContextEmailProtectionSignupPromptCall; -},{"../../../packages/device-api":12,"./validators.zod.js":69}],69:[function(require,module,exports){ +},{"../../../packages/device-api":12,"./validators.zod.js":70}],70:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; +exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; var _zod = require("zod"); /* DO NOT EDIT, this file was generated by scripts/api-call-generator.js */ // Generated by ts-to-zod @@ -17944,6 +18093,11 @@ const getAliasResultSchema = exports.getAliasResultSchema = _zod.z.object({ alias: _zod.z.string().optional() }) }); +const emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAliasParamsSchema = _zod.z.object({ + requiresUserPermission: _zod.z.boolean(), + shouldConsumeAliasIfProvided: _zod.z.boolean(), + isIncontextSignupAvailable: _zod.z.boolean().optional() +}); const emailProtectionStoreUserDataParamsSchema = exports.emailProtectionStoreUserDataParamsSchema = _zod.z.object({ token: _zod.z.string(), userName: _zod.z.string(), @@ -17998,10 +18152,6 @@ const userPreferencesSchema = exports.userPreferencesSchema = _zod.z.object({ settings: _zod.z.record(_zod.z.unknown()) })) }); -const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = _zod.z.object({ - username: _zod.z.string().optional(), - password: _zod.z.string().optional() -}); const availableInputTypesSchema = exports.availableInputTypesSchema = _zod.z.object({ credentials: _zod.z.object({ username: _zod.z.boolean().optional(), @@ -18034,6 +18184,10 @@ const availableInputTypesSchema = exports.availableInputTypesSchema = _zod.z.obj credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = _zod.z.object({ + username: _zod.z.string().optional(), + password: _zod.z.string().optional() +}); const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.object({ credentials: _zod.z.object({ username: _zod.z.boolean().optional(), @@ -18066,6 +18220,11 @@ const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.o credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ + status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), + credentials: _zod.z.array(credentialsSchema), + availableInputTypes: availableInputTypesSchema +}); const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = _zod.z.object({ inputType_credentials: _zod.z.boolean().optional(), inputType_identities: _zod.z.boolean().optional(), @@ -18101,7 +18260,7 @@ const storeFormDataSchema = exports.storeFormDataSchema = _zod.z.object({ }); const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = _zod.z.object({ type: _zod.z.literal("getAvailableInputTypesResponse").optional(), - success: availableInputTypesSchema, + success: availableInputTypes1Schema, error: genericErrorSchema.optional() }); const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = _zod.z.object({ @@ -18124,9 +18283,25 @@ const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultS }).optional(), error: genericErrorSchema.optional() }); +const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = _zod.z.object({ + type: _zod.z.literal("askToUnlockProviderResponse").optional(), + success: providerStatusUpdatedSchema, + error: genericErrorSchema.optional() +}); +const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = _zod.z.object({ + type: _zod.z.literal("checkCredentialsProviderStatusResponse").optional(), + success: providerStatusUpdatedSchema, + error: genericErrorSchema.optional() +}); const autofillSettingsSchema = exports.autofillSettingsSchema = _zod.z.object({ featureToggles: autofillFeatureTogglesSchema }); +const emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasResultSchema = _zod.z.object({ + success: _zod.z.object({ + alias: _zod.z.string() + }).optional(), + error: genericErrorSchema.optional() +}); const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = _zod.z.object({ success: _zod.z.boolean().optional(), error: genericErrorSchema.optional() @@ -18164,28 +18339,14 @@ const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtection const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = _zod.z.object({ contentScope: contentScopeSchema, userUnprotectedDomains: _zod.z.array(_zod.z.string()), - userPreferences: userPreferencesSchema -}); -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ - status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), - credentials: _zod.z.array(credentialsSchema), - availableInputTypes: availableInputTypes1Schema + userPreferences: userPreferencesSchema, + availableInputTypes: availableInputTypesSchema.optional() }); const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = _zod.z.object({ type: _zod.z.literal("getRuntimeConfigurationResponse").optional(), success: runtimeConfigurationSchema.optional(), error: genericErrorSchema.optional() }); -const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = _zod.z.object({ - type: _zod.z.literal("askToUnlockProviderResponse").optional(), - success: providerStatusUpdatedSchema, - error: genericErrorSchema.optional() -}); -const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = _zod.z.object({ - type: _zod.z.literal("checkCredentialsProviderStatusResponse").optional(), - success: providerStatusUpdatedSchema, - error: genericErrorSchema.optional() -}); const apiSchema = exports.apiSchema = _zod.z.object({ addDebugFlag: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ paramsValidator: addDebugFlagParamsSchema.optional() @@ -18253,6 +18414,11 @@ const apiSchema = exports.apiSchema = _zod.z.object({ openManageCreditCards: _zod.z.record(_zod.z.unknown()).optional(), openManageIdentities: _zod.z.record(_zod.z.unknown()).optional(), startCredentialsImportFlow: _zod.z.record(_zod.z.unknown()).optional(), + emailProtectionGetAlias: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ + id: _zod.z.literal("emailProtectionGetAliasResponse").optional(), + paramsValidator: emailProtectionGetAliasParamsSchema.optional(), + resultValidator: emailProtectionGetAliasResultSchema.optional() + })).optional(), emailProtectionStoreUserData: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ id: _zod.z.literal("emailProtectionStoreUserDataResponse").optional(), paramsValidator: emailProtectionStoreUserDataParamsSchema.optional() @@ -18286,7 +18452,7 @@ const apiSchema = exports.apiSchema = _zod.z.object({ })).optional() }); -},{"zod":9}],70:[function(require,module,exports){ +},{"zod":9}],71:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18312,7 +18478,7 @@ class GetAlias extends _index.DeviceApiCall { } exports.GetAlias = GetAlias; -},{"../../packages/device-api/index.js":12,"./__generated__/validators.zod.js":69}],71:[function(require,module,exports){ +},{"../../packages/device-api/index.js":12,"./__generated__/validators.zod.js":70}],72:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18320,7 +18486,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.AndroidTransport = void 0; var _index = require("../../../packages/device-api/index.js"); -var _deviceApiCalls = require("../__generated__/deviceApiCalls.js"); +var _messaging = require("../../../packages/messaging/messaging.js"); +var _android = require("../../../packages/messaging/android.js"); class AndroidTransport extends _index.DeviceApiTransport { /** @type {GlobalConfig} */ config; @@ -18329,133 +18496,39 @@ class AndroidTransport extends _index.DeviceApiTransport { constructor(globalConfig) { super(); this.config = globalConfig; - if (this.config.isDDGTestMode) { - if (typeof window.BrowserAutofill?.getAutofillData !== 'function') { - console.warn('window.BrowserAutofill.getAutofillData missing'); - } - if (typeof window.BrowserAutofill?.storeFormData !== 'function') { - console.warn('window.BrowserAutofill.storeFormData missing'); - } - } + const messageHandlerNames = ['EmailProtectionStoreUserData', 'EmailProtectionRemoveUserData', 'EmailProtectionGetUserData', 'EmailProtectionGetCapabilities', 'EmailProtectionGetAlias', 'SetIncontextSignupPermanentlyDismissedAt', 'StartEmailProtectionSignup', 'CloseEmailProtectionTab', 'ShowInContextEmailProtectionSignupPrompt', 'StoreFormData', 'GetIncontextSignupDismissedAt', 'GetRuntimeConfiguration', 'GetAutofillData']; + const androidMessagingConfig = new _android.AndroidMessagingConfig({ + messageHandlerNames + }); + this.messaging = new _messaging.Messaging(androidMessagingConfig); } /** * @param {import("../../../packages/device-api").DeviceApiCall} deviceApiCall * @returns {Promise} */ async send(deviceApiCall) { - if (deviceApiCall instanceof _deviceApiCalls.GetRuntimeConfigurationCall) { - return androidSpecificRuntimeConfiguration(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAvailableInputTypesCall) { - return androidSpecificAvailableInputTypes(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetIncontextSignupDismissedAtCall) { - window.BrowserAutofill.getIncontextSignupDismissedAt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.SetIncontextSignupPermanentlyDismissedAtCall) { - return window.BrowserAutofill.setIncontextSignupPermanentlyDismissedAt(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.StartEmailProtectionSignupCall) { - return window.BrowserAutofill.startEmailProtectionSignup(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.CloseEmailProtectionTabCall) { - return window.BrowserAutofill.closeEmailProtectionTab(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall) { - window.BrowserAutofill.showInContextEmailProtectionSignupPrompt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAutofillDataCall) { - window.BrowserAutofill.getAutofillData(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.StoreFormDataCall) { - return window.BrowserAutofill.storeFormData(JSON.stringify(deviceApiCall.params)); - } - throw new Error('android: not implemented: ' + deviceApiCall.method); - } -} - -/** - * @param {string} expectedResponse - the name/id of the response - * @param {GlobalConfig} config - * @returns {Promise<*>} - */ -exports.AndroidTransport = AndroidTransport; -function waitForResponse(expectedResponse, config) { - return new Promise(resolve => { - const handler = e => { - if (!config.isDDGTestMode) { - if (e.origin !== '') { - return; - } - } - if (!e.data) { - return; - } - if (typeof e.data !== 'string') { - if (config.isDDGTestMode) { - console.log('❌ event.data was not a string. Expected a string so that it can be JSON parsed'); - } - return; + try { + // if the call has an `id`, it means that it expects a response + if (deviceApiCall.id) { + return await this.messaging.request(deviceApiCall.method, deviceApiCall.params || undefined); + } else { + return this.messaging.notify(deviceApiCall.method, deviceApiCall.params || undefined); } - try { - let data = JSON.parse(e.data); - if (data.type === expectedResponse) { - window.removeEventListener('message', handler); - return resolve(data); - } - if (config.isDDGTestMode) { - console.log(`❌ event.data.type was '${data.type}', which didnt match '${expectedResponse}'`, JSON.stringify(data)); - } - } catch (e) { - window.removeEventListener('message', handler); - if (config.isDDGTestMode) { - console.log('❌ Could not JSON.parse the response'); + } catch (e) { + if (e instanceof _messaging.MissingHandler) { + if (this.config.isDDGTestMode) { + console.log('MissingAndroidHandler error for:', deviceApiCall.method); } + throw new Error('unimplemented handler: ' + deviceApiCall.method); + } else { + throw e; } - }; - window.addEventListener('message', handler); - }); -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').RuntimeConfiguration}} - */ -function androidSpecificRuntimeConfiguration(globalConfig) { - if (!globalConfig.userPreferences) { - throw new Error('globalConfig.userPreferences not supported yet on Android'); - } - return { - success: { - // @ts-ignore - contentScope: globalConfig.contentScope, - // @ts-ignore - userPreferences: globalConfig.userPreferences, - // @ts-ignore - userUnprotectedDomains: globalConfig.userUnprotectedDomains, - // @ts-ignore - availableInputTypes: globalConfig.availableInputTypes } - }; -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').AvailableInputTypes}} - */ -function androidSpecificAvailableInputTypes(globalConfig) { - if (!globalConfig.availableInputTypes) { - throw new Error('globalConfig.availableInputTypes not supported yet on Android'); } - return { - success: globalConfig.availableInputTypes - }; } +exports.AndroidTransport = AndroidTransport; -},{"../../../packages/device-api/index.js":12,"../__generated__/deviceApiCalls.js":68}],72:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12,"../../../packages/messaging/android.js":15,"../../../packages/messaging/messaging.js":16}],73:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18498,7 +18571,7 @@ class AppleTransport extends _index.DeviceApiTransport { } exports.AppleTransport = AppleTransport; -},{"../../../packages/device-api/index.js":12,"../../../packages/messaging/messaging.js":15}],73:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12,"../../../packages/messaging/messaging.js":16}],74:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18652,7 +18725,7 @@ async function extensionSpecificSetIncontextSignupPermanentlyDismissedAtCall(par }); } -},{"../../../packages/device-api/index.js":12,"../../Settings.js":51,"../../autofill-utils.js":64,"../__generated__/deviceApiCalls.js":68}],74:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12,"../../Settings.js":52,"../../autofill-utils.js":65,"../__generated__/deviceApiCalls.js":69}],75:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18696,7 +18769,7 @@ function createTransport(globalConfig) { return new _extensionTransport.ExtensionTransport(globalConfig); } -},{"./android.transport.js":71,"./apple.transport.js":72,"./extension.transport.js":73,"./windows.transport.js":75}],75:[function(require,module,exports){ +},{"./android.transport.js":72,"./apple.transport.js":73,"./extension.transport.js":74,"./windows.transport.js":76}],76:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -18781,7 +18854,7 @@ function waitForWindowsResponse(responseId, options) { }); } -},{"../../../packages/device-api/index.js":12}],76:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":12}],77:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -18882,7 +18955,7 @@ module.exports={ } } -},{}],77:[function(require,module,exports){ +},{}],78:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -18983,7 +19056,7 @@ module.exports={ } } -},{}],78:[function(require,module,exports){ +},{}],79:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19084,7 +19157,7 @@ module.exports={ } } -},{}],79:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19185,7 +19258,7 @@ module.exports={ } } -},{}],80:[function(require,module,exports){ +},{}],81:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19286,7 +19359,7 @@ module.exports={ } } -},{}],81:[function(require,module,exports){ +},{}],82:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -19388,7 +19461,7 @@ module.exports={ } } -},{}],82:[function(require,module,exports){ +},{}],83:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19489,7 +19562,7 @@ module.exports={ } } -},{}],83:[function(require,module,exports){ +},{}],84:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19590,7 +19663,7 @@ module.exports={ } } -},{}],84:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19691,7 +19764,7 @@ module.exports={ } } -},{}],85:[function(require,module,exports){ +},{}],86:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19792,7 +19865,7 @@ module.exports={ } } -},{}],86:[function(require,module,exports){ +},{}],87:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19893,7 +19966,7 @@ module.exports={ } } -},{}],87:[function(require,module,exports){ +},{}],88:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -19994,7 +20067,7 @@ module.exports={ } } -},{}],88:[function(require,module,exports){ +},{}],89:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20095,7 +20168,7 @@ module.exports={ } } -},{}],89:[function(require,module,exports){ +},{}],90:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20196,7 +20269,7 @@ module.exports={ } } -},{}],90:[function(require,module,exports){ +},{}],91:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20297,7 +20370,7 @@ module.exports={ } } -},{}],91:[function(require,module,exports){ +},{}],92:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20398,7 +20471,7 @@ module.exports={ } } -},{}],92:[function(require,module,exports){ +},{}],93:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20499,7 +20572,7 @@ module.exports={ } } -},{}],93:[function(require,module,exports){ +},{}],94:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20600,7 +20673,7 @@ module.exports={ } } -},{}],94:[function(require,module,exports){ +},{}],95:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20701,7 +20774,7 @@ module.exports={ } } -},{}],95:[function(require,module,exports){ +},{}],96:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20802,7 +20875,7 @@ module.exports={ } } -},{}],96:[function(require,module,exports){ +},{}],97:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -20903,7 +20976,7 @@ module.exports={ } } -},{}],97:[function(require,module,exports){ +},{}],98:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21004,7 +21077,7 @@ module.exports={ } } -},{}],98:[function(require,module,exports){ +},{}],99:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21105,7 +21178,7 @@ module.exports={ } } -},{}],99:[function(require,module,exports){ +},{}],100:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -21193,7 +21266,7 @@ function translateImpl(library, namespacedId, opts) { return out; } -},{"./translations.js":102}],100:[function(require,module,exports){ +},{"./translations.js":103}],101:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21294,7 +21367,7 @@ module.exports={ } } -},{}],101:[function(require,module,exports){ +},{}],102:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -21395,7 +21468,7 @@ module.exports={ } } -},{}],102:[function(require,module,exports){ +},{}],103:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -21514,7 +21587,7 @@ var _default = exports.default = { } }; -},{"./bg/autofill.json":76,"./cs/autofill.json":77,"./da/autofill.json":78,"./de/autofill.json":79,"./el/autofill.json":80,"./en/autofill.json":81,"./es/autofill.json":82,"./et/autofill.json":83,"./fi/autofill.json":84,"./fr/autofill.json":85,"./hr/autofill.json":86,"./hu/autofill.json":87,"./it/autofill.json":88,"./lt/autofill.json":89,"./lv/autofill.json":90,"./nb/autofill.json":91,"./nl/autofill.json":92,"./pl/autofill.json":93,"./pt/autofill.json":94,"./ro/autofill.json":95,"./ru/autofill.json":96,"./sk/autofill.json":97,"./sl/autofill.json":98,"./sv/autofill.json":100,"./tr/autofill.json":101,"./xa/autofill.json":103}],103:[function(require,module,exports){ +},{"./bg/autofill.json":77,"./cs/autofill.json":78,"./da/autofill.json":79,"./de/autofill.json":80,"./el/autofill.json":81,"./en/autofill.json":82,"./es/autofill.json":83,"./et/autofill.json":84,"./fi/autofill.json":85,"./fr/autofill.json":86,"./hr/autofill.json":87,"./hu/autofill.json":88,"./it/autofill.json":89,"./lt/autofill.json":90,"./lv/autofill.json":91,"./nb/autofill.json":92,"./nl/autofill.json":93,"./pl/autofill.json":94,"./pt/autofill.json":95,"./ro/autofill.json":96,"./ru/autofill.json":97,"./sk/autofill.json":98,"./sl/autofill.json":99,"./sv/autofill.json":101,"./tr/autofill.json":102,"./xa/autofill.json":104}],104:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -21607,7 +21680,7 @@ module.exports={ "note": "Button that prevents the DuckDuckGo email protection signup prompt from appearing again." } } -},{}],104:[function(require,module,exports){ +},{}],105:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -21650,4 +21723,4 @@ window.cancelIdleCallback = window.cancelIdleCallback || function (id) { }; var _default = exports.default = {}; -},{}]},{},[65]); +},{}]},{},[66]); diff --git a/swift-package/Resources/assets/autofill.js b/swift-package/Resources/assets/autofill.js index 7b2e5f08e..e07247a53 100644 --- a/swift-package/Resources/assets/autofill.js +++ b/swift-package/Resources/assets/autofill.js @@ -425,6 +425,130 @@ exports.DeviceApi = DeviceApi; },{}],5:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidMessagingTransport = exports.AndroidMessagingConfig = void 0; +var _messaging = require("./messaging.js"); +/** + * @module Android Messaging + * + * @description A wrapper for messaging on Android. See example usage in android.transport.js + */ + +/** + * @typedef {import("./messaging").MessagingTransport} MessagingTransport + */ + +/** + * On Android, handlers are added to the window object and are prefixed with `ddg`. The object looks like this: + * + * ```typescript + * { + * onMessage: undefined, + * postMessage: (message) => void, + * addEventListener: (eventType: string, Function) => void, + * removeEventListener: (eventType: string, Function) => void + * } + * ``` + * + * You send messages to `postMessage` and listen with `addEventListener`. Once the event is received, + * we also remove the listener with `removeEventListener`. + * + * @link https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener) + * @implements {MessagingTransport} + */ +class AndroidMessagingTransport { + /** @type {AndroidMessagingConfig} */ + config; + globals = { + capturedHandlers: {} + }; + /** + * @param {AndroidMessagingConfig} config + */ + constructor(config) { + this.config = config; + } + + /** + * Given the method name, returns the related Android handler + * @param {string} methodName + * @returns {AndroidHandler} + * @private + */ + _getHandler(methodName) { + const androidSpecificName = this._getHandlerName(methodName); + if (!(androidSpecificName in window)) { + throw new _messaging.MissingHandler(`Missing android handler: '${methodName}'`, methodName); + } + return window[androidSpecificName]; + } + + /** + * Given the autofill method name, it returns the Android-specific handler name + * @param {string} internalName + * @returns {string} + * @private + */ + _getHandlerName(internalName) { + return 'ddg' + internalName[0].toUpperCase() + internalName.slice(1); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + notify(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const handler = this._getHandler(name); + const message = data ? JSON.stringify(data) : ''; + handler.postMessage(message); + } + + /** + * @param {string} name + * @param {Record} [data] + */ + async request(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + // Set up the listener first + const handler = this._getHandler(name); + const responseOnce = new Promise(resolve => { + const responseHandler = e => { + handler.removeEventListener('message', responseHandler); + resolve(e.data); + }; + handler.addEventListener('message', responseHandler); + }); + + // Then send the message + this.notify(name, data); + + // And return once the promise resolves + const responseJSON = await responseOnce; + return JSON.parse(responseJSON); + } +} + +/** + * Use this configuration to create an instance of {@link Messaging} for Android + */ +exports.AndroidMessagingTransport = AndroidMessagingTransport; +class AndroidMessagingConfig { + /** + * All the expected Android handler names + * @param {{messageHandlerNames: string[]}} config + */ + constructor(config) { + this.messageHandlerNames = config.messageHandlerNames; + } +} +exports.AndroidMessagingConfig = AndroidMessagingConfig; + +},{"./messaging.js":6}],6:[function(require,module,exports){ +"use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); @@ -436,6 +560,7 @@ Object.defineProperty(exports, "WebkitMessagingConfig", { } }); var _webkit = require("./webkit.js"); +var _android = require("./android.js"); /** * @module Messaging * @@ -494,7 +619,7 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config */ constructor(config) { this.transport = getTransport(config); @@ -566,7 +691,7 @@ class MessagingTransport { } /** - * @param {WebkitMessagingConfig} config + * @param {WebkitMessagingConfig | AndroidMessagingConfig} config * @returns {MessagingTransport} */ exports.MessagingTransport = MessagingTransport; @@ -574,6 +699,9 @@ function getTransport(config) { if (config instanceof _webkit.WebkitMessagingConfig) { return new _webkit.WebkitMessagingTransport(config); } + if (config instanceof _android.AndroidMessagingConfig) { + return new _android.AndroidMessagingTransport(config); + } throw new Error('unreachable'); } @@ -596,7 +724,7 @@ class MissingHandler extends Error { */ exports.MissingHandler = MissingHandler; -},{"./webkit.js":6}],6:[function(require,module,exports){ +},{"./android.js":5,"./webkit.js":7}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -991,7 +1119,7 @@ function captureGlobals() { }; } -},{"./messaging.js":5}],7:[function(require,module,exports){ +},{"./messaging.js":6}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1122,7 +1250,7 @@ function _safeHostname(inputHostname) { } } -},{"./lib/apple.password.js":8,"./lib/constants.js":9,"./lib/rules-parser.js":10}],8:[function(require,module,exports){ +},{"./lib/apple.password.js":9,"./lib/constants.js":10,"./lib/rules-parser.js":11}],9:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1651,7 +1779,7 @@ class Password { } exports.Password = Password; -},{"./constants.js":9,"./rules-parser.js":10}],9:[function(require,module,exports){ +},{"./constants.js":10,"./rules-parser.js":11}],10:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1671,7 +1799,7 @@ const constants = exports.constants = { DEFAULT_UNAMBIGUOUS_CHARS }; -},{}],10:[function(require,module,exports){ +},{}],11:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -2267,7 +2395,7 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return newPasswordRules; } -},{}],11:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ module.exports={ "163.com": { "password-rules": "minlength: 6; maxlength: 16;" @@ -3299,7 +3427,7 @@ module.exports={ "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 6; required: lower; required: upper; required: digit;" } } -},{}],12:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3363,7 +3491,7 @@ class CredentialsImport { } exports.CredentialsImport = CredentialsImport; -},{"./deviceApiCalls/__generated__/deviceApiCalls.js":58}],13:[function(require,module,exports){ +},{"./deviceApiCalls/__generated__/deviceApiCalls.js":59}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3419,7 +3547,7 @@ function createDevice() { return new _ExtensionInterface.ExtensionInterface(globalConfig, deviceApi, settings); } -},{"../packages/device-api/index.js":2,"./DeviceInterface/AndroidInterface.js":14,"./DeviceInterface/AppleDeviceInterface.js":15,"./DeviceInterface/AppleOverlayDeviceInterface.js":16,"./DeviceInterface/ExtensionInterface.js":17,"./DeviceInterface/WindowsInterface.js":19,"./DeviceInterface/WindowsOverlayDeviceInterface.js":20,"./Settings.js":41,"./config.js":56,"./deviceApiCalls/transports/transports.js":64}],14:[function(require,module,exports){ +},{"../packages/device-api/index.js":2,"./DeviceInterface/AndroidInterface.js":15,"./DeviceInterface/AppleDeviceInterface.js":16,"./DeviceInterface/AppleOverlayDeviceInterface.js":17,"./DeviceInterface/ExtensionInterface.js":18,"./DeviceInterface/WindowsInterface.js":20,"./DeviceInterface/WindowsOverlayDeviceInterface.js":21,"./Settings.js":42,"./config.js":57,"./deviceApiCalls/transports/transports.js":65}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3439,25 +3567,35 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {Promise} */ async getAlias() { - const { - alias - } = await (0, _autofillUtils.sendAndWaitForAnswer)(async () => { - if (this.inContextSignup.isAvailable()) { - const { - isSignedIn - } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + // If in-context signup is available, do that first + if (this.inContextSignup.isAvailable()) { + const { + isSignedIn + } = await this.deviceApi.request(new _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall(null)); + if (isSignedIn) { // On Android we can't get the input type data again without // refreshing the page, so instead we can mutate it now that we // know the user has Email Protection available. - if (this.globalConfig.availableInputTypes) { - this.globalConfig.availableInputTypes.email = isSignedIn; + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: isSignedIn + }); } this.updateForStateChange(); this.onFinishedAutofill(); } - return window.EmailInterface.showTooltip(); - }, 'getAliasResponse'); - return alias; + } + // Then, if successful actually prompt to fill + if (this.settings.availableInputTypes.email) { + const { + alias + } = await this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetAliasCall({ + requiresUserPermission: !this.globalConfig.isApp, + shouldConsumeAliasIfProvided: !this.globalConfig.isApp, + isIncontextSignupAvailable: this.inContextSignup.isAvailable() + })); + return alias ? (0, _autofillUtils.formatDuckAddress)(alias) : undefined; + } } /** @@ -3472,14 +3610,9 @@ class AndroidInterface extends _InterfacePrototype.default { * @returns {boolean} */ isDeviceSignedIn() { - // on DDG domains, always check via `window.EmailInterface.isSignedIn()` - if (this.globalConfig.isDDGDomain) { - return window.EmailInterface.isSignedIn() === 'true'; - } - // on non-DDG domains, where `availableInputTypes.email` is present, use it - if (typeof this.globalConfig.availableInputTypes?.email === 'boolean') { - return this.globalConfig.availableInputTypes.email; + if (typeof this.settings.availableInputTypes?.email === 'boolean') { + return this.settings.availableInputTypes.email; } // ...on other domains we assume true because the script wouldn't exist otherwise @@ -3494,15 +3627,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Settings page displays data of the logged in user data */ getUserData() { - let userData = null; - try { - userData = JSON.parse(window.EmailInterface.getUserData()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(userData); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetUserDataCall({})); } /** @@ -3510,25 +3635,13 @@ class AndroidInterface extends _InterfacePrototype.default { * Device capabilities determine which functionality is available to the user */ getEmailProtectionCapabilities() { - let deviceCapabilities = null; - try { - deviceCapabilities = JSON.parse(window.EmailInterface.getDeviceCapabilities()); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } - return Promise.resolve(deviceCapabilities); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionGetCapabilitiesCall({})); } storeUserData(_ref) { let { - addUserData: { - token, - userName, - cohort - } + addUserData } = _ref; - return window.EmailInterface.storeCredentials(token, userName, cohort); + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionStoreUserDataCall(addUserData)); } /** @@ -3536,13 +3649,7 @@ class AndroidInterface extends _InterfacePrototype.default { * Provides functionality to log the user out */ removeUserData() { - try { - return window.EmailInterface.removeCredentials(); - } catch (e) { - if (this.globalConfig.isDDGTestMode) { - console.error(e); - } - } + return this.deviceApi.request(new _deviceApiCalls.EmailProtectionRemoveUserDataCall({})); } /** @@ -3567,7 +3674,7 @@ class AndroidInterface extends _InterfacePrototype.default { } exports.AndroidInterface = AndroidInterface; -},{"../InContextSignup.js":35,"../UI/controllers/NativeUIController.js":49,"../autofill-utils.js":54,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./InterfacePrototype.js":18}],15:[function(require,module,exports){ +},{"../InContextSignup.js":36,"../UI/controllers/NativeUIController.js":50,"../autofill-utils.js":55,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./InterfacePrototype.js":19}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3923,7 +4030,7 @@ class AppleDeviceInterface extends _InterfacePrototype.default { } exports.AppleDeviceInterface = AppleDeviceInterface; -},{"../../packages/device-api/index.js":2,"../Form/matching.js":34,"../InContextSignup.js":35,"../ThirdPartyProvider.js":42,"../UI/HTMLTooltip.js":47,"../UI/controllers/HTMLTooltipUIController.js":48,"../UI/controllers/NativeUIController.js":49,"../UI/controllers/OverlayUIController.js":50,"../autofill-utils.js":54,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"../deviceApiCalls/additionalDeviceApiCalls.js":60,"./InterfacePrototype.js":18}],16:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"../Form/matching.js":35,"../InContextSignup.js":36,"../ThirdPartyProvider.js":43,"../UI/HTMLTooltip.js":48,"../UI/controllers/HTMLTooltipUIController.js":49,"../UI/controllers/NativeUIController.js":50,"../UI/controllers/OverlayUIController.js":51,"../autofill-utils.js":55,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"../deviceApiCalls/additionalDeviceApiCalls.js":61,"./InterfacePrototype.js":19}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4042,7 +4149,7 @@ class AppleOverlayDeviceInterface extends _AppleDeviceInterface.AppleDeviceInter } exports.AppleOverlayDeviceInterface = AppleOverlayDeviceInterface; -},{"../../packages/device-api/index.js":2,"../UI/controllers/HTMLTooltipUIController.js":48,"./AppleDeviceInterface.js":15,"./overlayApi.js":22}],17:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"../UI/controllers/HTMLTooltipUIController.js":49,"./AppleDeviceInterface.js":16,"./overlayApi.js":23}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4261,7 +4368,7 @@ class ExtensionInterface extends _InterfacePrototype.default { } exports.ExtensionInterface = ExtensionInterface; -},{"../Form/matching.js":34,"../InContextSignup.js":35,"../UI/HTMLTooltip.js":47,"../UI/controllers/HTMLTooltipUIController.js":48,"../autofill-utils.js":54,"./InterfacePrototype.js":18}],18:[function(require,module,exports){ +},{"../Form/matching.js":35,"../InContextSignup.js":36,"../UI/HTMLTooltip.js":48,"../UI/controllers/HTMLTooltipUIController.js":49,"../autofill-utils.js":55,"./InterfacePrototype.js":19}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4864,11 +4971,19 @@ class InterfacePrototype { let userData; try { userData = await this.getUserData(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('getUserData failed with', e); + } + } let capabilities; try { capabilities = await this.getEmailProtectionCapabilities(); - } catch (e) {} + } catch (e) { + if (this.isTestMode()) { + console.log('capabilities fetching failed with', e); + } + } // Set up listener for web app actions if (this.globalConfig.isDDGDomain) { @@ -4924,6 +5039,13 @@ class InterfacePrototype { const data = await (0, _autofillUtils.sendAndWaitForAnswer)(_autofillUtils.SIGN_IN_MSG, 'addUserData'); // This call doesn't send a response, so we can't know if it succeeded this.storeUserData(data); + + // Assuming the previous call succeeded, let's update availableInputTypes + if (this.settings.availableInputTypes) { + this.settings.setAvailableInputTypes({ + email: true + }); + } await this.setupAutofill(); await this.settings.refresh(); await this.setupSettingsPage({ @@ -5092,7 +5214,7 @@ class InterfacePrototype { } var _default = exports.default = InterfacePrototype; -},{"../../packages/device-api/index.js":2,"../CredentialsImport.js":12,"../EmailProtection.js":23,"../Form/formatters.js":27,"../Form/matching.js":34,"../InputTypes/Credentials.js":36,"../PasswordGenerator.js":39,"../Scanner.js":40,"../Settings.js":41,"../UI/controllers/NativeUIController.js":49,"../autofill-utils.js":54,"../config.js":56,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"../deviceApiCalls/transports/transports.js":64,"../locales/strings.js":89,"./initFormSubmissionsApi.js":21}],19:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"../CredentialsImport.js":13,"../EmailProtection.js":24,"../Form/formatters.js":28,"../Form/matching.js":35,"../InputTypes/Credentials.js":37,"../PasswordGenerator.js":40,"../Scanner.js":41,"../Settings.js":42,"../UI/controllers/NativeUIController.js":50,"../autofill-utils.js":55,"../config.js":57,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"../deviceApiCalls/transports/transports.js":65,"../locales/strings.js":90,"./initFormSubmissionsApi.js":22}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5177,13 +5299,13 @@ class WindowsInterface extends _InterfacePrototype.default { return await this.credentialsImport.refresh(); } default: - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { console.warn('unhandled response', resp); } return this._closeAutofillParent(); } } catch (e) { - if (this.globalConfig.isDDGTestMode) { + if (this.isTestMode()) { if (e instanceof DOMException && e.name === 'AbortError') { console.log('Promise Aborted'); } else { @@ -5258,7 +5380,7 @@ class WindowsInterface extends _InterfacePrototype.default { } exports.WindowsInterface = WindowsInterface; -},{"../UI/controllers/OverlayUIController.js":50,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./InterfacePrototype.js":18}],20:[function(require,module,exports){ +},{"../UI/controllers/OverlayUIController.js":51,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./InterfacePrototype.js":19}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5437,7 +5559,7 @@ class WindowsOverlayDeviceInterface extends _InterfacePrototype.default { } exports.WindowsOverlayDeviceInterface = WindowsOverlayDeviceInterface; -},{"../UI/controllers/HTMLTooltipUIController.js":48,"../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./InterfacePrototype.js":18,"./overlayApi.js":22}],21:[function(require,module,exports){ +},{"../UI/controllers/HTMLTooltipUIController.js":49,"../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./InterfacePrototype.js":19,"./overlayApi.js":23}],22:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5536,7 +5658,7 @@ function initFormSubmissionsApi(forms, matching) { }); } -},{"../Form/label-util.js":30,"../autofill-utils.js":54}],22:[function(require,module,exports){ +},{"../Form/label-util.js":31,"../autofill-utils.js":55}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5594,7 +5716,7 @@ function overlayApi(device) { }; } -},{"../deviceApiCalls/__generated__/deviceApiCalls.js":58}],23:[function(require,module,exports){ +},{"../deviceApiCalls/__generated__/deviceApiCalls.js":59}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5629,7 +5751,7 @@ class EmailProtection { } exports.EmailProtection = EmailProtection; -},{}],24:[function(require,module,exports){ +},{}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -5769,7 +5891,7 @@ class Form { } submitHandler() { let via = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown'; - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('Form.submitHandler via:', via, this); } if (this.submitHandlerExecuted) return; @@ -6536,7 +6658,7 @@ class Form { } exports.Form = Form; -},{"../InputTypes/Credentials.js":36,"../autofill-utils.js":54,"../constants.js":57,"./FormAnalyzer.js":25,"./formatters.js":27,"./inputStyles.js":28,"./inputTypeConfig.js":29,"./matching.js":34}],25:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":37,"../autofill-utils.js":55,"../constants.js":58,"./FormAnalyzer.js":26,"./formatters.js":28,"./inputStyles.js":29,"./inputTypeConfig.js":30,"./matching.js":35}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -6906,7 +7028,7 @@ class FormAnalyzer { } var _default = exports.default = FormAnalyzer; -},{"../autofill-utils.js":54,"../constants.js":57,"./matching-config/__generated__/compiled-matching-config.js":32,"./matching.js":34}],26:[function(require,module,exports){ +},{"../autofill-utils.js":55,"../constants.js":58,"./matching-config/__generated__/compiled-matching-config.js":33,"./matching.js":35}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7471,7 +7593,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { 'Unknown Region': 'ZZ' }; -},{}],27:[function(require,module,exports){ +},{}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7776,7 +7898,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":26,"./matching.js":34}],28:[function(require,module,exports){ +},{"./countryNames.js":27,"./matching.js":35}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7867,7 +7989,7 @@ const getIconStylesAutofilled = (input, form) => { }; exports.getIconStylesAutofilled = getIconStylesAutofilled; -},{"./inputTypeConfig.js":29}],29:[function(require,module,exports){ +},{"./inputTypeConfig.js":30}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8121,7 +8243,7 @@ const isFieldDecorated = input => { }; exports.isFieldDecorated = isFieldDecorated; -},{"../InputTypes/Credentials.js":36,"../InputTypes/CreditCard.js":37,"../InputTypes/Identity.js":38,"../UI/img/ddgPasswordIcon.js":52,"../constants.js":57,"./logo-svg.js":31,"./matching.js":34}],30:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":37,"../InputTypes/CreditCard.js":38,"../InputTypes/Identity.js":39,"../UI/img/ddgPasswordIcon.js":53,"../constants.js":58,"./logo-svg.js":32,"./matching.js":35}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8169,7 +8291,7 @@ const extractElementStrings = element => { }; exports.extractElementStrings = extractElementStrings; -},{"./matching.js":34}],31:[function(require,module,exports){ +},{"./matching.js":35}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8202,7 +8324,7 @@ const daxGrayscaleSvg = ` `.trim(); const daxGrayscaleBase64 = exports.daxGrayscaleBase64 = `data:image/svg+xml;base64,${window.btoa(daxGrayscaleSvg)}`; -},{}],32:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8655,7 +8777,7 @@ const matchingConfiguration = exports.matchingConfiguration = { } }; -},{}],33:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -8730,7 +8852,7 @@ function logUnmatched(el, allStrings) { console.groupEnd(); } -},{"../autofill-utils.js":54,"./matching.js":34}],34:[function(require,module,exports){ +},{"../autofill-utils.js":55,"./matching.js":35}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9722,7 +9844,7 @@ function createMatching() { return new Matching(_compiledMatchingConfig.matchingConfiguration); } -},{"../autofill-utils.js":54,"../constants.js":57,"./label-util.js":30,"./matching-config/__generated__/compiled-matching-config.js":32,"./matching-utils.js":33}],35:[function(require,module,exports){ +},{"../autofill-utils.js":55,"../constants.js":58,"./label-util.js":31,"./matching-config/__generated__/compiled-matching-config.js":33,"./matching-utils.js":34}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -9854,7 +9976,7 @@ class InContextSignup { } exports.InContextSignup = InContextSignup; -},{"./autofill-utils.js":54,"./deviceApiCalls/__generated__/deviceApiCalls.js":58}],36:[function(require,module,exports){ +},{"./autofill-utils.js":55,"./deviceApiCalls/__generated__/deviceApiCalls.js":59}],37:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10010,7 +10132,7 @@ function createCredentialsTooltipItem(data) { return new CredentialsTooltipItem(data); } -},{"../autofill-utils.js":54}],37:[function(require,module,exports){ +},{"../autofill-utils.js":55}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10035,7 +10157,7 @@ class CreditCardTooltipItem { } exports.CreditCardTooltipItem = CreditCardTooltipItem; -},{}],38:[function(require,module,exports){ +},{}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10081,7 +10203,7 @@ class IdentityTooltipItem { } exports.IdentityTooltipItem = IdentityTooltipItem; -},{"../Form/formatters.js":27}],39:[function(require,module,exports){ +},{"../Form/formatters.js":28}],40:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10123,7 +10245,7 @@ class PasswordGenerator { } exports.PasswordGenerator = PasswordGenerator; -},{"../packages/password/index.js":7,"../packages/password/rules.json":11}],40:[function(require,module,exports){ +},{"../packages/password/index.js":8,"../packages/password/rules.json":12}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10584,7 +10706,7 @@ function createScanner(device, scannerOptions) { }); } -},{"./Form/Form.js":24,"./Form/matching.js":34,"./autofill-utils.js":54,"./constants.js":57,"./deviceApiCalls/__generated__/deviceApiCalls.js":58}],41:[function(require,module,exports){ +},{"./Form/Form.js":25,"./Form/matching.js":35,"./autofill-utils.js":55,"./constants.js":58,"./deviceApiCalls/__generated__/deviceApiCalls.js":59}],42:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -10730,6 +10852,11 @@ class Settings { if (this._runtimeConfiguration) return this._runtimeConfiguration; const runtimeConfig = await this.deviceApi.request(new _deviceApiCalls.GetRuntimeConfigurationCall(null)); this._runtimeConfiguration = runtimeConfig; + + // If the platform sends availableInputTypes here, store them + if (runtimeConfig.availableInputTypes) { + this.setAvailableInputTypes(runtimeConfig.availableInputTypes); + } return this._runtimeConfiguration; } @@ -10745,6 +10872,9 @@ class Settings { if (this.globalConfig.isTopFrame) { return Settings.defaults.availableInputTypes; } + if (this._availableInputTypes) { + return this.availableInputTypes; + } return await this.deviceApi.request(new _deviceApiCalls.GetAvailableInputTypesCall(null)); } catch (e) { if (this.globalConfig.isDDGTestMode) { @@ -10997,7 +11127,7 @@ class Settings { } exports.Settings = Settings; -},{"../packages/device-api/index.js":2,"./autofill-utils.js":54,"./deviceApiCalls/__generated__/deviceApiCalls.js":58,"./deviceApiCalls/__generated__/validators.zod.js":59}],42:[function(require,module,exports){ +},{"../packages/device-api/index.js":2,"./autofill-utils.js":55,"./deviceApiCalls/__generated__/deviceApiCalls.js":59,"./deviceApiCalls/__generated__/validators.zod.js":60}],43:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11064,7 +11194,7 @@ class ThirdPartyProvider { this.device.scanner.forms.forEach(form => form.recategorizeAllInputs()); } } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: providerStatusUpdated error: ❌', e); } } @@ -11079,7 +11209,7 @@ class ThirdPartyProvider { } setTimeout(() => this._pollForUpdatesToCredentialsProvider(), 2000); } catch (e) { - if (this.device.globalConfig.isDDGTestMode) { + if (this.device.isTestMode()) { console.log('isDDGTestMode: _pollForUpdatesToCredentialsProvider: ❌', e); } } @@ -11087,7 +11217,7 @@ class ThirdPartyProvider { } exports.ThirdPartyProvider = ThirdPartyProvider; -},{"../packages/device-api/index.js":2,"./Form/matching.js":34,"./deviceApiCalls/__generated__/deviceApiCalls.js":58,"./deviceApiCalls/__generated__/validators.zod.js":59}],43:[function(require,module,exports){ +},{"../packages/device-api/index.js":2,"./Form/matching.js":35,"./deviceApiCalls/__generated__/deviceApiCalls.js":59,"./deviceApiCalls/__generated__/validators.zod.js":60}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11128,7 +11258,7 @@ ${this.options.css} } var _default = exports.default = CredentialsImportTooltip; -},{"./HTMLTooltip.js":47}],44:[function(require,module,exports){ +},{"./HTMLTooltip.js":48}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11279,7 +11409,7 @@ ${css} } var _default = exports.default = DataHTMLTooltip; -},{"../InputTypes/Credentials.js":36,"../autofill-utils.js":54,"./HTMLTooltip.js":47}],45:[function(require,module,exports){ +},{"../InputTypes/Credentials.js":37,"../autofill-utils.js":55,"./HTMLTooltip.js":48}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11361,7 +11491,7 @@ ${this.options.css} } var _default = exports.default = EmailHTMLTooltip; -},{"../autofill-utils.js":54,"./HTMLTooltip.js":47}],46:[function(require,module,exports){ +},{"../autofill-utils.js":55,"./HTMLTooltip.js":48}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11414,7 +11544,7 @@ ${this.options.css} } var _default = exports.default = EmailSignupHTMLTooltip; -},{"./HTMLTooltip.js":47}],47:[function(require,module,exports){ +},{"./HTMLTooltip.js":48}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -11802,7 +11932,7 @@ class HTMLTooltip { exports.HTMLTooltip = HTMLTooltip; var _default = exports.default = HTMLTooltip; -},{"../Form/matching.js":34,"../autofill-utils.js":54,"./styles/styles.js":53}],48:[function(require,module,exports){ +},{"../Form/matching.js":35,"../autofill-utils.js":55,"./styles/styles.js":54}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12170,7 +12300,7 @@ class HTMLTooltipUIController extends _UIController.UIController { } exports.HTMLTooltipUIController = HTMLTooltipUIController; -},{"../../Form/inputTypeConfig.js":29,"../../Form/matching.js":34,"../../autofill-utils.js":54,"../CredentialsImportTooltip.js":43,"../DataHTMLTooltip.js":44,"../EmailHTMLTooltip.js":45,"../EmailSignupHTMLTooltip.js":46,"../HTMLTooltip.js":47,"./UIController.js":51}],49:[function(require,module,exports){ +},{"../../Form/inputTypeConfig.js":30,"../../Form/matching.js":35,"../../autofill-utils.js":55,"../CredentialsImportTooltip.js":44,"../DataHTMLTooltip.js":45,"../EmailHTMLTooltip.js":46,"../EmailSignupHTMLTooltip.js":47,"../HTMLTooltip.js":48,"./UIController.js":52}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12272,6 +12402,11 @@ class NativeUIController extends _UIController.UIController { form.activeInput?.focus(); break; } + case 'none': + { + // do nothing + break; + } default: { if (args.device.isTestMode()) { @@ -12332,7 +12467,7 @@ class NativeUIController extends _UIController.UIController { } exports.NativeUIController = NativeUIController; -},{"../../Form/matching.js":34,"../../InputTypes/Credentials.js":36,"../../deviceApiCalls/__generated__/deviceApiCalls.js":58,"./UIController.js":51}],50:[function(require,module,exports){ +},{"../../Form/matching.js":35,"../../InputTypes/Credentials.js":37,"../../deviceApiCalls/__generated__/deviceApiCalls.js":59,"./UIController.js":52}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12569,7 +12704,7 @@ class OverlayUIController extends _UIController.UIController { } exports.OverlayUIController = OverlayUIController; -},{"../../Form/matching.js":34,"./UIController.js":51}],51:[function(require,module,exports){ +},{"../../Form/matching.js":35,"./UIController.js":52}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12653,7 +12788,7 @@ class UIController { } exports.UIController = UIController; -},{}],52:[function(require,module,exports){ +},{}],53:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12670,7 +12805,7 @@ const ddgCcIconBase = exports.ddgCcIconBase = 'data:image/svg+xml;base64,PD94bWw const ddgCcIconFilled = exports.ddgCcIconFilled = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzc2NDMxMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjNzY0MzEwIi8+Cjwvc3ZnPgo='; const ddgIdentityIconBase = exports.ddgIdentityIconBase = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4KPHBhdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJub25lIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyMWMyLjE0MyAwIDQuMTExLS43NSA1LjY1Ny0yLS42MjYtLjUwNi0xLjMxOC0uOTI3LTIuMDYtMS4yNS0xLjEtLjQ4LTIuMjg1LS43MzUtMy40ODYtLjc1LTEuMi0uMDE0LTIuMzkyLjIxMS0zLjUwNC42NjQtLjgxNy4zMzMtMS41OC43ODMtMi4yNjQgMS4zMzYgMS41NDYgMS4yNSAzLjUxNCAyIDUuNjU3IDJ6bTQuMzk3LTUuMDgzYy45NjcuNDIyIDEuODY2Ljk4IDIuNjcyIDEuNjU1QzIwLjI3OSAxNi4wMzkgMjEgMTQuMTA0IDIxIDEyYzAtNC45Ny00LjAzLTktOS05cy05IDQuMDMtOSA5YzAgMi4xMDQuNzIyIDQuMDQgMS45MzIgNS41NzIuODc0LS43MzQgMS44Ni0xLjMyOCAyLjkyMS0xLjc2IDEuMzYtLjU1NCAyLjgxNi0uODMgNC4yODMtLjgxMSAxLjQ2Ny4wMTggMi45MTYuMzMgNC4yNi45MTZ6TTEyIDIzYzYuMDc1IDAgMTEtNC45MjUgMTEtMTFTMTguMDc1IDEgMTIgMSAxIDUuOTI1IDEgMTJzNC45MjUgMTEgMTEgMTF6bTMtMTNjMCAxLjY1Ny0xLjM0MyAzLTMgM3MtMy0xLjM0My0zLTMgMS4zNDMtMyAzLTMgMyAxLjM0MyAzIDN6bTIgMGMwIDIuNzYxLTIuMjM5IDUtNSA1cy01LTIuMjM5LTUtNSAyLjIzOS01IDUtNSA1IDIuMjM5IDUgNXoiIGZpbGw9IiMwMDAiLz4KPC9zdmc+Cg==`; -},{}],53:[function(require,module,exports){ +},{}],54:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12679,7 +12814,7 @@ Object.defineProperty(exports, "__esModule", { exports.CSS_STYLES = void 0; const CSS_STYLES = exports.CSS_STYLES = ":root {\n color-scheme: light dark;\n}\n\n.wrapper *, .wrapper *::before, .wrapper *::after {\n box-sizing: border-box;\n}\n.wrapper {\n position: fixed;\n top: 0;\n left: 0;\n padding: 0;\n font-family: 'DDG_ProximaNova', 'Proxima Nova', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n z-index: 2147483647;\n}\n.wrapper--data {\n font-family: 'SF Pro Text', system-ui, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n}\n.wrapper:not(.top-autofill) .tooltip {\n position: absolute;\n width: 300px;\n max-width: calc(100vw - 25px);\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--data, #topAutofill {\n background-color: rgba(242, 240, 240, 1);\n -webkit-backdrop-filter: blur(40px);\n backdrop-filter: blur(40px);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data, #topAutofill {\n background: rgb(100, 98, 102, .9);\n }\n}\n.tooltip--data {\n padding: 6px;\n font-size: 13px;\n line-height: 14px;\n width: 315px;\n max-height: 290px;\n overflow-y: auto;\n}\n.top-autofill .tooltip--data {\n min-height: 100vh;\n}\n.tooltip--data.tooltip--incontext-signup {\n width: 360px;\n}\n.wrapper:not(.top-autofill) .tooltip--data {\n top: 100%;\n left: 100%;\n border: 0.5px solid rgba(255, 255, 255, 0.2);\n border-radius: 6px;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.32);\n}\n@media (prefers-color-scheme: dark) {\n .wrapper:not(.top-autofill) .tooltip--data {\n border: 1px solid rgba(255, 255, 255, 0.2);\n }\n}\n.wrapper:not(.top-autofill) .tooltip--email {\n top: calc(100% + 6px);\n right: calc(100% - 48px);\n padding: 8px;\n border: 1px solid #D0D0D0;\n border-radius: 10px;\n background-color: #FFFFFF;\n font-size: 14px;\n line-height: 1.3;\n color: #333333;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);\n}\n.tooltip--email__caret {\n position: absolute;\n transform: translate(-1000px, -1000px);\n z-index: 2147483647;\n}\n.tooltip--email__caret::before,\n.tooltip--email__caret::after {\n content: \"\";\n width: 0;\n height: 0;\n border-left: 10px solid transparent;\n border-right: 10px solid transparent;\n display: block;\n border-bottom: 8px solid #D0D0D0;\n position: absolute;\n right: -28px;\n}\n.tooltip--email__caret::before {\n border-bottom-color: #D0D0D0;\n top: -1px;\n}\n.tooltip--email__caret::after {\n border-bottom-color: #FFFFFF;\n top: 0px;\n}\n\n/* Buttons */\n.tooltip__button {\n display: flex;\n width: 100%;\n padding: 8px 8px 8px 0px;\n font-family: inherit;\n color: inherit;\n background: transparent;\n border: none;\n border-radius: 6px;\n text-align: left;\n}\n.tooltip__button.currentFocus,\n.wrapper:not(.top-autofill) .tooltip__button:hover {\n background-color: #3969EF;\n color: #FFFFFF;\n}\n\n/* Data autofill tooltip specific */\n.tooltip__button--data {\n position: relative;\n min-height: 48px;\n flex-direction: row;\n justify-content: flex-start;\n font-size: inherit;\n font-weight: 500;\n line-height: 16px;\n text-align: left;\n border-radius: 3px;\n}\n.tooltip--data__item-container {\n max-height: 220px;\n overflow: auto;\n}\n.tooltip__button--data:first-child {\n margin-top: 0;\n}\n.tooltip__button--data:last-child {\n margin-bottom: 0;\n}\n.tooltip__button--data::before {\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 20px 20px;\n background-repeat: no-repeat;\n background-position: center center;\n}\n#provider_locked::after {\n position: absolute;\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 11px 13px;\n background-repeat: no-repeat;\n background-position: right bottom;\n}\n.tooltip__button--data.currentFocus:not(.tooltip__button--data--bitwarden)::before,\n.wrapper:not(.top-autofill) .tooltip__button--data:not(.tooltip__button--data--bitwarden):hover::before {\n filter: invert(100%);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before,\n .tooltip__button--data:not(.tooltip__button--data--bitwarden)::before {\n filter: invert(100%);\n opacity: .9;\n }\n}\n.tooltip__button__text-container {\n margin: auto 0;\n}\n.label {\n display: block;\n font-weight: 400;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.8);\n font-size: 13px;\n line-height: 1;\n}\n.label + .label {\n margin-top: 2px;\n}\n.label.label--medium {\n font-weight: 500;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.9);\n}\n.label.label--small {\n font-size: 11px;\n font-weight: 400;\n letter-spacing: 0.06px;\n color: rgba(0,0,0,0.6);\n}\n@media (prefers-color-scheme: dark) {\n .tooltip--data .label {\n color: #ffffff;\n }\n .tooltip--data .label--medium {\n color: #ffffff;\n }\n .tooltip--data .label--small {\n color: #cdcdcd;\n }\n}\n.tooltip__button.currentFocus .label,\n.wrapper:not(.top-autofill) .tooltip__button:hover .label {\n color: #FFFFFF;\n}\n\n.tooltip__button--manage {\n font-size: 13px;\n padding: 5px 9px;\n border-radius: 3px;\n margin: 0;\n}\n\n/* Icons */\n.tooltip__button--data--credentials::before,\n.tooltip__button--data--credentials__current::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS4zMzQgNi42NjdhMiAyIDAgMSAwIDAgNCAyIDIgMCAwIDAgMC00Wm0tLjY2NyAyYS42NjcuNjY3IDAgMSAxIDEuMzMzIDAgLjY2Ny42NjcgMCAwIDEtMS4zMzMgMFoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTQuNjY3IDRhNS4zMzMgNS4zMzMgMCAwIDAtNS4xODggNi41NzhsLTUuMjg0IDUuMjg0YS42NjcuNjY3IDAgMCAwLS4xOTUuNDcxdjNjMCAuMzY5LjI5OC42NjcuNjY3LjY2N2gyLjY2NmMuNzM3IDAgMS4zMzQtLjU5NyAxLjMzNC0xLjMzM1YxOGguNjY2Yy43MzcgMCAxLjMzNC0uNTk3IDEuMzM0LTEuMzMzdi0xLjMzNEgxMmMuMTc3IDAgLjM0Ni0uMDcuNDcxLS4xOTVsLjY4OC0uNjg4QTUuMzMzIDUuMzMzIDAgMSAwIDE0LjY2NyA0Wm0tNCA1LjMzM2E0IDQgMCAxIDEgMi41NTUgMy43MzIuNjY3LjY2NyAwIDAgMC0uNzEzLjE1bC0uNzg1Ljc4NUgxMGEuNjY3LjY2NyAwIDAgMC0uNjY3LjY2N3YySDhhLjY2Ny42NjcgMCAwIDAtLjY2Ny42NjZ2MS4zMzRoLTJ2LTIuMDU4bDUuMzY1LTUuMzY0YS42NjcuNjY3IDAgMCAwIC4xNjMtLjY3NyAzLjk5NiAzLjk5NiAwIDAgMS0uMTk0LTEuMjM1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--credentials__new::before {\n background-size: 28px 28px;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBkPSJNOC4wNDcgNC42MjVDNy45MzcgNC4xMjUgNy44NjIgNCA3LjUgNGMtLjM2MiAwLS40MzguMTI1LS41NDcuNjI1LS4wNjguMzEtLjE3NyAxLjMzOC0uMjUxIDIuMDc3LS43MzguMDc0LTEuNzY3LjE4My0yLjA3Ny4yNTEtLjUuMTEtLjYyNS4xODQtLjYyNS41NDcgMCAuMzYyLjEyNS40MzcuNjI1LjU0Ny4zMS4wNjcgMS4zMzYuMTc3IDIuMDc0LjI1LjA3My43NjcuMTg1IDEuODQyLjI1NCAyLjA3OC4xMS4zNzUuMTg1LjYyNS41NDcuNjI1LjM2MiAwIC40MzgtLjEyNS41NDctLjYyNS4wNjgtLjMxLjE3Ny0xLjMzNi4yNS0yLjA3NC43NjctLjA3MyAxLjg0Mi0uMTg1IDIuMDc4LS4yNTQuMzc1LS4xMS42MjUtLjE4NS42MjUtLjU0NyAwLS4zNjMtLjEyNS0uNDM4LS42MjUtLjU0Ny0uMzEtLjA2OC0xLjMzOS0uMTc3LTIuMDc3LS4yNTEtLjA3NC0uNzM5LS4xODMtMS43NjctLjI1MS0yLjA3N1oiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0xNC42ODEgNS4xOTljLS43NjYgMC0xLjQ4Mi4yMS0yLjA5My41NzhhLjYzNi42MzYgMCAwIDEtLjY1NS0xLjA5IDUuMzQgNS4zNCAwIDEgMSAxLjMwMiA5LjcyMmwtLjc3NS43NzZhLjYzNi42MzYgMCAwIDEtLjQ1LjE4NmgtMS4zOTh2MS42NWMwIC40OTMtLjQuODkzLS44OTMuODkzSDguNTc4djEuMTQxYzAgLjQ5NC0uNC44OTMtLjg5NC44OTNINC42MzZBLjYzNi42MzYgMCAwIDEgNCAxOS4zMTNWMTYuMjZjMC0uMTY5LjA2Ny0uMzMuMTg2LS40NWw1LjU2Mi01LjU2MmEuNjM2LjYzNiAwIDEgMSAuOS45bC01LjM3NiA1LjM3NXYyLjE1M2gyLjAzNHYtMS4zOTljMC0uMzUuMjg1LS42MzYuNjM2LS42MzZIOS4zNHYtMS45MDdjMC0uMzUxLjI4NC0uNjM2LjYzNS0uNjM2aDEuNzcxbC44NjQtLjg2M2EuNjM2LjYzNiAwIDAgMSAuNjY4LS4xNDcgNC4wNjkgNC4wNjkgMCAxIDAgMS40MDItNy44OVoiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTEzLjYyNSA4LjQ5OWExLjg3NSAxLjg3NSAwIDEgMSAzLjc1IDAgMS44NzUgMS44NzUgMCAwIDEtMy43NSAwWm0xLjg3NS0uNjI1YS42MjUuNjI1IDAgMSAwIDAgMS4yNS42MjUuNjI1IDAgMCAwIDAtMS4yNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogICAgPHBhdGggZmlsbD0iIzAwMCIgZD0iTTQuNjI1IDEyLjEyNWEuNjI1LjYyNSAwIDEgMCAwLTEuMjUuNjI1LjYyNSAwIDAgMCAwIDEuMjVaIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--creditCards::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--identities::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4=');\n}\n.tooltip__button--data--credentials.tooltip__button--data--bitwarden::before,\n.tooltip__button--data--credentials__current.tooltip__button--data--bitwarden::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iOCIgZmlsbD0iIzE3NUREQyIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE4LjU2OTYgNS40MzM1NUMxOC41MDg0IDUuMzc0NDIgMTguNDM0NyA1LjMyNzYzIDE4LjM1MzEgNS4yOTYxMUMxOC4yNzE1IDUuMjY0NiAxOC4xODM3IDUuMjQ5MDQgMTguMDk1MyA1LjI1MDQxSDUuOTIxOTFDNS44MzMyNiA1LjI0NzI5IDUuNzQ0OTMgNS4yNjIwNSA1LjY2MzA0IDUuMjkzNjdDNS41ODExNSA1LjMyNTI5IDUuNTA3NjUgNS4zNzMwMiA1LjQ0NzYyIDUuNDMzNTVDNS4zMjE3IDUuNTUwMTMgNS4yNTA2NSA1LjcwODE1IDUuMjUgNS44NzMxVjEzLjM4MjFDNS4yNTMzNiAxMy45NTM1IDUuMzc0MDggMTQuNTE5MSA1LjYwNTcyIDE1LjA0ODdDNS44MTkzMSAxNS41NzI4IDYuMTEyMDcgMTYuMDY2MSA2LjQ3NTI0IDE2LjUxMzlDNi44NDIgMTYuOTY4MyA3LjI1OTI5IDE3LjM4NTcgNy43MjAyNSAxNy43NTkzQzguMTQwNTMgMTguMTI1NiA4LjU4OTcxIDE4LjQ2MjMgOS4wNjQwNyAxOC43NjY2QzkuNDU5MzEgMTkuMDIzIDkuOTEzODMgMTkuMjc5NCAxMC4zNDg2IDE5LjUxNzVDMTAuNzgzNCAxOS43NTU2IDExLjA5OTYgMTkuOTIwNCAxMS4yNzc0IDE5Ljk5MzdDMTEuNDU1MyAyMC4wNjY5IDExLjYxMzQgMjAuMTQwMiAxMS43MTIyIDIwLjE5NTFDMTEuNzk5MiAyMC4yMzEzIDExLjg5MzUgMjAuMjUgMTEuOTg4OCAyMC4yNUMxMi4wODQyIDIwLjI1IDEyLjE3ODUgMjAuMjMxMyAxMi4yNjU1IDIwLjE5NTFDMTIuNDIxMiAyMC4xMzYzIDEyLjU3MjkgMjAuMDY5IDEyLjcyIDE5Ljk5MzdDMTIuNzcxMSAxOS45Njc0IDEyLjgzMzUgMTkuOTM2NiAxMi45MDY5IDE5LjkwMDRDMTMuMDg5MSAxOS44MTA1IDEzLjMzODggMTkuNjg3MiAxMy42NDg5IDE5LjUxNzVDMTQuMDgzNiAxOS4yNzk0IDE0LjUxODQgMTkuMDIzIDE0LjkzMzQgMTguNzY2NkMxNS40MDQgMTguNDU3NyAxNS44NTI4IDE4LjEyMTIgMTYuMjc3MiAxNy43NTkzQzE2LjczMzEgMTcuMzgwOSAxNy4xNDk5IDE2Ljk2NCAxNy41MjIyIDE2LjUxMzlDMTcuODc4IDE2LjA2MTcgMTguMTcwMiAxNS41NjkzIDE4LjM5MTcgMTUuMDQ4N0MxOC42MjM0IDE0LjUxOTEgMTguNzQ0MSAxMy45NTM1IDE4Ljc0NzQgMTMuMzgyMVY1Ljg3MzFDMTguNzU1NyA1Ljc5MjE0IDE4Ljc0MzkgNS43MTA1IDE4LjcxMzEgNS42MzQzNUMxOC42ODIzIDUuNTU4MiAxOC42MzMyIDUuNDg5NTQgMTguNTY5NiA1LjQzMzU1Wk0xNy4wMDg0IDEzLjQ1NTNDMTcuMDA4NCAxNi4xODQyIDEyLjAwODYgMTguNTI4NSAxMi4wMDg2IDE4LjUyODVWNi44NjIwOUgxNy4wMDg0VjEzLjQ1NTNaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');\n}\n#provider_locked:after {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMSAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEgNy42MDA1N1Y3LjYwMjVWOS41MjI1QzEgMTAuMDgwMSAxLjIyMTUxIDEwLjYxNDkgMS42MTU4MSAxMS4wMDkyQzIuMDEwMSAxMS40MDM1IDIuNTQ0ODggMTEuNjI1IDMuMTAyNSAxMS42MjVINy4yNzI1QzcuNTQ4NjEgMTEuNjI1IDcuODIyMDEgMTEuNTcwNiA4LjA3NzA5IDExLjQ2NUM4LjMzMjE4IDExLjM1OTMgOC41NjM5NiAxMS4yMDQ0IDguNzU5MTkgMTEuMDA5MkM4Ljk1NDQzIDEwLjgxNCA5LjEwOTMgMTAuNTgyMiA5LjIxNDk2IDEwLjMyNzFDOS4zMjA2MiAxMC4wNzIgOS4zNzUgOS43OTg2MSA5LjM3NSA5LjUyMjVMOS4zNzUgNy42MDI1TDkuMzc1IDcuNjAwNTdDOS4zNzQxNSA3LjE2MTMxIDkuMjM1NzQgNi43MzMzNSA4Ljk3OTIyIDYuMzc2NzhDOC44NzY4MyA2LjIzNDQ2IDguNzU3NjggNi4xMDYzNyA4LjYyNSA1Ljk5NDg5VjUuMTg3NUM4LjYyNSA0LjI3NTgyIDguMjYyODQgMy40MDE0OCA3LjYxODE4IDIuNzU2ODJDNi45NzM1MiAyLjExMjE2IDYuMDk5MTggMS43NSA1LjE4NzUgMS43NUM0LjI3NTgyIDEuNzUgMy40MDE0OCAyLjExMjE2IDIuNzU2ODIgMi43NTY4MkMyLjExMjE2IDMuNDAxNDggMS43NSA0LjI3NTgyIDEuNzUgNS4xODc1VjUuOTk0ODlDMS42MTczMiA2LjEwNjM3IDEuNDk4MTcgNi4yMzQ0NiAxLjM5NTc4IDYuMzc2NzhDMS4xMzkyNiA2LjczMzM1IDEuMDAwODUgNy4xNjEzMSAxIDcuNjAwNTdaTTQuOTY4NyA0Ljk2ODdDNS4wMjY5NCA0LjkxMDQ3IDUuMTA1MzIgNC44NzY5OSA1LjE4NzUgNC44NzUwN0M1LjI2OTY4IDQuODc2OTkgNS4zNDgwNiA0LjkxMDQ3IDUuNDA2MyA0Ljk2ODdDNS40NjU0MiA1LjAyNzgzIDUuNDk5MDQgNS4xMDc3NCA1LjUgNS4xOTEzVjUuNUg0Ljg3NVY1LjE5MTNDNC44NzU5NiA1LjEwNzc0IDQuOTA5NTggNS4wMjc4MyA0Ljk2ODcgNC45Njg3WiIgZmlsbD0iIzIyMjIyMiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIi8+Cjwvc3ZnPgo=');\n}\n\nhr {\n display: block;\n margin: 5px 9px;\n border: none; /* reset the border */\n border-top: 1px solid rgba(0,0,0,.1);\n}\n\nhr:first-child {\n display: none;\n}\n\n@media (prefers-color-scheme: dark) {\n hr {\n border-top: 1px solid rgba(255,255,255,.2);\n }\n}\n\n#privateAddress {\n align-items: flex-start;\n}\n#personalAddress::before,\n#privateAddress::before,\n#incontextSignup::before,\n#personalAddress.currentFocus::before,\n#personalAddress:hover::before,\n#privateAddress.currentFocus::before,\n#privateAddress:hover::before {\n filter: none;\n /* This is the same icon as `daxBase64` in `src/Form/logo-svg.js` */\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTY0IDEyOGMzNS4zNDYgMCA2NC0yOC42NTQgNjQtNjRzLTI4LjY1NC02NC02NC02NC02NCAyOC42NTQtNjQgNjQgMjguNjU0IDY0IDY0IDY0eiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im03MyAxMTEuNzVjMC0uNS4xMjMtLjYxNC0xLjQ2Ni0zLjc4Mi00LjIyNC04LjQ1OS04LjQ3LTIwLjM4NC02LjU0LTI4LjA3NS4zNTMtMS4zOTctMy45NzgtNTEuNzQ0LTcuMDQtNTMuMzY1LTMuNDAyLTEuODEzLTcuNTg4LTQuNjktMTEuNDE4LTUuMzMtMS45NDMtLjMxLTQuNDktLjE2NC02LjQ4Mi4xMDUtLjM1My4wNDctLjM2OC42ODMtLjAzLjc5OCAxLjMwOC40NDMgMi44OTUgMS4yMTIgMy44MyAyLjM3NS4xNzguMjItLjA2LjU2Ni0uMzQyLjU3Ny0uODgyLjAzMi0yLjQ4Mi40MDItNC41OTMgMi4xOTUtLjI0NC4yMDctLjA0MS41OTIuMjczLjUzIDQuNTM2LS44OTcgOS4xNy0uNDU1IDExLjkgMi4wMjcuMTc3LjE2LjA4NC40NS0uMTQ3LjUxMi0yMy42OTQgNi40NC0xOS4wMDMgMjcuMDUtMTIuNjk2IDUyLjM0NCA1LjYxOSAyMi41MyA3LjczMyAyOS43OTIgOC40IDMyLjAwNGEuNzE4LjcxOCAwIDAgMCAuNDIzLjQ2N2M4LjE1NiAzLjI0OCAyNS45MjggMy4zOTIgMjUuOTI4LTIuMTMyeiIgZmlsbD0iI2RkZCIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8cGF0aCBkPSJtNzYuMjUgMTE2LjVjLTIuODc1IDEuMTI1LTguNSAxLjYyNS0xMS43NSAxLjYyNS00Ljc2NCAwLTExLjYyNS0uNzUtMTQuMTI1LTEuODc1LTEuNTQ0LTQuNzUxLTYuMTY0LTE5LjQ4LTEwLjcyNy0zOC4xODVsLS40NDctMS44MjctLjAwNC0uMDE1Yy01LjQyNC0yMi4xNTctOS44NTUtNDAuMjUzIDE0LjQyNy00NS45MzguMjIyLS4wNTIuMzMtLjMxNy4xODQtLjQ5Mi0yLjc4Ni0zLjMwNS04LjAwNS00LjM4OC0xNC42MDUtMi4xMTEtLjI3LjA5My0uNTA2LS4xOC0uMzM3LS40MTIgMS4yOTQtMS43ODMgMy44MjMtMy4xNTUgNS4wNzEtMy43NTYuMjU4LS4xMjQuMjQyLS41MDItLjAzLS41ODhhMjcuODc3IDI3Ljg3NyAwIDAgMCAtMy43NzItLjljLS4zNy0uMDU5LS40MDMtLjY5My0uMDMyLS43NDMgOS4zNTYtMS4yNTkgMTkuMTI1IDEuNTUgMjQuMDI4IDcuNzI2YS4zMjYuMzI2IDAgMCAwIC4xODYuMTE0YzE3Ljk1MiAzLjg1NiAxOS4yMzggMzIuMjM1IDE3LjE3IDMzLjUyOC0uNDA4LjI1NS0xLjcxNS4xMDgtMy40MzgtLjA4NS02Ljk4Ni0uNzgxLTIwLjgxOC0yLjMyOS05LjQwMiAxOC45NDguMTEzLjIxLS4wMzYuNDg4LS4yNzIuNTI1LTYuNDM4IDEgMS44MTIgMjEuMTczIDcuODc1IDM0LjQ2MXoiIGZpbGw9IiNmZmYiLz4KICAgIDxwYXRoIGQ9Im04NC4yOCA5MC42OThjLTEuMzY3LS42MzMtNi42MjEgMy4xMzUtMTAuMTEgNi4wMjgtLjcyOC0xLjAzMS0yLjEwMy0xLjc4LTUuMjAzLTEuMjQyLTIuNzEzLjQ3Mi00LjIxMSAxLjEyNi00Ljg4IDIuMjU0LTQuMjgzLTEuNjIzLTExLjQ4OC00LjEzLTEzLjIyOS0xLjcxLTEuOTAyIDIuNjQ2LjQ3NiAxNS4xNjEgMy4wMDMgMTYuNzg2IDEuMzIuODQ5IDcuNjMtMy4yMDggMTAuOTI2LTYuMDA1LjUzMi43NDkgMS4zODggMS4xNzggMy4xNDggMS4xMzcgMi42NjItLjA2MiA2Ljk3OS0uNjgxIDcuNjQ5LTEuOTIxLjA0LS4wNzUuMDc1LS4xNjQuMTA1LS4yNjYgMy4zODggMS4yNjYgOS4zNSAyLjYwNiAxMC42ODIgMi40MDYgMy40Ny0uNTIxLS40ODQtMTYuNzIzLTIuMDktMTcuNDY3eiIgZmlsbD0iIzNjYTgyYiIvPgogICAgPHBhdGggZD0ibTc0LjQ5IDk3LjA5N2MuMTQ0LjI1Ni4yNi41MjYuMzU4LjguNDgzIDEuMzUyIDEuMjcgNS42NDguNjc0IDYuNzA5LS41OTUgMS4wNjItNC40NTkgMS41NzQtNi44NDMgMS42MTVzLTIuOTItLjgzMS0zLjQwMy0yLjE4MWMtLjM4Ny0xLjA4MS0uNTc3LTMuNjIxLS41NzItNS4wNzUtLjA5OC0yLjE1OC42OS0yLjkxNiA0LjMzNC0zLjUwNiAyLjY5Ni0uNDM2IDQuMTIxLjA3MSA0Ljk0NC45NCAzLjgyOC0yLjg1NyAxMC4yMTUtNi44ODkgMTAuODM4LTYuMTUyIDMuMTA2IDMuNjc0IDMuNDk5IDEyLjQyIDIuODI2IDE1LjkzOS0uMjIgMS4xNTEtMTAuNTA1LTEuMTM5LTEwLjUwNS0yLjM4IDAtNS4xNTItMS4zMzctNi41NjUtMi42NS02Ljcxem0tMjIuNTMtMS42MDljLjg0My0xLjMzMyA3LjY3NC4zMjUgMTEuNDI0IDEuOTkzIDAgMC0uNzcgMy40OTEuNDU2IDcuNjA0LjM1OSAxLjIwMy04LjYyNyA2LjU1OC05LjggNS42MzctMS4zNTUtMS4wNjUtMy44NS0xMi40MzItMi4wOC0xNS4yMzR6IiBmaWxsPSIjNGNiYTNjIi8+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im01NS4yNjkgNjguNDA2Yy41NTMtMi40MDMgMy4xMjctNi45MzIgMTIuMzIxLTYuODIyIDQuNjQ4LS4wMTkgMTAuNDIyLS4wMDIgMTQuMjUtLjQzNmE1MS4zMTIgNTEuMzEyIDAgMCAwIDEyLjcyNi0zLjA5NWMzLjk4LTEuNTE5IDUuMzkyLTEuMTggNS44ODctLjI3Mi41NDQuOTk5LS4wOTcgMi43MjItMS40ODggNC4zMDktMi42NTYgMy4wMy03LjQzMSA1LjM4LTE1Ljg2NSA2LjA3Ni04LjQzMy42OTgtMTQuMDItMS41NjUtMTYuNDI1IDIuMTE4LTEuMDM4IDEuNTg5LS4yMzYgNS4zMzMgNy45MiA2LjUxMiAxMS4wMiAxLjU5IDIwLjA3Mi0xLjkxNyAyMS4xOS4yMDEgMS4xMTkgMi4xMTgtNS4zMjMgNi40MjgtMTYuMzYyIDYuNTE4cy0xNy45MzQtMy44NjUtMjAuMzc5LTUuODNjLTMuMTAyLTIuNDk1LTQuNDktNi4xMzMtMy43NzUtOS4yNzl6IiBmaWxsPSIjZmMzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KICAgIDxnIGZpbGw9IiMxNDMwN2UiIG9wYWNpdHk9Ii44Ij4KICAgICAgPHBhdGggZD0ibTY5LjMyNyA0Mi4xMjdjLjYxNi0xLjAwOCAxLjk4MS0xLjc4NiA0LjIxNi0xLjc4NiAyLjIzNCAwIDMuMjg1Ljg4OSA0LjAxMyAxLjg4LjE0OC4yMDItLjA3Ni40NC0uMzA2LjM0YTU5Ljg2OSA1OS44NjkgMCAwIDEgLS4xNjgtLjA3M2MtLjgxNy0uMzU3LTEuODItLjc5NS0zLjU0LS44Mi0xLjgzOC0uMDI2LTIuOTk3LjQzNS0zLjcyNy44MzEtLjI0Ni4xMzQtLjYzNC0uMTMzLS40ODgtLjM3MnptLTI1LjE1NyAxLjI5YzIuMTctLjkwNyAzLjg3Ni0uNzkgNS4wODEtLjUwNC4yNTQuMDYuNDMtLjIxMy4yMjctLjM3Ny0uOTM1LS43NTUtMy4wMy0xLjY5Mi01Ljc2LS42NzQtMi40MzcuOTA5LTMuNTg1IDIuNzk2LTMuNTkyIDQuMDM4LS4wMDIuMjkyLjYuMzE3Ljc1Ni4wNy40Mi0uNjcgMS4xMi0xLjY0NiAzLjI4OS0yLjU1M3oiLz4KICAgICAgPHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtNzUuNDQgNTUuOTJhMy40NyAzLjQ3IDAgMCAxIC0zLjQ3NC0zLjQ2MiAzLjQ3IDMuNDcgMCAwIDEgMy40NzUtMy40NiAzLjQ3IDMuNDcgMCAwIDEgMy40NzQgMy40NiAzLjQ3IDMuNDcgMCAwIDEgLTMuNDc1IDMuNDYyem0yLjQ0Ny00LjYwOGEuODk5Ljg5OSAwIDAgMCAtMS43OTkgMGMwIC40OTQuNDA1Ljg5NS45Ljg5NS40OTkgMCAuOS0uNC45LS44OTV6bS0yNS40NjQgMy41NDJhNC4wNDIgNC4wNDIgMCAwIDEgLTQuMDQ5IDQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIC00LjA1LTQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIDQuMDUtNC4wMzcgNC4wNDUgNC4wNDUgMCAwIDEgNC4wNSA0LjAzN3ptLTEuMTkzLTEuMzM4YTEuMDUgMS4wNSAwIDAgMCAtMi4wOTcgMCAxLjA0OCAxLjA0OCAwIDAgMCAyLjA5NyAweiIgZmlsbC1ydWxlPSJldmVub2RkIi8+CiAgICA8L2c+CiAgICA8cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im02NCAxMTcuNzVjMjkuNjg1IDAgNTMuNzUtMjQuMDY1IDUzLjc1LTUzLjc1cy0yNC4wNjUtNTMuNzUtNTMuNzUtNTMuNzUtNTMuNzUgMjQuMDY1LTUzLjc1IDUzLjc1IDI0LjA2NSA1My43NSA1My43NSA1My43NXptMCA1YzMyLjQ0NyAwIDU4Ljc1LTI2LjMwMyA1OC43NS01OC43NXMtMjYuMzAzLTU4Ljc1LTU4Ljc1LTU4Ljc1LTU4Ljc1IDI2LjMwMy01OC43NSA1OC43NSAyNi4zMDMgNTguNzUgNTguNzUgNTguNzV6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KPC9zdmc+');\n}\n\n/* Email tooltip specific */\n.tooltip__button--email {\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n font-size: 14px;\n padding: 4px 8px;\n}\n.tooltip__button--email__primary-text {\n font-weight: bold;\n}\n.tooltip__button--email__secondary-text {\n font-size: 12px;\n}\n\n/* Email Protection signup notice */\n:not(.top-autofill) .tooltip--email-signup {\n text-align: left;\n color: #222222;\n padding: 16px 20px;\n width: 380px;\n}\n\n.tooltip--email-signup h1 {\n font-weight: 700;\n font-size: 16px;\n line-height: 1.5;\n margin: 0;\n}\n\n.tooltip--email-signup p {\n font-weight: 400;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.notice-controls {\n display: flex;\n}\n\n.tooltip--email-signup .notice-controls > * {\n border-radius: 8px;\n border: 0;\n cursor: pointer;\n display: inline-block;\n font-family: inherit;\n font-style: normal;\n font-weight: bold;\n padding: 8px 12px;\n text-decoration: none;\n}\n\n.notice-controls .ghost {\n margin-left: 1rem;\n}\n\n.tooltip--email-signup a.primary {\n background: #3969EF;\n color: #fff;\n}\n\n.tooltip--email-signup a.primary:hover,\n.tooltip--email-signup a.primary:focus {\n background: #2b55ca;\n}\n\n.tooltip--email-signup a.primary:active {\n background: #1e42a4;\n}\n\n.tooltip--email-signup button.ghost {\n background: transparent;\n color: #3969EF;\n}\n\n.tooltip--email-signup button.ghost:hover,\n.tooltip--email-signup button.ghost:focus {\n background-color: rgba(0, 0, 0, 0.06);\n color: #2b55ca;\n}\n\n.tooltip--email-signup button.ghost:active {\n background-color: rgba(0, 0, 0, 0.12);\n color: #1e42a4;\n}\n\n.tooltip--email-signup button.close-tooltip {\n background-color: transparent;\n background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAxMiAxMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjI5Mjg5NCAwLjY1NjkwN0MwLjY4MzQxOCAwLjI2NjM4MyAxLjMxNjU4IDAuMjY2MzgzIDEuNzA3MTEgMC42NTY5MDdMNiA0Ljk0OThMMTAuMjkyOSAwLjY1NjkwN0MxMC42ODM0IDAuMjY2MzgzIDExLjMxNjYgMC4yNjYzODMgMTEuNzA3MSAwLjY1NjkwN0MxMi4wOTc2IDEuMDQ3NDMgMTIuMDk3NiAxLjY4MDYgMTEuNzA3MSAyLjA3MTEyTDcuNDE0MjEgNi4zNjQwMUwxMS43MDcxIDEwLjY1NjlDMTIuMDk3NiAxMS4wNDc0IDEyLjA5NzYgMTEuNjgwNiAxMS43MDcxIDEyLjA3MTFDMTEuMzE2NiAxMi40NjE2IDEwLjY4MzQgMTIuNDYxNiAxMC4yOTI5IDEyLjA3MTFMNiA3Ljc3ODIzTDEuNzA3MTEgMTIuMDcxMUMxLjMxNjU4IDEyLjQ2MTYgMC42ODM0MTcgMTIuNDYxNiAwLjI5Mjg5MyAxMi4wNzExQy0wLjA5NzYzMTEgMTEuNjgwNiAtMC4wOTc2MzExIDExLjA0NzQgMC4yOTI4OTMgMTAuNjU2OUw0LjU4NTc5IDYuMzY0MDFMMC4yOTI4OTQgMi4wNzExMkMtMC4wOTc2MzA2IDEuNjgwNiAtMC4wOTc2MzA2IDEuMDQ3NDMgMC4yOTI4OTQgMC42NTY5MDdaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjg0Ii8+Cjwvc3ZnPgo=);\n background-position: center center;\n background-repeat: no-repeat;\n border: 0;\n cursor: pointer;\n padding: 16px;\n position: absolute;\n right: 12px;\n top: 12px;\n}\n\n/* Import promotion prompt icon style */\n\n.tooltip__button--credentials-import::before {\n content: \"\";\n background-image: url(data:image/svg+xml;base64,Cjxzdmcgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik03Ljk3MjY5IDkuMDEzN0M3Ljk3MjY5IDUuMTQwMTQgMTEuMTEyOCAyIDE0Ljk4NjQgMkMxOC44NTk5IDIgMjIuMDAwMSA1LjE0MDE0IDIyLjAwMDEgOS4wMTM3QzIyLjAwMDEgOS44MDM5NyAyMS44Njk0IDEwLjU2MzcgMjEuNjI4NCAxMS4yNzI1QzIxLjQ2MDEgMTEuNzY3NiAyMC44NjU2IDExLjkxMzUgMjAuMzk3NyAxMS42OEMxOS45MjIxIDExLjQ0MjggMTkuNjc3OSAxMC44NjQ0IDE5LjgxOTUgMTAuMzUyQzE5LjkzNzIgOS45MjU5OSAyMC4wMDAxIDkuNDc3MTkgMjAuMDAwMSA5LjAxMzdDMjAuMDAwMSA2LjI0NDcxIDE3Ljc1NTQgNCAxNC45ODY0IDRDMTIuMjE3NCA0IDkuOTcyNjkgNi4yNDQ3MSA5Ljk3MjY5IDkuMDEzN0M5Ljk3MjY5IDkuNTU1NCAxMC4wNTgyIDEwLjA3NTIgMTAuMjE1OCAxMC41NjEzQzEwLjMzMTcgMTAuOTE4OCAxMC4yMzc0IDExLjMxMTEgOS45NzE2NSAxMS41NzY4TDMuOTk5OTQgMTcuNTQ4NVYyMC4wMDAyTDYuNDk5OTggMjAuMDAwMlYxOC4zMDAyQzYuNDk5OTggMTcuNzQ3OSA2Ljk0NzcgMTcuMzAwMiA3LjQ5OTk4IDE3LjMwMDJIOS4yMDAwMVYxNS42MDAxQzkuMjAwMDEgMTUuMDQ3OCA5LjY0NzczIDE0LjYwMDEgMTAuMiAxNC42MDAxSDEwLjVDMTEuMjEwNiAxNC41ODcgMTEuNDI1MiAxNS4zMzY5IDExLjMxNTYgMTUuNzMzMUMxMS4xNTY1IDE2LjMwODUgMTEgMTcuMDAxIDExIDE3LjVDMTEgMTcuNzI4NCAxMS4wMTE4IDE3Ljk1NCAxMS4wMzQ4IDE4LjE3NjNDMTAuNzM3OSAxOC44Mzg3IDEwLjA3MjkgMTkuMzAwMiA5LjMgMTkuMzAwMkg4LjQ5OTk4VjIwLjEwMDJDOC40OTk5OCAyMS4xNDk1IDcuNjQ5MzMgMjIuMDAwMiA2LjU5OTk5IDIyLjAwMDJMMi45OTk5NSAyMi4wMDAyQzIuNzM0NzMgMjIuMDAwMiAyLjQ4MDM3IDIxLjg5NDkgMi4yOTI4NCAyMS43MDczQzIuMTA1MyAyMS41MTk4IDEuOTk5OTQgMjEuMjY1NCAxLjk5OTk0IDIxLjAwMDJWMTcuMTM0M0MxLjk5OTk0IDE2Ljg2OTEgMi4xMDUzIDE2LjYxNDcgMi4yOTI4MyAxNi40MjcyTDguMTQ2ODkgMTAuNTczMUM4LjAzMjc5IDEwLjA3MDkgNy45NzI2OSA5LjU0ODgxIDcuOTcyNjkgOS4wMTM3WiIgZmlsbD0iYmxhY2siIC8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTMgOC40OTk4OUMxMyA3LjExOTE4IDE0LjExOTMgNS45OTk4OSAxNS41IDUuOTk5ODlDMTYuODgwNyA1Ljk5OTg5IDE4IDcuMTE5MTggMTggOC40OTk4OUMxOCA5Ljg4MDYgMTYuODgwNyAxMC45OTk5IDE1LjUgMTAuOTk5OUMxNC4xMTkzIDEwLjk5OTkgMTMgOS44ODA2IDEzIDguNDk5ODlaTTE1LjUgNy45OTk4OUMxNS4yMjM5IDcuOTk5ODkgMTUgOC4yMjM3NSAxNSA4LjQ5OTg5QzE1IDguNzc2MDQgMTUuMjIzOSA4Ljk5OTg5IDE1LjUgOC45OTk4OUMxNS43NzYyIDguOTk5ODkgMTYgOC43NzYwNCAxNiA4LjQ5OTg5QzE2IDguMjIzNzUgMTUuNzc2MiA3Ljk5OTg5IDE1LjUgNy45OTk4OVoiIGZpbGw9ImJsYWNrIiAvPgo8cGF0aCBkPSJNMTcgMTVMMTQuNSAxNy41TDE3IDIwIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMjEuNSAxNy41TDE2IDE3LjUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=);\n background-repeat: no-repeat;\n}\n"; -},{}],54:[function(require,module,exports){ +},{}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13325,7 +13460,7 @@ function findEnclosedElements(root, selector) { return shadowElements; } -},{"./Form/matching.js":34,"./constants.js":57,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],55:[function(require,module,exports){ +},{"./Form/matching.js":35,"./constants.js":58,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],56:[function(require,module,exports){ "use strict"; require("./requestIdleCallback.js"); @@ -13356,7 +13491,7 @@ var _autofillUtils = require("./autofill-utils.js"); } })(); -},{"./DeviceInterface.js":13,"./autofill-utils.js":54,"./requestIdleCallback.js":94}],56:[function(require,module,exports){ +},{"./DeviceInterface.js":14,"./autofill-utils.js":55,"./requestIdleCallback.js":95}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13373,6 +13508,10 @@ const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a- * @returns {GlobalConfig} */ function createGlobalConfig(overrides) { + /** + * Defines whether it's one of our desktop apps + * @type {boolean} + */ let isApp = false; let isTopFrame = false; let supportsTopFrame = false; @@ -13442,7 +13581,7 @@ function createGlobalConfig(overrides) { return config; } -},{}],57:[function(require,module,exports){ +},{}],58:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13459,13 +13598,13 @@ const constants = exports.constants = { MAX_FORM_RESCANS: 50 }; -},{}],58:[function(require,module,exports){ +},{}],59:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; +exports.StoreFormDataCall = exports.StartEmailProtectionSignupCall = exports.StartCredentialsImportFlowCall = exports.ShowInContextEmailProtectionSignupPromptCall = exports.SetSizeCall = exports.SetIncontextSignupPermanentlyDismissedAtCall = exports.SendJSPixelCall = exports.SelectedDetailCall = exports.OpenManagePasswordsCall = exports.OpenManageIdentitiesCall = exports.OpenManageCreditCardsCall = exports.GetRuntimeConfigurationCall = exports.GetIncontextSignupDismissedAtCall = exports.GetAvailableInputTypesCall = exports.GetAutofillInitDataCall = exports.GetAutofillDataCall = exports.GetAutofillCredentialsCall = exports.EmailProtectionStoreUserDataCall = exports.EmailProtectionRemoveUserDataCall = exports.EmailProtectionRefreshPrivateAddressCall = exports.EmailProtectionGetUserDataCall = exports.EmailProtectionGetIsLoggedInCall = exports.EmailProtectionGetCapabilitiesCall = exports.EmailProtectionGetAliasCall = exports.EmailProtectionGetAddressesCall = exports.CloseEmailProtectionTabCall = exports.CloseAutofillParentCall = exports.CheckCredentialsProviderStatusCall = exports.AskToUnlockProviderCall = exports.AddDebugFlagCall = void 0; var _validatorsZod = require("./validators.zod.js"); var _deviceApi = require("../../../packages/device-api"); /* DO NOT EDIT, this file was generated by scripts/api-call-generator.js */ @@ -13627,9 +13766,19 @@ class StartCredentialsImportFlowCall extends _deviceApi.DeviceApiCall { method = "startCredentialsImportFlow"; } /** - * @extends {DeviceApiCall} + * @extends {DeviceApiCall} */ exports.StartCredentialsImportFlowCall = StartCredentialsImportFlowCall; +class EmailProtectionGetAliasCall extends _deviceApi.DeviceApiCall { + method = "emailProtectionGetAlias"; + id = "emailProtectionGetAliasResponse"; + paramsValidator = _validatorsZod.emailProtectionGetAliasParamsSchema; + resultValidator = _validatorsZod.emailProtectionGetAliasResultSchema; +} +/** + * @extends {DeviceApiCall} + */ +exports.EmailProtectionGetAliasCall = EmailProtectionGetAliasCall; class EmailProtectionStoreUserDataCall extends _deviceApi.DeviceApiCall { method = "emailProtectionStoreUserData"; id = "emailProtectionStoreUserDataResponse"; @@ -13712,13 +13861,13 @@ class ShowInContextEmailProtectionSignupPromptCall extends _deviceApi.DeviceApiC } exports.ShowInContextEmailProtectionSignupPromptCall = ShowInContextEmailProtectionSignupPromptCall; -},{"../../../packages/device-api":2,"./validators.zod.js":59}],59:[function(require,module,exports){ +},{"../../../packages/device-api":2,"./validators.zod.js":60}],60:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; +exports.userPreferencesSchema = exports.triggerContextSchema = exports.storeFormDataSchema = exports.showInContextEmailProtectionSignupPromptSchema = exports.setSizeParamsSchema = exports.setIncontextSignupPermanentlyDismissedAtSchema = exports.sendJSPixelParamsSchema = exports.selectedDetailParamsSchema = exports.runtimeConfigurationSchema = exports.providerStatusUpdatedSchema = exports.outgoingCredentialsSchema = exports.getRuntimeConfigurationResponseSchema = exports.getIncontextSignupDismissedAtSchema = exports.getAvailableInputTypesResultSchema = exports.getAutofillInitDataResponseSchema = exports.getAutofillDataResponseSchema = exports.getAutofillDataRequestSchema = exports.getAutofillCredentialsResultSchema = exports.getAutofillCredentialsParamsSchema = exports.getAliasResultSchema = exports.getAliasParamsSchema = exports.genericErrorSchema = exports.generatedPasswordSchema = exports.emailProtectionStoreUserDataParamsSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionGetUserDataResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAddressesResultSchema = exports.credentialsSchema = exports.contentScopeSchema = exports.checkCredentialsProviderStatusResultSchema = exports.availableInputTypesSchema = exports.availableInputTypes1Schema = exports.autofillSettingsSchema = exports.autofillFeatureTogglesSchema = exports.askToUnlockProviderResultSchema = exports.apiSchema = exports.addDebugFlagParamsSchema = void 0; const sendJSPixelParamsSchema = exports.sendJSPixelParamsSchema = null; const addDebugFlagParamsSchema = exports.addDebugFlagParamsSchema = null; const getAutofillCredentialsParamsSchema = exports.getAutofillCredentialsParamsSchema = null; @@ -13728,6 +13877,7 @@ const setIncontextSignupPermanentlyDismissedAtSchema = exports.setIncontextSignu const getIncontextSignupDismissedAtSchema = exports.getIncontextSignupDismissedAtSchema = null; const getAliasParamsSchema = exports.getAliasParamsSchema = null; const getAliasResultSchema = exports.getAliasResultSchema = null; +const emailProtectionGetAliasParamsSchema = exports.emailProtectionGetAliasParamsSchema = null; const emailProtectionStoreUserDataParamsSchema = exports.emailProtectionStoreUserDataParamsSchema = null; const showInContextEmailProtectionSignupPromptSchema = exports.showInContextEmailProtectionSignupPromptSchema = null; const generatedPasswordSchema = exports.generatedPasswordSchema = null; @@ -13736,9 +13886,10 @@ const credentialsSchema = exports.credentialsSchema = null; const genericErrorSchema = exports.genericErrorSchema = null; const contentScopeSchema = exports.contentScopeSchema = null; const userPreferencesSchema = exports.userPreferencesSchema = null; -const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = null; const availableInputTypesSchema = exports.availableInputTypesSchema = null; +const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = null; const availableInputTypes1Schema = exports.availableInputTypes1Schema = null; +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = null; const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = null; const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = null; @@ -13746,20 +13897,20 @@ const storeFormDataSchema = exports.storeFormDataSchema = null; const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = null; const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = null; const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = null; +const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = null; +const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = null; const autofillSettingsSchema = exports.autofillSettingsSchema = null; +const emailProtectionGetAliasResultSchema = exports.emailProtectionGetAliasResultSchema = null; const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = null; const emailProtectionGetUserDataResultSchema = exports.emailProtectionGetUserDataResultSchema = null; const emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = null; const emailProtectionGetAddressesResultSchema = exports.emailProtectionGetAddressesResultSchema = null; const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = null; const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = null; -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = null; -const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = null; -const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = null; const apiSchema = exports.apiSchema = null; -},{}],60:[function(require,module,exports){ +},{}],61:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13785,7 +13936,7 @@ class GetAlias extends _index.DeviceApiCall { } exports.GetAlias = GetAlias; -},{"../../packages/device-api/index.js":2,"./__generated__/validators.zod.js":59}],61:[function(require,module,exports){ +},{"../../packages/device-api/index.js":2,"./__generated__/validators.zod.js":60}],62:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13793,7 +13944,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.AndroidTransport = void 0; var _index = require("../../../packages/device-api/index.js"); -var _deviceApiCalls = require("../__generated__/deviceApiCalls.js"); +var _messaging = require("../../../packages/messaging/messaging.js"); +var _android = require("../../../packages/messaging/android.js"); class AndroidTransport extends _index.DeviceApiTransport { /** @type {GlobalConfig} */ config; @@ -13802,133 +13954,39 @@ class AndroidTransport extends _index.DeviceApiTransport { constructor(globalConfig) { super(); this.config = globalConfig; - if (this.config.isDDGTestMode) { - if (typeof window.BrowserAutofill?.getAutofillData !== 'function') { - console.warn('window.BrowserAutofill.getAutofillData missing'); - } - if (typeof window.BrowserAutofill?.storeFormData !== 'function') { - console.warn('window.BrowserAutofill.storeFormData missing'); - } - } + const messageHandlerNames = ['EmailProtectionStoreUserData', 'EmailProtectionRemoveUserData', 'EmailProtectionGetUserData', 'EmailProtectionGetCapabilities', 'EmailProtectionGetAlias', 'SetIncontextSignupPermanentlyDismissedAt', 'StartEmailProtectionSignup', 'CloseEmailProtectionTab', 'ShowInContextEmailProtectionSignupPrompt', 'StoreFormData', 'GetIncontextSignupDismissedAt', 'GetRuntimeConfiguration', 'GetAutofillData']; + const androidMessagingConfig = new _android.AndroidMessagingConfig({ + messageHandlerNames + }); + this.messaging = new _messaging.Messaging(androidMessagingConfig); } /** * @param {import("../../../packages/device-api").DeviceApiCall} deviceApiCall * @returns {Promise} */ async send(deviceApiCall) { - if (deviceApiCall instanceof _deviceApiCalls.GetRuntimeConfigurationCall) { - return androidSpecificRuntimeConfiguration(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAvailableInputTypesCall) { - return androidSpecificAvailableInputTypes(this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetIncontextSignupDismissedAtCall) { - window.BrowserAutofill.getIncontextSignupDismissedAt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.SetIncontextSignupPermanentlyDismissedAtCall) { - return window.BrowserAutofill.setIncontextSignupPermanentlyDismissedAt(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.StartEmailProtectionSignupCall) { - return window.BrowserAutofill.startEmailProtectionSignup(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.CloseEmailProtectionTabCall) { - return window.BrowserAutofill.closeEmailProtectionTab(JSON.stringify(deviceApiCall.params)); - } - if (deviceApiCall instanceof _deviceApiCalls.ShowInContextEmailProtectionSignupPromptCall) { - window.BrowserAutofill.showInContextEmailProtectionSignupPrompt(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.GetAutofillDataCall) { - window.BrowserAutofill.getAutofillData(JSON.stringify(deviceApiCall.params)); - return waitForResponse(deviceApiCall.id, this.config); - } - if (deviceApiCall instanceof _deviceApiCalls.StoreFormDataCall) { - return window.BrowserAutofill.storeFormData(JSON.stringify(deviceApiCall.params)); - } - throw new Error('android: not implemented: ' + deviceApiCall.method); - } -} - -/** - * @param {string} expectedResponse - the name/id of the response - * @param {GlobalConfig} config - * @returns {Promise<*>} - */ -exports.AndroidTransport = AndroidTransport; -function waitForResponse(expectedResponse, config) { - return new Promise(resolve => { - const handler = e => { - if (!config.isDDGTestMode) { - if (e.origin !== '') { - return; - } - } - if (!e.data) { - return; - } - if (typeof e.data !== 'string') { - if (config.isDDGTestMode) { - console.log('❌ event.data was not a string. Expected a string so that it can be JSON parsed'); - } - return; + try { + // if the call has an `id`, it means that it expects a response + if (deviceApiCall.id) { + return await this.messaging.request(deviceApiCall.method, deviceApiCall.params || undefined); + } else { + return this.messaging.notify(deviceApiCall.method, deviceApiCall.params || undefined); } - try { - let data = JSON.parse(e.data); - if (data.type === expectedResponse) { - window.removeEventListener('message', handler); - return resolve(data); - } - if (config.isDDGTestMode) { - console.log(`❌ event.data.type was '${data.type}', which didnt match '${expectedResponse}'`, JSON.stringify(data)); - } - } catch (e) { - window.removeEventListener('message', handler); - if (config.isDDGTestMode) { - console.log('❌ Could not JSON.parse the response'); + } catch (e) { + if (e instanceof _messaging.MissingHandler) { + if (this.config.isDDGTestMode) { + console.log('MissingAndroidHandler error for:', deviceApiCall.method); } + throw new Error('unimplemented handler: ' + deviceApiCall.method); + } else { + throw e; } - }; - window.addEventListener('message', handler); - }); -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').RuntimeConfiguration}} - */ -function androidSpecificRuntimeConfiguration(globalConfig) { - if (!globalConfig.userPreferences) { - throw new Error('globalConfig.userPreferences not supported yet on Android'); - } - return { - success: { - // @ts-ignore - contentScope: globalConfig.contentScope, - // @ts-ignore - userPreferences: globalConfig.userPreferences, - // @ts-ignore - userUnprotectedDomains: globalConfig.userUnprotectedDomains, - // @ts-ignore - availableInputTypes: globalConfig.availableInputTypes } - }; -} - -/** - * @param {GlobalConfig} globalConfig - * @returns {{success: import('../__generated__/validators-ts').AvailableInputTypes}} - */ -function androidSpecificAvailableInputTypes(globalConfig) { - if (!globalConfig.availableInputTypes) { - throw new Error('globalConfig.availableInputTypes not supported yet on Android'); } - return { - success: globalConfig.availableInputTypes - }; } +exports.AndroidTransport = AndroidTransport; -},{"../../../packages/device-api/index.js":2,"../__generated__/deviceApiCalls.js":58}],62:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2,"../../../packages/messaging/android.js":5,"../../../packages/messaging/messaging.js":6}],63:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -13971,7 +14029,7 @@ class AppleTransport extends _index.DeviceApiTransport { } exports.AppleTransport = AppleTransport; -},{"../../../packages/device-api/index.js":2,"../../../packages/messaging/messaging.js":5}],63:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2,"../../../packages/messaging/messaging.js":6}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14125,7 +14183,7 @@ async function extensionSpecificSetIncontextSignupPermanentlyDismissedAtCall(par }); } -},{"../../../packages/device-api/index.js":2,"../../Settings.js":41,"../../autofill-utils.js":54,"../__generated__/deviceApiCalls.js":58}],64:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2,"../../Settings.js":42,"../../autofill-utils.js":55,"../__generated__/deviceApiCalls.js":59}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14169,7 +14227,7 @@ function createTransport(globalConfig) { return new _extensionTransport.ExtensionTransport(globalConfig); } -},{"./android.transport.js":61,"./apple.transport.js":62,"./extension.transport.js":63,"./windows.transport.js":65}],65:[function(require,module,exports){ +},{"./android.transport.js":62,"./apple.transport.js":63,"./extension.transport.js":64,"./windows.transport.js":66}],66:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -14254,7 +14312,7 @@ function waitForWindowsResponse(responseId, options) { }); } -},{"../../../packages/device-api/index.js":2}],66:[function(require,module,exports){ +},{"../../../packages/device-api/index.js":2}],67:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14355,7 +14413,7 @@ module.exports={ } } -},{}],67:[function(require,module,exports){ +},{}],68:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14456,7 +14514,7 @@ module.exports={ } } -},{}],68:[function(require,module,exports){ +},{}],69:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14557,7 +14615,7 @@ module.exports={ } } -},{}],69:[function(require,module,exports){ +},{}],70:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14658,7 +14716,7 @@ module.exports={ } } -},{}],70:[function(require,module,exports){ +},{}],71:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14759,7 +14817,7 @@ module.exports={ } } -},{}],71:[function(require,module,exports){ +},{}],72:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -14861,7 +14919,7 @@ module.exports={ } } -},{}],72:[function(require,module,exports){ +},{}],73:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -14962,7 +15020,7 @@ module.exports={ } } -},{}],73:[function(require,module,exports){ +},{}],74:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15063,7 +15121,7 @@ module.exports={ } } -},{}],74:[function(require,module,exports){ +},{}],75:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15164,7 +15222,7 @@ module.exports={ } } -},{}],75:[function(require,module,exports){ +},{}],76:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15265,7 +15323,7 @@ module.exports={ } } -},{}],76:[function(require,module,exports){ +},{}],77:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15366,7 +15424,7 @@ module.exports={ } } -},{}],77:[function(require,module,exports){ +},{}],78:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15467,7 +15525,7 @@ module.exports={ } } -},{}],78:[function(require,module,exports){ +},{}],79:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15568,7 +15626,7 @@ module.exports={ } } -},{}],79:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15669,7 +15727,7 @@ module.exports={ } } -},{}],80:[function(require,module,exports){ +},{}],81:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15770,7 +15828,7 @@ module.exports={ } } -},{}],81:[function(require,module,exports){ +},{}],82:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15871,7 +15929,7 @@ module.exports={ } } -},{}],82:[function(require,module,exports){ +},{}],83:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -15972,7 +16030,7 @@ module.exports={ } } -},{}],83:[function(require,module,exports){ +},{}],84:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16073,7 +16131,7 @@ module.exports={ } } -},{}],84:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16174,7 +16232,7 @@ module.exports={ } } -},{}],85:[function(require,module,exports){ +},{}],86:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16275,7 +16333,7 @@ module.exports={ } } -},{}],86:[function(require,module,exports){ +},{}],87:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16376,7 +16434,7 @@ module.exports={ } } -},{}],87:[function(require,module,exports){ +},{}],88:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16477,7 +16535,7 @@ module.exports={ } } -},{}],88:[function(require,module,exports){ +},{}],89:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16578,7 +16636,7 @@ module.exports={ } } -},{}],89:[function(require,module,exports){ +},{}],90:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16666,7 +16724,7 @@ function translateImpl(library, namespacedId, opts) { return out; } -},{"./translations.js":92}],90:[function(require,module,exports){ +},{"./translations.js":93}],91:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16767,7 +16825,7 @@ module.exports={ } } -},{}],91:[function(require,module,exports){ +},{}],92:[function(require,module,exports){ module.exports={ "smartling" : { "string_format" : "icu", @@ -16868,7 +16926,7 @@ module.exports={ } } -},{}],92:[function(require,module,exports){ +},{}],93:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -16987,7 +17045,7 @@ var _default = exports.default = { } }; -},{"./bg/autofill.json":66,"./cs/autofill.json":67,"./da/autofill.json":68,"./de/autofill.json":69,"./el/autofill.json":70,"./en/autofill.json":71,"./es/autofill.json":72,"./et/autofill.json":73,"./fi/autofill.json":74,"./fr/autofill.json":75,"./hr/autofill.json":76,"./hu/autofill.json":77,"./it/autofill.json":78,"./lt/autofill.json":79,"./lv/autofill.json":80,"./nb/autofill.json":81,"./nl/autofill.json":82,"./pl/autofill.json":83,"./pt/autofill.json":84,"./ro/autofill.json":85,"./ru/autofill.json":86,"./sk/autofill.json":87,"./sl/autofill.json":88,"./sv/autofill.json":90,"./tr/autofill.json":91,"./xa/autofill.json":93}],93:[function(require,module,exports){ +},{"./bg/autofill.json":67,"./cs/autofill.json":68,"./da/autofill.json":69,"./de/autofill.json":70,"./el/autofill.json":71,"./en/autofill.json":72,"./es/autofill.json":73,"./et/autofill.json":74,"./fi/autofill.json":75,"./fr/autofill.json":76,"./hr/autofill.json":77,"./hu/autofill.json":78,"./it/autofill.json":79,"./lt/autofill.json":80,"./lv/autofill.json":81,"./nb/autofill.json":82,"./nl/autofill.json":83,"./pl/autofill.json":84,"./pt/autofill.json":85,"./ro/autofill.json":86,"./ru/autofill.json":87,"./sk/autofill.json":88,"./sl/autofill.json":89,"./sv/autofill.json":91,"./tr/autofill.json":92,"./xa/autofill.json":94}],94:[function(require,module,exports){ module.exports={ "smartling": { "string_format": "icu", @@ -17080,7 +17138,7 @@ module.exports={ "note": "Button that prevents the DuckDuckGo email protection signup prompt from appearing again." } } -},{}],94:[function(require,module,exports){ +},{}],95:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -17123,4 +17181,4 @@ window.cancelIdleCallback = window.cancelIdleCallback || function (id) { }; var _default = exports.default = {}; -},{}]},{},[55]); +},{}]},{},[56]); diff --git a/types.d.ts b/types.d.ts index 02d8bc8cf..254885087 100644 --- a/types.d.ts +++ b/types.d.ts @@ -23,6 +23,14 @@ declare const windowsInteropPostMessage: (message: WindowsMessageFormat|WindowsR declare const windowsInteropAddEventListener: Window['addEventListener']; declare const windowsInteropRemoveEventListener: Window['removeEventListener']; +// Injected handlers on the Android app. +interface AndroidHandler { + onMessage: undefined, + postMessage: (message) => void, + addEventListener: (eventType: string, Function) => void, + removeEventListener: (eventType: string, Function) => void +} + interface Window { // Used in the Android app