emailengine-app 2.69.0 → 2.71.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 (97) hide show
  1. package/.github/workflows/deploy.yml +6 -3
  2. package/.github/workflows/release.yaml +2 -0
  3. package/.github/workflows/test.yml +73 -12
  4. package/.ncurc.js +3 -3
  5. package/CHANGELOG.md +37 -0
  6. package/Gruntfile.js +21 -23
  7. package/bin/emailengine.js +8 -1
  8. package/config/default.toml +5 -0
  9. package/config/test.toml +5 -0
  10. package/data/google-crawlers.json +1 -1
  11. package/getswagger.sh +44 -4
  12. package/gettext-extract.js +163 -0
  13. package/lib/account.js +104 -72
  14. package/lib/api-routes/account-routes.js +231 -71
  15. package/lib/api-routes/blocklist-routes.js +25 -18
  16. package/lib/api-routes/chat-routes.js +32 -14
  17. package/lib/api-routes/delivery-test-routes.js +30 -5
  18. package/lib/api-routes/export-routes.js +27 -2
  19. package/lib/api-routes/gateway-routes.js +63 -12
  20. package/lib/api-routes/license-routes.js +18 -4
  21. package/lib/api-routes/mailbox-routes.js +33 -7
  22. package/lib/api-routes/message-routes.js +291 -145
  23. package/lib/api-routes/oauth2-app-routes.js +90 -24
  24. package/lib/api-routes/outbox-routes.js +16 -4
  25. package/lib/api-routes/pubsub-routes.js +8 -4
  26. package/lib/api-routes/route-helpers.js +14 -1
  27. package/lib/api-routes/settings-routes.js +51 -25
  28. package/lib/api-routes/stats-routes.js +37 -3
  29. package/lib/api-routes/submit-routes.js +31 -42
  30. package/lib/api-routes/template-routes.js +54 -21
  31. package/lib/api-routes/token-routes.js +67 -67
  32. package/lib/api-routes/webhook-route-routes.js +37 -8
  33. package/lib/autodetect-imap-settings.js +0 -2
  34. package/lib/consts.js +5 -0
  35. package/lib/document-store.js +22 -1
  36. package/lib/email-client/base-client.js +31 -8
  37. package/lib/email-client/gmail-client.js +119 -112
  38. package/lib/email-client/imap/mailbox.js +2 -2
  39. package/lib/email-client/imap/subconnection.js +0 -1
  40. package/lib/email-client/imap/sync-operations.js +1 -1
  41. package/lib/email-client/imap-client.js +36 -17
  42. package/lib/email-client/notification-handler.js +3 -6
  43. package/lib/email-client/outlook-client.js +49 -62
  44. package/lib/export.js +49 -1
  45. package/lib/feature-flags.js +8 -2
  46. package/lib/gateway.js +4 -9
  47. package/lib/get-raw-email.js +5 -5
  48. package/lib/imapproxy/imap-core/lib/imap-connection.js +0 -1
  49. package/lib/license-beacon.js +367 -0
  50. package/lib/logger.js +35 -22
  51. package/lib/metrics-collector.js +0 -2
  52. package/lib/oauth2-apps.js +13 -4
  53. package/lib/outbox.js +24 -40
  54. package/lib/redis-operations.js +1 -1
  55. package/lib/routes-ui.js +2 -1
  56. package/lib/schemas.js +403 -83
  57. package/lib/sentry.js +139 -0
  58. package/lib/settings.js +9 -3
  59. package/lib/stream-encrypt.js +1 -1
  60. package/lib/templates.js +1 -1
  61. package/lib/tokens.js +5 -3
  62. package/lib/tools.js +28 -6
  63. package/lib/ui-routes/account-routes.js +7 -4
  64. package/lib/ui-routes/admin-config-routes.js +20 -6
  65. package/lib/ui-routes/document-store-routes.js +7 -1
  66. package/lib/ui-routes/oauth-config-routes.js +0 -2
  67. package/lib/ui-routes/route-helpers.js +0 -2
  68. package/lib/ui-routes/unsubscribe-routes.js +0 -2
  69. package/lib/webhooks.js +8 -4
  70. package/package.json +23 -19
  71. package/sbom.json +1 -1
  72. package/server.js +38 -31
  73. package/static/licenses.html +171 -391
  74. package/translations/de.mo +0 -0
  75. package/translations/de.po +154 -142
  76. package/translations/et.mo +0 -0
  77. package/translations/et.po +129 -131
  78. package/translations/fr.mo +0 -0
  79. package/translations/fr.po +133 -136
  80. package/translations/ja.mo +0 -0
  81. package/translations/ja.po +126 -129
  82. package/translations/messages.pot +107 -107
  83. package/translations/nl.mo +0 -0
  84. package/translations/nl.po +128 -130
  85. package/translations/pl.mo +0 -0
  86. package/translations/pl.po +125 -128
  87. package/update-info.sh +19 -1
  88. package/views/config/logging.hbs +48 -0
  89. package/views/dashboard.hbs +22 -0
  90. package/workers/api.js +33 -37
  91. package/workers/documents.js +2 -22
  92. package/workers/export.js +73 -92
  93. package/workers/imap-proxy.js +3 -23
  94. package/workers/imap.js +2 -22
  95. package/workers/smtp.js +2 -22
  96. package/workers/submit.js +6 -24
  97. package/workers/webhooks.js +2 -22
