From 09f418c6dddec3261c1c1d1ac4ef40467881cbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Fors=C3=A9n?= Date: Wed, 29 Jul 2026 06:55:21 +0000 Subject: [PATCH 1/2] Set error icon in a navigation event --- extension/src/background.ts | 16 ---------------- extension/src/webcat/handler.ts | 13 ++++++++++++- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/extension/src/background.ts b/extension/src/background.ts index 8e1eaa6..2e0331a 100644 --- a/extension/src/background.ts +++ b/extension/src/background.ts @@ -9,7 +9,6 @@ import validator_set from "./validator_set.json"; import { isInPartition } from "./webcat/cache"; import { WebcatDatabase } from "./webcat/db"; import { WebcatRequestHandler } from "./webcat/handler"; -import { setErrorIcon } from "./webcat/ui"; import { EnrollmentUpdater } from "./webcat/updater"; import { clearBrowserCaches } from "./webcat/utils"; @@ -17,21 +16,6 @@ console.log("[webcat] Starting up background"); const db = new WebcatDatabase(); -// Not the best performance idea to act on all tab just for this -browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { - const errorUrl = browser.runtime.getURL("pages/error.html"); - if (changeInfo.status === "complete" && tab.url?.startsWith(errorUrl)) { - setErrorIcon(tabId); - } -}); - -// Grey out and make page action unclickable unless a website is enrolled -browser.tabs.onCreated.addListener((tab) => { - if (tab.id !== undefined) { - browser.pageAction.hide(tab.id); - } -}); - // Handle incognito sessions ending browser.windows.onRemoved.addListener(async () => { const windows = await browser.windows.getAll(); diff --git a/extension/src/webcat/handler.ts b/extension/src/webcat/handler.ts index 76023ca..202b4b3 100644 --- a/extension/src/webcat/handler.ts +++ b/extension/src/webcat/handler.ts @@ -17,7 +17,7 @@ import { OriginStateVerifiedManifest } from "./originstate"; import { validateOrigin } from "./request"; import { FRAME_TYPES } from "./resources"; import { ResponseValidator } from "./response"; -import { errorpage } from "./ui"; +import { errorpage, setErrorIcon } from "./ui"; import { getFQDN, isExtensionRequest, isNewerSemver } from "./utils"; // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging @@ -44,6 +44,13 @@ export class WebcatRequestHandler extends RequestHandler { this.#responseValidator = new ResponseValidator(this.#db, this.#hooks); this.addEventListener("beforerequest", this.#onRequest); this.addEventListener("headersreceived", this.#onHeaders); + browser.webNavigation.onCommitted.addListener(this.#onErrorPageNavigation, { + url: [ + { + urlPrefix: browser.runtime.getURL("pages/error.html"), + }, + ], + }); } override async bind(fqdns: string[]): Promise { @@ -298,4 +305,8 @@ export class WebcatRequestHandler extends RequestHandler { ); return details.requestId; } + + #onErrorPageNavigation(details: browser.webNavigation._OnCommittedDetails) { + setErrorIcon(details.tabId); + } } From 0649ef8dba5b7d549dd5810f243175b8b1733c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Fors=C3=A9n?= Date: Wed, 29 Jul 2026 07:09:44 +0000 Subject: [PATCH 2/2] Move window close handler to WebcatRequestHandler --- extension/src/background.ts | 18 ---------------- extension/src/webcat/handler.ts | 37 ++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/extension/src/background.ts b/extension/src/background.ts index 2e0331a..efcf9fe 100644 --- a/extension/src/background.ts +++ b/extension/src/background.ts @@ -6,7 +6,6 @@ import { UPDATE_INTERVAL_MS, } from "./config"; import validator_set from "./validator_set.json"; -import { isInPartition } from "./webcat/cache"; import { WebcatDatabase } from "./webcat/db"; import { WebcatRequestHandler } from "./webcat/handler"; import { EnrollmentUpdater } from "./webcat/updater"; @@ -16,23 +15,6 @@ console.log("[webcat] Starting up background"); const db = new WebcatDatabase(); -// Handle incognito sessions ending -browser.windows.onRemoved.addListener(async () => { - const windows = await browser.windows.getAll(); - if (windows.filter((win) => win.incognito).length === 0) { - for (const key of db.origins.keys()) { - if (isInPartition(key, { incognito: true })) { - db.origins.delete(key); - } - } - for (const value of db.nonOrigins.values()) { - if (isInPartition(value, { incognito: true })) { - db.nonOrigins.delete(value); - } - } - } -}); - const requestHandler = new WebcatRequestHandler(db); const updater = new EnrollmentUpdater({ endpoint: endpoint, diff --git a/extension/src/webcat/handler.ts b/extension/src/webcat/handler.ts index 202b4b3..940686b 100644 --- a/extension/src/webcat/handler.ts +++ b/extension/src/webcat/handler.ts @@ -6,7 +6,7 @@ import { RequestHandler, } from "../browser/requests"; import { ContentScript } from "../browser/scripting"; -import { CacheKey } from "./cache"; +import { CacheKey, isInPartition } from "./cache"; import { HookBuilder } from "./hookbuilder"; import { Database } from "./interfaces/database"; import { WebcatError } from "./interfaces/errors"; @@ -44,13 +44,17 @@ export class WebcatRequestHandler extends RequestHandler { this.#responseValidator = new ResponseValidator(this.#db, this.#hooks); this.addEventListener("beforerequest", this.#onRequest); this.addEventListener("headersreceived", this.#onHeaders); - browser.webNavigation.onCommitted.addListener(this.#onErrorPageNavigation, { - url: [ - { - urlPrefix: browser.runtime.getURL("pages/error.html"), - }, - ], - }); + browser.webNavigation.onCommitted.addListener( + this.#onErrorPageNavigation.bind(this), + { + url: [ + { + urlPrefix: browser.runtime.getURL("pages/error.html"), + }, + ], + }, + ); + browser.windows.onRemoved.addListener(this.#onWindowClosed.bind(this)); } override async bind(fqdns: string[]): Promise { @@ -309,4 +313,21 @@ export class WebcatRequestHandler extends RequestHandler { #onErrorPageNavigation(details: browser.webNavigation._OnCommittedDetails) { setErrorIcon(details.tabId); } + + async #onWindowClosed() { + // Handle incognito sessions ending + const windows = await browser.windows.getAll(); + if (windows.filter((win) => win.incognito).length === 0) { + for (const key of this.#db.origins.keys()) { + if (isInPartition(key, { incognito: true })) { + this.#db.origins.delete(key); + } + } + for (const value of this.#db.nonOrigins.values()) { + if (isInPartition(value, { incognito: true })) { + this.#db.nonOrigins.delete(value); + } + } + } + } }