diff --git a/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx b/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx index dfdeccdfff4..21665f029ea 100644 --- a/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx +++ b/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx @@ -62,10 +62,10 @@ export const InferEntitiesAction = ({ }; try { - const sourceWebPage = await (browser.tabs.sendMessage( - activeTab.id, - message, - ) as Promise); + const sourceWebPage = await browser.tabs.sendMessage< + GetTabContentRequest, + GetTabContentReturn + >(activeTab.id, message); void sendMessageToBackground({ createAs, diff --git a/apps/plugin-browser/src/scripts/background.ts b/apps/plugin-browser/src/scripts/background.ts index 6dd14195db0..fc7adda01ce 100644 --- a/apps/plugin-browser/src/scripts/background.ts +++ b/apps/plugin-browser/src/scripts/background.ts @@ -5,8 +5,8 @@ import { getUser } from "../shared/get-user"; import type { GetTabContentRequest, GetTabContentReturn, - Message, } from "../shared/messages"; +import { isWellFormattedMessage } from "../shared/messages"; import { clearLocalStorage, getFromLocalStorage, @@ -36,7 +36,11 @@ browser.runtime.onInstalled.addListener(({ reason }) => { } }); -browser.runtime.onMessage.addListener(async (message: Message, sender) => { +browser.runtime.onMessage.addListener(async (message, sender) => { + if (!isWellFormattedMessage(message)) { + return `Unrecognised message format ${String(message)}`; + } + if (sender.tab) { // We are not expecting any messages from the content script return; @@ -63,9 +67,12 @@ browser.tabs.onUpdated.addListener((tabId, changeInfo) => { setTimeout(resolve, 2_000); }); - const webPage = await (browser.tabs.sendMessage(tabId, { + const webPage = await browser.tabs.sendMessage< + GetTabContentRequest, + GetTabContentReturn + >(tabId, { type: "get-tab-content", - } satisfies GetTabContentRequest) as Promise); + }); const applicableRules = automaticInferenceConfig.rules.filter( ({ restrictToDomains }) => { diff --git a/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts b/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts index 331e9bbf5f4..56b7aa8ca2b 100644 --- a/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts +++ b/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts @@ -45,9 +45,12 @@ export const getWebsiteContent = async (urls: string[]) => { browser.tabs.onUpdated.addListener(tabChangeListener); }); - const webPage = await (browser.tabs.sendMessage(tab.id, { + const webPage = await browser.tabs.sendMessage< + GetTabContentRequest, + GetTabContentReturn + >(tab.id, { type: "get-tab-content", - } satisfies GetTabContentRequest) as Promise); + }); webPages.push(webPage); diff --git a/apps/plugin-browser/src/scripts/content.ts b/apps/plugin-browser/src/scripts/content.ts index 19fe32bb204..50679f092b6 100644 --- a/apps/plugin-browser/src/scripts/content.ts +++ b/apps/plugin-browser/src/scripts/content.ts @@ -1,6 +1,12 @@ import browser from "webextension-polyfill"; +import { + type GetTabContentReturn, + isWellFormattedMessage, +} from "../shared/messages"; + /** + * @file * Content scripts operate in the context of the webpage itself, for reading and manipulating context. * * They have access to a limited set of browser APIs @@ -10,11 +16,15 @@ import browser from "webextension-polyfill"; * * You must update the extension if you amend this file, from the extensions manager page in the browser. */ -import type { GetTabContentReturn, Message } from "../shared/messages"; -// Promise based API (see: https://github.com/mozilla/webextension-polyfill/?tab=readme-ov-file#using-the-promise-based-apis) +// Promise based API (see: +// https://github.com/mozilla/webextension-polyfill/?tab=readme-ov-file#using-the-promise-based-apis) // eslint-disable-next-line @typescript-eslint/require-await -browser.runtime.onMessage.addListener(async (message: Message, _sender) => { +browser.runtime.onMessage.addListener(async (message) => { + if (!isWellFormattedMessage(message)) { + return `Unrecognised message format ${String(message)}`; + } + if (message.type === "get-tab-content") { const docContent = document.querySelector("main") ?? document.querySelector("body"); diff --git a/apps/plugin-browser/src/shared/messages.ts b/apps/plugin-browser/src/shared/messages.ts index acb8d5c1e24..ab3adeec31a 100644 --- a/apps/plugin-browser/src/shared/messages.ts +++ b/apps/plugin-browser/src/shared/messages.ts @@ -27,3 +27,8 @@ export type Message = | InferEntitiesRequest | CancelInferEntitiesRequest | GetTabContentRequest; + +export const isWellFormattedMessage = (message: unknown): message is Message => + typeof message === "object" && + message !== null && + typeof (message as { type: unknown }).type === "string";