@@ -1,7 +1,7 @@
1
1
  msgid ""
2
2
  msgstr ""
3
3
  "Project-Id-Version: \n"
4
- "POT-Creation-Date: 2026-03-31 08:47+0000\n"
4
+ "POT-Creation-Date: 2026-06-15 18:35+0000\n"
5
5
  "PO-Revision-Date: \n"
6
6
  "Last-Translator: \n"
7
7
  "Language-Team: \n"
@@ -13,7 +13,7 @@ msgstr ""
13
13
  "|| n%100>14) ? 1 : 2);\n"
14
14
  "X-Generator: Poedit 3.9\n"
15
15
 
16
- #: views/error.hbs:4 workers/api.js:7103
16
+ #: views/error.hbs:4 workers/api.js:2957
17
17
  msgid "Something went wrong"
18
18
  msgstr "Ups... Coś poszło nie tak"
19
19
 
@@ -29,7 +29,7 @@ msgstr "Wstecz"
29
29
  msgid "Dashboard"
30
30
  msgstr "Pulpit"
31
31
 
32
- #: views/config/license.hbs:45 lib/routes-ui.js:2497
32
+ #: views/config/license.hbs:45 lib/ui-routes/oauth-config-routes.js:217
33
33
  msgid "%d day"
34
34
  msgid_plural "%d days"
35
35
  msgstr[0] "%d dzień"
@@ -40,6 +40,34 @@ msgstr[2] "%d dni"
40
40
  msgid "Click <a href=\"%s\">here</a> to continue&mldr;"
41
41
  msgstr "Kliknij <a href=\"%s\">tutaj</a>, aby kontynuować&mldr;"
42
42
 
43
+ #: views/oauth-scope-error.hbs:2
44
+ msgid "Insufficient Permissions"
45
+ msgstr "Niewystarczające uprawnienia"
46
+
47
+ #: views/oauth-scope-error.hbs:8
48
+ msgid ""
49
+ "All requested permissions are required for this service to function "
50
+ "properly. Some required permissions were not granted during sign-in."
51
+ msgstr ""
52
+ "Wszystkie wymagane uprawnienia są niezbędne do prawidłowego działania tej "
53
+ "usługi. Niektóre z nich nie zostały przyznane podczas logowania."
54
+
55
+ #: views/oauth-scope-error.hbs:12
56
+ msgid "The following permissions were not granted:"
57
+ msgstr "Nie przyznano następujących uprawnień:"
58
+
59
+ #: views/oauth-scope-error.hbs:21
60
+ msgid ""
61
+ "Please try again and make sure all permission checkboxes are selected on the "
62
+ "Google consent screen."
63
+ msgstr ""
64
+ "Spróbuj ponownie i upewnij się, że na ekranie zgody Google zaznaczone są "
65
+ "wszystkie pola wyboru dotyczące uprawnień."
66
+
67
+ #: views/oauth-scope-error.hbs:27
68
+ msgid "Try Again"
69
+ msgstr "Spróbuj ponownie"
70
+
43
71
  #: views/unsubscribe.hbs:3 views/unsubscribe.hbs:62 views/unsubscribe.hbs:85
44
72
  msgid "Unsubscribe"
45
73
  msgstr "Wypisz się"
@@ -85,34 +113,6 @@ msgstr "Adres e-mail"
85
113
  msgid "Enter your email address"
86
114
  msgstr "Wprowadź swój adres e-mail"
87
115
 
88
- #: views/oauth-scope-error.hbs:2
89
- msgid "Insufficient Permissions"
90
- msgstr "Niewystarczające uprawnienia"
91
-
92
- #: views/oauth-scope-error.hbs:8
93
- msgid ""
94
- "All requested permissions are required for this service to function properly. "
95
- "Some required permissions were not granted during sign-in."
96
- msgstr ""
97
- "Wszystkie wymagane uprawnienia są niezbędne do prawidłowego działania tej "
98
- "usługi. Niektóre z nich nie zostały przyznane podczas logowania."
99
-
100
- #: views/oauth-scope-error.hbs:12
101
- msgid "The following permissions were not granted:"
102
- msgstr "Nie przyznano następujących uprawnień:"
103
-
104
- #: views/oauth-scope-error.hbs:21
105
- msgid ""
106
- "Please try again and make sure all permission checkboxes are selected on the "
107
- "Google consent screen."
108
- msgstr ""
109
- "Spróbuj ponownie i upewnij się, że na ekranie zgody Google zaznaczone są "
110
- "wszystkie pola wyboru dotyczące uprawnień."
111
-
112
- #: views/oauth-scope-error.hbs:27
113
- msgid "Try Again"
114
- msgstr "Spróbuj ponownie"
115
-
116
116
  #: views/accounts/register/imap.hbs:11
117
117
  msgid "Your name"
118
118
  msgstr "Twoje imię"
