proton-mail-bridge-client 2.16.2 → 2.17.0

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.
Files changed (245) hide show
  1. package/README.md +149 -12
  2. package/dist/cli.d.ts +16 -0
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +178 -1
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config-env.d.ts +2 -1
  7. package/dist/config-env.d.ts.map +1 -1
  8. package/dist/config-env.js +24 -0
  9. package/dist/config-env.js.map +1 -1
  10. package/dist/index.d.ts +5 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +180 -11
  13. package/dist/index.js.map +1 -1
  14. package/dist/services/account-manager.d.ts +7 -0
  15. package/dist/services/account-manager.d.ts.map +1 -1
  16. package/dist/services/account-manager.js +59 -0
  17. package/dist/services/account-manager.js.map +1 -1
  18. package/dist/services/audit-service.d.ts +20 -0
  19. package/dist/services/audit-service.d.ts.map +1 -1
  20. package/dist/services/audit-service.js +266 -9
  21. package/dist/services/audit-service.js.map +1 -1
  22. package/dist/services/autoresponder-service.d.ts +35 -6
  23. package/dist/services/autoresponder-service.d.ts.map +1 -1
  24. package/dist/services/autoresponder-service.js +223 -108
  25. package/dist/services/autoresponder-service.js.map +1 -1
  26. package/dist/services/brief-service.d.ts +7 -1
  27. package/dist/services/brief-service.d.ts.map +1 -1
  28. package/dist/services/brief-service.js +19 -5
  29. package/dist/services/brief-service.js.map +1 -1
  30. package/dist/services/category-service.d.ts +91 -0
  31. package/dist/services/category-service.d.ts.map +1 -0
  32. package/dist/services/category-service.js +320 -0
  33. package/dist/services/category-service.js.map +1 -0
  34. package/dist/services/commitment-service.d.ts.map +1 -1
  35. package/dist/services/commitment-service.js +9 -3
  36. package/dist/services/commitment-service.js.map +1 -1
  37. package/dist/services/contact-service.d.ts +60 -0
  38. package/dist/services/contact-service.d.ts.map +1 -0
  39. package/dist/services/contact-service.js +248 -0
  40. package/dist/services/contact-service.js.map +1 -0
  41. package/dist/services/delivery-queue-service.d.ts +4 -0
  42. package/dist/services/delivery-queue-service.d.ts.map +1 -1
  43. package/dist/services/delivery-queue-service.js +12 -2
  44. package/dist/services/delivery-queue-service.js.map +1 -1
  45. package/dist/services/draft-store-service.d.ts.map +1 -1
  46. package/dist/services/draft-store-service.js +3 -2
  47. package/dist/services/draft-store-service.js.map +1 -1
  48. package/dist/services/embedding-service.d.ts +68 -0
  49. package/dist/services/embedding-service.d.ts.map +1 -0
  50. package/dist/services/embedding-service.js +465 -0
  51. package/dist/services/embedding-service.js.map +1 -0
  52. package/dist/services/event-log-service.d.ts +67 -0
  53. package/dist/services/event-log-service.d.ts.map +1 -0
  54. package/dist/services/event-log-service.js +280 -0
  55. package/dist/services/event-log-service.js.map +1 -0
  56. package/dist/services/grant-service.d.ts +84 -0
  57. package/dist/services/grant-service.d.ts.map +1 -0
  58. package/dist/services/grant-service.js +214 -0
  59. package/dist/services/grant-service.js.map +1 -0
  60. package/dist/services/local-index-service.d.ts +18 -1
  61. package/dist/services/local-index-service.d.ts.map +1 -1
  62. package/dist/services/local-index-service.js +54 -4
  63. package/dist/services/local-index-service.js.map +1 -1
  64. package/dist/services/reply-reminder-service.d.ts +4 -0
  65. package/dist/services/reply-reminder-service.d.ts.map +1 -1
  66. package/dist/services/reply-reminder-service.js +22 -2
  67. package/dist/services/reply-reminder-service.js.map +1 -1
  68. package/dist/services/rules-service.d.ts +9 -1
  69. package/dist/services/rules-service.d.ts.map +1 -1
  70. package/dist/services/rules-service.js +8 -3
  71. package/dist/services/rules-service.js.map +1 -1
  72. package/dist/services/sieve-export.d.ts +19 -0
  73. package/dist/services/sieve-export.d.ts.map +1 -0
  74. package/dist/services/sieve-export.js +192 -0
  75. package/dist/services/sieve-export.js.map +1 -0
  76. package/dist/services/simple-imap-service.d.ts +13 -0
  77. package/dist/services/simple-imap-service.d.ts.map +1 -1
  78. package/dist/services/simple-imap-service.js +142 -18
  79. package/dist/services/simple-imap-service.js.map +1 -1
  80. package/dist/services/smtp-service.d.ts +1 -0
  81. package/dist/services/smtp-service.d.ts.map +1 -1
  82. package/dist/services/smtp-service.js +20 -0
  83. package/dist/services/smtp-service.js.map +1 -1
  84. package/dist/services/snooze-service.d.ts +4 -0
  85. package/dist/services/snooze-service.d.ts.map +1 -1
  86. package/dist/services/snooze-service.js +12 -3
  87. package/dist/services/snooze-service.js.map +1 -1
  88. package/dist/services/template-service.d.ts.map +1 -1
  89. package/dist/services/template-service.js +3 -2
  90. package/dist/services/template-service.js.map +1 -1
  91. package/dist/services/triage-plan-service.d.ts +10 -2
  92. package/dist/services/triage-plan-service.d.ts.map +1 -1
  93. package/dist/services/triage-plan-service.js +23 -3
  94. package/dist/services/triage-plan-service.js.map +1 -1
  95. package/dist/tools/attachments.js +1 -1
  96. package/dist/tools/attachments.js.map +1 -1
  97. package/dist/tools/brief.d.ts.map +1 -1
  98. package/dist/tools/brief.js +14 -4
  99. package/dist/tools/brief.js.map +1 -1
  100. package/dist/tools/categories.d.ts +4 -0
  101. package/dist/tools/categories.d.ts.map +1 -0
  102. package/dist/tools/categories.js +269 -0
  103. package/dist/tools/categories.js.map +1 -0
  104. package/dist/tools/commitments.d.ts.map +1 -1
  105. package/dist/tools/commitments.js +6 -2
  106. package/dist/tools/commitments.js.map +1 -1
  107. package/dist/tools/contacts.d.ts +6 -0
  108. package/dist/tools/contacts.d.ts.map +1 -0
  109. package/dist/tools/contacts.js +295 -0
  110. package/dist/tools/contacts.js.map +1 -0
  111. package/dist/tools/context.d.ts +4 -0
  112. package/dist/tools/context.d.ts.map +1 -1
  113. package/dist/tools/context.js +3 -0
  114. package/dist/tools/context.js.map +1 -1
  115. package/dist/tools/definitions.d.ts +333 -5
  116. package/dist/tools/definitions.d.ts.map +1 -1
  117. package/dist/tools/definitions.js +169 -5
  118. package/dist/tools/definitions.js.map +1 -1
  119. package/dist/tools/delegation.d.ts +44 -0
  120. package/dist/tools/delegation.d.ts.map +1 -0
  121. package/dist/tools/delegation.js +180 -0
  122. package/dist/tools/delegation.js.map +1 -0
  123. package/dist/tools/diagnostics.d.ts.map +1 -1
  124. package/dist/tools/diagnostics.js +6 -0
  125. package/dist/tools/diagnostics.js.map +1 -1
  126. package/dist/tools/drafts-support.d.ts +2 -1
  127. package/dist/tools/drafts-support.d.ts.map +1 -1
  128. package/dist/tools/drafts-support.js +14 -6
  129. package/dist/tools/drafts-support.js.map +1 -1
  130. package/dist/tools/drafts.d.ts.map +1 -1
  131. package/dist/tools/drafts.js +22 -1
  132. package/dist/tools/drafts.js.map +1 -1
  133. package/dist/tools/events.d.ts +47 -0
  134. package/dist/tools/events.d.ts.map +1 -0
  135. package/dist/tools/events.js +240 -0
  136. package/dist/tools/events.js.map +1 -0
  137. package/dist/tools/reading.d.ts.map +1 -1
  138. package/dist/tools/reading.js +125 -4
  139. package/dist/tools/reading.js.map +1 -1
  140. package/dist/tools/resources.d.ts +4 -0
  141. package/dist/tools/resources.d.ts.map +1 -1
  142. package/dist/tools/resources.js +9 -0
  143. package/dist/tools/resources.js.map +1 -1
  144. package/dist/tools/rules-runner.d.ts.map +1 -1
  145. package/dist/tools/rules-runner.js +1 -0
  146. package/dist/tools/rules-runner.js.map +1 -1
  147. package/dist/tools/rules.d.ts +9 -0
  148. package/dist/tools/rules.d.ts.map +1 -1
  149. package/dist/tools/rules.js +50 -19
  150. package/dist/tools/rules.js.map +1 -1
  151. package/dist/tools/sending.d.ts.map +1 -1
  152. package/dist/tools/sending.js +4 -0
  153. package/dist/tools/sending.js.map +1 -1
  154. package/dist/tools/style.d.ts +2 -0
  155. package/dist/tools/style.d.ts.map +1 -1
  156. package/dist/tools/style.js +3 -3
  157. package/dist/tools/style.js.map +1 -1
  158. package/dist/tools/templates-and-reminders.d.ts +3 -0
  159. package/dist/tools/templates-and-reminders.d.ts.map +1 -1
  160. package/dist/tools/templates-and-reminders.js +31 -17
  161. package/dist/tools/templates-and-reminders.js.map +1 -1
  162. package/dist/tools/triage.d.ts.map +1 -1
  163. package/dist/tools/triage.js +33 -11
  164. package/dist/tools/triage.js.map +1 -1
  165. package/dist/types/index.d.ts +23 -0
  166. package/dist/types/index.d.ts.map +1 -1
  167. package/dist/utils/account-identity.d.ts.map +1 -1
  168. package/dist/utils/account-identity.js +3 -2
  169. package/dist/utils/account-identity.js.map +1 -1
  170. package/dist/utils/approval.d.ts +133 -0
  171. package/dist/utils/approval.d.ts.map +1 -0
  172. package/dist/utils/approval.js +507 -0
  173. package/dist/utils/approval.js.map +1 -0
  174. package/dist/utils/atomic-write.d.ts +1 -1
  175. package/dist/utils/atomic-write.d.ts.map +1 -1
  176. package/dist/utils/atomic-write.js +10 -3
  177. package/dist/utils/atomic-write.js.map +1 -1
  178. package/dist/utils/commitment-phrases.d.ts.map +1 -1
  179. package/dist/utils/commitment-phrases.js +31 -18
  180. package/dist/utils/commitment-phrases.js.map +1 -1
  181. package/dist/utils/contact-text.d.ts +8 -0
  182. package/dist/utils/contact-text.d.ts.map +1 -0
  183. package/dist/utils/contact-text.js +24 -0
  184. package/dist/utils/contact-text.js.map +1 -0
  185. package/dist/utils/delegation.d.ts +17 -0
  186. package/dist/utils/delegation.d.ts.map +1 -0
  187. package/dist/utils/delegation.js +72 -0
  188. package/dist/utils/delegation.js.map +1 -0
  189. package/dist/utils/file-lock.d.ts.map +1 -1
  190. package/dist/utils/file-lock.js +5 -4
  191. package/dist/utils/file-lock.js.map +1 -1
  192. package/dist/utils/mail-security.d.ts +9 -1
  193. package/dist/utils/mail-security.d.ts.map +1 -1
  194. package/dist/utils/mail-security.js +444 -62
  195. package/dist/utils/mail-security.js.map +1 -1
  196. package/dist/utils/ocr.d.ts +24 -0
  197. package/dist/utils/ocr.d.ts.map +1 -0
  198. package/dist/utils/ocr.js +109 -0
  199. package/dist/utils/ocr.js.map +1 -0
  200. package/dist/utils/office-text-worker.d.ts +2 -0
  201. package/dist/utils/office-text-worker.d.ts.map +1 -0
  202. package/dist/utils/office-text-worker.js +17 -0
  203. package/dist/utils/office-text-worker.js.map +1 -0
  204. package/dist/utils/office-text.d.ts +32 -0
  205. package/dist/utils/office-text.d.ts.map +1 -0
  206. package/dist/utils/office-text.js +540 -0
  207. package/dist/utils/office-text.js.map +1 -0
  208. package/dist/utils/pdf-text-worker.js +2 -2
  209. package/dist/utils/pdf-text-worker.js.map +1 -1
  210. package/dist/utils/pdf-text.d.ts +10 -0
  211. package/dist/utils/pdf-text.d.ts.map +1 -1
  212. package/dist/utils/pdf-text.js +49 -9
  213. package/dist/utils/pdf-text.js.map +1 -1
  214. package/dist/utils/png.d.ts +2 -0
  215. package/dist/utils/png.d.ts.map +1 -0
  216. package/dist/utils/png.js +26 -0
  217. package/dist/utils/png.js.map +1 -0
  218. package/dist/utils/regular-file.d.ts +9 -0
  219. package/dist/utils/regular-file.d.ts.map +1 -0
  220. package/dist/utils/regular-file.js +34 -0
  221. package/dist/utils/regular-file.js.map +1 -0
  222. package/dist/utils/runtime-policy.d.ts.map +1 -1
  223. package/dist/utils/runtime-policy.js +2 -0
  224. package/dist/utils/runtime-policy.js.map +1 -1
  225. package/dist/utils/safe-write.d.ts +8 -0
  226. package/dist/utils/safe-write.d.ts.map +1 -0
  227. package/dist/utils/safe-write.js +46 -0
  228. package/dist/utils/safe-write.js.map +1 -0
  229. package/dist/utils/server-state-paths.d.ts +12 -0
  230. package/dist/utils/server-state-paths.d.ts.map +1 -0
  231. package/dist/utils/server-state-paths.js +69 -0
  232. package/dist/utils/server-state-paths.js.map +1 -0
  233. package/dist/utils/style-profile.d.ts +18 -0
  234. package/dist/utils/style-profile.d.ts.map +1 -1
  235. package/dist/utils/style-profile.js +63 -14
  236. package/dist/utils/style-profile.js.map +1 -1
  237. package/dist/utils/vcard.d.ts +27 -0
  238. package/dist/utils/vcard.d.ts.map +1 -0
  239. package/dist/utils/vcard.js +141 -0
  240. package/dist/utils/vcard.js.map +1 -0
  241. package/dist/utils/zip-reader.d.ts +16 -0
  242. package/dist/utils/zip-reader.d.ts.map +1 -0
  243. package/dist/utils/zip-reader.js +108 -0
  244. package/dist/utils/zip-reader.js.map +1 -0
  245. package/package.json +3 -3
