emailengine-app 2.69.0 → 2.70.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.
- package/.github/workflows/deploy.yml +6 -3
- package/.github/workflows/release.yaml +2 -0
- package/CHANGELOG.md +19 -0
- package/Gruntfile.js +3 -1
- package/data/google-crawlers.json +1 -1
- package/getswagger.sh +40 -4
- package/gettext-extract.js +163 -0
- package/lib/account.js +73 -47
- package/lib/api-routes/account-routes.js +231 -71
- package/lib/api-routes/blocklist-routes.js +25 -18
- package/lib/api-routes/chat-routes.js +32 -14
- package/lib/api-routes/delivery-test-routes.js +30 -5
- package/lib/api-routes/export-routes.js +27 -2
- package/lib/api-routes/gateway-routes.js +63 -12
- package/lib/api-routes/license-routes.js +18 -4
- package/lib/api-routes/mailbox-routes.js +33 -7
- package/lib/api-routes/message-routes.js +200 -58
- package/lib/api-routes/oauth2-app-routes.js +90 -24
- package/lib/api-routes/outbox-routes.js +16 -4
- package/lib/api-routes/pubsub-routes.js +8 -4
- package/lib/api-routes/route-helpers.js +14 -1
- package/lib/api-routes/settings-routes.js +51 -25
- package/lib/api-routes/stats-routes.js +37 -3
- package/lib/api-routes/submit-routes.js +31 -42
- package/lib/api-routes/template-routes.js +54 -21
- package/lib/api-routes/token-routes.js +67 -67
- package/lib/api-routes/webhook-route-routes.js +37 -8
- package/lib/autodetect-imap-settings.js +0 -2
- package/lib/consts.js +5 -0
- package/lib/email-client/base-client.js +28 -6
- package/lib/email-client/gmail-client.js +119 -112
- package/lib/email-client/imap/subconnection.js +0 -1
- package/lib/email-client/imap/sync-operations.js +1 -1
- package/lib/email-client/imap-client.js +36 -17
- package/lib/email-client/notification-handler.js +1 -4
- package/lib/email-client/outlook-client.js +49 -62
- package/lib/export.js +37 -1
- package/lib/feature-flags.js +2 -2
- package/lib/gateway.js +4 -9
- package/lib/get-raw-email.js +5 -5
- package/lib/imapproxy/imap-core/lib/imap-connection.js +0 -1
- package/lib/logger.js +24 -21
- package/lib/metrics-collector.js +0 -2
- package/lib/oauth2-apps.js +13 -4
- package/lib/outbox.js +24 -40
- package/lib/redis-operations.js +1 -1
- package/lib/schemas.js +403 -83
- package/lib/sentry.js +139 -0
- package/lib/settings.js +9 -3
- package/lib/stream-encrypt.js +1 -1
- package/lib/templates.js +1 -1
- package/lib/tokens.js +5 -3
- package/lib/tools.js +2 -4
- package/lib/ui-routes/account-routes.js +7 -4
- package/lib/ui-routes/admin-config-routes.js +16 -3
- package/lib/ui-routes/oauth-config-routes.js +0 -2
- package/lib/ui-routes/route-helpers.js +0 -2
- package/lib/ui-routes/unsubscribe-routes.js +0 -2
- package/lib/webhooks.js +8 -4
- package/package.json +9 -8
- package/sbom.json +1 -1
- package/server.js +8 -23
- package/static/licenses.html +152 -292
- package/translations/messages.pot +122 -122
- package/update-info.sh +19 -1
- package/views/config/logging.hbs +48 -0
- package/workers/api.js +11 -32
- package/workers/documents.js +2 -22
- package/workers/export.js +16 -50
- package/workers/imap-proxy.js +3 -23
- package/workers/imap.js +2 -22
- package/workers/smtp.js +2 -22
- package/workers/submit.js +6 -24
- package/workers/webhooks.js +2 -22
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
msgid ""
|
|
2
2
|
msgstr ""
|
|
3
3
|
"Content-Type: text/plain; charset=ascii\n"
|
|
4
|
-
"POT-Creation-Date: 2026-06-
|
|
4
|
+
"POT-Creation-Date: 2026-06-11 10:37+0000\n"
|
|
5
5
|
|
|
6
6
|
#: views/error.hbs:4
|
|
7
|
-
#: workers/api.js:
|
|
7
|
+
#: workers/api.js:2940
|
|
8
8
|
msgid "Something went wrong"
|
|
9
9
|
msgstr ""
|
|
10
10
|
|
|
@@ -21,7 +21,7 @@ msgid "Dashboard"
|
|
|
21
21
|
msgstr ""
|
|
22
22
|
|
|
23
23
|
#: views/config/license.hbs:45
|
|
24
|
-
#: lib/ui-routes/oauth-config-routes.js:
|
|
24
|
+
#: lib/ui-routes/oauth-config-routes.js:217
|
|
25
25
|
msgid "%d day"
|
|
26
26
|
msgid_plural "%d days"
|
|
27
27
|
msgstr[0] ""
|
|
@@ -31,48 +31,63 @@ msgstr[1] ""
|
|
|
31
31
|
msgid "Click <a href=\"%s\">here</a> to continue…"
|
|
32
32
|
msgstr ""
|
|
33
33
|
|
|
34
|
-
#: views/
|
|
35
|
-
|
|
34
|
+
#: views/unsubscribe.hbs:3
|
|
35
|
+
#: views/unsubscribe.hbs:62
|
|
36
|
+
#: views/unsubscribe.hbs:85
|
|
37
|
+
msgid "Unsubscribe"
|
|
36
38
|
msgstr ""
|
|
37
39
|
|
|
38
|
-
#: views/
|
|
39
|
-
msgid ""
|
|
40
|
-
"All requested permissions are required for this service to function "
|
|
41
|
-
"properly. Some required permissions were not granted during sign-in."
|
|
40
|
+
#: views/unsubscribe.hbs:5
|
|
41
|
+
msgid "Your email address was unsubscribed."
|
|
42
42
|
msgstr ""
|
|
43
43
|
|
|
44
|
-
#: views/
|
|
45
|
-
msgid "
|
|
44
|
+
#: views/unsubscribe.hbs:7
|
|
45
|
+
msgid "Was this a mistake? Click <a%s>here</a> to re-subscribe."
|
|
46
46
|
msgstr ""
|
|
47
47
|
|
|
48
|
-
#: views/
|
|
49
|
-
msgid ""
|
|
50
|
-
"Please try again and make sure all permission checkboxes are selected on "
|
|
51
|
-
"the Google consent screen."
|
|
48
|
+
#: views/unsubscribe.hbs:15
|
|
49
|
+
msgid "Re-subscribe"
|
|
52
50
|
msgstr ""
|
|
53
51
|
|
|
54
|
-
#: views/
|
|
55
|
-
msgid "
|
|
52
|
+
#: views/unsubscribe.hbs:21
|
|
53
|
+
msgid "Are you sure you want to re-subscribe your email address <em>%s</em>?"
|
|
56
54
|
msgstr ""
|
|
57
55
|
|
|
58
|
-
#: views/
|
|
59
|
-
|
|
56
|
+
#: views/unsubscribe.hbs:32
|
|
57
|
+
#: views/accounts/register/imap-server.hbs:251
|
|
58
|
+
msgid "Close"
|
|
60
59
|
msgstr ""
|
|
61
60
|
|
|
62
|
-
#: views/
|
|
63
|
-
msgid "
|
|
61
|
+
#: views/unsubscribe.hbs:34
|
|
62
|
+
msgid "Subscribe"
|
|
63
|
+
msgstr ""
|
|
64
|
+
|
|
65
|
+
#: views/unsubscribe.hbs:56
|
|
66
|
+
msgid "Subscription resumed"
|
|
67
|
+
msgstr ""
|
|
68
|
+
|
|
69
|
+
#: views/unsubscribe.hbs:58
|
|
70
|
+
msgid "Your email address <em>%s</em> was re-subscribed."
|
|
64
71
|
msgstr ""
|
|
65
72
|
|
|
66
|
-
#: views/accounts/register/imap.hbs:21
|
|
67
73
|
#: views/unsubscribe.hbs:75
|
|
74
|
+
#: views/accounts/register/imap.hbs:21
|
|
68
75
|
msgid "Email address"
|
|
69
76
|
msgstr ""
|
|
70
77
|
|
|
71
|
-
#: views/accounts/register/imap.hbs:27
|
|
72
78
|
#: views/unsubscribe.hbs:81
|
|
79
|
+
#: views/accounts/register/imap.hbs:27
|
|
73
80
|
msgid "Enter your email address"
|
|
74
81
|
msgstr ""
|
|
75
82
|
|
|
83
|
+
#: views/accounts/register/imap.hbs:11
|
|
84
|
+
msgid "Your name"
|
|
85
|
+
msgstr ""
|
|
86
|
+
|
|
87
|
+
#: views/accounts/register/imap.hbs:17
|
|
88
|
+
msgid "Enter your full name"
|
|
89
|
+
msgstr ""
|
|
90
|
+
|
|
76
91
|
#: views/accounts/register/imap.hbs:31
|
|
77
92
|
#: views/accounts/register/imap-server.hbs:36
|
|
78
93
|
#: views/accounts/register/imap-server.hbs:128
|
|
@@ -87,51 +102,28 @@ msgstr ""
|
|
|
87
102
|
msgid "Continue"
|
|
88
103
|
msgstr ""
|
|
89
104
|
|
|
90
|
-
#: views/
|
|
91
|
-
msgid "
|
|
92
|
-
msgstr ""
|
|
93
|
-
|
|
94
|
-
#: views/accounts/register/index.hbs:15
|
|
95
|
-
msgid "Standard IMAP"
|
|
96
|
-
msgstr ""
|
|
97
|
-
|
|
98
|
-
#: views/unsubscribe.hbs:3
|
|
99
|
-
#: views/unsubscribe.hbs:62
|
|
100
|
-
#: views/unsubscribe.hbs:85
|
|
101
|
-
msgid "Unsubscribe"
|
|
102
|
-
msgstr ""
|
|
103
|
-
|
|
104
|
-
#: views/unsubscribe.hbs:5
|
|
105
|
-
msgid "Your email address was unsubscribed."
|
|
106
|
-
msgstr ""
|
|
107
|
-
|
|
108
|
-
#: views/unsubscribe.hbs:7
|
|
109
|
-
msgid "Was this a mistake? Click <a%s>here</a> to re-subscribe."
|
|
110
|
-
msgstr ""
|
|
111
|
-
|
|
112
|
-
#: views/unsubscribe.hbs:15
|
|
113
|
-
msgid "Re-subscribe"
|
|
114
|
-
msgstr ""
|
|
115
|
-
|
|
116
|
-
#: views/unsubscribe.hbs:21
|
|
117
|
-
msgid "Are you sure you want to re-subscribe your email address <em>%s</em>?"
|
|
105
|
+
#: views/oauth-scope-error.hbs:2
|
|
106
|
+
msgid "Insufficient Permissions"
|
|
118
107
|
msgstr ""
|
|
119
108
|
|
|
120
|
-
#: views/
|
|
121
|
-
|
|
122
|
-
|
|
109
|
+
#: views/oauth-scope-error.hbs:8
|
|
110
|
+
msgid ""
|
|
111
|
+
"All requested permissions are required for this service to function "
|
|
112
|
+
"properly. Some required permissions were not granted during sign-in."
|
|
123
113
|
msgstr ""
|
|
124
114
|
|
|
125
|
-
#: views/
|
|
126
|
-
msgid "
|
|
115
|
+
#: views/oauth-scope-error.hbs:12
|
|
116
|
+
msgid "The following permissions were not granted:"
|
|
127
117
|
msgstr ""
|
|
128
118
|
|
|
129
|
-
#: views/
|
|
130
|
-
msgid "
|
|
119
|
+
#: views/oauth-scope-error.hbs:21
|
|
120
|
+
msgid ""
|
|
121
|
+
"Please try again and make sure all permission checkboxes are selected on "
|
|
122
|
+
"the Google consent screen."
|
|
131
123
|
msgstr ""
|
|
132
124
|
|
|
133
|
-
#: views/
|
|
134
|
-
msgid "
|
|
125
|
+
#: views/oauth-scope-error.hbs:27
|
|
126
|
+
msgid "Try Again"
|
|
135
127
|
msgstr ""
|
|
136
128
|
|
|
137
129
|
#: views/accounts/register/imap-server.hbs:19
|
|
@@ -249,149 +241,157 @@ msgstr ""
|
|
|
249
241
|
msgid "Request failed."
|
|
250
242
|
msgstr ""
|
|
251
243
|
|
|
252
|
-
#:
|
|
253
|
-
|
|
254
|
-
#: lib/ui-routes/account-routes.js:399
|
|
255
|
-
#: lib/ui-routes/account-routes.js:434
|
|
256
|
-
#: lib/ui-routes/account-routes.js:549
|
|
257
|
-
#: lib/ui-routes/account-routes.js:596
|
|
258
|
-
#: lib/ui-routes/account-routes.js:843
|
|
259
|
-
#: lib/ui-routes/account-routes.js:879
|
|
260
|
-
msgid "Email Account Setup"
|
|
244
|
+
#: views/accounts/register/index.hbs:2
|
|
245
|
+
msgid "Choose your email account provider"
|
|
261
246
|
msgstr ""
|
|
262
247
|
|
|
263
|
-
#:
|
|
264
|
-
|
|
265
|
-
msgid "Requested page not found"
|
|
248
|
+
#: views/accounts/register/index.hbs:15
|
|
249
|
+
msgid "Standard IMAP"
|
|
266
250
|
msgstr ""
|
|
267
251
|
|
|
268
|
-
#: lib/
|
|
269
|
-
|
|
252
|
+
#: lib/autodetect-imap-settings.js:80
|
|
253
|
+
msgid ""
|
|
254
|
+
"Microsoft has disabled password-based sign-ins (including app passwords) "
|
|
255
|
+
"for Outlook.com, Hotmail.com, and Microsoft 365 email accounts. To "
|
|
256
|
+
"continue, please use the \"Sign in with Microsoft\" button to securely "
|
|
257
|
+
"connect your account."
|
|
258
|
+
msgstr ""
|
|
259
|
+
|
|
260
|
+
#: lib/tools.js:956
|
|
261
|
+
#: lib/ui-routes/unsubscribe-routes.js:28
|
|
270
262
|
msgid "Invalid input"
|
|
271
263
|
msgstr ""
|
|
272
264
|
|
|
273
|
-
#: lib/tools.js:
|
|
265
|
+
#: lib/tools.js:1723
|
|
274
266
|
msgid "Signature validation failed"
|
|
275
267
|
msgstr ""
|
|
276
268
|
|
|
277
|
-
#: lib/tools.js:
|
|
278
|
-
#: lib/tools.js:
|
|
269
|
+
#: lib/tools.js:1732
|
|
270
|
+
#: lib/tools.js:1737
|
|
279
271
|
msgid "Invalid or expired account setup URL"
|
|
280
272
|
msgstr ""
|
|
281
273
|
|
|
282
|
-
#: lib/
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
274
|
+
#: lib/ui-routes/account-routes.js:402
|
|
275
|
+
#: lib/ui-routes/account-routes.js:437
|
|
276
|
+
#: lib/ui-routes/account-routes.js:552
|
|
277
|
+
#: lib/ui-routes/account-routes.js:599
|
|
278
|
+
#: lib/ui-routes/account-routes.js:846
|
|
279
|
+
#: lib/ui-routes/account-routes.js:882
|
|
280
|
+
#: workers/api.js:2158
|
|
281
|
+
#: workers/api.js:2486
|
|
282
|
+
msgid "Email Account Setup"
|
|
283
|
+
msgstr ""
|
|
284
|
+
|
|
285
|
+
#: lib/ui-routes/account-routes.js:462
|
|
286
|
+
#: lib/ui-routes/account-routes.js:495
|
|
287
|
+
#: lib/ui-routes/unsubscribe-routes.js:65
|
|
288
|
+
msgid "Invalid request. Check your input and try again."
|
|
289
|
+
msgstr ""
|
|
290
|
+
|
|
291
|
+
#: lib/ui-routes/account-routes.js:592
|
|
292
|
+
#: lib/ui-routes/account-routes.js:875
|
|
293
|
+
msgid "Couldn't set up account. Try again."
|
|
288
294
|
msgstr ""
|
|
289
295
|
|
|
296
|
+
#: lib/ui-routes/account-routes.js:655
|
|
297
|
+
#: lib/ui-routes/account-routes.js:666
|
|
290
298
|
#: lib/ui-routes/admin-entities-routes.js:2020
|
|
291
|
-
#: lib/ui-routes/account-routes.js:652
|
|
292
|
-
#: lib/ui-routes/account-routes.js:663
|
|
293
299
|
msgid "Server hostname was not found"
|
|
294
300
|
msgstr ""
|
|
295
301
|
|
|
302
|
+
#: lib/ui-routes/account-routes.js:658
|
|
303
|
+
#: lib/ui-routes/account-routes.js:669
|
|
296
304
|
#: lib/ui-routes/admin-entities-routes.js:2023
|
|
297
|
-
#: lib/ui-routes/account-routes.js:655
|
|
298
|
-
#: lib/ui-routes/account-routes.js:666
|
|
299
305
|
msgid "Invalid username or password"
|
|
300
306
|
msgstr ""
|
|
301
307
|
|
|
308
|
+
#: lib/ui-routes/account-routes.js:672
|
|
302
309
|
#: lib/ui-routes/admin-entities-routes.js:2026
|
|
303
|
-
#: lib/ui-routes/account-routes.js:669
|
|
304
310
|
msgid "Authentication credentials were not provided"
|
|
305
311
|
msgstr ""
|
|
306
312
|
|
|
313
|
+
#: lib/ui-routes/account-routes.js:675
|
|
307
314
|
#: lib/ui-routes/admin-entities-routes.js:2029
|
|
308
|
-
#: lib/ui-routes/account-routes.js:672
|
|
309
315
|
msgid "OAuth2 authentication failed"
|
|
310
316
|
msgstr ""
|
|
311
317
|
|
|
318
|
+
#: lib/ui-routes/account-routes.js:678
|
|
319
|
+
#: lib/ui-routes/account-routes.js:682
|
|
312
320
|
#: lib/ui-routes/admin-entities-routes.js:2032
|
|
313
321
|
#: lib/ui-routes/admin-entities-routes.js:2036
|
|
314
|
-
#: lib/ui-routes/account-routes.js:675
|
|
315
|
-
#: lib/ui-routes/account-routes.js:679
|
|
316
322
|
msgid "TLS protocol error"
|
|
317
323
|
msgstr ""
|
|
318
324
|
|
|
325
|
+
#: lib/ui-routes/account-routes.js:686
|
|
319
326
|
#: lib/ui-routes/admin-entities-routes.js:2040
|
|
320
|
-
#: lib/ui-routes/account-routes.js:683
|
|
321
327
|
msgid "Connection timed out"
|
|
322
328
|
msgstr ""
|
|
323
329
|
|
|
330
|
+
#: lib/ui-routes/account-routes.js:689
|
|
324
331
|
#: lib/ui-routes/admin-entities-routes.js:2043
|
|
325
|
-
#: lib/ui-routes/account-routes.js:686
|
|
326
332
|
msgid "Could not connect to server"
|
|
327
333
|
msgstr ""
|
|
328
334
|
|
|
335
|
+
#: lib/ui-routes/account-routes.js:692
|
|
329
336
|
#: lib/ui-routes/admin-entities-routes.js:2046
|
|
330
|
-
#: lib/ui-routes/account-routes.js:689
|
|
331
337
|
msgid "Unexpected server response"
|
|
332
338
|
msgstr ""
|
|
333
339
|
|
|
334
|
-
#: lib/ui-routes/
|
|
335
|
-
|
|
336
|
-
#: lib/ui-routes/unsubscribe-routes.js:67
|
|
337
|
-
msgid "Invalid request. Check your input and try again."
|
|
338
|
-
msgstr ""
|
|
339
|
-
|
|
340
|
-
#: lib/ui-routes/account-routes.js:589
|
|
341
|
-
#: lib/ui-routes/account-routes.js:872
|
|
342
|
-
msgid "Couldn't set up account. Try again."
|
|
340
|
+
#: lib/ui-routes/admin-config-routes.js:144
|
|
341
|
+
msgid "Invalid API key for OpenAI"
|
|
343
342
|
msgstr ""
|
|
344
343
|
|
|
345
|
-
#: lib/ui-routes/oauth-config-routes.js:
|
|
344
|
+
#: lib/ui-routes/oauth-config-routes.js:210
|
|
346
345
|
msgid "Unknown"
|
|
347
346
|
msgstr ""
|
|
348
347
|
|
|
349
|
-
#: lib/ui-routes/oauth-config-routes.js:
|
|
348
|
+
#: lib/ui-routes/oauth-config-routes.js:219
|
|
350
349
|
msgid "Indefinite"
|
|
351
350
|
msgstr ""
|
|
352
351
|
|
|
353
|
-
#: lib/ui-routes/
|
|
354
|
-
msgid "Invalid API key for OpenAI"
|
|
355
|
-
msgstr ""
|
|
356
|
-
|
|
357
|
-
#: lib/ui-routes/route-helpers.js:83
|
|
352
|
+
#: lib/ui-routes/route-helpers.js:81
|
|
358
353
|
msgid "Delegated"
|
|
359
354
|
msgstr ""
|
|
360
355
|
|
|
361
|
-
#: lib/ui-routes/route-helpers.js:
|
|
356
|
+
#: lib/ui-routes/route-helpers.js:82
|
|
362
357
|
msgid "Using credentials from \"%s\""
|
|
363
358
|
msgstr ""
|
|
364
359
|
|
|
365
|
-
#: lib/ui-routes/route-helpers.js:
|
|
360
|
+
#: lib/ui-routes/route-helpers.js:132
|
|
366
361
|
msgid ""
|
|
367
362
|
"Connection timed out. This usually occurs if you are behind a firewall or "
|
|
368
363
|
"connecting to the wrong port."
|
|
369
364
|
msgstr ""
|
|
370
365
|
|
|
371
|
-
#: lib/ui-routes/route-helpers.js:
|
|
366
|
+
#: lib/ui-routes/route-helpers.js:135
|
|
372
367
|
msgid "The server unexpectedly closed the connection."
|
|
373
368
|
msgstr ""
|
|
374
369
|
|
|
375
|
-
#: lib/ui-routes/route-helpers.js:
|
|
370
|
+
#: lib/ui-routes/route-helpers.js:138
|
|
376
371
|
msgid ""
|
|
377
372
|
"The server unexpectedly closed the connection. This usually happens when "
|
|
378
373
|
"attempting to connect to a TLS port without TLS enabled."
|
|
379
374
|
msgstr ""
|
|
380
375
|
|
|
381
|
-
#: lib/ui-routes/route-helpers.js:
|
|
376
|
+
#: lib/ui-routes/route-helpers.js:143
|
|
382
377
|
msgid ""
|
|
383
378
|
"The server refused the connection. This typically occurs if the server is "
|
|
384
379
|
"not running, is overloaded, or you are connecting to the wrong host or port."
|
|
385
380
|
msgstr ""
|
|
386
381
|
|
|
387
|
-
#: lib/ui-routes/unsubscribe-routes.js:
|
|
388
|
-
#: lib/ui-routes/unsubscribe-routes.js:
|
|
389
|
-
#: lib/ui-routes/unsubscribe-routes.js:
|
|
390
|
-
#: lib/ui-routes/unsubscribe-routes.js:
|
|
382
|
+
#: lib/ui-routes/unsubscribe-routes.js:38
|
|
383
|
+
#: lib/ui-routes/unsubscribe-routes.js:156
|
|
384
|
+
#: lib/ui-routes/unsubscribe-routes.js:173
|
|
385
|
+
#: lib/ui-routes/unsubscribe-routes.js:209
|
|
391
386
|
msgid "Subscription Management"
|
|
392
387
|
msgstr ""
|
|
393
388
|
|
|
394
|
-
#: lib/ui-routes/unsubscribe-routes.js:
|
|
395
|
-
#: lib/ui-routes/unsubscribe-routes.js:
|
|
389
|
+
#: lib/ui-routes/unsubscribe-routes.js:167
|
|
390
|
+
#: lib/ui-routes/unsubscribe-routes.js:202
|
|
396
391
|
msgid "Couldn't process request. Try again."
|
|
397
|
-
msgstr ""
|
|
392
|
+
msgstr ""
|
|
393
|
+
|
|
394
|
+
#: workers/api.js:2939
|
|
395
|
+
#: workers/api.js:3054
|
|
396
|
+
msgid "Requested page not found"
|
|
397
|
+
msgstr ""
|
package/update-info.sh
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
|
|
3
|
-
|
|
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
|
{
|
package/views/config/logging.hbs
CHANGED
|
@@ -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">
|
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
|
|
44
|
-
|
|
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');
|
|
@@ -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(
|
|
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
|
|
|
@@ -2659,7 +2639,8 @@ Include your token in requests using one of these methods:
|
|
|
2659
2639
|
|
|
2660
2640
|
plugins: {
|
|
2661
2641
|
'hapi-swagger': {
|
|
2662
|
-
produces: ['text/event-stream']
|
|
2642
|
+
produces: ['text/event-stream'],
|
|
2643
|
+
responses: errorResponses(401, 403, 429, 500)
|
|
2663
2644
|
}
|
|
2664
2645
|
},
|
|
2665
2646
|
|
|
@@ -2684,7 +2665,7 @@ Include your token in requests using one of these methods:
|
|
|
2684
2665
|
skip: (request /*, h*/) => {
|
|
2685
2666
|
let tags = (request.route && request.route.settings && request.route.settings.tags) || [];
|
|
2686
2667
|
|
|
2687
|
-
if (tags.includes('api') || tags.includes('metrics') || tags.includes('external')) {
|
|
2668
|
+
if (tags.includes('api') || tags.includes('scope:metrics') || tags.includes('static') || tags.includes('external')) {
|
|
2688
2669
|
return true;
|
|
2689
2670
|
}
|
|
2690
2671
|
|
|
@@ -3055,9 +3036,7 @@ Include your token in requests using one of these methods:
|
|
|
3055
3036
|
|
|
3056
3037
|
async handler(request, h) {
|
|
3057
3038
|
const renderedMetrics = await call({ cmd: 'metrics', timeout: request.headers['x-ee-timeout'] });
|
|
3058
|
-
|
|
3059
|
-
response.type('text/plain');
|
|
3060
|
-
return renderedMetrics;
|
|
3039
|
+
return h.response(renderedMetrics).type('text/plain');
|
|
3061
3040
|
},
|
|
3062
3041
|
options: {
|
|
3063
3042
|
tags: ['scope:metrics'],
|
package/workers/documents.js
CHANGED
|
@@ -14,28 +14,8 @@ const GB_COLLECT_DELAY = 6 * 3600 * 1000; // 6h
|
|
|
14
14
|
const GB_FAILURE_DELAY = 3 * 1000;
|
|
15
15
|
const GB_EMPTY_DELAY = 10 * 1000;
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
Bugsnag.start({
|
|
20
|
-
apiKey: readEnvValue('BUGSNAG_API_KEY'),
|
|
21
|
-
appVersion: packageData.version,
|
|
22
|
-
logger: {
|
|
23
|
-
debug(...args) {
|
|
24
|
-
logger.debug({ msg: args.shift(), worker: 'documents', source: 'bugsnag', args: args.length ? args : undefined });
|
|
25
|
-
},
|
|
26
|
-
info(...args) {
|
|
27
|
-
logger.debug({ msg: args.shift(), worker: 'documents', source: 'bugsnag', args: args.length ? args : undefined });
|
|
28
|
-
},
|
|
29
|
-
warn(...args) {
|
|
30
|
-
logger.warn({ msg: args.shift(), worker: 'documents', source: 'bugsnag', args: args.length ? args : undefined });
|
|
31
|
-
},
|
|
32
|
-
error(...args) {
|
|
33
|
-
logger.error({ msg: args.shift(), worker: 'documents', source: 'bugsnag', args: args.length ? args : undefined });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
logger.notifyError = Bugsnag.notify.bind(Bugsnag);
|
|
38
|
-
}
|
|
17
|
+
const { initSentry } = require('../lib/sentry');
|
|
18
|
+
initSentry('documents');
|
|
39
19
|
|
|
40
20
|
const { redis, queueConf } = require('../lib/db');
|
|
41
21
|
const { Worker } = require('bullmq');
|