@@ -190,8 +190,8 @@ msgstr "TLS dla IMAP"
190
190
 
191
191
  #: views/accounts/register/imap-server.hbs:100
192
192
  msgid ""
193
- "TLS (also known as SSL) is usually only needed when using port 993. For other "
194
- "ports EmailEngine falls back to using STARTTLS based encryption."
193
+ "TLS (also known as SSL) is usually only needed when using port 993. For "
194
+ "other ports EmailEngine falls back to using STARTTLS based encryption."
195
195
  msgstr ""
196
196
  "TLS (znany również jako SSL) jest zwykle potrzebny tylko w przypadku "
197
197
  "korzystania z portu 993. W przypadku innych portów EmailEngine powraca do "
@@ -212,8 +212,8 @@ msgstr "TLS dla SMTP"
212
212
 
213
213
  #: views/accounts/register/imap-server.hbs:191
214
214
  msgid ""
215
- "TLS (also known as SSL) is usually only needed when using port 465. For other "
216
- "ports EmailEngine falls back to using STARTTLS based encryption."
215
+ "TLS (also known as SSL) is usually only needed when using port 465. For "
216
+ "other ports EmailEngine falls back to using STARTTLS based encryption."
217
217
  msgstr ""
218
218
  "TLS (znany również jako SSL) jest zwykle potrzebny tylko w przypadku "
219
219
  "korzystania z portu 465. W przypadku innych portów EmailEngine powraca do "
@@ -264,150 +264,147 @@ msgstr "Nie udało się połączyć z serwerem SMTP"
264
264
  msgid "Request failed."
265
265
  msgstr "Żądanie nie powiodło się."
266
266
 
267
- #: lib/routes-ui.js:384 lib/ui-routes/account-routes.js:60
268
- msgid "Delegated"
269
- msgstr "Delegowany"
270
-
271
- #: lib/routes-ui.js:385 lib/ui-routes/account-routes.js:61
272
- msgid "Using credentials from \"%s\""
273
- msgstr "Używanie poświadczeń z \"%s\""
274
-
275
- #: lib/routes-ui.js:435 lib/ui-routes/account-routes.js:111
276
- msgid ""
277
- "Connection timed out. This usually occurs if you are behind a firewall or "
278
- "connecting to the wrong port."
279
- msgstr ""
280
- "Przekroczono limit czasu połączenia. Zwykle dzieje się tak, gdy użytkownik "
281
- "znajduje się za zaporą sieciową lub łączy się z niewłaściwym portem."
282
-
283
- #: lib/routes-ui.js:438 lib/ui-routes/account-routes.js:114
284
- msgid "The server unexpectedly closed the connection."
285
- msgstr "Serwer nieoczekiwanie zamknął połączenie."
286
-
287
- #: lib/routes-ui.js:441 lib/ui-routes/account-routes.js:117
288
- msgid ""
289
- "The server unexpectedly closed the connection. This usually happens when "
290
- "attempting to connect to a TLS port without TLS enabled."
291
- msgstr ""
292
- "Serwer nieoczekiwanie zamknął połączenie. Zwykle dzieje się tak podczas próby "
293
- "połączenia z portem TLS bez włączonego protokołu TLS."
294
-
295
- #: lib/routes-ui.js:446 lib/ui-routes/account-routes.js:122
267
+ #: lib/autodetect-imap-settings.js:80
296
268
  msgid ""
297
- "The server refused the connection. This typically occurs if the server is not "
298
- "running, is overloaded, or you are connecting to the wrong host or port."
269
+ "Microsoft has disabled password-based sign-ins (including app passwords) for "
270
+ "Outlook.com, Hotmail.com, and Microsoft 365 email accounts. To continue, "
271
+ "please use the \"Sign in with Microsoft\" button to securely connect your "
272
+ "account."
299
273
  msgstr ""
300
- "Serwer odmówił połączenia. Zwykle dzieje się tak, gdy serwer nie działa, jest "
301
- "przeciążony lub łączysz się z niewłaściwym hostem lub portem."
274
+ "Firma Microsoft wyłączyła logowanie oparte na hasłach (w tym hasłach "
275
+ "aplikacji) dla kont e-mail w usługach Outlook.com, Hotmail.com i Microsoft "
276
+ "365. Aby kontynuować, użyj przycisku \"Zaloguj się za pomocą Microsoft\", "
277
+ "aby bezpiecznie połączyć swoje konto."
302
278
 
303
- #: lib/routes-ui.js:573
304
- msgid "Invalid API key for OpenAI"
305
- msgstr "Nieprawidłowy klucz API dla OpenAI"
279
+ #: lib/tools.js:975 lib/ui-routes/unsubscribe-routes.js:28
280
+ msgid "Invalid input"
281
+ msgstr "Nieprawidłowe dane wejściowe"
306
282
 
307
- #: lib/routes-ui.js:2490
308
- msgid "Unknown"
309
- msgstr "Nieznany"
283
+ #: lib/tools.js:1742
284
+ msgid "Signature validation failed"
285
+ msgstr "Walidacja podpisu nie powiodła się"
310
286
 
