emailengine-app 2.68.1 → 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.
Files changed (95) hide show
  1. package/.github/workflows/deploy.yml +8 -3
  2. package/.github/workflows/release.yaml +6 -0
  3. package/CHANGELOG.md +59 -0
  4. package/Gruntfile.js +3 -1
  5. package/config/default.toml +2 -0
  6. package/data/google-crawlers.json +7 -1
  7. package/getswagger.sh +40 -4
  8. package/gettext-extract.js +163 -0
  9. package/lib/account.js +135 -72
  10. package/lib/api-routes/account-routes.js +684 -106
  11. package/lib/api-routes/blocklist-routes.js +344 -0
  12. package/lib/api-routes/chat-routes.js +32 -14
  13. package/lib/api-routes/delivery-test-routes.js +346 -0
  14. package/lib/api-routes/export-routes.js +28 -14
  15. package/lib/api-routes/gateway-routes.js +427 -0
  16. package/lib/api-routes/license-routes.js +156 -0
  17. package/lib/api-routes/mailbox-routes.js +344 -0
  18. package/lib/api-routes/message-routes.js +221 -187
  19. package/lib/api-routes/oauth2-app-routes.js +697 -0
  20. package/lib/api-routes/outbox-routes.js +185 -0
  21. package/lib/api-routes/pubsub-routes.js +102 -0
  22. package/lib/api-routes/route-helpers.js +58 -0
  23. package/lib/api-routes/settings-routes.js +357 -0
  24. package/lib/api-routes/stats-routes.js +111 -0
  25. package/lib/api-routes/submit-routes.js +461 -0
  26. package/lib/api-routes/template-routes.js +60 -75
  27. package/lib/api-routes/token-routes.js +297 -0
  28. package/lib/api-routes/webhook-route-routes.js +181 -0
  29. package/lib/autodetect-imap-settings.js +0 -2
  30. package/lib/consts.js +5 -0
  31. package/lib/email-client/base-client.js +28 -6
  32. package/lib/email-client/gmail-client.js +133 -112
  33. package/lib/email-client/imap/mailbox.js +34 -11
  34. package/lib/email-client/imap/subconnection.js +20 -13
  35. package/lib/email-client/imap/sync-operations.js +131 -3
  36. package/lib/email-client/imap-client.js +152 -75
  37. package/lib/email-client/notification-handler.js +1 -4
  38. package/lib/email-client/outlook-client.js +134 -75
  39. package/lib/export.js +97 -20
  40. package/lib/feature-flags.js +2 -2
  41. package/lib/gateway.js +4 -9
  42. package/lib/get-raw-email.js +5 -5
  43. package/lib/imapproxy/imap-core/lib/commands/starttls.js +18 -0
  44. package/lib/imapproxy/imap-core/lib/imap-command.js +6 -1
  45. package/lib/imapproxy/imap-core/lib/imap-connection.js +106 -24
  46. package/lib/imapproxy/imap-core/lib/imap-server.js +24 -0
  47. package/lib/imapproxy/imap-core/lib/imap-stream.js +26 -0
  48. package/lib/logger.js +24 -21
  49. package/lib/message-port-stream.js +113 -16
  50. package/lib/metrics-collector.js +0 -2
  51. package/lib/oauth2-apps.js +13 -4
  52. package/lib/outbox.js +24 -40
  53. package/lib/redis-operations.js +1 -1
  54. package/lib/reject-worker-calls.js +42 -0
  55. package/lib/routes-ui.js +37 -8778
  56. package/lib/schemas.js +429 -84
  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 +70 -4
  63. package/lib/ui-routes/account-routes.js +45 -212
  64. package/lib/ui-routes/admin-config-routes.js +928 -489
  65. package/lib/ui-routes/admin-entities-routes.js +1 -0
  66. package/lib/ui-routes/auth-routes.js +1339 -0
  67. package/lib/ui-routes/dashboard-routes.js +188 -0
  68. package/lib/ui-routes/document-store-routes.js +800 -0
  69. package/lib/ui-routes/export-routes.js +217 -0
  70. package/lib/ui-routes/internals-routes.js +354 -0
  71. package/lib/ui-routes/network-config-routes.js +759 -0
  72. package/lib/ui-routes/{oauth-routes.js → oauth-config-routes.js} +369 -91
  73. package/lib/ui-routes/route-helpers.js +314 -0
  74. package/lib/ui-routes/smtp-test-routes.js +236 -0
  75. package/lib/ui-routes/unsubscribe-routes.js +232 -0
  76. package/lib/webhook-request.js +36 -0
  77. package/lib/webhooks.js +8 -4
  78. package/package.json +13 -12
  79. package/sbom.json +1 -1
  80. package/server.js +222 -39
  81. package/static/licenses.html +160 -300
  82. package/translations/messages.pot +112 -132
  83. package/update-info.sh +19 -1
  84. package/views/config/logging.hbs +48 -0
  85. package/views/dashboard.hbs +7 -26
  86. package/views/internals/index.hbs +15 -0
  87. package/views/tokens/index.hbs +9 -0
  88. package/workers/api.js +200 -4424
  89. package/workers/documents.js +2 -22
  90. package/workers/export.js +103 -104
  91. package/workers/imap-proxy.js +3 -23
  92. package/workers/imap.js +32 -36
  93. package/workers/smtp.js +2 -22
  94. package/workers/submit.js +26 -35
  95. package/workers/webhooks.js +9 -43
