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.
- package/.github/workflows/deploy.yml +6 -3
- package/.github/workflows/release.yaml +2 -0
- package/.github/workflows/test.yml +73 -12
- package/.ncurc.js +3 -3
- package/CHANGELOG.md +37 -0
- package/Gruntfile.js +21 -23
- package/bin/emailengine.js +8 -1
- package/config/default.toml +5 -0
- package/config/test.toml +5 -0
- package/data/google-crawlers.json +1 -1
- package/getswagger.sh +44 -4
- package/gettext-extract.js +163 -0
- package/lib/account.js +104 -72
- 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 +291 -145
- 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/document-store.js +22 -1
- package/lib/email-client/base-client.js +31 -8
- package/lib/email-client/gmail-client.js +119 -112
- package/lib/email-client/imap/mailbox.js +2 -2
- 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 +3 -6
- package/lib/email-client/outlook-client.js +49 -62
- package/lib/export.js +49 -1
- package/lib/feature-flags.js +8 -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/license-beacon.js +367 -0
- package/lib/logger.js +35 -22
- 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/routes-ui.js +2 -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 +28 -6
- package/lib/ui-routes/account-routes.js +7 -4
- package/lib/ui-routes/admin-config-routes.js +20 -6
- package/lib/ui-routes/document-store-routes.js +7 -1
- 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 +23 -19
- package/sbom.json +1 -1
- package/server.js +38 -31
- package/static/licenses.html +171 -391
- package/translations/de.mo +0 -0
- package/translations/de.po +154 -142
- package/translations/et.mo +0 -0
- package/translations/et.po +129 -131
- package/translations/fr.mo +0 -0
- package/translations/fr.po +133 -136
- package/translations/ja.mo +0 -0
- package/translations/ja.po +126 -129
- package/translations/messages.pot +107 -107
- package/translations/nl.mo +0 -0
- package/translations/nl.po +128 -130
- package/translations/pl.mo +0 -0
- package/translations/pl.po +125 -128
- package/update-info.sh +19 -1
- package/views/config/logging.hbs +48 -0
- package/views/dashboard.hbs +22 -0
- package/workers/api.js +33 -37
- package/workers/documents.js +2 -22
- package/workers/export.js +73 -92
- 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
|
@@ -11,7 +11,7 @@ const util = require('util');
|
|
|
11
11
|
|
|
12
12
|
const LOG_VERBOSE = getBoolean(process.env.EE_OPENAPI_VERBOSE);
|
|
13
13
|
|
|
14
|
-
const { accountIdSchema,
|
|
14
|
+
const { accountIdSchema, messageSpecialUseSchema, responseAddressSchema, responseFromAddressSchema, errorResponses } = require('../schemas');
|
|
15
15
|
|
|
16
16
|
function getDateValue(str) {
|
|
17
17
|
try {
|
|
@@ -97,7 +97,7 @@ async function init(args) {
|
|
|
97
97
|
startTime: sortingResponse?.start_time,
|
|
98
98
|
endTime: sortingResponse?.end_time,
|
|
99
99
|
model: sortingResponse?.model,
|
|
100
|
-
tokens: sortingResponse
|
|
100
|
+
tokens: sortingResponse?.tokens
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
// Step 2. Embeddings for the request
|
|
@@ -195,7 +195,7 @@ async function init(args) {
|
|
|
195
195
|
filter: vectorsFilter?.bool?.must
|
|
196
196
|
});
|
|
197
197
|
return {
|
|
198
|
-
success:
|
|
198
|
+
success: false,
|
|
199
199
|
answer: null,
|
|
200
200
|
processPipeline
|
|
201
201
|
};
|
|
@@ -281,7 +281,7 @@ async function init(args) {
|
|
|
281
281
|
message: 'Retrieved the answer',
|
|
282
282
|
messages: queryResponse?.messageId?.length || 0,
|
|
283
283
|
model: queryResponse?.model,
|
|
284
|
-
tokens: queryResponse
|
|
284
|
+
tokens: queryResponse?.tokens
|
|
285
285
|
});
|
|
286
286
|
|
|
287
287
|
if (queryResponse?.answer) {
|
|
@@ -360,7 +360,7 @@ async function init(args) {
|
|
|
360
360
|
}
|
|
361
361
|
|
|
362
362
|
return {
|
|
363
|
-
success: !!
|
|
363
|
+
success: !!responseData.answer,
|
|
364
364
|
...responseData,
|
|
365
365
|
processPipeline
|
|
366
366
|
};
|
|
@@ -399,9 +399,13 @@ async function init(args) {
|
|
|
399
399
|
options: {
|
|
400
400
|
description: 'Chat with emails',
|
|
401
401
|
notes: 'Use OpenAI API and embeddings stored in the Document Store to "chat" with account emails. Requires Document Store indexing and the "Chat with emails" feature to be enabled.',
|
|
402
|
-
tags: ['Deprecated endpoints (Document Store)'],
|
|
402
|
+
tags: ['api', 'Deprecated endpoints (Document Store)'],
|
|
403
403
|
|
|
404
|
-
plugins: {
|
|
404
|
+
plugins: {
|
|
405
|
+
'hapi-swagger': {
|
|
406
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
407
|
+
}
|
|
408
|
+
},
|
|
405
409
|
|
|
406
410
|
auth: {
|
|
407
411
|
strategy: 'api-token',
|
|
@@ -434,30 +438,44 @@ async function init(args) {
|
|
|
434
438
|
|
|
435
439
|
response: {
|
|
436
440
|
schema: Joi.object({
|
|
437
|
-
success: Joi.boolean()
|
|
438
|
-
|
|
441
|
+
success: Joi.boolean()
|
|
442
|
+
.example(true)
|
|
443
|
+
.description('Whether the LLM produced an answer. Can be false on a 200 response when no answer was found')
|
|
444
|
+
.label('ReturnChatResponseSuccess'),
|
|
445
|
+
answer: Joi.string()
|
|
446
|
+
.trim()
|
|
447
|
+
.allow(null)
|
|
448
|
+
.example('Last tuesday')
|
|
449
|
+
.description('Chat response. Not present (or null) when no answer was produced')
|
|
450
|
+
.label('ChatResponse'),
|
|
439
451
|
messages: Joi.array()
|
|
440
452
|
.items(
|
|
441
453
|
Joi.object({
|
|
442
454
|
id: Joi.string().example('AAAAAgAACrI').description('Unique identifier for the message').label('ChatMessageId'),
|
|
443
455
|
path: Joi.string().example('INBOX').description('Folder this message was found from').label('ChatMessagePath'),
|
|
444
456
|
date: Joi.date().iso().example('2023-09-29T10:03:49.000Z').description('Date of the email'),
|
|
445
|
-
from:
|
|
457
|
+
from: responseFromAddressSchema,
|
|
446
458
|
|
|
447
459
|
to: Joi.array()
|
|
448
|
-
.items(
|
|
460
|
+
.items(responseAddressSchema)
|
|
449
461
|
.single()
|
|
450
462
|
.description('List of addresses')
|
|
451
463
|
.example([{ address: 'recipient@example.com' }])
|
|
452
|
-
.label('
|
|
453
|
-
|
|
464
|
+
.label('ChatToAddressList'),
|
|
465
|
+
cc: Joi.array().items(responseAddressSchema).single().description('List of CC addresses').label('ChatCcAddressList'),
|
|
466
|
+
bcc: Joi.array().items(responseAddressSchema).single().description('List of BCC addresses').label('ChatBccAddressList'),
|
|
467
|
+
subject: Joi.string().example('What a wonderful message').description('Message subject'),
|
|
454
468
|
messageSpecialUse: messageSpecialUseSchema
|
|
455
469
|
})
|
|
456
470
|
.description('Email that best matched the question')
|
|
457
471
|
.label('ChatResponseMessage')
|
|
458
472
|
)
|
|
459
473
|
.description('Emails that best matched the question')
|
|
460
|
-
.label('ChatResponseMessages')
|
|
474
|
+
.label('ChatResponseMessages'),
|
|
475
|
+
processPipeline: Joi.array()
|
|
476
|
+
.items(Joi.object().unknown().label('ChatProcessPipelineStep'))
|
|
477
|
+
.description('Diagnostic information about the chat processing steps, including timings and token usage')
|
|
478
|
+
.label('ChatProcessPipeline')
|
|
461
479
|
}).label('ReturnChatResponse'),
|
|
462
480
|
failAction: 'log'
|
|
463
481
|
}
|
|
@@ -8,7 +8,7 @@ const { Account } = require('../account');
|
|
|
8
8
|
const { Gateway } = require('../gateway');
|
|
9
9
|
const getSecret = require('../get-secret');
|
|
10
10
|
const { failAction, httpAgent } = require('../tools');
|
|
11
|
-
const { accountIdSchema } = require('../schemas');
|
|
11
|
+
const { accountIdSchema, errorResponses } = require('../schemas');
|
|
12
12
|
const { REDIS_PREFIX } = require('../consts');
|
|
13
13
|
const packageData = require('../../package.json');
|
|
14
14
|
|
|
@@ -137,6 +137,12 @@ ${now}`,
|
|
|
137
137
|
notes: 'Initiate a delivery test',
|
|
138
138
|
tags: ['api', 'Delivery Test'],
|
|
139
139
|
|
|
140
|
+
plugins: {
|
|
141
|
+
'hapi-swagger': {
|
|
142
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
|
|
140
146
|
auth: {
|
|
141
147
|
strategy: 'api-token',
|
|
142
148
|
mode: 'required'
|
|
@@ -162,13 +168,20 @@ ${now}`,
|
|
|
162
168
|
|
|
163
169
|
response: {
|
|
164
170
|
schema: Joi.object({
|
|
165
|
-
success: Joi.boolean()
|
|
171
|
+
success: Joi.boolean()
|
|
172
|
+
.example(true)
|
|
173
|
+
.description('Was the test started. Not present if queueing the test message failed')
|
|
174
|
+
.label('ResponseDeliveryStartSuccess'),
|
|
166
175
|
deliveryTest: Joi.string()
|
|
167
176
|
.guid({
|
|
168
177
|
version: ['uuidv4', 'uuidv5']
|
|
169
178
|
})
|
|
170
179
|
.example('6420a6ad-7f82-4e4f-8112-82a9dad1f34d')
|
|
171
|
-
.description('Test ID')
|
|
180
|
+
.description('Test ID. Not present if queueing the test message failed'),
|
|
181
|
+
error: Joi.string()
|
|
182
|
+
.example('Oops, something went wrong')
|
|
183
|
+
.description('Error message. Only present if queueing the test message failed - in that case success and deliveryTest are not set')
|
|
184
|
+
.label('ResponseDeliveryStartError')
|
|
172
185
|
}).label('DeliveryStartResponse'),
|
|
173
186
|
failAction: 'log'
|
|
174
187
|
}
|
|
@@ -242,7 +255,7 @@ ${now}`,
|
|
|
242
255
|
};
|
|
243
256
|
|
|
244
257
|
if (testResponse.spf && testResponse.spf.status && testResponse.spf.status.comment) {
|
|
245
|
-
testResponse.spf.status.comment = testResponse.spf.status.comment.replace(/^[^:\s]
|
|
258
|
+
testResponse.spf.status.comment = testResponse.spf.status.comment.replace(/^[^:\s]+:\s*/, '');
|
|
246
259
|
}
|
|
247
260
|
}
|
|
248
261
|
|
|
@@ -274,6 +287,12 @@ ${now}`,
|
|
|
274
287
|
notes: 'Check delivery test status',
|
|
275
288
|
tags: ['api', 'Delivery Test'],
|
|
276
289
|
|
|
290
|
+
plugins: {
|
|
291
|
+
'hapi-swagger': {
|
|
292
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
|
|
277
296
|
auth: {
|
|
278
297
|
strategy: 'api-token',
|
|
279
298
|
mode: 'required'
|
|
@@ -302,6 +321,10 @@ ${now}`,
|
|
|
302
321
|
response: {
|
|
303
322
|
schema: Joi.object({
|
|
304
323
|
success: Joi.boolean().example(true).description('Was the test completed').label('ResponseDeliveryCheckSuccess'),
|
|
324
|
+
status: Joi.string()
|
|
325
|
+
.example('pending')
|
|
326
|
+
.description('Test status. Only present while the test message has not yet been received (success=false)')
|
|
327
|
+
.label('ResponseDeliveryCheckStatus'),
|
|
305
328
|
dkim: Joi.object().unknown().description('DKIM results').label('DkimResults'),
|
|
306
329
|
spf: Joi.object().unknown().description('SPF results').label('SpfResults'),
|
|
307
330
|
dmarc: Joi.object().unknown().description('DMARC results').label('DmarcResults'),
|
|
@@ -311,7 +334,9 @@ ${now}`,
|
|
|
311
334
|
.unknown()
|
|
312
335
|
.description('Primary DKIM signature. `status.aligned` should be set, otherwise DKIM check should not be considered as passed.')
|
|
313
336
|
.label('MainSignature')
|
|
314
|
-
})
|
|
337
|
+
})
|
|
338
|
+
.unknown()
|
|
339
|
+
.label('DeliveryCheckResponse'),
|
|
315
340
|
failAction: 'log'
|
|
316
341
|
}
|
|
317
342
|
}
|
|
@@ -5,7 +5,7 @@ const { Export } = require('../export');
|
|
|
5
5
|
const Boom = require('@hapi/boom');
|
|
6
6
|
const Joi = require('joi');
|
|
7
7
|
const { failAction } = require('../tools');
|
|
8
|
-
const { accountIdSchema, exportRequestSchema, exportStatusSchema, exportListSchema, exportIdSchema } = require('../schemas');
|
|
8
|
+
const { accountIdSchema, exportRequestSchema, exportStatusSchema, exportListSchema, exportIdSchema, errorResponses } = require('../schemas');
|
|
9
9
|
const getSecret = require('../get-secret');
|
|
10
10
|
const { createDecryptStream } = require('../stream-encrypt');
|
|
11
11
|
const { handleError } = require('./route-helpers');
|
|
@@ -37,6 +37,12 @@ async function init(args) {
|
|
|
37
37
|
notes: 'Creates a new bulk message export job. The export runs asynchronously and notifies via webhook when complete.',
|
|
38
38
|
tags: ['api', 'Export (Beta)'],
|
|
39
39
|
|
|
40
|
+
plugins: {
|
|
41
|
+
'hapi-swagger': {
|
|
42
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
40
46
|
auth: {
|
|
41
47
|
strategy: 'api-token',
|
|
42
48
|
mode: 'required'
|
|
@@ -90,6 +96,12 @@ async function init(args) {
|
|
|
90
96
|
notes: 'Returns the status and progress of an export job.',
|
|
91
97
|
tags: ['api', 'Export (Beta)'],
|
|
92
98
|
|
|
99
|
+
plugins: {
|
|
100
|
+
'hapi-swagger': {
|
|
101
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
93
105
|
auth: {
|
|
94
106
|
strategy: 'api-token',
|
|
95
107
|
mode: 'required'
|
|
@@ -167,7 +179,8 @@ async function init(args) {
|
|
|
167
179
|
|
|
168
180
|
plugins: {
|
|
169
181
|
'hapi-swagger': {
|
|
170
|
-
produces: ['application/gzip']
|
|
182
|
+
produces: ['application/gzip'],
|
|
183
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500, 503)
|
|
171
184
|
}
|
|
172
185
|
},
|
|
173
186
|
|
|
@@ -214,6 +227,12 @@ async function init(args) {
|
|
|
214
227
|
notes: 'Cancels a pending export or deletes a completed export. Removes both Redis data and the export file.',
|
|
215
228
|
tags: ['api', 'Export (Beta)'],
|
|
216
229
|
|
|
230
|
+
plugins: {
|
|
231
|
+
'hapi-swagger': {
|
|
232
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
|
|
217
236
|
auth: {
|
|
218
237
|
strategy: 'api-token',
|
|
219
238
|
mode: 'required'
|
|
@@ -263,6 +282,12 @@ async function init(args) {
|
|
|
263
282
|
notes: 'Lists all exports for an account with pagination.',
|
|
264
283
|
tags: ['api', 'Export (Beta)'],
|
|
265
284
|
|
|
285
|
+
plugins: {
|
|
286
|
+
'hapi-swagger': {
|
|
287
|
+
responses: errorResponses(400, 401, 403, 429, 500)
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
|
|
266
291
|
auth: {
|
|
267
292
|
strategy: 'api-token',
|
|
268
293
|
mode: 'required'
|
|
@@ -6,7 +6,23 @@ const { Gateway } = require('../gateway');
|
|
|
6
6
|
const getSecret = require('../get-secret');
|
|
7
7
|
const { failAction } = require('../tools');
|
|
8
8
|
const { handleError } = require('./route-helpers');
|
|
9
|
-
const {
|
|
9
|
+
const { errorResponses } = require('../schemas');
|
|
10
|
+
|
|
11
|
+
// Gateways store SMTP delivery errors, not OAuth2 errors, so the error shape differs from the
|
|
12
|
+
// account-level lastErrorSchema
|
|
13
|
+
const gatewayLastErrorSchema = Joi.object({
|
|
14
|
+
created: Joi.number().integer().example(1623868624153).description('Timestamp of the error as milliseconds from epoch'),
|
|
15
|
+
status: Joi.string().valid('error').example('error').description('Status of the last delivery attempt'),
|
|
16
|
+
response: Joi.string().example('535 Authentication failed').description('SMTP server response for the failed delivery'),
|
|
17
|
+
responseCode: Joi.number().integer().example(535).description('SMTP response code'),
|
|
18
|
+
code: Joi.string().example('EAUTH').description('Error type identifier'),
|
|
19
|
+
command: Joi.string().example('AUTH PLAIN').description('SMTP command that failed'),
|
|
20
|
+
description: Joi.string().example('Authentication failed').description('Error description'),
|
|
21
|
+
networkRouting: Joi.object().unknown().allow(null).description('Network routing information for the delivery attempt').label('GatewayErrorNetworkRouting')
|
|
22
|
+
})
|
|
23
|
+
.unknown()
|
|
24
|
+
.description('Information about the last failed delivery attempt using this gateway')
|
|
25
|
+
.label('GatewayErrorEntry');
|
|
10
26
|
|
|
11
27
|
async function init(args) {
|
|
12
28
|
const { server, call, CORS_CONFIG } = args;
|
|
@@ -30,7 +46,11 @@ async function init(args) {
|
|
|
30
46
|
notes: 'Lists registered gateways',
|
|
31
47
|
tags: ['api', 'SMTP Gateway'],
|
|
32
48
|
|
|
33
|
-
plugins: {
|
|
49
|
+
plugins: {
|
|
50
|
+
'hapi-swagger': {
|
|
51
|
+
responses: errorResponses(400, 401, 403, 429, 500)
|
|
52
|
+
}
|
|
53
|
+
},
|
|
34
54
|
|
|
35
55
|
auth: {
|
|
36
56
|
strategy: 'api-token',
|
|
@@ -71,8 +91,12 @@ async function init(args) {
|
|
|
71
91
|
gateway: Joi.string().max(256).required().example('example').description('Gateway ID'),
|
|
72
92
|
name: Joi.string().max(256).example('My Email Gateway').description('Display name for the gateway'),
|
|
73
93
|
deliveries: Joi.number().integer().empty('').example(100).description('Count of email deliveries using this gateway'),
|
|
74
|
-
lastUse: Joi.date()
|
|
75
|
-
|
|
94
|
+
lastUse: Joi.date()
|
|
95
|
+
.iso()
|
|
96
|
+
.allow(null)
|
|
97
|
+
.example('2021-02-17T13:43:18.860Z')
|
|
98
|
+
.description('Last delivery time. Null for gateways that have not been used yet'),
|
|
99
|
+
lastError: gatewayLastErrorSchema.allow(null)
|
|
76
100
|
}).label('GatewayResponseItem')
|
|
77
101
|
)
|
|
78
102
|
.label('GatewayEntries')
|
|
@@ -114,6 +138,12 @@ async function init(args) {
|
|
|
114
138
|
notes: 'Returns stored information about the gateway. Passwords are not included.',
|
|
115
139
|
tags: ['api', 'SMTP Gateway'],
|
|
116
140
|
|
|
141
|
+
plugins: {
|
|
142
|
+
'hapi-swagger': {
|
|
143
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
|
|
117
147
|
auth: {
|
|
118
148
|
strategy: 'api-token',
|
|
119
149
|
mode: 'required'
|
|
@@ -139,10 +169,18 @@ async function init(args) {
|
|
|
139
169
|
|
|
140
170
|
name: Joi.string().max(256).required().example('My Email Gateway').description('Display name for the gateway'),
|
|
141
171
|
deliveries: Joi.number().integer().empty('').example(100).description('Count of email deliveries using this gateway'),
|
|
142
|
-
lastUse: Joi.date()
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
172
|
+
lastUse: Joi.date()
|
|
173
|
+
.iso()
|
|
174
|
+
.allow(null)
|
|
175
|
+
.example('2021-02-17T13:43:18.860Z')
|
|
176
|
+
.description('Last delivery time. Null for gateways that have not been used yet'),
|
|
177
|
+
|
|
178
|
+
user: Joi.string().empty('').trim().allow(null).max(1024).description('SMTP authentication username').label('UserName'),
|
|
179
|
+
pass: Joi.string()
|
|
180
|
+
.empty('')
|
|
181
|
+
.max(1024)
|
|
182
|
+
.description('SMTP authentication password. Always returned as the masked value "******" when a password is set')
|
|
183
|
+
.label('Password'),
|
|
146
184
|
|
|
147
185
|
host: Joi.string().hostname().example('smtp.gmail.com').description('Hostname to connect to').label('Hostname'),
|
|
148
186
|
port: Joi.number()
|
|
@@ -156,12 +194,13 @@ async function init(args) {
|
|
|
156
194
|
secure: Joi.boolean()
|
|
157
195
|
.truthy('Y', 'true', '1', 'on')
|
|
158
196
|
.falsy('N', 'false', 0, '')
|
|
197
|
+
.allow(null)
|
|
159
198
|
.default(false)
|
|
160
199
|
.example(true)
|
|
161
200
|
.description('Should connection use TLS. Usually true for port 465')
|
|
162
201
|
.label('GatewayTlsOptions'),
|
|
163
202
|
|
|
164
|
-
lastError:
|
|
203
|
+
lastError: gatewayLastErrorSchema.allow(null)
|
|
165
204
|
}).label('GatewayResponse'),
|
|
166
205
|
failAction: 'log'
|
|
167
206
|
}
|
|
@@ -188,7 +227,11 @@ async function init(args) {
|
|
|
188
227
|
notes: 'Registers a new SMP gateway',
|
|
189
228
|
tags: ['api', 'SMTP Gateway'],
|
|
190
229
|
|
|
191
|
-
plugins: {
|
|
230
|
+
plugins: {
|
|
231
|
+
'hapi-swagger': {
|
|
232
|
+
responses: errorResponses(400, 401, 403, 429, 500)
|
|
233
|
+
}
|
|
234
|
+
},
|
|
192
235
|
|
|
193
236
|
auth: {
|
|
194
237
|
strategy: 'api-token',
|
|
@@ -265,7 +308,11 @@ async function init(args) {
|
|
|
265
308
|
notes: 'Updates gateway information',
|
|
266
309
|
tags: ['api', 'SMTP Gateway'],
|
|
267
310
|
|
|
268
|
-
plugins: {
|
|
311
|
+
plugins: {
|
|
312
|
+
'hapi-swagger': {
|
|
313
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
314
|
+
}
|
|
315
|
+
},
|
|
269
316
|
|
|
270
317
|
auth: {
|
|
271
318
|
strategy: 'api-token',
|
|
@@ -341,7 +388,11 @@ async function init(args) {
|
|
|
341
388
|
notes: 'Delete SMTP gateway data',
|
|
342
389
|
tags: ['api', 'SMTP Gateway'],
|
|
343
390
|
|
|
344
|
-
plugins: {
|
|
391
|
+
plugins: {
|
|
392
|
+
'hapi-swagger': {
|
|
393
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500)
|
|
394
|
+
}
|
|
395
|
+
},
|
|
345
396
|
|
|
346
397
|
auth: {
|
|
347
398
|
strategy: 'api-token',
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const Joi = require('joi');
|
|
4
4
|
const { failAction } = require('../tools');
|
|
5
5
|
const { handleError } = require('./route-helpers');
|
|
6
|
-
const { licenseSchema } = require('../schemas');
|
|
6
|
+
const { licenseSchema, errorResponses } = require('../schemas');
|
|
7
7
|
|
|
8
8
|
async function init(args) {
|
|
9
9
|
const { server, call, CORS_CONFIG } = args;
|
|
@@ -30,6 +30,12 @@ async function init(args) {
|
|
|
30
30
|
notes: 'Get active license information',
|
|
31
31
|
tags: ['api', 'License'],
|
|
32
32
|
|
|
33
|
+
plugins: {
|
|
34
|
+
'hapi-swagger': {
|
|
35
|
+
responses: errorResponses(401, 403, 429, 500)
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
33
39
|
auth: {
|
|
34
40
|
strategy: 'api-token',
|
|
35
41
|
mode: 'required'
|
|
@@ -65,7 +71,11 @@ async function init(args) {
|
|
|
65
71
|
notes: 'Remove registered active license',
|
|
66
72
|
tags: ['api', 'License'],
|
|
67
73
|
|
|
68
|
-
plugins: {
|
|
74
|
+
plugins: {
|
|
75
|
+
'hapi-swagger': {
|
|
76
|
+
responses: errorResponses(401, 403, 429, 500)
|
|
77
|
+
}
|
|
78
|
+
},
|
|
69
79
|
|
|
70
80
|
auth: {
|
|
71
81
|
strategy: 'api-token',
|
|
@@ -77,7 +87,7 @@ async function init(args) {
|
|
|
77
87
|
schema: Joi.object({
|
|
78
88
|
active: Joi.boolean().example(false),
|
|
79
89
|
details: Joi.boolean().example(false),
|
|
80
|
-
type: Joi.string().example('
|
|
90
|
+
type: Joi.string().example('LICENSE_EMAILENGINE')
|
|
81
91
|
}).label('EmptyLicenseResponse'),
|
|
82
92
|
failAction: 'log'
|
|
83
93
|
}
|
|
@@ -106,7 +116,11 @@ async function init(args) {
|
|
|
106
116
|
notes: 'Set up a license for EmailEngine to unlock all features',
|
|
107
117
|
tags: ['api', 'License'],
|
|
108
118
|
|
|
109
|
-
plugins: {
|
|
119
|
+
plugins: {
|
|
120
|
+
'hapi-swagger': {
|
|
121
|
+
responses: errorResponses(400, 401, 403, 429, 500)
|
|
122
|
+
}
|
|
123
|
+
},
|
|
110
124
|
|
|
111
125
|
auth: {
|
|
112
126
|
strategy: 'api-token',
|
|
@@ -7,7 +7,7 @@ const { Account } = require('../account');
|
|
|
7
7
|
const getSecret = require('../get-secret');
|
|
8
8
|
const { failAction } = require('../tools');
|
|
9
9
|
const { handleError } = require('./route-helpers');
|
|
10
|
-
const { accountIdSchema, mailboxesSchema } = require('../schemas');
|
|
10
|
+
const { accountIdSchema, mailboxesSchema, errorResponses } = require('../schemas');
|
|
11
11
|
|
|
12
12
|
async function init(args) {
|
|
13
13
|
const { server, call, CORS_CONFIG, FLAG_SORT_ORDER } = args;
|
|
@@ -55,6 +55,12 @@ async function init(args) {
|
|
|
55
55
|
notes: 'Lists all available mailboxes',
|
|
56
56
|
tags: ['api', 'Mailbox'],
|
|
57
57
|
|
|
58
|
+
plugins: {
|
|
59
|
+
'hapi-swagger': {
|
|
60
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500, 503)
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
|
|
58
64
|
auth: {
|
|
59
65
|
strategy: 'api-token',
|
|
60
66
|
mode: 'required'
|
|
@@ -128,7 +134,11 @@ async function init(args) {
|
|
|
128
134
|
notes: 'Create new mailbox folder',
|
|
129
135
|
tags: ['api', 'Mailbox'],
|
|
130
136
|
|
|
131
|
-
plugins: {
|
|
137
|
+
plugins: {
|
|
138
|
+
'hapi-swagger': {
|
|
139
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500, 503)
|
|
140
|
+
}
|
|
141
|
+
},
|
|
132
142
|
|
|
133
143
|
auth: {
|
|
134
144
|
strategy: 'api-token',
|
|
@@ -154,13 +164,13 @@ async function init(args) {
|
|
|
154
164
|
.single()
|
|
155
165
|
.example(['Parent folder', 'Subfolder'])
|
|
156
166
|
.description('Mailbox path as an array or a string. If account is namespaced then namespace prefix is added by default.')
|
|
157
|
-
.label('
|
|
167
|
+
.label('CreateMailboxPathInput')
|
|
158
168
|
}).label('CreateMailbox')
|
|
159
169
|
},
|
|
160
170
|
|
|
161
171
|
response: {
|
|
162
172
|
schema: Joi.object({
|
|
163
|
-
path: Joi.string().required().example('Kalender/S&APw-nnip&AOQ-evad').description('Full path to mailbox').label('
|
|
173
|
+
path: Joi.string().required().example('Kalender/S&APw-nnip&AOQ-evad').description('Full path to mailbox').label('CreatedMailboxPath'),
|
|
164
174
|
mailboxId: Joi.string().example('1439876283476').description('Mailbox ID (if server has support)').label('MailboxId'),
|
|
165
175
|
created: Joi.boolean().example(true).description('Was the mailbox created')
|
|
166
176
|
}).label('CreateMailboxResponse'),
|
|
@@ -205,7 +215,11 @@ async function init(args) {
|
|
|
205
215
|
notes: 'Modify an existing mailbox folder (rename or change subscription status)',
|
|
206
216
|
tags: ['api', 'Mailbox'],
|
|
207
217
|
|
|
208
|
-
plugins: {
|
|
218
|
+
plugins: {
|
|
219
|
+
'hapi-swagger': {
|
|
220
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500, 503)
|
|
221
|
+
}
|
|
222
|
+
},
|
|
209
223
|
|
|
210
224
|
auth: {
|
|
211
225
|
strategy: 'api-token',
|
|
@@ -244,8 +258,12 @@ async function init(args) {
|
|
|
244
258
|
|
|
245
259
|
response: {
|
|
246
260
|
schema: Joi.object({
|
|
247
|
-
path: Joi.string().
|
|
261
|
+
path: Joi.string().example('Mail').description('Mailbox folder path').label('ExistingMailboxPath'),
|
|
248
262
|
newPath: Joi.string().example('Kalender/S&APw-nnip&AOQ-evad').description('Full path to mailbox if renamed').label('NewMailboxPath'),
|
|
263
|
+
mailboxId: Joi.string()
|
|
264
|
+
.example('1439876283476')
|
|
265
|
+
.description('Mailbox ID after the rename (Gmail API and MS Graph API accounts only)')
|
|
266
|
+
.label('ModifyMailboxId'),
|
|
249
267
|
renamed: Joi.boolean().example(true).description('Was the mailbox renamed'),
|
|
250
268
|
subscribed: Joi.boolean().example(true).description('Subscription status after modification')
|
|
251
269
|
}).label('ModifyMailboxResponse'),
|
|
@@ -279,7 +297,11 @@ async function init(args) {
|
|
|
279
297
|
notes: 'Delete existing mailbox folder',
|
|
280
298
|
tags: ['api', 'Mailbox'],
|
|
281
299
|
|
|
282
|
-
plugins: {
|
|
300
|
+
plugins: {
|
|
301
|
+
'hapi-swagger': {
|
|
302
|
+
responses: errorResponses(400, 401, 403, 404, 429, 500, 503)
|
|
303
|
+
}
|
|
304
|
+
},
|
|
283
305
|
|
|
284
306
|
auth: {
|
|
285
307
|
strategy: 'api-token',
|
|
@@ -307,6 +329,10 @@ async function init(args) {
|
|
|
307
329
|
response: {
|
|
308
330
|
schema: Joi.object({
|
|
309
331
|
path: Joi.string().required().example('Kalender/S&APw-nnip&AOQ-evad').description('Full path to mailbox').label('MailboxPath'),
|
|
332
|
+
mailboxId: Joi.string()
|
|
333
|
+
.example('1439876283476')
|
|
334
|
+
.description('ID of the deleted mailbox (Gmail API and MS Graph API accounts only)')
|
|
335
|
+
.label('DeleteMailboxId'),
|
|
310
336
|
deleted: Joi.boolean().example(true).description('Was the mailbox deleted')
|
|
311
337
|
}).label('DeleteMailboxResponse'),
|
|
312
338
|
failAction: 'log'
|