311
- #: lib/routes-ui.js:2499
312
- msgid "Indefinite"
313
- msgstr "Na czas nieokreślony"
287
+ #: lib/tools.js:1751 lib/tools.js:1756
288
+ msgid "Invalid or expired account setup URL"
289
+ msgstr "Nieprawidłowy lub wygasły adres URL konfiguracji konta"
314
290
 
315
- #: lib/routes-ui.js:5133 lib/routes-ui.js:5168 lib/routes-ui.js:5283
316
- #: lib/routes-ui.js:5330 lib/routes-ui.js:5577 lib/routes-ui.js:5613
317
- #: workers/api.js:2279 workers/api.js:2607 lib/ui-routes/account-routes.js:554
318
- #: lib/ui-routes/account-routes.js:590 lib/ui-routes/account-routes.js:707
319
- #: lib/ui-routes/account-routes.js:754 lib/ui-routes/account-routes.js:1003
320
- #: lib/ui-routes/account-routes.js:1039
291
+ #: lib/ui-routes/account-routes.js:402 lib/ui-routes/account-routes.js:437
292
+ #: lib/ui-routes/account-routes.js:552 lib/ui-routes/account-routes.js:599
293
+ #: lib/ui-routes/account-routes.js:846 lib/ui-routes/account-routes.js:882
294
+ #: workers/api.js:2158 workers/api.js:2486
321
295
  msgid "Email Account Setup"
322
296
  msgstr "Konfiguracja konta e-mail"
323
297
 
324
- #: lib/routes-ui.js:5193 lib/routes-ui.js:5226 lib/routes-ui.js:8186
325
- #: lib/ui-routes/account-routes.js:615 lib/ui-routes/account-routes.js:649
298
+ #: lib/ui-routes/account-routes.js:462 lib/ui-routes/account-routes.js:495
299
+ #: lib/ui-routes/unsubscribe-routes.js:65
326
300
  msgid "Invalid request. Check your input and try again."
327
301
  msgstr "Nieprawidłowe żądanie. Sprawdź wprowadzone dane i spróbuj ponownie."
328
302
 
329
- #: lib/routes-ui.js:5386 lib/routes-ui.js:5397
330
- #: lib/ui-routes/account-routes.js:811 lib/ui-routes/account-routes.js:822
303
+ #: lib/ui-routes/account-routes.js:592 lib/ui-routes/account-routes.js:875
304
+ msgid "Couldn't set up account. Try again."
305
+ msgstr "Nie udało się założyć konta. Spróbuj ponownie."
306
+
307
+ #: lib/ui-routes/account-routes.js:655 lib/ui-routes/account-routes.js:666
331
308
  #: lib/ui-routes/admin-entities-routes.js:2020
332
309
  msgid "Server hostname was not found"
333
310
  msgstr "Nie znaleziono nazwy hosta serwera"
334
311
 
335
- #: lib/routes-ui.js:5389 lib/routes-ui.js:5400
336
- #: lib/ui-routes/account-routes.js:814 lib/ui-routes/account-routes.js:825
312
+ #: lib/ui-routes/account-routes.js:658 lib/ui-routes/account-routes.js:669
337
313
  #: lib/ui-routes/admin-entities-routes.js:2023
338
314
  msgid "Invalid username or password"
339
315
  msgstr "Nieprawidłowa nazwa użytkownika lub hasło"
340
316
 
341
- #: lib/routes-ui.js:5403 lib/ui-routes/account-routes.js:828
317
+ #: lib/ui-routes/account-routes.js:672
342
318
  #: lib/ui-routes/admin-entities-routes.js:2026
343
319
  msgid "Authentication credentials were not provided"
344
320
  msgstr "Nie podano danych uwierzytelniających"
345
321
 
346
- #: lib/routes-ui.js:5406 lib/ui-routes/account-routes.js:831
322
+ #: lib/ui-routes/account-routes.js:675
347
323
  #: lib/ui-routes/admin-entities-routes.js:2029
348
324
  msgid "OAuth2 authentication failed"
349
325
  msgstr "Uwierzytelnianie OAuth2 nie powiodło się"
350
326
 
351
- #: lib/routes-ui.js:5409 lib/routes-ui.js:5413
352
- #: lib/ui-routes/account-routes.js:834 lib/ui-routes/account-routes.js:838
327
+ #: lib/ui-routes/account-routes.js:678 lib/ui-routes/account-routes.js:682
353
328
  #: lib/ui-routes/admin-entities-routes.js:2032
354
329
  #: lib/ui-routes/admin-entities-routes.js:2036
355
330
  msgid "TLS protocol error"
356
331
  msgstr "Błąd protokołu TLS"
357
332
 
358
- #: lib/routes-ui.js:5417 lib/ui-routes/account-routes.js:842
333
+ #: lib/ui-routes/account-routes.js:686
359
334
  #: lib/ui-routes/admin-entities-routes.js:2040
360
335
  msgid "Connection timed out"
361
336
  msgstr "Przekroczono limit czasu połączenia"
362
337
 
363
- #: lib/routes-ui.js:5420 lib/ui-routes/account-routes.js:845
338
+ #: lib/ui-routes/account-routes.js:689
364
339
  #: lib/ui-routes/admin-entities-routes.js:2043