@@ -0,0 +1,188 @@
1
+ 'use strict';
2
+
3
+ // Admin UI routes for the dashboard and standalone informational pages: the main
4
+ // /admin dashboard (stats counters), the Swagger API reference, the legal page, and the
5
+ // upgrade page. Extracted verbatim from lib/routes-ui.js.
6
+
7
+ const { getStats, getBoolean, readEnvValue } = require('../tools');
8
+ const settings = require('../settings');
9
+ const { redis } = require('../db');
10
+ const { ALLOWED_REDIS_LATENCY } = require('../consts');
11
+
12
+ function init(args) {
13
+ const { server, call } = args;
14
+
15
+ server.route({
16
+ method: 'GET',
17
+ path: '/admin',
18
+ async handler(request, h) {
19
+ let stats = await getStats(redis, call, request.query.seconds || 24 * 3600);
20
+
21
+ let counterList = [
22
+ {
23
+ key: 'events:messageNew',
24
+ title: 'New emails',
25
+ color: 'primary',
26
+ icon: 'envelope',
27
+ comment: 'Detected new emails in IMAP mailboxes.'
28
+ },
29
+ {
30
+ key: 'webhooks:success',
31
+ title: 'Webhooks sent',
32
+ color: 'primary',
33
+ icon: 'network-wired',
34
+ comment: 'Count of successfully delivered webhooks.'
35
+ },
36
+ {
37
+ key: 'webhooks:fail',
38
+ title: 'Webhooks failed',
39
+ color: 'danger',
40
+ icon: 'network-wired',
41
+ comment: 'Count of webhooks that failed to deliver.'
42
+ },
43
+ {
44
+ key: 'submit:success',
45
+ title: 'Emails sent',
46
+ color: 'primary',
47
+ icon: 'mail-bulk',
48
+ comment: 'Count of emails sent to MTA servers.'
49
+ },
50
+ {
51
+ key: 'submit:fail',
52
+ title: 'Emails rejected',
53
+ color: 'danger',
54
+ icon: 'mail-bulk',
55
+ comment: 'Count of emails rejected by MTA servers.'
56
+ },
57
+ {
58
+ key: 'apiCall:success',
59
+ title: 'Successful API calls',
60
+ color: 'primary',
61
+ icon: 'file-code',
62
+ comment: 'Successful API calls with positive responses.'
63
+ },
64
+ {
65
+ key: 'apiCall:fail',
66
+ title: 'Failed API calls',
67
+ color: 'danger',
68
+ icon: 'file-code',
69
+ comment: 'API calls that returned error responses.'
70
+ }
71
+ ];
72
+
73
+ for (let counter of counterList) {
74
+ counter.value = stats.counters[counter.key] || 0;
75
+ }
76
+
77
+ let hasAccounts = !!stats.accounts;
78
+ stats.connectedAccounts = (stats.connections.connected || 0) + (stats.connections.syncing || 0);
79
+
80
+ let defaultLocale = (await settings.get('locale')) || 'en';
81
+
82
+ let nrFormatter;
83
+
84
+ let nrFormatterOpts = {
85
+ style: 'decimal'
86
+ };
87
+
88
+ try {
89
+ nrFormatter = new Intl.NumberFormat(defaultLocale, nrFormatterOpts);
90
+ } catch (err) {
91
+ nrFormatter = new Intl.NumberFormat('en-US', nrFormatterOpts);
92
+ }
93
+
94
+ return h.view(
95
+ 'dashboard',
96
+ {
97
+ pageTitle: 'Dashboard',
98
+ menuDashboard: true,
99
+ stats,
100
+ counterList,
101
+ hasAccounts,
102
+
103
+ redisWarnings: stats.redisWarnings || [],
104
+
105
+ redisPing: {
106
+ key: 'redisPing',
107
+ title: 'Redis Latency',
108
+ color: typeof stats.redisPing !== 'number' ? 'warning' : stats.redisPing < ALLOWED_REDIS_LATENCY ? 'success' : 'danger',
109
+ icon: 'clock',
110
+ comment: 'How many milliseconds does it take to run a Redis command',
111
+ value: typeof stats.redisPing !== 'number' ? '\u2013' : nrFormatter.format(stats.redisPing / 1000000)
112
+ }
113
+ },
114
+ {
115
+ layout: 'app'
116
+ }
117
+ );
118
+ }
119
+ });
120
+
121
+ server.route({
122
+ method: 'GET',
123
+ path: '/admin/swagger',
124
+ async handler(request, h) {
125
+ return h.view(
126
+ 'swagger/index',
127
+ {
128
+ pageTitle: 'API Reference',
129
+ menuSwagger: true,
130
+ injectHtmlHead: `<link rel="stylesheet" type="text/css" href="/admin/swagger/resources/swagger-ui.css" />
131
+ <style>
132
+ .download-url-wrapper,
133
+ .topbar {
134
+ display: none !important;
135
+ }
136
+ </style>`
137
+ },
138
+ {
139
+ layout: 'app'
140
+ }
141
+ );
142
+ }
143
+ });
144
+
145
+ server.route({
146
+ method: 'GET',
147
+ path: '/admin/legal',
148
+ async handler(request, h) {
149
+ return h.view(
150
+ 'legal',
151
+ {
152
+ pageTitle: 'Legal',
153
+ menuLegal: true
154
+ },
155
+ {
156
+ layout: 'app'
157
+ }
158
+ );
159
+ }
160
+ });
161
+
162
+ server.route({
163
+ method: 'GET',
164
+ path: '/admin/upgrade',
165
+ async handler(request, h) {
166
+ const isDO = getBoolean(readEnvValue('EENGINE_DOCEAN'));
167
+ const isScriptInstalled = getBoolean(readEnvValue('EENGINE_INSTALL_SCRIPT'));
168
+ const isRender = typeof readEnvValue('RENDER_SERVICE_SLUG') === 'string' && readEnvValue('RENDER_SERVICE_SLUG');
169
+ const isGeneral = !isDO && !isRender && !isScriptInstalled;
170
+
171
+ return h.view(
172
+ 'upgrade',
173
+ {
174
+ pageTitle: 'Upgrade',
175
+ isDO,
176
+ isRender,
177
+ isScriptInstalled,
178
+ isGeneral
179
+ },
180
+ {
181
+ layout: 'app'
182
+ }
183
+ );
184
+ }
185
+ });
186
+ }
187
+
188
+ module.exports = init;