@@ -0,0 +1,320 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { readRegularFile } from "../utils/regular-file.js";
3
+ import { dirname, join } from "node:path";
4
+ import { writeFileAtomic } from "../utils/atomic-write.js";
5
+ import { INVISIBLE } from "../utils/contact-text.js";
6
+ import { isFileNotFound, setAsideCorruptStore } from "../utils/corrupt-store.js";
7
+ import { withFileLock } from "../utils/file-lock.js";
8
+ import { InvalidArgumentError } from "../utils/helpers.js";
9
+ import { logger } from "../utils/logger.js";
10
+ import { assessMail } from "../utils/mail-security.js";
11
+ // Proton Mail's own categories (proton.me/support/mail-categories). A user category or label with one of these names
12
+ // is separate from Proton's and is reported as a clash; nothing here can see or change Proton's sorting.
13
+ export const PROTON_CATEGORIES = ["Primary", "Social", "Promotions", "Newsletters", "Transactions", "Updates"];
14
+ export const MAX_CATEGORIES = 30;
15
+ const MAX_LEARNED = 2000;
16
+ const MAX_SUBJECT_SCANNED = 1000;
17
+ const MAX_KEYWORDS_COUNTED = 2;
18
+ export const MIN_SCORE = 2;
19
+ const SCORE = { learned: 10, senderAddress: 6, senderDomain: 5, keyword: 3, automated: 2, knownContact: 4 };
20
+ // Offered only when the user asks for it.
21
+ export const STARTER_CATEGORIES = [
22
+ {
23
+ name: "Receipts",
24
+ description: "Receipts, invoices, orders, bookings and payment confirmations.",
25
+ keywords: ["receipt", "invoice", "order", "payment", "purchase", "booking", "faktur", "rachun", "paragon", "zamówieni", "płatnoś", "rechnung", "quittung", "bestellung", "zahlung"],
26
+ },
27
+ { name: "Newsletters", description: "Newsletters, digests and other mail you subscribed to.", automated: true, keywords: ["newsletter", "digest", "weekly", "edition"] },
28
+ {
29
+ name: "Social",
30
+ description: "Notifications from social networks.",
31
+ senders: ["@facebookmail.com", "@linkedin.com", "@x.com", "@twitter.com", "@instagram.com", "@redditmail.com", "@discord.com", "@pinterest.com", "@tiktok.com", "@mastodon.social"],
32
+ },
33
+ {
34
+ name: "Updates",
35
+ description: "Automatic notices: account and security alerts, shipping, reminders.",
36
+ automated: true,
37
+ keywords: ["alert", "security", "sign-in", "login", "password", "verify", "verification", "confirm", "shipped", "delivery", "reminder", "notification", "powiadomieni", "przesyłk", "benachrichtigung", "lieferung"],
38
+ },
39
+ { name: "People", description: "Mail written to you by a person.", automated: false, knownContact: true },
40
+ ];
41
+ const key = (name) => name.trim().toLowerCase();
42
+ const WORD_CHAR = /[\p{L}\p{N}]/u;
43
+ const CONTROL = /[\u0000-\u001f\u007f]/g;
44
+ /** Keywords that start a word in the subject (case-insensitive), in the order they were defined. */
45
+ function matchingKeywords(keywords, subject) {
46
+ const hay = subject.slice(0, MAX_SUBJECT_SCANNED).toLowerCase();
47
+ const found = [];
48
+ for (const keyword of keywords ?? []) {
49
+ const needle = keyword.toLowerCase();
50
+ for (let at = hay.indexOf(needle); at !== -1; at = hay.indexOf(needle, at + 1)) {
51
+ if (at === 0 || !WORD_CHAR.test(hay[at - 1])) {
52
+ found.push(keyword);
53
+ break;
54
+ }
55
+ }
56
+ }
57
+ return found;
58
+ }
59
+ function matchSender(patterns, address) {
60
+ if (!address.includes("@"))
61
+ return undefined;
62
+ const domain = address.slice(address.lastIndexOf("@") + 1);
63
+ const list = patterns ?? [];
64
+ const exact = list.find((pattern) => !pattern.includes("*") && !pattern.startsWith("@") && pattern.toLowerCase() === address);
65
+ if (exact)
66
+ return { pattern: exact, exact: true };
67
+ for (const pattern of list) {
68
+ const lower = pattern.toLowerCase();
69
+ if (!lower.startsWith("@") && !lower.startsWith("*@"))
70
+ continue;
71
+ const wanted = lower.slice(lower.indexOf("@") + 1);
72
+ if (domain === wanted || domain.endsWith(`.${wanted}`))
73
+ return { pattern, exact: false };
74
+ }
75
+ return undefined;
76
+ }
77
+ /** Which category a message belongs to and why. Pure: the same definitions, weights and message give the same verdict. */
78
+ export function classifyMessage(categories, learned, message) {
79
+ const from = message.from.trim().toLowerCase();
80
+ const trustSender = !message.authFailure;
81
+ const weights = new Map(learned.filter((entry) => entry.sender === from).map((entry) => [entry.category, entry.weight]));
82
+ const scored = [];
83
+ for (const category of categories) {
84
+ const reasons = [];
85
+ let score = 0;
86
+ let senderScore = 0;
87
+ const learnedWeight = trustSender ? (weights.get(key(category.name)) ?? 0) : 0;
88
+ if (learnedWeight > 0) {
89
+ score += learnedWeight * SCORE.learned;
90
+ senderScore += learnedWeight * SCORE.learned;
91
+ reasons.push(`you put mail from ${from} in ${category.name} (${learnedWeight} correction${learnedWeight === 1 ? "" : "s"})`);
92
+ }
93
+ if (category.automated !== undefined && message.automated !== undefined) {
94
+ if (category.automated === message.automated) {
95
+ score += SCORE.automated;
96
+ reasons.push(category.automated ? "list or bulk mail (List-Unsubscribe, List-Id or Precedence header)" : "written by a person (no list or bulk headers)");
97
+ }
98
+ else if (learnedWeight === 0) {
99
+ continue;
100
+ }
101
+ }
102
+ if (trustSender) {
103
+ const sender = matchSender(category.senders, from);
104
+ if (sender) {
105
+ const points = sender.exact ? SCORE.senderAddress : SCORE.senderDomain;
106
+ score += points;
107
+ senderScore += points;
108
+ reasons.push(`sender ${from} matches ${sender.pattern}`);
109
+ }
110
+ if (category.knownContact && message.knownContact) {
111
+ score += SCORE.knownContact;
112
+ senderScore += SCORE.knownContact;
113
+ reasons.push(`you have written to ${from} before`);
114
+ }
115
+ }
116
+ for (const keyword of matchingKeywords(category.keywords, message.subject).slice(0, MAX_KEYWORDS_COUNTED)) {
117
+ score += SCORE.keyword;
118
+ reasons.push(`subject contains "${keyword}"`);
119
+ }
120
+ if (score >= MIN_SCORE)
121
+ scored.push({ name: category.name, score, senderScore, reasons });
122
+ }
123
+ // Highest score wins; a tie goes to the category defined first.
124
+ const ranked = scored.map((entry, index) => ({ ...entry, index })).sort((a, b) => b.score - a.score || a.index - b.index);
125
+ const distrust = message.authFailure ? [`who the sender is was not used: the message failed ${message.authFailure}`] : [];
126
+ const [best, second] = ranked;
127
+ if (!best)
128
+ return { category: null, score: 0, reasons: [...distrust, "no signal of any category matched"], senderBased: false };
129
+ return {
130
+ category: best.name,
131
+ score: best.score,
132
+ reasons: [...best.reasons, ...distrust],
133
+ senderBased: best.senderScore > 0,
134
+ ...(second ? { runnerUp: { category: second.name, score: second.score } } : {}),
135
+ };
136
+ }
137
+ /** What a failing Authentication-Results says ("dmarc=fail"), or undefined when nothing failed or it is absent. */
138
+ export function authFailureOf(authenticationResults) {
139
+ const failed = [...(authenticationResults ?? "").slice(0, 4000).toLowerCase().matchAll(/\b(dkim|spf|dmarc)=fail\b/g)].map((match) => `${match[1]}=fail`);
140
+ return failed.length ? [...new Set(failed)].join(", ") : undefined;
141
+ }
142
+ /** A note when a category or its label shares a name with one of Proton's own categories. */
143
+ export function protonClash(category) {
144
+ const byName = PROTON_CATEGORIES.find((name) => key(name) === key(category.name));
145
+ const byLabel = category.label ? PROTON_CATEGORIES.find((name) => key(name) === key(category.label)) : undefined;
146
+ if (!byName && !byLabel)
147
+ return undefined;
148
+ const parts = [
149
+ byName ? `Proton Mail has its own "${byName}" category; this one is separate, kept by this server, and Proton's sorting is neither visible nor changed here.` : "",
150
+ byLabel ? `The label "${category.label}" is an ordinary label (Labels/${category.label}), not Proton's ${byLabel} category.` : "",
151
+ ];
152
+ return parts.filter(Boolean).join(" ");
153
+ }
154
+ // ---- validation -----------------------------------------------------------------------------------------------
155
+ function text(value, field, max) {
156
+ if (typeof value !== "string")
157
+ throw new InvalidArgumentError(`${field} must be text.`);
158
+ const clean = value.replace(CONTROL, " ").replace(/\s+/g, " ").trim();
159
+ if (clean.length > max)
160
+ throw new InvalidArgumentError(`${field} is longer than ${max} characters.`);
161
+ return clean;
162
+ }
163
+ function list(value, field, maxItems, maxLength) {
164
+ if (!Array.isArray(value) || value.length > maxItems)
165
+ throw new InvalidArgumentError(`${field} must be a list of at most ${maxItems} entries.`);
166
+ const items = value.map((entry) => text(entry, field, maxLength));
167
+ if (items.some((entry) => !entry))
168
+ throw new InvalidArgumentError(`${field} has an empty entry.`);
169
+ return [...new Set(items)];
170
+ }
171
+ // Lookalikes of Latin letters in Cyrillic and Greek (lowercase; the text is lowercased first).
172
+ const CONFUSABLES = new Map(Object.entries({
173
+ "\u0430": "a", "\u0432": "b", "\u0435": "e", "\u043A": "k", "\u043C": "m", "\u043D": "h", "\u043E": "o", "\u0440": "p", "\u0441": "c", "\u0442": "t", "\u0443": "y", "\u0445": "x", "\u0456": "i", "\u0457": "i", "\u0458": "j", "\u0455": "s", "\u0501": "d", "\u04BB": "h", "\u04CF": "l", "\u051B": "q", "\u051D": "w",
174
+ "\u03B1": "a", "\u03B2": "b", "\u03B3": "y", "\u03B5": "e", "\u03B9": "i", "\u03BA": "k", "\u03BD": "v", "\u03BF": "o", "\u03C1": "p", "\u03C4": "t", "\u03C5": "u", "\u03C7": "x",
175
+ }));
176
+ /** Text as the instruction filter should read it: compatibility forms folded, invisible characters dropped, lookalike letters read as Latin. A heuristic: it narrows the common disguises, it does not make the filter complete. */
177
+ function foldForFilter(value) {
178
+ return value.normalize("NFKC").replace(INVISIBLE, "").toLowerCase().replace(/[\u0370-\u03ff\u0400-\u052f]/g, (char) => CONFUSABLES.get(char) ?? char);
179
+ }
180
+ const SENDER_PATTERN = /^(\*?@|[^\s@*]+@)[a-z0-9-]+(\.[a-z0-9-]+)+$/i;
181
+ /**
182
+ * Checks a definition (a new one, or the fields that change on an existing one). An empty list or an empty label
183
+ * clears that field. Text that reads like an instruction to an AI is refused: categories are described in plain words.
184
+ */
185
+ export function validateCategory(raw, existing) {
186
+ const name = existing?.name ?? text(raw.name, "name", 60);
187
+ if (!name)
188
+ throw new InvalidArgumentError("A category needs a name.");
189
+ const draft = existing ? { ...existing } : { name };
190
+ delete draft.createdAt;
191
+ delete draft.updatedAt;
192
+ if (raw.description !== undefined)
193
+ draft.description = text(raw.description, "description", 300) || undefined;
194
+ if (raw.senders !== undefined) {
195
+ const senders = list(raw.senders, "senders", 50, 100);
196
+ const bad = senders.find((entry) => !SENDER_PATTERN.test(entry));
197
+ if (bad)
198
+ throw new InvalidArgumentError(`senders: "${bad}" is not an address or a domain written as @example.com.`);
199
+ draft.senders = senders.length ? senders : undefined;
200
+ }
201
+ if (raw.keywords !== undefined) {
202
+ const keywords = list(raw.keywords, "keywords", 30, 60);
203
+ draft.keywords = keywords.length ? keywords : undefined;
204
+ }
205
+ for (const field of ["automated", "knownContact"]) {
206
+ if (raw[field] === undefined)
207
+ continue;
208
+ if (typeof raw[field] !== "boolean")
209
+ throw new InvalidArgumentError(`${field} must be true or false.`);
210
+ draft[field] = raw[field];
211
+ }
212
+ if (raw.label !== undefined) {
213
+ const label = text(raw.label, "label", 100).replace(/^Labels\//i, "");
214
+ if (label && (/^\/|\/$/.test(label) || label.split("/").includes("..")))
215
+ throw new InvalidArgumentError("label must be a label name such as Receipts.");
216
+ draft.label = label || undefined;
217
+ }
218
+ const words = foldForFilter([draft.name, draft.description ?? "", draft.label ?? "", ...(draft.keywords ?? [])].join("\n"));
219
+ const verdict = assessMail({ text: words });
220
+ if (verdict.level === "high") {
221
+ throw new InvalidArgumentError(`The category reads like an instruction to an AI (${verdict.reasons.join(" ")}). Describe what mail belongs in it, in plain words.`);
222
+ }
223
+ for (const field of Object.keys(draft))
224
+ if (draft[field] === undefined)
225
+ delete draft[field];
226
+ return draft;
227
+ }
228
+ // ---- store ----------------------------------------------------------------------------------------------------
229
+ export class CategoryService {
230
+ storePath;
231
+ constructor(options) {
232
+ this.storePath = join(options.dataDir, "categories.json");
233
+ }
234
+ async list() {
235
+ return this.load();
236
+ }
237
+ async find(name) {
238
+ return (await this.load()).categories.find((category) => key(category.name) === key(name));
239
+ }
240
+ /** Creates the category, or changes the fields given on the one with that name. */
241
+ async define(raw, now = new Date()) {
242
+ return this.withLock(async () => {
243
+ const state = await this.load();
244
+ const wanted = typeof raw.name === "string" ? key(raw.name) : "";
245
+ const index = state.categories.findIndex((category) => key(category.name) === wanted);
246
+ const existing = index === -1 ? undefined : state.categories[index];
247
+ if (!existing && state.categories.length >= MAX_CATEGORIES)
248
+ throw new InvalidArgumentError(`At most ${MAX_CATEGORIES} categories per account.`);
249
+ const draft = validateCategory(raw, existing);
250
+ const category = existing ? { ...draft, createdAt: existing.createdAt, updatedAt: now.toISOString() } : { ...draft, createdAt: now.toISOString() };
251
+ if (existing)
252
+ state.categories[index] = category;
253
+ else
254
+ state.categories.push(category);
255
+ await this.save(state);
256
+ return { category, created: !existing };
257
+ });
258
+ }
259
+ /** Adds definitions (the starter set, or another account's), leaving any category with the same name as it is. */
260
+ async addAll(drafts, now = new Date()) {
261
+ return this.withLock(async () => {
262
+ const state = await this.load();
263
+ const added = [];
264
+ const skipped = [];
265
+ for (const draft of drafts) {
266
+ if (state.categories.some((category) => key(category.name) === key(draft.name)) || state.categories.length >= MAX_CATEGORIES) {
267
+ skipped.push(draft.name);
268
+ continue;
269
+ }
270
+ state.categories.push({ ...validateCategory({ ...draft }), createdAt: now.toISOString() });
271
+ added.push(draft.name);
272
+ }
273
+ await this.save(state);
274
+ return { added, skipped };
275
+ });
276
+ }
277
+ /**
278
+ * A correction: mail from `sender` belongs in `category`. Its weight goes up by one and the sender's weight towards
279
+ * every other category down by one, so the latest correction wins over an older one.
280
+ */
281
+ async learn(sender, category, now = new Date()) {
282
+ return this.withLock(async () => {
283
+ const state = await this.load();
284
+ const who = sender.trim().toLowerCase();
285
+ const target = key(category);
286
+ const mine = state.learned.filter((entry) => entry.sender === who);
287
+ const others = state.learned.filter((entry) => entry.sender !== who);
288
+ const next = mine.map((entry) => (entry.category === target ? entry : { ...entry, weight: entry.weight - 1 })).filter((entry) => entry.weight > 0);
289
+ const current = next.find((entry) => entry.category === target);
290
+ if (current)
291
+ Object.assign(current, { weight: current.weight + 1, at: now.toISOString() });
292
+ else
293
+ next.push({ sender: who, category: target, weight: 1, at: now.toISOString() });
294
+ // The oldest corrections make room first.
295
+ state.learned = [...others, ...next].sort((a, b) => a.at.localeCompare(b.at)).slice(-MAX_LEARNED);
296
+ await this.save(state);
297
+ return next;
298
+ });
299
+ }
300
+ async withLock(fn) {
301
+ await mkdir(dirname(this.storePath), { recursive: true, mode: 0o700 });
302
+ return withFileLock(this.storePath, fn);
303
+ }
304
+ async load() {
305
+ try {
306
+ const parsed = JSON.parse(await readRegularFile(this.storePath));
307
+ return { categories: Array.isArray(parsed.categories) ? parsed.categories : [], learned: Array.isArray(parsed.learned) ? parsed.learned : [] };
308
+ }
309
+ catch (error) {
310
+ if (isFileNotFound(error))
311
+ return { categories: [], learned: [] };
312
+ setAsideCorruptStore(this.storePath, error, logger, "CategoryService");
313
+ return { categories: [], learned: [] };
314
+ }
315
+ }
316
+ async save(state) {
317
+ await writeFileAtomic(this.storePath, JSON.stringify(state, null, 2));
318
+ }
319
+ }
320
+ //# sourceMappingURL=category-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-service.js","sourceRoot":"","sources":["../../src/services/category-service.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"commitment-service.d.ts","sourceRoot":"","sources":["../../src/services/commitment-service.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,CAAC;AACpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,mBAAmB,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0GAA0G;IAC1G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,YAAY,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,EAEvC;IAEK,GAAG,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,mBAAmB,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,OAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAwB3K;IAEK,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,OAAa,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAUvG;IAEK,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAElC;IAED,wFAAwF;IAClF,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAE5C;YAEa,QAAQ;YAKR,IAAI;YAWJ,IAAI;CAGnB"}
1
+ {"version":3,"file":"commitment-service.d.ts","sourceRoot":"","sources":["../../src/services/commitment-service.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,CAAC;AACpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,mBAAmB,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0GAA0G;IAC1G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,YAAY,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,EAEvC;IAEK,GAAG,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,mBAAmB,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,OAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CA6B3K;IAEK,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,OAAa,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAUvG;IAEK,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAElC;IAED,wFAAwF;IAClF,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAE5C;YAEa,QAAQ;YAKR,IAAI;YAWJ,IAAI;CAGnB"}
@@ -1,5 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { mkdir, readFile } from "node:fs/promises";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { readRegularFile } from "../utils/regular-file.js";
3
4
  import { dirname, join } from "node:path";
4
5
  import { writeFileAtomic } from "../utils/atomic-write.js";
5
6
  import { isFileNotFound, setAsideCorruptStore } from "../utils/corrupt-store.js";
@@ -36,7 +37,12 @@ export class CommitmentService {
36
37
  createdAt: now.toISOString(),
37
38
  status: "open",
38
39
  };
39
- state.items = [...state.items, item].slice(-MAX_ITEMS);
40
+ state.items = [...state.items, item];
41
+ // At the cap the oldest closed entries go first; an open promise is the point of the ledger.
42
+ while (state.items.length > MAX_ITEMS) {
43
+ const closed = state.items.findIndex((candidate) => candidate.status !== "open");
44
+ state.items.splice(closed === -1 ? 0 : closed, 1);
45
+ }
40
46
  await this.save(state);
41
47
  return item;
42
48
  });