365
340
  msgid "Could not connect to server"
366
341
  msgstr "Nie można połączyć się z serwerem"
367
342
 
368
- #: lib/routes-ui.js:5423 lib/ui-routes/account-routes.js:848
343
+ #: lib/ui-routes/account-routes.js:692
369
344
  #: lib/ui-routes/admin-entities-routes.js:2046
370
345
  msgid "Unexpected server response"
371
346
  msgstr "Nieoczekiwana odpowiedź serwera"
372
347
 
373
- #: lib/routes-ui.js:8149 lib/tools.js:950
374
- msgid "Invalid input"
375
- msgstr "Nieprawidłowe dane wejściowe"
348
+ #: lib/ui-routes/admin-config-routes.js:145
349
+ msgid "Invalid API key for OpenAI"
350
+ msgstr "Nieprawidłowy klucz API dla OpenAI"
376
351
 
377
- #: lib/routes-ui.js:8159 lib/routes-ui.js:8277 lib/routes-ui.js:8294
378
- #: lib/routes-ui.js:8330
379
- msgid "Subscription Management"
380
- msgstr "Zarządzanie subskrypcjami"
352
+ #: lib/ui-routes/oauth-config-routes.js:210
353
+ msgid "Unknown"
354
+ msgstr "Nieznany"
381
355
 
382
- #: workers/api.js:7102 workers/api.js:7219
383
- msgid "Requested page not found"
384
- msgstr "Nie znaleziono żądanej strony"
356
+ #: lib/ui-routes/oauth-config-routes.js:219
357
+ msgid "Indefinite"
358
+ msgstr "Na czas nieokreślony"
385
359
 
386
- #: lib/tools.js:1653
387
- msgid "Signature validation failed"
388
- msgstr "Walidacja podpisu nie powiodła się"
360
+ #: lib/ui-routes/route-helpers.js:81
361
+ msgid "Delegated"
362
+ msgstr "Delegowany"
389
363
 
390
- #: lib/tools.js:1662 lib/tools.js:1667
391
- msgid "Invalid or expired account setup URL"
392
- msgstr "Nieprawidłowy lub wygasły adres URL konfiguracji konta"
364
+ #: lib/ui-routes/route-helpers.js:82
365
+ msgid "Using credentials from \"%s\""
366
+ msgstr "Używanie poświadczeń z \"%s\""
393
367
 
394
- #: lib/autodetect-imap-settings.js:80
368
+ #: lib/ui-routes/route-helpers.js:132
395
369
  msgid ""
396
- "Microsoft has disabled password-based sign-ins (including app passwords) for "
397
- "Outlook.com, Hotmail.com, and Microsoft 365 email accounts. To continue, "
398
- "please use the \"Sign in with Microsoft\" button to securely connect your "
399
- "account."
370
+ "Connection timed out. This usually occurs if you are behind a firewall or "
371
+ "connecting to the wrong port."
400
372
  msgstr ""
401
- "Firma Microsoft wyłączyła logowanie oparte na hasłach (w tym hasłach "
402
- "aplikacji) dla kont e-mail w usługach Outlook.com, Hotmail.com i Microsoft "
403
- "365. Aby kontynuować, użyj przycisku \"Zaloguj się za pomocą Microsoft\", aby "
404
- "bezpiecznie połączyć swoje konto."
373
+ "Przekroczono limit czasu połączenia. Zwykle dzieje się tak, gdy użytkownik "
374
+ "znajduje się za zaporą sieciową lub łączy się z niewłaściwym portem."
405
375
 
406
- #: lib/ui-routes/account-routes.js:747 lib/ui-routes/account-routes.js:1032
407
- msgid "Couldn't set up account. Try again."
408
- msgstr "Nie udało się założyć konta. Spróbuj ponownie."
376
+ #: lib/ui-routes/route-helpers.js:135
377
+ msgid "The server unexpectedly closed the connection."
378
+ msgstr "Serwer nieoczekiwanie zamknął połączenie."
379
+
380
+ #: lib/ui-routes/route-helpers.js:138
381
+ msgid ""
382
+ "The server unexpectedly closed the connection. This usually happens when "
383
+ "attempting to connect to a TLS port without TLS enabled."
384
+ msgstr ""
385
+ "Serwer nieoczekiwanie zamknął połączenie. Zwykle dzieje się tak podczas "
386
+ "próby połączenia z portem TLS bez włączonego protokołu TLS."
409
387
 
