@bobfrankston/rmfmail 1.2.272 → 1.2.274
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/android-bootstrap.bundle.js +15 -0
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +112 -8
- package/client/app.bundle.js.map +4 -4
- package/client/app.js +19 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +20 -0
- package/client/components/message-list.js +9 -1
- package/client/components/message-list.js.map +1 -1
- package/client/components/message-list.ts +9 -1
- package/client/components/message-viewer.js +40 -2
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +37 -2
- package/client/compose/compose.bundle.js +4 -0
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/lib/api-client.js +6 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +6 -0
- package/client/lib/approved-senders.js +66 -0
- package/client/lib/approved-senders.js.map +1 -0
- package/client/lib/approved-senders.ts +63 -0
- package/client/lib/mailxapi.js +3 -0
- package/client/package.json +1 -1
- package/package.json +5 -5
- package/packages/mailx-service/index.d.ts +15 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +18 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +19 -0
- package/packages/mailx-service/jsonrpc.js +2 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +2 -0
- package/packages/mailx-service/package.json +1 -1
- package/packages/mailx-store-web/android-bootstrap.js +1 -0
- package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.ts +1 -0
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-store-web/web-service.d.ts +11 -0
- package/packages/mailx-store-web/web-service.d.ts.map +1 -1
- package/packages/mailx-store-web/web-service.js +14 -0
- package/packages/mailx-store-web/web-service.js.map +1 -1
- package/packages/mailx-store-web/web-service.ts +15 -0
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-72180 → node_modules.npmglobalize-stash-31304}/.package-lock.json +0 -0
package/client/app.bundle.js
CHANGED
|
@@ -56,6 +56,7 @@ __export(api_client_exports, {
|
|
|
56
56
|
flagSenderOrDomain: () => flagSenderOrDomain,
|
|
57
57
|
formatJsonc: () => formatJsonc,
|
|
58
58
|
getAccounts: () => getAccounts,
|
|
59
|
+
getAllowlist: () => getAllowlist,
|
|
59
60
|
getAttachment: () => getAttachment,
|
|
60
61
|
getAutocompleteSettings: () => getAutocompleteSettings,
|
|
61
62
|
getCalendarEvents: () => getCalendarEvents,
|
|
@@ -350,6 +351,9 @@ function addUserDictWords(words) {
|
|
|
350
351
|
function removeUserDictWord(word) {
|
|
351
352
|
return ipc().removeUserDictWord?.(word) ?? Promise.resolve([]);
|
|
352
353
|
}
|
|
354
|
+
function getAllowlist() {
|
|
355
|
+
return ipc().getAllowlist?.() ?? Promise.resolve({ senders: [], domains: [], recipients: [], flaggedSenders: [], flaggedDomains: [] });
|
|
356
|
+
}
|
|
353
357
|
function flagSenderOrDomain(type, value) {
|
|
354
358
|
return ipc().flagSenderOrDomain?.(type, value) ?? Promise.resolve({ flagged: false });
|
|
355
359
|
}
|
|
@@ -1310,6 +1314,61 @@ var init_message_state = __esm({
|
|
|
1310
1314
|
}
|
|
1311
1315
|
});
|
|
1312
1316
|
|
|
1317
|
+
// client/lib/approved-senders.js
|
|
1318
|
+
var approved_senders_exports = {};
|
|
1319
|
+
__export(approved_senders_exports, {
|
|
1320
|
+
approvedCounts: () => approvedCounts,
|
|
1321
|
+
isSenderApproved: () => isSenderApproved,
|
|
1322
|
+
noteApprovedLocally: () => noteApprovedLocally,
|
|
1323
|
+
refreshApprovedSenders: () => refreshApprovedSenders
|
|
1324
|
+
});
|
|
1325
|
+
async function refreshApprovedSenders() {
|
|
1326
|
+
try {
|
|
1327
|
+
const list = await getAllowlist();
|
|
1328
|
+
senders = new Set((list.senders || []).map(norm));
|
|
1329
|
+
domains = new Set((list.domains || []).map(norm));
|
|
1330
|
+
loaded = true;
|
|
1331
|
+
} catch (e) {
|
|
1332
|
+
console.warn("[approved-senders] refresh failed:", e?.message || e);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
function isSenderApproved(address) {
|
|
1336
|
+
if (!loaded)
|
|
1337
|
+
return false;
|
|
1338
|
+
const a = norm(address);
|
|
1339
|
+
if (!a)
|
|
1340
|
+
return false;
|
|
1341
|
+
if (senders.has(a))
|
|
1342
|
+
return true;
|
|
1343
|
+
const d = domainOf(a);
|
|
1344
|
+
return !!d && domains.has(d);
|
|
1345
|
+
}
|
|
1346
|
+
function noteApprovedLocally(type, value) {
|
|
1347
|
+
const v = norm(value);
|
|
1348
|
+
if (!v)
|
|
1349
|
+
return;
|
|
1350
|
+
if (type === "sender")
|
|
1351
|
+
senders.add(v);
|
|
1352
|
+
else
|
|
1353
|
+
domains.add(v);
|
|
1354
|
+
loaded = true;
|
|
1355
|
+
}
|
|
1356
|
+
function approvedCounts() {
|
|
1357
|
+
return { senders: senders.size, domains: domains.size, loaded };
|
|
1358
|
+
}
|
|
1359
|
+
var senders, domains, loaded, norm, domainOf;
|
|
1360
|
+
var init_approved_senders = __esm({
|
|
1361
|
+
"client/lib/approved-senders.js"() {
|
|
1362
|
+
"use strict";
|
|
1363
|
+
init_api_client();
|
|
1364
|
+
senders = /* @__PURE__ */ new Set();
|
|
1365
|
+
domains = /* @__PURE__ */ new Set();
|
|
1366
|
+
loaded = false;
|
|
1367
|
+
norm = (s) => (s || "").trim().toLowerCase();
|
|
1368
|
+
domainOf = (addr) => norm(addr).split("@").pop() || "";
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1371
|
+
|
|
1313
1372
|
// packages/mailx-types/contact-rules.js
|
|
1314
1373
|
var init_contact_rules = __esm({
|
|
1315
1374
|
"packages/mailx-types/contact-rules.js"() {
|
|
@@ -2693,6 +2752,36 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
2693
2752
|
items.push({ label: "", action: () => {
|
|
2694
2753
|
}, separator: true });
|
|
2695
2754
|
}
|
|
2755
|
+
if (el === fromEl && msg.from?.address) {
|
|
2756
|
+
const addr = String(msg.from.address);
|
|
2757
|
+
const dom = addr.split("@").pop() || "";
|
|
2758
|
+
const claimed = displayNameClaimsOtherAddress(String(msg.from.name || ""), addr);
|
|
2759
|
+
if (claimed && !isSenderApproved(addr)) {
|
|
2760
|
+
const approve = async (type, value) => {
|
|
2761
|
+
noteApprovedLocally(type, value);
|
|
2762
|
+
try {
|
|
2763
|
+
await allowRemoteContent(type, value);
|
|
2764
|
+
await refreshApprovedSenders();
|
|
2765
|
+
document.dispatchEvent(new CustomEvent("mailx-allowlist-changed"));
|
|
2766
|
+
const st = document.getElementById("status-sync");
|
|
2767
|
+
if (st)
|
|
2768
|
+
st.textContent = `Marked valid: ${value}`;
|
|
2769
|
+
} catch (e2) {
|
|
2770
|
+
const st = document.getElementById("status-sync");
|
|
2771
|
+
if (st) {
|
|
2772
|
+
st.textContent = `Couldn't save "${value}" to the allowlist \u2014 ${e2?.message || e2}`;
|
|
2773
|
+
st.style.color = "oklch(0.65 0.2 25)";
|
|
2774
|
+
}
|
|
2775
|
+
console.error("[allowlist] approve failed:", e2);
|
|
2776
|
+
}
|
|
2777
|
+
};
|
|
2778
|
+
items.push({ label: `\u2713 Mark ${addr} as a valid sender`, action: () => void approve("sender", addr) });
|
|
2779
|
+
if (dom)
|
|
2780
|
+
items.push({ label: `\u2713 Trust all senders at ${dom}`, action: () => void approve("domain", dom) });
|
|
2781
|
+
items.push({ label: "", action: () => {
|
|
2782
|
+
}, separator: true });
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2696
2785
|
if (omitted > 0) {
|
|
2697
2786
|
items.push({
|
|
2698
2787
|
label: `\u2026 ${omitted} more recipients \u2014 copy the whole list`,
|
|
@@ -3282,7 +3371,7 @@ ${escapeText(reputationBlind)}"` : ""}>${reputationText}</div>` : "") + `<div cl
|
|
|
3282
3371
|
}
|
|
3283
3372
|
function formatAddr(addr) {
|
|
3284
3373
|
const { text, claimed } = formatSender(addr);
|
|
3285
|
-
if (!claimed)
|
|
3374
|
+
if (!claimed || isSenderApproved(addr.address))
|
|
3286
3375
|
return text;
|
|
3287
3376
|
return `${text} \u2014 display name claims ${claimed}`;
|
|
3288
3377
|
}
|
|
@@ -4107,6 +4196,7 @@ var init_message_viewer = __esm({
|
|
|
4107
4196
|
"client/components/message-viewer.js"() {
|
|
4108
4197
|
"use strict";
|
|
4109
4198
|
init_api_client();
|
|
4199
|
+
init_approved_senders();
|
|
4110
4200
|
init_context_menu();
|
|
4111
4201
|
init_message_state();
|
|
4112
4202
|
init_message_list();
|
|
@@ -5530,6 +5620,7 @@ var init_message_list = __esm({
|
|
|
5530
5620
|
init_folder_picker();
|
|
5531
5621
|
init_fold_text();
|
|
5532
5622
|
init_mailx_types();
|
|
5623
|
+
init_approved_senders();
|
|
5533
5624
|
currentSpecialUse = "";
|
|
5534
5625
|
lastClickedRow = null;
|
|
5535
5626
|
loading = false;
|
|
@@ -5644,7 +5735,7 @@ var init_message_list = __esm({
|
|
|
5644
5735
|
from.textContent = msg.to.map((a) => a.name || a.address).join(", ");
|
|
5645
5736
|
} else {
|
|
5646
5737
|
const fromName2 = msg.from.name || msg.from.address;
|
|
5647
|
-
const fromClaim = displayNameClaimsOtherAddress(msg.from.name || "", msg.from.address || "");
|
|
5738
|
+
const fromClaim = isSenderApproved(msg.from.address || "") ? null : displayNameClaimsOtherAddress(msg.from.name || "", msg.from.address || "");
|
|
5648
5739
|
from.textContent = fromClaim ? `${fromName2} \u2014 actually ${msg.from.address}` : fromName2;
|
|
5649
5740
|
if (fromClaim) {
|
|
5650
5741
|
from.classList.add("ml-from-spoofed");
|
|
@@ -9902,12 +9993,12 @@ async function openCompose(mode, overrideMsg, overrideAccountId) {
|
|
|
9902
9993
|
}
|
|
9903
9994
|
if (msg && (mode === "editAsNew" || mode === "forward") && Array.isArray(msg.attachments) && msg.attachments.length) {
|
|
9904
9995
|
const msgAccountId = current?.accountId || accountId;
|
|
9905
|
-
const
|
|
9996
|
+
const loaded2 = [];
|
|
9906
9997
|
for (const att of msg.attachments) {
|
|
9907
9998
|
try {
|
|
9908
9999
|
const data = await getAttachment(msgAccountId, msg.uid, att.id, msg.folderId);
|
|
9909
10000
|
if (data?.content) {
|
|
9910
|
-
|
|
10001
|
+
loaded2.push({
|
|
9911
10002
|
filename: data.filename || att.filename || "attachment",
|
|
9912
10003
|
mimeType: data.contentType || att.contentType || "application/octet-stream",
|
|
9913
10004
|
dataBase64: data.content
|
|
@@ -9917,7 +10008,7 @@ async function openCompose(mode, overrideMsg, overrideAccountId) {
|
|
|
9917
10008
|
console.error(`[compose] ${mode}: failed to load attachment ${att.id}: ${e?.message || e}`);
|
|
9918
10009
|
}
|
|
9919
10010
|
}
|
|
9920
|
-
if (
|
|
10011
|
+
if (loaded2.length) init.attachments = loaded2;
|
|
9921
10012
|
}
|
|
9922
10013
|
if (preferWindow && !frame) {
|
|
9923
10014
|
try {
|
|
@@ -12379,6 +12470,19 @@ function applyThreadFilter() {
|
|
|
12379
12470
|
console.error("pending mailto pickup failed:", e?.message || e);
|
|
12380
12471
|
}
|
|
12381
12472
|
})();
|
|
12473
|
+
(async () => {
|
|
12474
|
+
try {
|
|
12475
|
+
const { refreshApprovedSenders: refreshApprovedSenders2 } = await Promise.resolve().then(() => (init_approved_senders(), approved_senders_exports));
|
|
12476
|
+
await refreshApprovedSenders2();
|
|
12477
|
+
document.dispatchEvent(new CustomEvent("mailx-allowlist-changed"));
|
|
12478
|
+
} catch (e) {
|
|
12479
|
+
console.warn("approved-sender index load failed:", e?.message || e);
|
|
12480
|
+
}
|
|
12481
|
+
})();
|
|
12482
|
+
document.addEventListener("mailx-allowlist-changed", () => {
|
|
12483
|
+
void Promise.resolve().then(() => (init_message_list(), message_list_exports)).then((m) => m.reloadCurrentFolder?.()).catch(() => {
|
|
12484
|
+
});
|
|
12485
|
+
});
|
|
12382
12486
|
(async () => {
|
|
12383
12487
|
try {
|
|
12384
12488
|
const { consumePendingShare: consumePendingShare2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
@@ -13630,12 +13734,12 @@ document.addEventListener("mailx-popout-message", (async (e) => {
|
|
|
13630
13734
|
draftId: msg.mailxDraftId || ""
|
|
13631
13735
|
};
|
|
13632
13736
|
if (Array.isArray(msg.attachments) && msg.attachments.length) {
|
|
13633
|
-
const
|
|
13737
|
+
const loaded2 = [];
|
|
13634
13738
|
for (const att of msg.attachments) {
|
|
13635
13739
|
try {
|
|
13636
13740
|
const data = await getAttachment(accountId, msg.uid, att.id, msg.folderId);
|
|
13637
13741
|
if (data?.content) {
|
|
13638
|
-
|
|
13742
|
+
loaded2.push({
|
|
13639
13743
|
filename: data.filename || att.filename || "attachment",
|
|
13640
13744
|
mimeType: data.contentType || att.contentType || "application/octet-stream",
|
|
13641
13745
|
dataBase64: data.content
|
|
@@ -13645,7 +13749,7 @@ document.addEventListener("mailx-popout-message", (async (e) => {
|
|
|
13645
13749
|
console.error(`[compose] edit draft: failed to load attachment ${att.id} ("${att.filename}"): ${e2?.message || e2}`);
|
|
13646
13750
|
}
|
|
13647
13751
|
}
|
|
13648
|
-
if (
|
|
13752
|
+
if (loaded2.length) init.attachments = loaded2;
|
|
13649
13753
|
}
|
|
13650
13754
|
handOffComposeInit(showComposeOverlay(msg.subject ? `Edit: ${msg.subject}` : "Edit draft"), init);
|
|
13651
13755
|
return;
|