emailengine-app 2.68.0 → 2.69.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 (74) hide show
  1. package/.github/codeql/codeql-config.yml +16 -0
  2. package/.github/workflows/codeql.yml +102 -0
  3. package/.github/workflows/deploy.yml +8 -0
  4. package/.github/workflows/release.yaml +4 -0
  5. package/.github/workflows/test.yml +3 -0
  6. package/CHANGELOG.md +49 -0
  7. package/SECURITY.md +80 -0
  8. package/SECURITY.txt +27 -0
  9. package/config/default.toml +2 -0
  10. package/data/google-crawlers.json +13 -1
  11. package/lib/account.js +62 -25
  12. package/lib/api-routes/account-routes.js +493 -75
  13. package/lib/api-routes/blocklist-routes.js +337 -0
  14. package/lib/api-routes/delivery-test-routes.js +321 -0
  15. package/lib/api-routes/export-routes.js +1 -12
  16. package/lib/api-routes/gateway-routes.js +376 -0
  17. package/lib/api-routes/license-routes.js +142 -0
  18. package/lib/api-routes/mailbox-routes.js +318 -0
  19. package/lib/api-routes/message-routes.js +21 -129
  20. package/lib/api-routes/oauth2-app-routes.js +631 -0
  21. package/lib/api-routes/outbox-routes.js +173 -0
  22. package/lib/api-routes/pubsub-routes.js +98 -0
  23. package/lib/api-routes/route-helpers.js +45 -0
  24. package/lib/api-routes/settings-routes.js +331 -0
  25. package/lib/api-routes/stats-routes.js +77 -0
  26. package/lib/api-routes/submit-routes.js +472 -0
  27. package/lib/api-routes/template-routes.js +7 -55
  28. package/lib/api-routes/token-routes.js +297 -0
  29. package/lib/api-routes/webhook-route-routes.js +152 -0
  30. package/lib/email-client/gmail-client.js +14 -0
  31. package/lib/email-client/imap/mailbox.js +34 -11
  32. package/lib/email-client/imap/subconnection.js +20 -12
  33. package/lib/email-client/imap/sync-operations.js +130 -2
  34. package/lib/email-client/imap-client.js +116 -58
  35. package/lib/email-client/outlook-client.js +85 -13
  36. package/lib/export.js +60 -19
  37. package/lib/imapproxy/imap-core/lib/commands/starttls.js +18 -0
  38. package/lib/imapproxy/imap-core/lib/imap-command.js +7 -2
  39. package/lib/imapproxy/imap-core/lib/imap-connection.js +113 -23
  40. package/lib/imapproxy/imap-core/lib/imap-server.js +25 -1
  41. package/lib/imapproxy/imap-core/lib/imap-stream.js +26 -0
  42. package/lib/imapproxy/imap-server.js +92 -29
  43. package/lib/message-port-stream.js +113 -16
  44. package/lib/reject-worker-calls.js +42 -0
  45. package/lib/routes-ui.js +37 -8778
  46. package/lib/schemas.js +26 -1
  47. package/lib/tools.js +73 -0
  48. package/lib/ui-routes/account-routes.js +40 -210
  49. package/lib/ui-routes/admin-config-routes.js +913 -487
  50. package/lib/ui-routes/admin-entities-routes.js +1 -0
  51. package/lib/ui-routes/auth-routes.js +1339 -0
  52. package/lib/ui-routes/dashboard-routes.js +188 -0
  53. package/lib/ui-routes/document-store-routes.js +800 -0
  54. package/lib/ui-routes/export-routes.js +217 -0
  55. package/lib/ui-routes/internals-routes.js +354 -0
  56. package/lib/ui-routes/network-config-routes.js +759 -0
  57. package/lib/ui-routes/{oauth-routes.js → oauth-config-routes.js} +371 -91
  58. package/lib/ui-routes/route-helpers.js +316 -0
  59. package/lib/ui-routes/smtp-test-routes.js +236 -0
  60. package/lib/ui-routes/unsubscribe-routes.js +234 -0
  61. package/lib/webhook-request.js +36 -0
  62. package/package.json +17 -17
  63. package/sbom.json +1 -1
  64. package/server.js +217 -19
  65. package/static/licenses.html +52 -182
  66. package/translations/messages.pot +131 -151
  67. package/views/dashboard.hbs +7 -26
  68. package/views/internals/index.hbs +15 -0
  69. package/views/tokens/index.hbs +9 -0
  70. package/workers/api.js +198 -4401
  71. package/workers/export.js +87 -54
  72. package/workers/imap.js +29 -13
  73. package/workers/submit.js +20 -11
  74. package/workers/webhooks.js +6 -20
@@ -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;