410
- #, fuzzy
411
- #~| msgid "Failed to process request"
412
- #~ msgid "Couldn't process request. Try again."
413
- #~ msgstr "Nie udało się przetworzyć żądania"
388
+ #: lib/ui-routes/route-helpers.js:143
389
+ msgid ""
390
+ "The server refused the connection. This typically occurs if the server is "
391
+ "not running, is overloaded, or you are connecting to the wrong host or port."
392
+ msgstr ""
393
+ "Serwer odmówił połączenia. Zwykle dzieje się tak, gdy serwer nie działa, "
394
+ "jest przeciążony lub łączysz się z niewłaściwym hostem lub portem."
395
+
396
+ #: lib/ui-routes/unsubscribe-routes.js:38
397
+ #: lib/ui-routes/unsubscribe-routes.js:156
398
+ #: lib/ui-routes/unsubscribe-routes.js:173
399
+ #: lib/ui-routes/unsubscribe-routes.js:209
400
+ msgid "Subscription Management"
401
+ msgstr "Zarządzanie subskrypcjami"
402
+
403
+ #: lib/ui-routes/unsubscribe-routes.js:167
404
+ #: lib/ui-routes/unsubscribe-routes.js:202
405
+ msgid "Couldn't process request. Try again."
406
+ msgstr "Nie udało się przetworzyć żądania. Spróbuj ponownie."
407
+
408
+ #: workers/api.js:2956 workers/api.js:3071
409
+ msgid "Requested page not found"
410
+ msgstr "Nie znaleziono żądanej strony"
package/update-info.sh CHANGED
@@ -1,6 +1,24 @@
1
1
  #!/bin/sh
2
2
 
3
- COMMIT_HASH=$(cat .git/refs/heads/master)
3
+ # Resolve the commit hash for version-info.json:
4
+ # 1. EE_COMMIT_HASH is the explicit override, set by the deploy workflow and
5
+ # by release builds that run from a git export without a .git directory
6
+ # 2. git rev-parse works in any normal checkout, also when refs are packed;
7
+ # the toplevel check makes sure the hash comes from this repository and
8
+ # not from an unrelated parent repository when this directory is not a
9
+ # git repository itself
10
+ # 3. the plain ref file is the fallback for the Docker image build, which
11
+ # only copies .git/refs/heads/master into the build context
12
+ if [ -n "$EE_COMMIT_HASH" ]; then
13
+ COMMIT_HASH="$EE_COMMIT_HASH"
14
+ elif [ "$(git rev-parse --show-toplevel 2>/dev/null)" = "$(pwd -P)" ] && git rev-parse HEAD >/dev/null 2>&1; then
15
+ COMMIT_HASH=$(git rev-parse HEAD)
16
+ elif [ -f .git/refs/heads/master ]; then
17
+ COMMIT_HASH=$(cat .git/refs/heads/master)
18
+ else
19
+ COMMIT_HASH=""
20
+ fi
21
+
4
22
  TIMESTAMP=$(node -e 'console.log(Date.now())')
5
23
  cat >version-info.json <<EOL
