diff --git a/_locales/en/messages.json b/_locales/en/messages.json index ac9ba167..72ea3f47 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1436,6 +1436,22 @@ "message": "No messages have screened for spam yet. Here you'll find a list of the last 100 spam reports.", "description": "" }, + "SpamFilter_skip_addresses_title": { + "message": "Email address skip list", + "description": "" + }, + "SpamFilter_skip_addresses_infoline": { + "message": "Emails from these addresses will not be sent to the AI for spam filtering.", + "description": "" + }, + "SpamFilter_skip_addresses_infoline2": { + "message": "Add one email address per line, or separated by a comma.", + "description": "" + }, + "spamfilter_skip_addresses_explanation": { + "message": "The sender is in the email address antispam skip list.", + "description": "" + }, "SpamReport_Title": { "message": "Spam Filter Reports", "description": "" diff --git a/mzta-background.js b/mzta-background.js index b4a66bc7..00f4a815 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -805,6 +805,28 @@ async function _generateSpamReportForMessage(headerMessageId, options = {}) { body_text = msg_text.text.replace(/\s+/g, ' ').trim(); } } +console.log(">>>>>>>>>>>>>> options.skip_addresses: " + JSON.stringify(options.skip_addresses)); + // Check if sender is in the skip addresses list + let skip_addresses = options.skip_addresses || (await browser.storage.sync.get({spamfilter_skip_addresses: prefs_default.spamfilter_skip_addresses})).spamfilter_skip_addresses; + if (skip_addresses.length > 0) { + let senderEmail = (message.author.match(/[\w.-]+@[\w.-]+\.\w+/) || [''])[0].toLowerCase(); + if (senderEmail && skip_addresses.includes(senderEmail)) { + taLog.log("Sender " + senderEmail + " is in the skip addresses list, skipping spam filter."); + let report_data = {}; + report_data.report_date = new Date(); + report_data.headerMessageId = headerMessageId; + report_data.spamValue = 0; + report_data.explanation = browser.i18n.getMessage('spamfilter_skip_addresses_explanation'); + report_data.subject = curr_fullMessage.headers.subject; + report_data.from = curr_fullMessage.headers.from; + report_data.message_date = new Date(message.date); + report_data.moved = false; + report_data.SpamThreshold = prefs.spamfilter_threshold || prefs_init.spamfilter_threshold; + spamReport.saveReportData(report_data, headerMessageId); + await updateSpamPanel(headerMessageId, "showSpamReport", report_data); + return { success: true }; + } + } let curr_prompt_spamfilter = await getSpamFilterPrompt(); let chatgpt_lang = await taPromptUtils.getDefaultLang(curr_prompt_spamfilter); @@ -1650,10 +1672,13 @@ async function processEmails(args) { add_tags_auto_uselist: prefs_default.add_tags_auto_uselist, add_tags_auto_uselist_list: prefs_default.add_tags_auto_uselist_list, spamfilter_enabled_accounts: prefs_default.spamfilter_enabled_accounts, + spamfilter_skip_addresses: prefs_default.spamfilter_skip_addresses, ...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type']), do_debug: prefs_default.do_debug, }); // console.log(">>>>>>>>>>>>>>>> prefs_aats: " + JSON.stringify(prefs_aats)); + let spamfilter_skip_addresses = prefs_aats.spamfilter_skip_addresses; + for await (let message of messages) { let curr_fullMessage = null; let msg_text = null; @@ -1729,7 +1754,8 @@ async function processEmails(args) { { messageData: { message, fullMessage: curr_fullMessage, body_text, msg_text }, prefs: prefs_aats, - autoMove: true + autoMove: true, + skip_addresses: spamfilter_skip_addresses }); if (!result.success) continue; } diff --git a/options/mzta-options-default.js b/options/mzta-options-default.js index 7c176f5a..3c16b111 100644 --- a/options/mzta-options-default.js +++ b/options/mzta-options-default.js @@ -138,6 +138,7 @@ export const prefs_default = { spamfilter: false, spamfilter_threshold: 70, spamfilter_enabled_accounts: [], + spamfilter_skip_addresses: [], summarize: false, summarize_auto: 1, // 0: disabled, 1: manual button, 2: automatic on message open, 3: generate on email receive summarize_display_mode: 'inline', // 'inline' or 'webchat' diff --git a/pages/spamfilter/mzta-spamfilter.css b/pages/spamfilter/mzta-spamfilter.css index 7d330186..f8dfbcb3 100644 --- a/pages/spamfilter/mzta-spamfilter.css +++ b/pages/spamfilter/mzta-spamfilter.css @@ -131,6 +131,15 @@ label:has(input[type="checkbox"]) { cursor: pointer; } +#spamfilter_skip_addresses_container{ + width: 90%; + margin: 40px auto; +} + +#spamfilter_skip_addresses{ + width: 30em; +} + @media (prefers-color-scheme: dark) { body { background-color: #1C1B22; diff --git a/pages/spamfilter/mzta-spamfilter.html b/pages/spamfilter/mzta-spamfilter.html index fb232647..2e7ba072 100644 --- a/pages/spamfilter/mzta-spamfilter.html +++ b/pages/spamfilter/mzta-spamfilter.html @@ -65,6 +65,13 @@ +
+ __MSG_SpamFilter_skip_addresses_title__ +
__MSG_SpamFilter_skip_addresses_infoline__ +
__MSG_SpamFilter_skip_addresses_infoline2__
+
+
+
__MSG_SpamReport_Title__
diff --git a/pages/spamfilter/mzta-spamfilter.js b/pages/spamfilter/mzta-spamfilter.js index fccea0cf..382690e6 100644 --- a/pages/spamfilter/mzta-spamfilter.js +++ b/pages/spamfilter/mzta-spamfilter.js @@ -34,6 +34,7 @@ import { taSpamReport } from '../../js/mzta-spamreport.js'; import { getAccountsList, isAPIKeyValue, + normalizeStringList, setTomSelectBorder } from "../../js/mzta-utils.js"; import { @@ -130,6 +131,33 @@ document.addEventListener('DOMContentLoaded', async () => { autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(mapPlaceholderToSuggestion); textareaAutocomplete(spamfilter_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email + // Skip addresses list + let skip_addresses_textarea = document.getElementById('spamfilter_skip_addresses'); + let skip_addresses_save_btn = document.getElementById('btn_save_skip_addresses'); + + let skip_addresses_value = await spamfilter_getSkipAddresses(); + let skip_addresses_string = skip_addresses_value.join('\n'); + + skip_addresses_textarea.value = skip_addresses_string; + + skip_addresses_textarea.addEventListener('input', (event) => { + skip_addresses_save_btn.disabled = (event.target.value === skip_addresses_string); + if(skip_addresses_save_btn.disabled){ + document.getElementById('skip_addresses_unsaved').classList.add('hidden'); + } else { + document.getElementById('skip_addresses_unsaved').classList.remove('hidden'); + } + }); + + skip_addresses_save_btn.addEventListener('click', () => { + let skip_array_new = normalizeStringList(skip_addresses_textarea.value, 2); + spamfilter_setSkipAddresses(skip_array_new); + skip_addresses_save_btn.disabled = true; + skip_addresses_string = skip_array_new.join('\n'); + skip_addresses_textarea.value = skip_addresses_string; + document.getElementById('skip_addresses_unsaved').classList.add('hidden'); + }); + //Accounts manager let accounts = await getAccountsList(); const accountsContainer = document.getElementById('account_selector_checkboxes'); @@ -374,3 +402,12 @@ async function restoreOptions() { setCurrentChoice(getting); } + +async function spamfilter_getSkipAddresses() { + let prefs = await browser.storage.sync.get({spamfilter_skip_addresses: []}); + return prefs.spamfilter_skip_addresses; +} + +function spamfilter_setSkipAddresses(spamfilter_skip_addresses) { + browser.storage.sync.set({spamfilter_skip_addresses: spamfilter_skip_addresses}); +}