@@ -66,7 +72,7 @@ export class CommitmentService {
66
72
  }
67
73
  async load() {
68
74
  try {
69
- const parsed = JSON.parse(await readFile(this.storePath, "utf8"));
75
+ const parsed = JSON.parse(await readRegularFile(this.storePath));
70
76
  return { items: Array.isArray(parsed.items) ? parsed.items : [] };
71
77
  }
72
78
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"commitment-service.js","sourceRoot":"","sources":["../../src/services/commitment-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commitment-service.js","sourceRoot":"","sources":["../../src/services/commitment-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { ProtonMailConfig } from "../types/index.js";
2
+ import { type Logger } from "../utils/logger.js";
3
+ import { type ParsedVCard } from "../utils/vcard.js";
4
+ export interface ContactRecord {
5
+ id: string;
6
+ /** Lowercased; an address belongs to at most one record. */
7
+ addresses: string[];
8
+ displayName?: string;
9
+ org?: string;
10
+ tags?: string[];
11
+ notes?: string;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ }
15
+ export interface ContactPatch {
16
+ /** null or "" clears it. */
17
+ displayName?: string | null;
18
+ notes?: string | null;
19
+ addTags?: string[];
20
+ removeTags?: string[];
21
+ /** Another address of the same person: its record (if any) is merged into this one. */
22
+ mergeWith?: string;
23
+ /** Split this address out of the person it was merged into. */
24
+ unmerge?: boolean;
25
+ }
26
+ export interface ContactImportOutcome {
27
+ added: number;
28
+ updated: number;
29
+ unchanged: number;
30
+ /** Addresses of a card that names a known person but are not that person's yet (or belong to another one); left out. A file never attaches an address to a person: merging is set_contact's mergeWith. First 20; `conflictCount` is the total. */
31
+ conflicts: string[];
32
+ conflictCount: number;
33
+ /** Cards not imported because the store is full. */
34
+ overLimit: number;
35
+ }
36
+ export declare const MAX_CONTACTS = 10000;
37
+ export declare function requireContactAddress(value: string, field?: string): string;
38
+ export declare class ContactService {
39
+ private readonly config;
40
+ private readonly log;
41
+ private readonly storePath;
42
+ private _lock;
43
+ private identityChecked;
44
+ constructor(config: ProtonMailConfig, log?: Logger);
45
+ list(): Promise<ContactRecord[]>;
46
+ tagsFor(address: string): Promise<string[]>;
47
+ /** Applies the patch to the person `address` belongs to. Returns the record now holding `address` (none when nothing is stored for it) and, after an unmerge, the record it was split from. */
48
+ update(address: string, patch: ContactPatch): Promise<{
49
+ contact?: ContactRecord;
50
+ splitFrom?: ContactRecord;
51
+ }>;
52
+ /** Adds the people of a vCard file. Fills only what is not set yet. A card that names a known person never adds an address to them: a file could otherwise give its own address that person's tags (vip changes the autoresponder). */
53
+ importCards(cards: ParsedVCard[]): Promise<ContactImportOutcome>;
54
+ private withLock;
55
+ private load;
56
+ private loadUnlocked;
57
+ private cleanOrphanedTempFiles;
58
+ private save;
59
+ }
60
+ //# sourceMappingURL=contact-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-service.d.ts","sourceRoot":"","sources":["../../src/services/contact-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAO1D,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAwD,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAO3G,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,kPAAkP;IAClP,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD,eAAO,MAAM,YAAY,QAAS,CAAC;AASnC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAY,GAAG,MAAM,CAI9E;AAgBD,qBAAa,cAAc;IAMvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,eAAe,CAAS;IAEhC,YACmB,MAAM,EAAE,gBAAgB,EACxB,GAAG,GAAE,MAAe,EAGtC;IAEK,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAErC;IAEK,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAIhD;IAED,+LAA+L;IACzL,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,aAAa,CAAC;QAAC,SAAS,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAiElH;IAED,uOAAuO;IACjO,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6CrE;YAGa,QAAQ;YAUR,IAAI;YAIJ,YAAY;YAoBZ,sBAAsB;YAiBtB,IAAI;CAInB"}