6
24
  {
@@ -49,6 +49,54 @@
49
49
  </div>
50
50
  </div>
51
51
 
52
+ <div class="card mb-4">
53
+ <div class="card-header py-3">
54
+ <h6 class="m-0 font-weight-bold text-primary">Error Reporting</h6>
55
+ </div>
56
+ <div class="card-body">
57
+
58
+ {{#if sentryEnvManaged}}
59
+ <div class="alert alert-info">Error reporting is currently managed by the <code>SENTRY_DSN</code>
60
+ environment variable. The settings below are ignored until that variable is removed.</div>
61
+ {{/if}}
62
+
63
+ <div class="form-group form-check">
64
+
65
+ <div class="text-muted float-right code-link">[<a href="/admin/swagger#/Settings/postV1Settings"
66
+ target="_blank" rel="noopener noreferrer">sentryEnabled</a>]</div>
67
+
68
+ <input type="checkbox" class="form-check-input {{#if errors.sentryEnabled}}is-invalid{{/if}}"
69
+ id="settingsSentryEnabled" name="sentryEnabled" {{#if values.sentryEnabled}}checked{{/if}}
70
+ {{#if sentryEnvManaged}}disabled{{/if}} />
71
+ <label class="form-check-label" for="settingsSentryEnabled">Report Unhandled Errors to Sentry</label>
72
+ {{#if errors.sentryEnabled}}
73
+ <span class="invalid-feedback">{{errors.sentryEnabled}}</span>
74
+ {{/if}}
75
+ <small class="form-text text-muted">Send unhandled errors to a Sentry server. Reports include stack
76
+ traces, account IDs, and error details, but never credentials or message content. Changes apply
77
+ within a minute - no restart needed.</small>
78
+ </div>
79
+
80
+ <div class="form-group">
81
+
82
+ <div class="text-muted float-right code-link">[<a href="/admin/swagger#/Settings/postV1Settings"
83
+ target="_blank" rel="noopener noreferrer">sentryDsn</a>]</div>
84
+
85
+ <label for="settingsSentryDsn">Sentry DSN</label>
86
+ <input type="text" class="form-control {{#if errors.sentryDsn}}is-invalid{{/if}}"
87
+ id="settingsSentryDsn" name="sentryDsn" placeholder="https://public-key@sentry.example.com/1"
88
+ value="{{values.sentryDsn}}" {{#if sentryEnvManaged}}disabled{{/if}} />
89
+ {{#if errors.sentryDsn}}
90
+ <span class="invalid-feedback">{{errors.sentryDsn}}</span>
91
+ {{/if}}
92
+ <small class="form-text text-muted">Leave empty to send reports to the Sentry instance run by the
93
+ EmailEngine developers (sentry.emailengine.dev). Enabling this temporarily during a support case
94
+ helps to debug problems with your installation. Set your own DSN to keep reports
95
+ in-house.</small>
96
+ </div>
97
+ </div>
98
+ </div>
99
+
52
100
  <div class="mb-4">
53
101
  <button type="submit" class="btn btn-primary btn-icon-split">
54
102
  <span class="icon text-white-50">
@@ -24,6 +24,28 @@
24
24
  </div>
25
25
  {{/each}}
26
26
 
27
+ {{#if documentStoreUnavailable}}
28
+ <div class="card border-left-danger mt-4">
29
+ <div class="card-body">
30
+ <div class="row no-gutters align-items-center">
31
+ <div class="col mr-2">
32
+ <div class="text-xs font-weight-bold text-danger text-uppercase mb-1">Document Store unavailable</div>
33
+ <p class="mb-0">The Document Store is enabled in the EmailEngine settings, but the feature is not
34
+ available because EmailEngine was not started with the Document Store enabled. The deprecated
35
+ Document Store only runs when started with the <code>--documentStore.enabled</code> command line
36
+ flag or the <code>EENGINE_DOCUMENT_STORE_ENABLED=true</code> environment variable. Until then the
37
+ document store worker is not running and all Document Store API and configuration endpoints
38
+ return 404. Either restart EmailEngine with the flag, or disable the <code>documentStoreEnabled</code>
39
+ setting to clear this warning.</p>
40
+ </div>
41
+ <div class="col-auto">
42
+ <i class="fas fa-database fa-2x text-gray-300"></i>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ {{/if}}
48
+
27
49
 
28
50
  {{#unless hasAccounts}}
29
51
 
package/workers/api.js CHANGED
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- // NB! This file is processed by gettext parser and can not use newer syntax like ?.
4
-
5
3
  const { parentPort, workerData } = require('worker_threads');
6
4
 
7
5
  const packageData = require('../package.json');
@@ -40,28 +38,8 @@ const {
40
38
  } = require('../lib/tools');
41
39
  const { matchIp, detectAutomatedRequest } = require('../lib/utils/network');
42
40
 
43
- const Bugsnag = require('@bugsnag/js');
44
- if (readEnvValue('BUGSNAG_API_KEY')) {
45
- Bugsnag.start({
46
- apiKey: readEnvValue('BUGSNAG_API_KEY'),
47
- appVersion: packageData.version,
48
- logger: {
49
- debug(...args) {
50
- logger.debug({ msg: args.shift(), worker: 'api', source: 'bugsnag', args: args.length ? args : undefined });
51
- },
52
- info(...args) {
53
- logger.debug({ msg: args.shift(), worker: 'api', source: 'bugsnag', args: args.length ? args : undefined });
54
- },
55
- warn(...args) {
56
- logger.warn({ msg: args.shift(), worker: 'api', source: 'bugsnag', args: args.length ? args : undefined });
57
- },
58
- error(...args) {
59
- logger.error({ msg: args.shift(), worker: 'api', source: 'bugsnag', args: args.length ? args : undefined });
60
- }
61
- }
62
- });
63
- logger.notifyError = Bugsnag.notify.bind(Bugsnag);
64
- }
41
+ const { initSentry } = require('../lib/sentry');
42
+ initSentry('api');
65
43
 
66
44
  const Hapi = require('@hapi/hapi');
67
45
  const Boom = require('@hapi/boom');
@@ -89,7 +67,7 @@ const { Account } = require('../lib/account');
89
67
  const settings = require('../lib/settings');
90
68
 
91
69
  const getSecret = require('../lib/get-secret');
92
- const { getESClient } = require('../lib/document-store');
70
+ const { getESClient, documentStoreFeatureEnabled } = require('../lib/document-store');
93
71
 
94
72
  const routesUi = require('../lib/routes-ui');
95
73
 
@@ -135,7 +113,7 @@ const deliveryTestRoutes = require('../lib/api-routes/delivery-test-routes');
135
113
  const blocklistRoutes = require('../lib/api-routes/blocklist-routes');
136
114
  const submitRoutes = require('../lib/api-routes/submit-routes');
137
115
 
138
- const { imapSchema, smtpSchema, oauth2Schema, accountIdSchema, headerTimeoutSchema } = require('../lib/schemas');
116
+ const { imapSchema, smtpSchema, oauth2Schema, accountIdSchema, headerTimeoutSchema, errorResponses } = require('../lib/schemas');
139
117
 
140
118
  const OAuth2ProviderSchema = Joi.string()
141
119
  .valid(...Object.keys(OAUTH_PROVIDERS))
@@ -145,9 +123,11 @@ const OAuth2ProviderSchema = Joi.string()
145
123
  .label('OAuth2Provider');
146
124
 
147
125
  const AccountTypeSchema = Joi.string()
148
- .valid(...['imap'].concat(Object.keys(OAUTH_PROVIDERS)).concat('oauth2'))
126
+ .valid(...['imap'].concat(Object.keys(OAUTH_PROVIDERS)).concat(['oauth2', 'delegated', 'sending', 'invalid']))
149
127
  .example('outlook')
150
- .description('Account type')
128
+ .description(
129
+ 'Account type: "imap" for IMAP accounts, an OAuth2 provider name for OAuth2 accounts, "oauth2" when the OAuth2 application is missing, "delegated" for delegated accounts, "sending" for send-only accounts, "invalid" when delegation cannot be resolved'
130
+ )
151
131
  .required()
152
132
  .label('AccountType');
153
133
 
@@ -2558,8 +2538,10 @@ Include your token in requests using one of these methods:
2558
2538
  // setup template routes
2559
2539
  await templateRoutes({ server, call, CORS_CONFIG });
2560
2540
 
2561
- // setup "chat with email" routes
2562
- await chatRoutes({ server, call, CORS_CONFIG });
2541
+ // setup "chat with email" routes (deprecated Document Store feature; only when enabled)
2542
+ if (documentStoreFeatureEnabled) {
2543
+ await chatRoutes({ server, call, CORS_CONFIG });
2544
+ }
2563
2545
 
2564
2546
  // setup account CRUD routes
2565
2547
  await accountRoutes({
@@ -2582,7 +2564,8 @@ Include your token in requests using one of these methods:
2582
2564
  CORS_CONFIG,
2583
2565
  MAX_ATTACHMENT_SIZE,
2584
2566
  MAX_BODY_SIZE,
2585
- MAX_PAYLOAD_TIMEOUT
2567
+ MAX_PAYLOAD_TIMEOUT,
2568
+ documentStoreFeatureEnabled
2586
2569
  });
2587
2570
 
2588
2571
  // setup export routes
@@ -2659,7 +2642,8 @@ Include your token in requests using one of these methods:
2659
2642
 
2660
2643
  plugins: {
2661
2644
  'hapi-swagger': {
2662
- produces: ['text/event-stream']
2645
+ produces: ['text/event-stream'],
2646
+ responses: errorResponses(401, 403, 429, 500)
2663
2647
  }
2664
2648
  },
2665
2649
 
@@ -2684,7 +2668,7 @@ Include your token in requests using one of these methods:
2684
2668
  skip: (request /*, h*/) => {
2685
2669
  let tags = (request.route && request.route.settings && request.route.settings.tags) || [];
2686
2670
 
2687
- if (tags.includes('api') || tags.includes('metrics') || tags.includes('external')) {
2671
+ if (tags.includes('api') || tags.includes('scope:metrics') || tags.includes('static') || tags.includes('external')) {
2688
2672
  return true;
2689
2673
  }
2690
2674
 
@@ -2754,6 +2738,10 @@ Include your token in requests using one of these methods:
2754
2738
  let systemAlerts = [];
2755
2739
  let authData;
2756
2740
 
2741
+ // Deprecated Document Store: enabled in settings but unavailable because EmailEngine
2742
+ // was not started with the document store gate (--documentStore.enabled / EENGINE_DOCUMENT_STORE_ENABLED).
2743
+ let documentStoreUnavailable = !documentStoreFeatureEnabled && !!showDocumentStore;
2744
+
2757
2745
  switch (request.auth.artifacts && request.auth.artifacts.provider) {
2758
2746
  case 'okta': {
2759
2747
  let profile = request.auth.artifacts.profile || {};
@@ -2880,6 +2868,15 @@ Include your token in requests using one of these methods:
2880
2868
  });
2881
2869
  }
2882
2870
 
2871
+ if (documentStoreUnavailable) {
2872
+ systemAlerts.push({
2873
+ url: '/admin',
2874
+ level: 'danger',
2875
+ icon: 'database',
2876
+ message: `The Document Store is enabled in settings but unavailable. Start EmailEngine with the document store gate to use it, or disable the setting.`
2877
+ });
2878
+ }
2879
+
2883
2880
  if (consts.EE_DOCKER_LEGACY) {
2884
2881
  systemAlerts.push({
2885
2882
  url: 'https://emailengine.app/docker',
@@ -2913,7 +2910,8 @@ Include your token in requests using one of these methods:
2913
2910
  embeddedTemplateHeader,
2914
2911
  embeddedTemplateHtmlHead,
2915
2912
  currentYear: new Date().getFullYear(),
2916
- showDocumentStore,
2913
+ showDocumentStore: documentStoreFeatureEnabled && showDocumentStore,
2914
+ documentStoreUnavailable,
2917
2915
  updateBrowserInfo: !serviceUrl || !language || !timezone,
2918
2916
 
2919
2917
  // Suppress large banner warnings when EENGINE_DISABLE_SETUP_WARNINGS is set
@@ -3055,9 +3053,7 @@ Include your token in requests using one of these methods:
3055
3053
 
3056
3054
  async handler(request, h) {
3057
3055
  const renderedMetrics = await call({ cmd: 'metrics', timeout: request.headers['x-ee-timeout'] });
3058
- const response = h.response('success');
3059
- response.type('text/plain');
3060
- return renderedMetrics;
3056
+ return h.response(renderedMetrics).type('text/plain');
3061
3057
  },
3062
3058
  options: {
3063
3059
  tags: ['scope:metrics'],