diff --git a/injected/entry-points/extension-mv3.js b/injected/entry-points/extension-mv3.js index 29f9f384b6..4d06d6e693 100644 --- a/injected/entry-points/extension-mv3.js +++ b/injected/entry-points/extension-mv3.js @@ -3,6 +3,7 @@ */ import { load, init, update } from '../src/content-scope-features.js'; import { computeLimitedSiteObject } from '../src/utils.js'; +import { getSharedMessagingTransport } from '../src/sendmessage-transport.js'; const secret = (crypto.getRandomValues(new Uint32Array(1))[0] / 2 ** 32).toString().replace('0.', ''); @@ -34,6 +35,16 @@ window.addEventListener(secret, ({ detail: encodedMessage }) => { init(message.argumentsObject); } break; + default: + // Messages with messageType are subscription responses from the extension. + // Route them to the shared transport so all subscribed features receive them. + if (message.messageType) { + const transport = getSharedMessagingTransport(); + if (transport?.onResponse) { + transport.onResponse(message); + } + } + break; } }); diff --git a/injected/src/detectors/README.md b/injected/src/detectors/README.md index 7482f20bb6..2111adb1df 100644 --- a/injected/src/detectors/README.md +++ b/injected/src/detectors/README.md @@ -20,7 +20,6 @@ detectors/ │ └── fraud-detection.js # fraud/phishing warning utility ├── utils/ │ └── detection-utils.js # DOM helpers (selectors, text matching, visibility) -└── default-config.js # fallback detector settings ``` ## How It Works diff --git a/injected/src/detectors/default-config.js b/injected/src/detectors/default-config.js deleted file mode 100644 index edde889a8e..0000000000 --- a/injected/src/detectors/default-config.js +++ /dev/null @@ -1,48 +0,0 @@ -export const DEFAULT_DETECTOR_SETTINGS = Object.freeze({ - botDetection: { - cloudflareTurnstile: { - state: 'enabled', - vendor: 'cloudflare', - selectors: ['.cf-turnstile', 'script[src*="challenges.cloudflare.com"]'], - windowProperties: ['turnstile'], - statusSelectors: [ - { - status: 'solved', - selectors: ['[data-state="success"]'], - }, - { - status: 'failed', - selectors: ['[data-state="error"]'], - }, - ], - }, - cloudflareChallengePage: { - state: 'enabled', - vendor: 'cloudflare', - selectors: ['#challenge-form', '.cf-browser-verification', '#cf-wrapper', 'script[src*="challenges.cloudflare.com"]'], - windowProperties: ['_cf_chl_opt', '__CF$cv$params', 'cfjsd'], - }, - hcaptcha: { - state: 'enabled', - vendor: 'hcaptcha', - selectors: ['.h-captcha', '[data-hcaptcha-widget-id]', 'script[src*="hcaptcha.com"]', 'script[src*="assets.hcaptcha.com"]'], - windowProperties: ['hcaptcha'], - }, - }, - fraudDetection: { - phishingWarning: { - state: 'enabled', - type: 'phishing', - selectors: ['.warning-banner', '#security-alert'], - textPatterns: ['suspicious.*activity', 'unusual.*login', 'verify.*account'], - textSources: ['innerText'], - }, - accountSuspension: { - state: 'enabled', - type: 'suspension', - selectors: ['.account-suspended', '#suspension-notice'], - textPatterns: ['account.*suspended', 'access.*restricted'], - textSources: ['innerText'], - }, - }, -}); diff --git a/injected/src/features.js b/injected/src/features.js index 9075035dbc..e4a3489749 100644 --- a/injected/src/features.js +++ b/injected/src/features.js @@ -79,7 +79,7 @@ export const platformSupport = { 'pageContext', 'duckAiDataClearing', ], - firefox: ['cookie', ...baseFeatures, 'clickToLoad'], + firefox: ['cookie', ...baseFeatures, 'clickToLoad', 'webInterferenceDetection', 'breakageReporting'], chrome: ['cookie', ...baseFeatures, 'clickToLoad', 'webInterferenceDetection', 'breakageReporting'], 'chrome-mv3': ['cookie', ...baseFeatures, 'clickToLoad', 'webInterferenceDetection', 'breakageReporting'], integration: [...baseFeatures, ...otherFeatures], diff --git a/injected/src/features/breakage-reporting.js b/injected/src/features/breakage-reporting.js index a7bed4042f..7bdf3440f6 100644 --- a/injected/src/features/breakage-reporting.js +++ b/injected/src/features/breakage-reporting.js @@ -29,6 +29,7 @@ export default class BreakageReporting extends ContentFeature { } // Only run detectors if explicitly configured + // Fetch interferenceTypes from webInterferenceDetection feature settings const detectorSettings = this.getFeatureSetting('interferenceTypes', 'webInterferenceDetection'); if (detectorSettings) { result.detectorData = { diff --git a/injected/src/sendmessage-transport.js b/injected/src/sendmessage-transport.js index f9f5f6d45d..0475ac0480 100644 --- a/injected/src/sendmessage-transport.js +++ b/injected/src/sendmessage-transport.js @@ -6,12 +6,30 @@ import { TestTransportConfig } from '../../messaging/index.js'; * @typedef {import('@duckduckgo/messaging').MessagingTransport} MessagingTransport */ +/** + * Singleton transport shared across all features. Without this, each feature would + * have its own transport/queue and wouldn't receive messages meant for other features. + * @type {SendMessageMessagingTransport | null} + */ +let sharedTransport = null; + /** * @deprecated - A temporary constructor for the extension to make the messaging config */ export function extensionConstructMessagingConfig() { - const messagingTransport = new SendMessageMessagingTransport(); - return new TestTransportConfig(messagingTransport); + return new TestTransportConfig(getSharedMessagingTransport()); +} + +/** + * Used by entry-points to route incoming extension messages to onResponse(). + * Ensures a singleton transport exists. + * @returns {SendMessageMessagingTransport} + */ +export function getSharedMessagingTransport() { + if (!sharedTransport) { + sharedTransport = new SendMessageMessagingTransport(); + } + return sharedTransport; } /**