proton-mail-bridge-client 2.15.0 → 2.15.2

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 (39) hide show
  1. package/README.md +3 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +9 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/scripts/install-claude-desktop.d.ts +1 -0
  6. package/dist/scripts/install-claude-desktop.d.ts.map +1 -1
  7. package/dist/scripts/install-claude-desktop.js +26 -7
  8. package/dist/scripts/install-claude-desktop.js.map +1 -1
  9. package/dist/services/imap-errors.d.ts +6 -0
  10. package/dist/services/imap-errors.d.ts.map +1 -0
  11. package/dist/services/imap-errors.js +135 -0
  12. package/dist/services/imap-errors.js.map +1 -0
  13. package/dist/services/simple-imap-service.d.ts +2 -5
  14. package/dist/services/simple-imap-service.d.ts.map +1 -1
  15. package/dist/services/simple-imap-service.js +2 -133
  16. package/dist/services/simple-imap-service.js.map +1 -1
  17. package/dist/tools/bulk.d.ts +1 -1
  18. package/dist/tools/bulk.d.ts.map +1 -1
  19. package/dist/tools/bulk.js +9 -8
  20. package/dist/tools/bulk.js.map +1 -1
  21. package/dist/tools/definitions.d.ts +16 -0
  22. package/dist/tools/definitions.d.ts.map +1 -1
  23. package/dist/tools/definitions.js +4 -0
  24. package/dist/tools/definitions.js.map +1 -1
  25. package/dist/tools/folders.js +3 -3
  26. package/dist/tools/folders.js.map +1 -1
  27. package/dist/tools/merge.d.ts +2 -0
  28. package/dist/tools/merge.d.ts.map +1 -1
  29. package/dist/tools/merge.js +5 -1
  30. package/dist/tools/merge.js.map +1 -1
  31. package/dist/tools/message-actions.d.ts.map +1 -1
  32. package/dist/tools/message-actions.js +50 -17
  33. package/dist/tools/message-actions.js.map +1 -1
  34. package/dist/tools/reading.js +2 -2
  35. package/dist/tools/reading.js.map +1 -1
  36. package/dist/tools/rules.d.ts.map +1 -1
  37. package/dist/tools/rules.js +5 -0
  38. package/dist/tools/rules.js.map +1 -1
  39. package/package.json +1 -1
@@ -8,6 +8,8 @@ import { logger } from "../utils/logger.js";
8
8
  import { ensureAccountIdentityMatches } from "../utils/account-identity.js";
9
9
  import { tlsOptionsFor } from "../utils/tls.js";
10
10
  import { DEFAULT_PDF_MAX_MB, DEFAULT_PDF_MAX_PAGES, extractPdfText, looksLikePdf, PdfTextError } from "../utils/pdf-text.js";
