emailengine-app 2.61.5 → 2.62.1
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/CHANGELOG.md +88 -0
- package/data/google-crawlers.json +1 -1
- package/lib/account.js +20 -7
- package/lib/api-routes/account-routes.js +28 -5
- package/lib/api-routes/chat-routes.js +1 -1
- package/lib/api-routes/export-routes.js +316 -0
- package/lib/api-routes/message-routes.js +28 -23
- package/lib/api-routes/template-routes.js +28 -7
- package/lib/arf-detect.js +1 -1
- package/lib/autodetect-imap-settings.js +5 -5
- package/lib/consts.js +16 -0
- package/lib/db.js +3 -0
- package/lib/email-client/base-client.js +6 -4
- package/lib/email-client/gmail-client.js +205 -35
- package/lib/email-client/imap/mailbox.js +99 -8
- package/lib/email-client/imap/subconnection.js +5 -5
- package/lib/email-client/imap-client.js +76 -19
- package/lib/email-client/message-builder.js +3 -1
- package/lib/email-client/notification-handler.js +12 -9
- package/lib/email-client/outlook-client.js +364 -73
- package/lib/email-client/smtp-pool-manager.js +1 -1
- package/lib/export.js +528 -0
- package/lib/oauth/gmail.js +24 -16
- package/lib/oauth/mail-ru.js +26 -13
- package/lib/oauth/outlook.js +29 -19
- package/lib/oauth/pubsub/google.js +5 -0
- package/lib/routes-ui.js +268 -9
- package/lib/schemas.js +274 -81
- package/lib/stream-encrypt.js +263 -0
- package/lib/sub-script.js +2 -2
- package/lib/tools.js +194 -12
- package/lib/ui-routes/account-routes.js +23 -0
- package/lib/ui-routes/admin-config-routes.js +13 -6
- package/lib/ui-routes/admin-entities-routes.js +18 -0
- package/lib/webhooks.js +16 -20
- package/package.json +20 -20
- package/sbom.json +1 -1
- package/server.js +66 -7
- package/static/js/ace/ace.js +1 -1
- package/static/js/ace/ext-language_tools.js +1 -1
- package/static/licenses.html +118 -149
- package/translations/de.mo +0 -0
- package/translations/de.po +63 -36
- package/translations/en.mo +0 -0
- package/translations/en.po +64 -37
- package/translations/et.mo +0 -0
- package/translations/et.po +63 -36
- package/translations/fr.mo +0 -0
- package/translations/fr.po +63 -36
- package/translations/ja.mo +0 -0
- package/translations/ja.po +63 -36
- package/translations/messages.pot +84 -51
- package/translations/nl.mo +0 -0
- package/translations/nl.po +63 -36
- package/translations/pl.mo +0 -0
- package/translations/pl.po +63 -36
- package/views/accounts/account.hbs +375 -2
- package/views/config/network.hbs +45 -0
- package/views/config/service.hbs +35 -0
- package/workers/api.js +130 -47
- package/workers/documents.js +3 -2
- package/workers/export.js +933 -0
- package/workers/imap.js +34 -1
- package/workers/submit.js +33 -6
- package/workers/webhooks.js +20 -4
package/workers/api.js
CHANGED
|
@@ -39,7 +39,8 @@ const {
|
|
|
39
39
|
hasEnvValue,
|
|
40
40
|
getBoolean,
|
|
41
41
|
loadTlsConfig,
|
|
42
|
-
|
|
42
|
+
httpAgent,
|
|
43
|
+
reloadHttpProxyAgent
|
|
43
44
|
} = require('../lib/tools');
|
|
44
45
|
const { matchIp, detectAutomatedRequest } = require('../lib/utils/network');
|
|
45
46
|
|
|
@@ -132,6 +133,7 @@ const chatRoutes = require('../lib/api-routes/chat-routes');
|
|
|
132
133
|
const bullBoardRoutes = require('../lib/api-routes/bull-board-routes');
|
|
133
134
|
const accountRoutes = require('../lib/api-routes/account-routes');
|
|
134
135
|
const messageRoutes = require('../lib/api-routes/message-routes');
|
|
136
|
+
const exportRoutes = require('../lib/api-routes/export-routes');
|
|
135
137
|
|
|
136
138
|
const {
|
|
137
139
|
settingsSchema,
|
|
@@ -174,7 +176,8 @@ const AccountTypeSchema = Joi.string()
|
|
|
174
176
|
.valid(...['imap'].concat(Object.keys(OAUTH_PROVIDERS)).concat('oauth2'))
|
|
175
177
|
.example('outlook')
|
|
176
178
|
.description('Account type')
|
|
177
|
-
.required()
|
|
179
|
+
.required()
|
|
180
|
+
.label('AccountType');
|
|
178
181
|
|
|
179
182
|
const SUPPORTED_LOCALES = locales.map(locale => locale.locale);
|
|
180
183
|
|
|
@@ -289,7 +292,7 @@ class ResponseStream extends Transform {
|
|
|
289
292
|
this._finalized = false;
|
|
290
293
|
|
|
291
294
|
// Ensure cleanup on all stream end scenarios
|
|
292
|
-
this.
|
|
295
|
+
this.on('error', () => this.finalize());
|
|
293
296
|
this.once('close', () => this.finalize());
|
|
294
297
|
this.once('end', () => this.finalize());
|
|
295
298
|
}
|
|
@@ -297,6 +300,7 @@ class ResponseStream extends Transform {
|
|
|
297
300
|
updateTimer() {
|
|
298
301
|
clearTimeout(this.periodicKeepAliveTimer);
|
|
299
302
|
this.periodicKeepAliveTimer = setTimeout(() => {
|
|
303
|
+
if (this._finalized || this.destroyed) return;
|
|
300
304
|
this.write(': still here\n\n');
|
|
301
305
|
if (this._compressor) {
|
|
302
306
|
this._compressor.flush();
|
|
@@ -311,6 +315,7 @@ class ResponseStream extends Transform {
|
|
|
311
315
|
}
|
|
312
316
|
|
|
313
317
|
sendMessage(payload) {
|
|
318
|
+
if (this._finalized || this.destroyed) return;
|
|
314
319
|
let sendData = JSON.stringify(payload);
|
|
315
320
|
this.write('event: message\ndata:' + sendData + '\n\n');
|
|
316
321
|
if (this._compressor) {
|
|
@@ -325,6 +330,10 @@ class ResponseStream extends Transform {
|
|
|
325
330
|
|
|
326
331
|
clearTimeout(this.periodicKeepAliveTimer);
|
|
327
332
|
registeredPublishers.delete(this);
|
|
333
|
+
|
|
334
|
+
if (!this.destroyed) {
|
|
335
|
+
this.destroy();
|
|
336
|
+
}
|
|
328
337
|
}
|
|
329
338
|
|
|
330
339
|
_transform(data, encoding, done) {
|
|
@@ -914,6 +923,8 @@ Include your token in requests using one of these methods:
|
|
|
914
923
|
|
|
915
924
|
security: [{ bearerAuth: [] }],
|
|
916
925
|
|
|
926
|
+
definitionPrefix: 'useLabel',
|
|
927
|
+
|
|
917
928
|
cors: !!CORS_CONFIG,
|
|
918
929
|
cache: {
|
|
919
930
|
expiresIn: 7 * 24 * 60 * 60 * 1000
|
|
@@ -1008,6 +1019,11 @@ Include your token in requests using one of these methods:
|
|
|
1008
1019
|
{
|
|
1009
1020
|
name: 'Multi Message Actions',
|
|
1010
1021
|
description: 'Perform bulk operations on multiple messages simultaneously, such as marking as read, moving, or deleting'
|
|
1022
|
+
},
|
|
1023
|
+
{
|
|
1024
|
+
name: 'Export (Beta)',
|
|
1025
|
+
description:
|
|
1026
|
+
'Bulk export messages from email accounts. This feature is in beta and the API may change in future releases. Export files are encrypted at rest when a service secret is configured.'
|
|
1011
1027
|
}
|
|
1012
1028
|
],
|
|
1013
1029
|
|
|
@@ -2027,10 +2043,10 @@ Include your token in requests using one of these methods:
|
|
|
2027
2043
|
}
|
|
2028
2044
|
|
|
2029
2045
|
// Validate nonce format: 16 bytes base64url encoded = 21-22 characters
|
|
2046
|
+
// Also accept base64 encoding (+, /, =) for backward compatibility with old cached nonces
|
|
2030
2047
|
const stateNonce = request.query.state.slice('account:add:'.length);
|
|
2031
|
-
if (!/^[A-Za-z0-9_
|
|
2032
|
-
|
|
2033
|
-
throw error;
|
|
2048
|
+
if (!/^[A-Za-z0-9_\-+/]{21,22}={0,2}$/.test(stateNonce)) {
|
|
2049
|
+
throw Boom.badRequest('Oauth failed: invalid state format');
|
|
2034
2050
|
}
|
|
2035
2051
|
|
|
2036
2052
|
let [[, accountData]] = await redis.multi().get(`${REDIS_PREFIX}${request.query.state}`).del(`${REDIS_PREFIX}${request.query.state}`).exec();
|
|
@@ -3314,7 +3330,7 @@ Include your token in requests using one of these methods:
|
|
|
3314
3330
|
|
|
3315
3331
|
envelope: Joi.object({
|
|
3316
3332
|
from: Joi.string().email().allow('').example('sender@example.com'),
|
|
3317
|
-
to: Joi.array().items(Joi.string().email().required().example('recipient@example.com')).single()
|
|
3333
|
+
to: Joi.array().items(Joi.string().email().required().example('recipient@example.com')).single().label('SmtpEnvelopeTo')
|
|
3318
3334
|
})
|
|
3319
3335
|
.description(
|
|
3320
3336
|
"An optional object specifying the SMTP envelope used during email transmission. If not provided, the envelope is automatically derived from the email's message headers. This is useful when you need the envelope addresses to differ from those in the email headers."
|
|
@@ -3386,7 +3402,11 @@ Include your token in requests using one of these methods:
|
|
|
3386
3402
|
template: Joi.string().max(256).example('example').description('Stored template ID to load the email content from'),
|
|
3387
3403
|
|
|
3388
3404
|
render: Joi.object({
|
|
3389
|
-
format: Joi.string()
|
|
3405
|
+
format: Joi.string()
|
|
3406
|
+
.valid('html', 'markdown')
|
|
3407
|
+
.default('html')
|
|
3408
|
+
.description('Markup language for HTML ("html" or "markdown")')
|
|
3409
|
+
.label('RenderFormat'),
|
|
3390
3410
|
params: Joi.object().label('RenderValues').description('An object of variables for the template renderer')
|
|
3391
3411
|
})
|
|
3392
3412
|
.allow(false)
|
|
@@ -3432,9 +3452,9 @@ Include your token in requests using one of these methods:
|
|
|
3432
3452
|
}),
|
|
3433
3453
|
|
|
3434
3454
|
contentType: Joi.string().lowercase().max(256).example('image/gif'),
|
|
3435
|
-
contentDisposition: Joi.string().lowercase().valid('inline', 'attachment'),
|
|
3455
|
+
contentDisposition: Joi.string().lowercase().valid('inline', 'attachment').label('AttachmentContentDisposition'),
|
|
3436
3456
|
cid: Joi.string().max(256).example('unique-image-id@localhost').description('Content-ID value for embedded images'),
|
|
3437
|
-
encoding: Joi.string().valid('base64').default('base64'),
|
|
3457
|
+
encoding: Joi.string().valid('base64').default('base64').label('AttachmentEncoding'),
|
|
3438
3458
|
|
|
3439
3459
|
reference: Joi.string()
|
|
3440
3460
|
.base64({ paddingRequired: false, urlSafe: true })
|
|
@@ -3444,6 +3464,7 @@ Include your token in requests using one of these methods:
|
|
|
3444
3464
|
.description(
|
|
3445
3465
|
'References an existing attachment by its ID instead of providing new attachment content. If this field is set, the `content` field must not be included. If not set, the `content` field is required.'
|
|
3446
3466
|
)
|
|
3467
|
+
.label('AttachmentReference')
|
|
3447
3468
|
}).label('UploadAttachment')
|
|
3448
3469
|
)
|
|
3449
3470
|
.description('List of attachments')
|
|
@@ -3475,7 +3496,7 @@ Include your token in requests using one of these methods:
|
|
|
3475
3496
|
.example('Sent Mail')
|
|
3476
3497
|
.description("Upload sent message to this folder. By default the account's Sent Mail folder is used."),
|
|
3477
3498
|
|
|
3478
|
-
locale: Joi.string().empty('').max(100).example('fr').description('Optional locale'),
|
|
3499
|
+
locale: Joi.string().empty('').max(100).example('fr').description('Optional locale').label('MessageLocale'),
|
|
3479
3500
|
tz: Joi.string().empty('').max(100).example('Europe/Tallinn').description('Optional timezone'),
|
|
3480
3501
|
|
|
3481
3502
|
sendAt: Joi.date().iso().example('2021-07-08T07:06:34.336Z').description('Send message at specified time'),
|
|
@@ -3483,7 +3504,7 @@ Include your token in requests using one of these methods:
|
|
|
3483
3504
|
.integer()
|
|
3484
3505
|
.example(10)
|
|
3485
3506
|
.description('How many delivery attempts to make until message is considered as failed'),
|
|
3486
|
-
gateway: Joi.string().max(256).example('example').description('Optional SMTP gateway ID for message routing'),
|
|
3507
|
+
gateway: Joi.string().max(256).example('example').description('Optional SMTP gateway ID for message routing').label('MessageGateway'),
|
|
3487
3508
|
|
|
3488
3509
|
listId: Joi.string()
|
|
3489
3510
|
.hostname()
|
|
@@ -3505,11 +3526,13 @@ Include your token in requests using one of these methods:
|
|
|
3505
3526
|
.empty('')
|
|
3506
3527
|
.valid('headers', 'full')
|
|
3507
3528
|
.required()
|
|
3508
|
-
.description('Specifies if only headers or the entire body of the message should be included in the response (RET)')
|
|
3529
|
+
.description('Specifies if only headers or the entire body of the message should be included in the response (RET)')
|
|
3530
|
+
.label('DsnReturn'),
|
|
3509
3531
|
notify: Joi.array()
|
|
3510
3532
|
.single()
|
|
3511
3533
|
.items(Joi.string().valid('never', 'success', 'failure', 'delay').label('NotifyEntry'))
|
|
3512
|
-
.description('Defines the conditions under which a DSN response should be sent')
|
|
3534
|
+
.description('Defines the conditions under which a DSN response should be sent')
|
|
3535
|
+
.label('DsnNotify'),
|
|
3513
3536
|
recipient: Joi.string().trim().empty('').email().description('The email address the DSN should be sent (ORCPT)')
|
|
3514
3537
|
})
|
|
3515
3538
|
.description('Request DSN notifications')
|
|
@@ -3636,7 +3659,9 @@ Include your token in requests using one of these methods:
|
|
|
3636
3659
|
skipped: Joi.object({
|
|
3637
3660
|
reason: Joi.string().example('unsubscribe').description('Why this message was skipped'),
|
|
3638
3661
|
listId: Joi.string().example('test-list')
|
|
3639
|
-
})
|
|
3662
|
+
})
|
|
3663
|
+
.description('Info about skipped message. If this value is set, then the message was not sent')
|
|
3664
|
+
.label('SkippedMessageInfo')
|
|
3640
3665
|
})
|
|
3641
3666
|
.label('BulkResponseEntry')
|
|
3642
3667
|
.example({
|
|
@@ -3752,6 +3777,9 @@ Include your token in requests using one of these methods:
|
|
|
3752
3777
|
}
|
|
3753
3778
|
|
|
3754
3779
|
notify('settings', request.payload);
|
|
3780
|
+
if ('httpProxyEnabled' in request.payload || 'httpProxyUrl' in request.payload) {
|
|
3781
|
+
reloadHttpProxyAgent().catch(err => logger.error({ msg: 'Failed to reload HTTP proxy agent', err }));
|
|
3782
|
+
}
|
|
3755
3783
|
return { updated };
|
|
3756
3784
|
},
|
|
3757
3785
|
options: {
|
|
@@ -3856,13 +3884,27 @@ Include your token in requests using one of these methods:
|
|
|
3856
3884
|
failAction,
|
|
3857
3885
|
|
|
3858
3886
|
params: Joi.object({
|
|
3859
|
-
queue: Joi.string()
|
|
3887
|
+
queue: Joi.string()
|
|
3888
|
+
.empty('')
|
|
3889
|
+
.trim()
|
|
3890
|
+
.valid('notify', 'submit', 'documents')
|
|
3891
|
+
.required()
|
|
3892
|
+
.example('notify')
|
|
3893
|
+
.description('Queue ID')
|
|
3894
|
+
.label('QueueId')
|
|
3860
3895
|
})
|
|
3861
3896
|
},
|
|
3862
3897
|
|
|
3863
3898
|
response: {
|
|
3864
3899
|
schema: Joi.object({
|
|
3865
|
-
queue: Joi.string()
|
|
3900
|
+
queue: Joi.string()
|
|
3901
|
+
.empty('')
|
|
3902
|
+
.trim()
|
|
3903
|
+
.valid('notify', 'submit', 'documents')
|
|
3904
|
+
.required()
|
|
3905
|
+
.example('notify')
|
|
3906
|
+
.description('Queue ID')
|
|
3907
|
+
.label('QueueIdResponse'),
|
|
3866
3908
|
jobs: Joi.object({
|
|
3867
3909
|
active: Joi.number().integer().example(123).description('Jobs that are currently being processed'),
|
|
3868
3910
|
delayed: Joi.number().integer().example(123).description('Jobs that are processed in the future'),
|
|
@@ -3946,7 +3988,14 @@ Include your token in requests using one of these methods:
|
|
|
3946
3988
|
failAction,
|
|
3947
3989
|
|
|
3948
3990
|
params: Joi.object({
|
|
3949
|
-
queue: Joi.string()
|
|
3991
|
+
queue: Joi.string()
|
|
3992
|
+
.empty('')
|
|
3993
|
+
.trim()
|
|
3994
|
+
.valid('notify', 'submit', 'documents')
|
|
3995
|
+
.required()
|
|
3996
|
+
.example('notify')
|
|
3997
|
+
.description('Queue ID')
|
|
3998
|
+
.label('QueueIdParam')
|
|
3950
3999
|
}),
|
|
3951
4000
|
|
|
3952
4001
|
payload: Joi.object({
|
|
@@ -3956,7 +4005,14 @@ Include your token in requests using one of these methods:
|
|
|
3956
4005
|
|
|
3957
4006
|
response: {
|
|
3958
4007
|
schema: Joi.object({
|
|
3959
|
-
queue: Joi.string()
|
|
4008
|
+
queue: Joi.string()
|
|
4009
|
+
.empty('')
|
|
4010
|
+
.trim()
|
|
4011
|
+
.valid('notify', 'submit', 'documents')
|
|
4012
|
+
.required()
|
|
4013
|
+
.example('notify')
|
|
4014
|
+
.description('Queue ID')
|
|
4015
|
+
.label('QueueIdPutResponse'),
|
|
3960
4016
|
paused: Joi.boolean().example(false).description('Is the queue paused or not')
|
|
3961
4017
|
}).label('SettingsPutQueueResponse'),
|
|
3962
4018
|
failAction: 'log'
|
|
@@ -4108,7 +4164,7 @@ Include your token in requests using one of these methods:
|
|
|
4108
4164
|
failAction,
|
|
4109
4165
|
|
|
4110
4166
|
payload: Joi.object({
|
|
4111
|
-
mailboxes: Joi.boolean().example(false).description('Include mailbox listing in response').default(false),
|
|
4167
|
+
mailboxes: Joi.boolean().example(false).description('Include mailbox listing in response').default(false).label('IncludeMailboxes'),
|
|
4112
4168
|
imap: Joi.object(imapSchema).allow(false).description('IMAP configuration').label('ImapConfiguration'),
|
|
4113
4169
|
smtp: Joi.object(smtpSchema).allow(false).description('SMTP configuration').label('SmtpConfiguration'),
|
|
4114
4170
|
proxy: settingsSchema.proxyUrl,
|
|
@@ -4127,7 +4183,7 @@ Include your token in requests using one of these methods:
|
|
|
4127
4183
|
.example('ERR_SSL_WRONG_VERSION_NUMBER')
|
|
4128
4184
|
.description('Error code. Only present if success=false')
|
|
4129
4185
|
.label('VerifyImapCode')
|
|
4130
|
-
}),
|
|
4186
|
+
}).label('VerifyImapResult'),
|
|
4131
4187
|
smtp: Joi.object({
|
|
4132
4188
|
success: Joi.boolean().example(true).description('Was SMTP account verified').label('VerifySmtpSuccess'),
|
|
4133
4189
|
error: Joi.string()
|
|
@@ -4138,7 +4194,7 @@ Include your token in requests using one of these methods:
|
|
|
4138
4194
|
.example('ERR_SSL_WRONG_VERSION_NUMBER')
|
|
4139
4195
|
.description('Error code. Only present if success=false')
|
|
4140
4196
|
.label('VerifySmtpCode')
|
|
4141
|
-
}),
|
|
4197
|
+
}).label('VerifySmtpResult'),
|
|
4142
4198
|
mailboxes: shortMailboxesSchema
|
|
4143
4199
|
}).label('VerifyAccountResponse'),
|
|
4144
4200
|
failAction: 'log'
|
|
@@ -4597,6 +4653,12 @@ Include your token in requests using one of these methods:
|
|
|
4597
4653
|
MAX_PAYLOAD_TIMEOUT
|
|
4598
4654
|
});
|
|
4599
4655
|
|
|
4656
|
+
// setup export routes
|
|
4657
|
+
await exportRoutes({
|
|
4658
|
+
server,
|
|
4659
|
+
CORS_CONFIG
|
|
4660
|
+
});
|
|
4661
|
+
|
|
4600
4662
|
server.route({
|
|
4601
4663
|
method: 'GET',
|
|
4602
4664
|
path: '/v1/webhookRoutes',
|
|
@@ -4867,7 +4929,8 @@ Include your token in requests using one of these methods:
|
|
|
4867
4929
|
|
|
4868
4930
|
clientId: Joi.string()
|
|
4869
4931
|
.example('4f05f488-d858-4f2c-bd12-1039062612fe')
|
|
4870
|
-
.description('Client or Application ID for 3-legged OAuth2 applications')
|
|
4932
|
+
.description('Client or Application ID for 3-legged OAuth2 applications')
|
|
4933
|
+
.label('OAuth2AppListClientId'),
|
|
4871
4934
|
clientSecret: Joi.string()
|
|
4872
4935
|
.example('******')
|
|
4873
4936
|
.description('Client secret for 3-legged OAuth2 applications. Actual value is not revealed.'),
|
|
@@ -4878,9 +4941,13 @@ Include your token in requests using one of these methods:
|
|
|
4878
4941
|
allowRelative: false
|
|
4879
4942
|
})
|
|
4880
4943
|
.example('https://myservice.com/oauth')
|
|
4881
|
-
.description('Redirect URL for 3-legged OAuth2 applications')
|
|
4944
|
+
.description('Redirect URL for 3-legged OAuth2 applications')
|
|
4945
|
+
.label('OAuth2AppListRedirectUrl'),
|
|
4882
4946
|
|
|
4883
|
-
serviceClient: Joi.string()
|
|
4947
|
+
serviceClient: Joi.string()
|
|
4948
|
+
.example('9103965568215821627203')
|
|
4949
|
+
.description('Service client ID for 2-legged OAuth2 applications')
|
|
4950
|
+
.label('OAuth2AppListServiceClient'),
|
|
4884
4951
|
|
|
4885
4952
|
googleProjectId: googleProjectIdSchema,
|
|
4886
4953
|
googleWorkspaceAccounts: googleWorkspaceAccountsSchema,
|
|
@@ -5002,7 +5069,8 @@ Include your token in requests using one of these methods:
|
|
|
5002
5069
|
|
|
5003
5070
|
clientId: Joi.string()
|
|
5004
5071
|
.example('4f05f488-d858-4f2c-bd12-1039062612fe')
|
|
5005
|
-
.description('Client or Application ID for 3-legged OAuth2 applications')
|
|
5072
|
+
.description('Client or Application ID for 3-legged OAuth2 applications')
|
|
5073
|
+
.label('OAuth2AppGetClientId'),
|
|
5006
5074
|
clientSecret: Joi.string().example('******').description('Client secret for 3-legged OAuth2 applications. Actual value is not revealed.'),
|
|
5007
5075
|
authority: Joi.string().example('common').description('Authorization tenant value for Outlook OAuth2 applications'),
|
|
5008
5076
|
redirectUrl: Joi.string()
|
|
@@ -5011,7 +5079,8 @@ Include your token in requests using one of these methods:
|
|
|
5011
5079
|
allowRelative: false
|
|
5012
5080
|
})
|
|
5013
5081
|
.example('https://myservice.com/oauth')
|
|
5014
|
-
.description('Redirect URL for 3-legged OAuth2 applications')
|
|
5082
|
+
.description('Redirect URL for 3-legged OAuth2 applications')
|
|
5083
|
+
.label('OAuth2AppGetRedirectUrl'),
|
|
5015
5084
|
|
|
5016
5085
|
googleProjectId: googleProjectIdSchema,
|
|
5017
5086
|
googleWorkspaceAccounts: googleWorkspaceAccountsSchema,
|
|
@@ -5023,7 +5092,10 @@ Include your token in requests using one of these methods:
|
|
|
5023
5092
|
.example('name@project-123.iam.gserviceaccount.com')
|
|
5024
5093
|
.description('Service Client Email for 2-legged OAuth2 applications'),
|
|
5025
5094
|
|
|
5026
|
-
serviceClient: Joi.string()
|
|
5095
|
+
serviceClient: Joi.string()
|
|
5096
|
+
.example('9103965568215821627203')
|
|
5097
|
+
.description('Service client ID for 2-legged OAuth2 applications')
|
|
5098
|
+
.label('OAuth2AppGetServiceClient'),
|
|
5027
5099
|
|
|
5028
5100
|
serviceKey: Joi.string()
|
|
5029
5101
|
.example('******')
|
|
@@ -5163,7 +5235,8 @@ Include your token in requests using one of these methods:
|
|
|
5163
5235
|
.allow('', null, false)
|
|
5164
5236
|
.max(256)
|
|
5165
5237
|
.example('52422112755-3uov8bjwlrullq122rdm6l8ui25ho7qf.apps.googleusercontent.com')
|
|
5166
|
-
.description('Client or Application ID for 3-legged OAuth2 applications')
|
|
5238
|
+
.description('Client or Application ID for 3-legged OAuth2 applications')
|
|
5239
|
+
.label('UpdateOAuth2ClientId'),
|
|
5167
5240
|
|
|
5168
5241
|
clientSecret: Joi.string()
|
|
5169
5242
|
.trim()
|
|
@@ -5177,18 +5250,26 @@ Include your token in requests using one of these methods:
|
|
|
5177
5250
|
.base64({ paddingRequired: false, urlSafe: true })
|
|
5178
5251
|
.max(512)
|
|
5179
5252
|
.example('AAAAAQAACnA')
|
|
5180
|
-
.description('Cloud Pub/Sub app for Gmail API webhooks')
|
|
5253
|
+
.description('Cloud Pub/Sub app for Gmail API webhooks')
|
|
5254
|
+
.label('UpdatePubSubAppId'),
|
|
5181
5255
|
|
|
5182
|
-
extraScopes: Joi.array()
|
|
5256
|
+
extraScopes: Joi.array()
|
|
5257
|
+
.items(Joi.string().trim().max(255).example('User.Read').label('UpdateExtraScopeEntry'))
|
|
5258
|
+
.description('OAuth2 Extra Scopes')
|
|
5259
|
+
.label('UpdateOAuth2ExtraScopes'),
|
|
5183
5260
|
|
|
5184
|
-
skipScopes: Joi.array()
|
|
5261
|
+
skipScopes: Joi.array()
|
|
5262
|
+
.items(Joi.string().trim().max(255).example('SMTP.Send').label('UpdateSkipScopeEntry'))
|
|
5263
|
+
.description('OAuth2 scopes to skip from the base set')
|
|
5264
|
+
.label('UpdateOAuth2SkipScopes'),
|
|
5185
5265
|
|
|
5186
5266
|
serviceClient: Joi.string()
|
|
5187
5267
|
.trim()
|
|
5188
5268
|
.allow('', null, false)
|
|
5189
5269
|
.max(256)
|
|
5190
5270
|
.example('7103296518315821565203')
|
|
5191
|
-
.description('Service client ID for 2-legged OAuth2 applications')
|
|
5271
|
+
.description('Service client ID for 2-legged OAuth2 applications')
|
|
5272
|
+
.label('UpdateServiceClient'),
|
|
5192
5273
|
|
|
5193
5274
|
googleProjectId: googleProjectIdSchema,
|
|
5194
5275
|
googleWorkspaceAccounts: googleWorkspaceAccountsSchema,
|
|
@@ -5230,6 +5311,7 @@ Include your token in requests using one of these methods:
|
|
|
5230
5311
|
.uri({ scheme: ['http', 'https'], allowRelative: false })
|
|
5231
5312
|
.example('https://myservice.com/oauth')
|
|
5232
5313
|
.description('Redirect URL for 3-legged OAuth2 applications')
|
|
5314
|
+
.label('UpdateOAuth2RedirectUrl')
|
|
5233
5315
|
}).label('UpdateOAuthApp')
|
|
5234
5316
|
},
|
|
5235
5317
|
|
|
@@ -5465,7 +5547,7 @@ Include your token in requests using one of these methods:
|
|
|
5465
5547
|
.default(false)
|
|
5466
5548
|
.example(true)
|
|
5467
5549
|
.description('Should connection use TLS. Usually true for port 465')
|
|
5468
|
-
.label('
|
|
5550
|
+
.label('GatewayTlsOptions'),
|
|
5469
5551
|
|
|
5470
5552
|
lastError: lastErrorSchema.allow(null)
|
|
5471
5553
|
}).label('GatewayResponse'),
|
|
@@ -5542,7 +5624,7 @@ Include your token in requests using one of these methods:
|
|
|
5542
5624
|
.default(false)
|
|
5543
5625
|
.example(true)
|
|
5544
5626
|
.description('Should connection use TLS. Usually true for port 465')
|
|
5545
|
-
.label('
|
|
5627
|
+
.label('GatewayCreateTlsOptions')
|
|
5546
5628
|
}).label('CreateGateway')
|
|
5547
5629
|
},
|
|
5548
5630
|
|
|
@@ -5628,7 +5710,7 @@ Include your token in requests using one of these methods:
|
|
|
5628
5710
|
.falsy('N', 'false', 0, '')
|
|
5629
5711
|
.example(true)
|
|
5630
5712
|
.description('Should connection use TLS. Usually true for port 465')
|
|
5631
|
-
.label('
|
|
5713
|
+
.label('GatewayUpdateTlsOptions')
|
|
5632
5714
|
}).label('UpdateGateway')
|
|
5633
5715
|
},
|
|
5634
5716
|
|
|
@@ -5696,7 +5778,7 @@ Include your token in requests using one of these methods:
|
|
|
5696
5778
|
schema: Joi.object({
|
|
5697
5779
|
gateway: Joi.string().max(256).required().example('example').description('Gateway ID'),
|
|
5698
5780
|
deleted: Joi.boolean().truthy('Y', 'true', '1').falsy('N', 'false', 0).default(true).description('Was the gateway deleted')
|
|
5699
|
-
}).label('
|
|
5781
|
+
}).label('DeleteGatewayResponse'),
|
|
5700
5782
|
failAction: 'log'
|
|
5701
5783
|
}
|
|
5702
5784
|
}
|
|
@@ -5778,7 +5860,7 @@ Include your token in requests using one of these methods:
|
|
|
5778
5860
|
schema: Joi.object({
|
|
5779
5861
|
account: accountIdSchema.required(),
|
|
5780
5862
|
user: Joi.string().max(256).required().example('user@example.com').description('Username'),
|
|
5781
|
-
accessToken: Joi.string().max(256).required().example('aGVsbG8gd29ybGQ=').description('Access Token'),
|
|
5863
|
+
accessToken: Joi.string().max(256).required().example('aGVsbG8gd29ybGQ=').description('Access Token').label('OAuthAccessToken'),
|
|
5782
5864
|
provider: OAuth2ProviderSchema
|
|
5783
5865
|
}).label('AccountTokenResponse'),
|
|
5784
5866
|
failAction: 'log'
|
|
@@ -5848,7 +5930,7 @@ Include your token in requests using one of these methods:
|
|
|
5848
5930
|
}).label('SignatureResponseItem')
|
|
5849
5931
|
)
|
|
5850
5932
|
.label('SignatureEntries')
|
|
5851
|
-
}).label('
|
|
5933
|
+
}).label('AccountSignaturesResponse'),
|
|
5852
5934
|
failAction: 'log'
|
|
5853
5935
|
}
|
|
5854
5936
|
}
|
|
@@ -5884,7 +5966,7 @@ Include your token in requests using one of these methods:
|
|
|
5884
5966
|
requestor: '@postalsys/emailengine-app'
|
|
5885
5967
|
}),
|
|
5886
5968
|
headers,
|
|
5887
|
-
dispatcher:
|
|
5969
|
+
dispatcher: httpAgent.retry
|
|
5888
5970
|
});
|
|
5889
5971
|
|
|
5890
5972
|
if (!res.ok) {
|
|
@@ -5995,7 +6077,7 @@ ${now}`,
|
|
|
5995
6077
|
}),
|
|
5996
6078
|
|
|
5997
6079
|
payload: Joi.object({
|
|
5998
|
-
gateway: Joi.string().allow(false, null).empty('').max(256).example(false).description('Optional gateway ID')
|
|
6080
|
+
gateway: Joi.string().allow(false, null).empty('').max(256).example(false).description('Optional gateway ID').label('DeliveryTestGateway')
|
|
5999
6081
|
}).label('DeliveryStartRequest')
|
|
6000
6082
|
},
|
|
6001
6083
|
|
|
@@ -6037,7 +6119,7 @@ ${now}`,
|
|
|
6037
6119
|
let res = await fetchCmd(`${SMTP_TEST_HOST}/test-address/${request.params.deliveryTest}`, {
|
|
6038
6120
|
method: 'get',
|
|
6039
6121
|
headers,
|
|
6040
|
-
dispatcher:
|
|
6122
|
+
dispatcher: httpAgent.retry
|
|
6041
6123
|
});
|
|
6042
6124
|
|
|
6043
6125
|
if (!res.ok) {
|
|
@@ -6141,14 +6223,15 @@ ${now}`,
|
|
|
6141
6223
|
response: {
|
|
6142
6224
|
schema: Joi.object({
|
|
6143
6225
|
success: Joi.boolean().example(true).description('Was the test completed').label('ResponseDeliveryCheckSuccess'),
|
|
6144
|
-
dkim: Joi.object().unknown().description('DKIM results'),
|
|
6145
|
-
spf: Joi.object().unknown().description('SPF results'),
|
|
6146
|
-
dmarc: Joi.object().unknown().description('DMARC results'),
|
|
6147
|
-
bimi: Joi.object().unknown().description('BIMI results'),
|
|
6148
|
-
arc: Joi.object().unknown().description('ARC results'),
|
|
6226
|
+
dkim: Joi.object().unknown().description('DKIM results').label('DkimResults'),
|
|
6227
|
+
spf: Joi.object().unknown().description('SPF results').label('SpfResults'),
|
|
6228
|
+
dmarc: Joi.object().unknown().description('DMARC results').label('DmarcResults'),
|
|
6229
|
+
bimi: Joi.object().unknown().description('BIMI results').label('BimiResults'),
|
|
6230
|
+
arc: Joi.object().unknown().description('ARC results').label('ArcResults'),
|
|
6149
6231
|
mainSig: Joi.object()
|
|
6150
6232
|
.unknown()
|
|
6151
6233
|
.description('Primary DKIM signature. `status.aligned` should be set, otherwise DKIM check should not be considered as passed.')
|
|
6234
|
+
.label('MainSignature')
|
|
6152
6235
|
}).label('DeliveryCheckResponse'),
|
|
6153
6236
|
failAction: 'log'
|
|
6154
6237
|
}
|
package/workers/documents.js
CHANGED
|
@@ -241,7 +241,7 @@ const documentsWorker = new Worker(
|
|
|
241
241
|
return;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
let deleteResult
|
|
244
|
+
let deleteResult;
|
|
245
245
|
|
|
246
246
|
let filterQuery = {
|
|
247
247
|
bool: {
|
|
@@ -612,7 +612,7 @@ const documentsWorker = new Worker(
|
|
|
612
612
|
return;
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
-
let deleteResult
|
|
615
|
+
let deleteResult;
|
|
616
616
|
|
|
617
617
|
try {
|
|
618
618
|
let messageIdHeader;
|
|
@@ -912,6 +912,7 @@ if( ctx._source.bounces != null) {
|
|
|
912
912
|
Object.assign(
|
|
913
913
|
{
|
|
914
914
|
concurrency: 1,
|
|
915
|
+
lockDuration: 2 * 60 * 1000, // 2 minutes for ES operations
|
|
915
916
|
maxStalledCount: 5,
|
|
916
917
|
stalledInterval: 60 * 1000
|
|
917
918
|
},
|