From 82671bda6ff6cdfbe08f787c349fdda70b8660ea Mon Sep 17 00:00:00 2001 From: wagesj45 Date: Sat, 28 Mar 2026 21:41:25 -0500 Subject: [PATCH] Removing legacy/internal calls so `strict_max_version` is no longer needed in the manifest. --- README.md | 2 +- manifest.json | 3 +-- modules/AiClassifier.js | 49 +++++------------------------------------ 3 files changed, 7 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 5b908ea..ab31284 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ containing `matched` and `reason` fields. Older installations with a separate ## Architecture Overview -Sortana is implemented entirely with standard WebExtension scripts—no custom experiment code is required: +Sortana is implemented entirely with documented MailExtension/WebExtension APIs. No custom experiment code or Thunderbird-internal fallback paths are required: - `background.js` loads saved settings, manages the classification queue and listens for new messages. - `modules/AiClassifier.js` implements the classification logic and cache handling. diff --git a/manifest.json b/manifest.json index dcddb67..4d7e170 100644 --- a/manifest.json +++ b/manifest.json @@ -6,8 +6,7 @@ "applications": { "gecko": { "id": "ai-filter@jordanwages", - "strict_min_version": "128.0", - "strict_max_version": "140.*" + "strict_min_version": "128.0" } }, "icons": { diff --git a/modules/AiClassifier.js b/modules/AiClassifier.js index b4c0907..dbbde92 100644 --- a/modules/AiClassifier.js +++ b/modules/AiClassifier.js @@ -4,17 +4,6 @@ import { DEFAULT_AI_PARAMS } from "./defaultParams.js"; const storage = (globalThis.messenger ?? globalThis.browser).storage; -let Services; -try { - if (typeof globalThis !== "undefined" && globalThis.Services) { - Services = globalThis.Services; - } else if (typeof ChromeUtils !== "undefined" && ChromeUtils.importESModule) { - ({ Services } = ChromeUtils.importESModule("resource://gre/modules/Services.sys.mjs")); - } -} catch (e) { - Services = undefined; -} - const COMPLETIONS_PATH = "/v1/completions"; const MODELS_PATH = "/v1/models"; @@ -81,26 +70,14 @@ function buildModelsUrl(endpointBase) { return `${withScheme}${needsSlash ? "" : "/"}${path}`; } -function sha256HexSync(str) { - try { - const hasher = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash); - hasher.init(Ci.nsICryptoHash.SHA256); - const data = new TextEncoder().encode(str); - hasher.update(data, data.length); - const binary = hasher.finish(false); - return Array.from(binary, c => ("0" + c.charCodeAt(0).toString(16)).slice(-2)).join(""); - } catch (e) { - aiLog(`sha256HexSync failed`, { level: 'error' }, e); - return ""; - } -} - async function sha256Hex(str) { - if (typeof crypto?.subtle?.digest === "function") { + try { const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(str)); return Array.from(new Uint8Array(buf), b => b.toString(16).padStart(2, "0")).join(""); + } catch (e) { + aiLog("sha256Hex failed", { level: "error" }, e); + return ""; } - return sha256HexSync(str); } async function resolveHeaderId(id) { @@ -119,9 +96,6 @@ async function resolveHeaderId(id) { async function buildCacheKey(id, criterion) { const resolvedId = await resolveHeaderId(id); - if (Services) { - return sha256HexSync(`${resolvedId}|${criterion}`); - } return sha256Hex(`${resolvedId}|${criterion}`); } @@ -188,17 +162,6 @@ async function loadTemplate(name) { return ""; } -function loadTemplateSync(name) { - if (!Services?.tm?.spinEventLoopUntil) { - throw new Error("loadTemplateSync requires Services"); - } - let text = ""; - let done = false; - loadTemplate(name).then(t => { text = t; }).catch(() => {}).finally(() => { done = true; }); - Services.tm.spinEventLoopUntil(() => done); - return text; -} - async function setConfig(config = {}) { if (typeof config.endpoint === "string") { const base = normalizeEndpointBase(config.endpoint); @@ -240,8 +203,6 @@ async function setConfig(config = {}) { } if (gTemplateName === "custom") { gTemplateText = gCustomTemplate; - } else if (Services?.tm?.spinEventLoopUntil) { - gTemplateText = loadTemplateSync(gTemplateName); } else { gTemplateText = await loadTemplate(gTemplateName); } @@ -278,7 +239,7 @@ function buildPrompt(body, criterion) { email: body, query: criterion, }; - let template = gTemplateText || loadTemplateSync(gTemplateName); + let template = gTemplateText || ""; return template.replace(/{{\s*(\w+)\s*}}/g, (m, key) => data[key] || ""); }