11
+ import { describeImapError, isLikelyAuthenticationError, isLikelyCertificateError, isLikelyConnectionError, isLikelyTlsMismatchError } from "./imap-errors.js";
12
+ export { describeImapError, isLikelyAuthenticationError, isLikelyCertificateError, isLikelyConnectionError, isLikelyTlsMismatchError };
11
13
  const FETCH_SUMMARY_QUERY = {
12
14
  uid: true,
13
15
  flags: true,
@@ -185,139 +187,6 @@ const LABEL_RESOLVE_BUDGET_MS = 15_000;
185
187
  // mutation would raise via assertMailboxUidValidity, rather than drifting into
186
188
  // two subtly different phrasings for what is the same underlying failure.
187
189
  export const UID_VALIDITY_MISMATCH_ERROR = "This email reference is from before the mailbox changed (folder was recreated or migrated) and no longer points to a valid message. Re-fetch the email (e.g. via search_emails or get_emails) to get a current reference.";
188
- function collectErrorText(error) {
189
- const values = [];
190
- if (error instanceof Error) {
191
- values.push(error.message);
192
- values.push(error.name);
193
- const maybeResponseText = error.responseText;
194
- if (typeof maybeResponseText === "string") {
195
- values.push(maybeResponseText);
196
- }
197
- const maybeCode = error.code;
198
- if (typeof maybeCode === "string") {
199
- values.push(maybeCode);
200
- }
201
- }
202
- else if (typeof error === "string") {
203
- values.push(error);
204
- }
205
- else if (typeof error === "object" && error !== null) {
206
- const maybeMessage = error.message;
207
- const maybeCode = error.code;
208
- const maybeResponse = error.response;
209
- if (typeof maybeMessage === "string") {
210
- values.push(maybeMessage);
211
- }
212
- if (typeof maybeCode === "string") {
213
- values.push(maybeCode);
214
- }
215
- if (typeof maybeResponse === "string") {
216
- values.push(maybeResponse);
217
- }
218
- }
219
- return values.join(" ").toLowerCase();
220
- }
221
- // imapflow throws a generic Error("Command failed") for every IMAP NO/BAD
222
- // response (mailbox create/rename/delete, move, flag change, ...) — the
223
- // server's actual reason (e.g. Bridge rejecting a reserved folder name)
224
- // lives in the non-standard `.responseText` property, never in `.message`.
225
- // Left alone, every one of these surfaces as an unhelpful "Command failed"
226
- // with no clue why. Surface both. Found live: create_label "Starred" failed
227
- // with just "Command failed" instead of Bridge's actual rejection reason.
228
- export function describeImapError(error) {
229
- if (!(error instanceof Error) || !error.message) {
230
- return undefined;
231
- }
232
- const responseText = error.responseText;
233
- if (typeof responseText === "string" && responseText.trim() && !error.message.includes(responseText.trim())) {
234
- return `${error.message}: ${responseText.trim()}`;
235
- }
236
- return error.message;
237
- }
238
- export function isLikelyAuthenticationError(error) {
239
- if (!error) {
240
- return false;
241
- }
242
- const haystack = collectErrorText(error);
243
- if (!haystack) {
244
- return false;
245
- }
246
- return [
247
- "auth",
248
- "login failed",
249
- "incorrect login credentials",
250
- "invalid credentials",
251
- "authentication failed",
252
- "no such user",
253
- "too many login attempts",
254
- ].some((needle) => haystack.includes(needle));
255
- }
256
- // Distinguishes "Bridge isn't running / wrong host-port" from other failures, so the
257
- // caller can point the user at Bridge instead of a generic "internal error occurred".
258
- // A TLS handshake attempted against a plaintext/STARTTLS-only port (or the
259
- // reverse — plaintext against an implicit-TLS port, though that direction
260
- // more often just surfaces as a bare ECONNRESET, already covered by
261
- // isLikelyConnectionError, and can't be reliably told apart from a genuinely
262
- // unreachable Bridge from the error text alone) surfaces as Node/OpenSSL's
263
- // own EPROTO error. Neither isLikelyAuthenticationError nor
264
- // isLikelyConnectionError matched this, so a PROTONMAIL_*_SECURE/port
265
- // mismatch (Bridge assigns essentially random ports per install — confirmed
266
- // live) produced a bare "connection failed" with zero diagnosis, despite
267
- // run_doctor's own description promising a classified cause for every
268
- // connection failure.
269
- export function isLikelyTlsMismatchError(error) {
270
- if (!error) {
271
- return false;
272
- }
273
- const haystack = collectErrorText(error);
274
- if (!haystack) {
275
- return false;
276
- }
277
- return ["eproto", "wrong version number", "ssl routines", "wrong_version_number"].some((needle) => haystack.includes(needle));
278
- }
279
- // A certificate Node does not trust: Bridge's own is self-signed, so a host reached by another name than localhost
280
- // fails this way until the certificate is pinned (PROTONMAIL_TLS_CA_FILE) or the host is listed.
281
- export function isLikelyCertificateError(error) {
282
- if (!error) {
283
- return false;
284
- }
285
- const haystack = collectErrorText(error);
286
- if (!haystack) {
287
- return false;
288
- }
289
- return [
290
- "self-signed certificate",
291
- "self signed certificate",
292
- "depth_zero_self_signed_cert",
293
- "unable to verify the first certificate",
294
- "unable_to_verify_leaf_signature",
295
- "unable to get local issuer certificate",
296
- "certificate has expired",
297
- "err_tls_cert_altname_invalid",
298
- "does not match certificate",
299
- ].some((needle) => haystack.includes(needle));
300
- }
301
- export function isLikelyConnectionError(error) {
302
- if (!error) {
303
- return false;
304
- }
305
- const haystack = collectErrorText(error);
306
- if (!haystack) {
307
- return false;
308
- }
309
- return [
310
- "econnrefused",
311
- "enotfound",
312
- "etimedout",
313
- "ehostunreach",
314
- "econnreset",
315
- "connect etimedout",
316
- "connection closed",
317
- "connection timed out",
318
- "timed out while connecting",
319
- ].some((needle) => haystack.includes(needle));
320
- }
321
190
  // Proton Bridge exposes "views" over mail that already lives in a real folder: All Mail
322
191
  // (every message), Labels/* (a message per label it carries) and Starred. A search over
323
192
  // "every folder" that includes them scans the same messages several times — measured live