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.
Files changed (74) hide show
  1. package/.github/workflows/deploy.yml +6 -3
  2. package/.github/workflows/release.yaml +2 -0
  3. package/CHANGELOG.md +19 -0
  4. package/Gruntfile.js +3 -1
  5. package/data/google-crawlers.json +1 -1
  6. package/getswagger.sh +40 -4
  7. package/gettext-extract.js +163 -0
  8. package/lib/account.js +73 -47
  9. package/lib/api-routes/account-routes.js +231 -71
  10. package/lib/api-routes/blocklist-routes.js +25 -18
  11. package/lib/api-routes/chat-routes.js +32 -14
  12. package/lib/api-routes/delivery-test-routes.js +30 -5
  13. package/lib/api-routes/export-routes.js +27 -2
  14. package/lib/api-routes/gateway-routes.js +63 -12
  15. package/lib/api-routes/license-routes.js +18 -4
  16. package/lib/api-routes/mailbox-routes.js +33 -7
  17. package/lib/api-routes/message-routes.js +200 -58
  18. package/lib/api-routes/oauth2-app-routes.js +90 -24
  19. package/lib/api-routes/outbox-routes.js +16 -4
  20. package/lib/api-routes/pubsub-routes.js +8 -4
  21. package/lib/api-routes/route-helpers.js +14 -1
  22. package/lib/api-routes/settings-routes.js +51 -25
  23. package/lib/api-routes/stats-routes.js +37 -3
  24. package/lib/api-routes/submit-routes.js +31 -42
  25. package/lib/api-routes/template-routes.js +54 -21
  26. package/lib/api-routes/token-routes.js +67 -67
  27. package/lib/api-routes/webhook-route-routes.js +37 -8
  28. package/lib/autodetect-imap-settings.js +0 -2
  29. package/lib/consts.js +5 -0
  30. package/lib/email-client/base-client.js +28 -6
  31. package/lib/email-client/gmail-client.js +119 -112
  32. package/lib/email-client/imap/subconnection.js +0 -1
  33. package/lib/email-client/imap/sync-operations.js +1 -1
  34. package/lib/email-client/imap-client.js +36 -17
  35. package/lib/email-client/notification-handler.js +1 -4
  36. package/lib/email-client/outlook-client.js +49 -62
  37. package/lib/export.js +37 -1
  38. package/lib/feature-flags.js +2 -2
  39. package/lib/gateway.js +4 -9
  40. package/lib/get-raw-email.js +5 -5
  41. package/lib/imapproxy/imap-core/lib/imap-connection.js +0 -1
  42. package/lib/logger.js +24 -21
  43. package/lib/metrics-collector.js +0 -2
  44. package/lib/oauth2-apps.js +13 -4
  45. package/lib/outbox.js +24 -40
  46. package/lib/redis-operations.js +1 -1
  47. package/lib/schemas.js +403 -83
  48. package/lib/sentry.js +139 -0
  49. package/lib/settings.js +9 -3
  50. package/lib/stream-encrypt.js +1 -1
  51. package/lib/templates.js +1 -1
  52. package/lib/tokens.js +5 -3
  53. package/lib/tools.js +2 -4
  54. package/lib/ui-routes/account-routes.js +7 -4
  55. package/lib/ui-routes/admin-config-routes.js +16 -3
  56. package/lib/ui-routes/oauth-config-routes.js +0 -2
  57. package/lib/ui-routes/route-helpers.js +0 -2
  58. package/lib/ui-routes/unsubscribe-routes.js +0 -2
  59. package/lib/webhooks.js +8 -4
  60. package/package.json +9 -8
  61. package/sbom.json +1 -1
  62. package/server.js +8 -23
  63. package/static/licenses.html +152 -292
  64. package/translations/messages.pot +122 -122
  65. package/update-info.sh +19 -1
  66. package/views/config/logging.hbs +48 -0
  67. package/workers/api.js +11 -32
  68. package/workers/documents.js +2 -22
  69. package/workers/export.js +16 -50
  70. package/workers/imap-proxy.js +3 -23
  71. package/workers/imap.js +2 -22
  72. package/workers/smtp.js +2 -22
  73. package/workers/submit.js +6 -24
  74. 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, addressSchema, messageSpecialUseSchema, fromAddressSchema } = require('../schemas');
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.tokens
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: true,
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.tokens
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: !!(responseData.answer || responseData.message),
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().example(true).description('Was the request successful').label('ReturnChatResponseSuccess'),
438
- answer: Joi.string().trim().example('Last tuesday').description('Chat response').label('ChatResponse').required(),
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: fromAddressSchema,
457
+ from: responseFromAddressSchema,
446
458
 
447
459
  to: Joi.array()
448
- .items(addressSchema)
460
+ .items(responseAddressSchema)
449
461
  .single()
450
462
  .description('List of addresses')
451
463
  .example([{ address: 'recipient@example.com' }])
452
- .label('AddressList'),
453
- subject: Joi.string().allow('').example('What a wonderful message').description('Message subject'),
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().example(true).description('Was the test started').label('ResponseDeliveryStartSuccess'),
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]+: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
- }).label('DeliveryCheckResponse'),
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 { lastErrorSchema } = require('../schemas');
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().iso().example('2021-02-17T13:43:18.860Z').description('Last delivery time'),
75
- lastError: lastErrorSchema.allow(null)
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().iso().example('2021-02-17T13:43:18.860Z').description('Last delivery time'),
143
-
144
- user: Joi.string().empty('').trim().max(1024).description('SMTP authentication username').label('UserName'),
145
- pass: Joi.string().empty('').max(1024).description('SMTP authentication password').label('Password'),
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: lastErrorSchema.allow(null)
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('SSPL-1.0-or-later')
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('MailboxPath')
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('MailboxPath'),
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().required().example('Mail').description('Mailbox folder path').label('ExistingMailboxPath'),
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'