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.
- package/.github/codeql/codeql-config.yml +16 -0
- package/.github/workflows/codeql.yml +102 -0
- package/.github/workflows/deploy.yml +8 -0
- package/.github/workflows/release.yaml +4 -0
- package/.github/workflows/test.yml +3 -0
- package/CHANGELOG.md +49 -0
- package/SECURITY.md +80 -0
- package/SECURITY.txt +27 -0
- package/config/default.toml +2 -0
- package/data/google-crawlers.json +13 -1
- package/lib/account.js +62 -25
- package/lib/api-routes/account-routes.js +493 -75
- package/lib/api-routes/blocklist-routes.js +337 -0
- package/lib/api-routes/delivery-test-routes.js +321 -0
- package/lib/api-routes/export-routes.js +1 -12
- package/lib/api-routes/gateway-routes.js +376 -0
- package/lib/api-routes/license-routes.js +142 -0
- package/lib/api-routes/mailbox-routes.js +318 -0
- package/lib/api-routes/message-routes.js +21 -129
- package/lib/api-routes/oauth2-app-routes.js +631 -0
- package/lib/api-routes/outbox-routes.js +173 -0
- package/lib/api-routes/pubsub-routes.js +98 -0
- package/lib/api-routes/route-helpers.js +45 -0
- package/lib/api-routes/settings-routes.js +331 -0
- package/lib/api-routes/stats-routes.js +77 -0
- package/lib/api-routes/submit-routes.js +472 -0
- package/lib/api-routes/template-routes.js +7 -55
- package/lib/api-routes/token-routes.js +297 -0
- package/lib/api-routes/webhook-route-routes.js +152 -0
- package/lib/email-client/gmail-client.js +14 -0
- package/lib/email-client/imap/mailbox.js +34 -11
- package/lib/email-client/imap/subconnection.js +20 -12
- package/lib/email-client/imap/sync-operations.js +130 -2
- package/lib/email-client/imap-client.js +116 -58
- package/lib/email-client/outlook-client.js +85 -13
- package/lib/export.js +60 -19
- package/lib/imapproxy/imap-core/lib/commands/starttls.js +18 -0
- package/lib/imapproxy/imap-core/lib/imap-command.js +7 -2
- package/lib/imapproxy/imap-core/lib/imap-connection.js +113 -23
- package/lib/imapproxy/imap-core/lib/imap-server.js +25 -1
- package/lib/imapproxy/imap-core/lib/imap-stream.js +26 -0
- package/lib/imapproxy/imap-server.js +92 -29
- package/lib/message-port-stream.js +113 -16
- package/lib/reject-worker-calls.js +42 -0
- package/lib/routes-ui.js +37 -8778
- package/lib/schemas.js +26 -1
- package/lib/tools.js +73 -0
- package/lib/ui-routes/account-routes.js +40 -210
- package/lib/ui-routes/admin-config-routes.js +913 -487
- package/lib/ui-routes/admin-entities-routes.js +1 -0
- package/lib/ui-routes/auth-routes.js +1339 -0
- package/lib/ui-routes/dashboard-routes.js +188 -0
- package/lib/ui-routes/document-store-routes.js +800 -0
- package/lib/ui-routes/export-routes.js +217 -0
- package/lib/ui-routes/internals-routes.js +354 -0
- package/lib/ui-routes/network-config-routes.js +759 -0
- package/lib/ui-routes/{oauth-routes.js → oauth-config-routes.js} +371 -91
- package/lib/ui-routes/route-helpers.js +316 -0
- package/lib/ui-routes/smtp-test-routes.js +236 -0
- package/lib/ui-routes/unsubscribe-routes.js +234 -0
- package/lib/webhook-request.js +36 -0
- package/package.json +17 -17
- package/sbom.json +1 -1
- package/server.js +217 -19
- package/static/licenses.html +52 -182
- package/translations/messages.pot +131 -151
- package/views/dashboard.hbs +7 -26
- package/views/internals/index.hbs +15 -0
- package/views/tokens/index.hbs +9 -0
- package/workers/api.js +198 -4401
- package/workers/export.js +87 -54
- package/workers/imap.js +29 -13
- package/workers/submit.js +20 -11
- package/workers/webhooks.js +6 -20
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Boom = require('@hapi/boom');
|
|
4
|
+
const Joi = require('joi');
|
|
5
|
+
const { redis } = require('../db');
|
|
6
|
+
const { Account } = require('../account');
|
|
7
|
+
const getSecret = require('../get-secret');
|
|
8
|
+
const { failAction } = require('../tools');
|
|
9
|
+
const { handleError } = require('./route-helpers');
|
|
10
|
+
const { accountIdSchema, mailboxesSchema } = require('../schemas');
|
|
11
|
+
|
|
12
|
+
async function init(args) {
|
|
13
|
+
const { server, call, CORS_CONFIG, FLAG_SORT_ORDER } = args;
|
|
14
|
+
|
|
15
|
+
server.route({
|
|
16
|
+
method: 'GET',
|
|
17
|
+
path: '/v1/account/{account}/mailboxes',
|
|
18
|
+
|
|
19
|
+
async handler(request) {
|
|
20
|
+
let accountObject = new Account({
|
|
21
|
+
redis,
|
|
22
|
+
account: request.params.account,
|
|
23
|
+
call,
|
|
24
|
+
secret: await getSecret(),
|
|
25
|
+
timeout: request.headers['x-ee-timeout']
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
let mailboxes = await accountObject.getMailboxListing(request.query);
|
|
30
|
+
|
|
31
|
+
if (mailboxes && Array.isArray(mailboxes)) {
|
|
32
|
+
mailboxes = mailboxes.sort((a, b) => {
|
|
33
|
+
if (a.specialUse && !b.specialUse) {
|
|
34
|
+
return -1;
|
|
35
|
+
}
|
|
36
|
+
if (!a.specialUse && b.specialUse) {
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
if (a.specialUse && b.specialUse) {
|
|
40
|
+
return FLAG_SORT_ORDER.indexOf(a.specialUse) - FLAG_SORT_ORDER.indexOf(b.specialUse);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return a.path.localeCompare(b.path);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { mailboxes };
|
|
48
|
+
} catch (err) {
|
|
49
|
+
handleError(request, err);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
options: {
|
|
54
|
+
description: 'List mailboxes',
|
|
55
|
+
notes: 'Lists all available mailboxes',
|
|
56
|
+
tags: ['api', 'Mailbox'],
|
|
57
|
+
|
|
58
|
+
auth: {
|
|
59
|
+
strategy: 'api-token',
|
|
60
|
+
mode: 'required'
|
|
61
|
+
},
|
|
62
|
+
cors: CORS_CONFIG,
|
|
63
|
+
|
|
64
|
+
validate: {
|
|
65
|
+
options: {
|
|
66
|
+
stripUnknown: false,
|
|
67
|
+
abortEarly: false,
|
|
68
|
+
convert: true
|
|
69
|
+
},
|
|
70
|
+
failAction,
|
|
71
|
+
|
|
72
|
+
params: Joi.object({
|
|
73
|
+
account: accountIdSchema.required()
|
|
74
|
+
}),
|
|
75
|
+
|
|
76
|
+
query: Joi.object({
|
|
77
|
+
counters: Joi.boolean()
|
|
78
|
+
.truthy('Y', 'true', '1')
|
|
79
|
+
.falsy('N', 'false', 0)
|
|
80
|
+
.default(false)
|
|
81
|
+
.description('If true, then includes message counters in the response')
|
|
82
|
+
.label('MailboxCounters')
|
|
83
|
+
}).label('MailboxListQuery')
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
response: {
|
|
87
|
+
schema: Joi.object({
|
|
88
|
+
mailboxes: mailboxesSchema
|
|
89
|
+
}).label('MailboxesFilterResponse'),
|
|
90
|
+
failAction: 'log'
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
server.route({
|
|
96
|
+
method: 'POST',
|
|
97
|
+
path: '/v1/account/{account}/mailbox',
|
|
98
|
+
|
|
99
|
+
async handler(request) {
|
|
100
|
+
let accountObject = new Account({
|
|
101
|
+
redis,
|
|
102
|
+
account: request.params.account,
|
|
103
|
+
call,
|
|
104
|
+
secret: await getSecret(),
|
|
105
|
+
timeout: request.headers['x-ee-timeout']
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
return await accountObject.createMailbox(request.payload.path);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
request.logger.error({ msg: 'API request failed', err });
|
|
112
|
+
if (Boom.isBoom(err)) {
|
|
113
|
+
throw err;
|
|
114
|
+
}
|
|
115
|
+
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
116
|
+
if (err.code) {
|
|
117
|
+
error.output.payload.code = err.code;
|
|
118
|
+
}
|
|
119
|
+
if (err.info) {
|
|
120
|
+
error.output.payload.details = err.info;
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
options: {
|
|
127
|
+
description: 'Create mailbox',
|
|
128
|
+
notes: 'Create new mailbox folder',
|
|
129
|
+
tags: ['api', 'Mailbox'],
|
|
130
|
+
|
|
131
|
+
plugins: {},
|
|
132
|
+
|
|
133
|
+
auth: {
|
|
134
|
+
strategy: 'api-token',
|
|
135
|
+
mode: 'required'
|
|
136
|
+
},
|
|
137
|
+
cors: CORS_CONFIG,
|
|
138
|
+
|
|
139
|
+
validate: {
|
|
140
|
+
options: {
|
|
141
|
+
stripUnknown: false,
|
|
142
|
+
abortEarly: false,
|
|
143
|
+
convert: true
|
|
144
|
+
},
|
|
145
|
+
failAction,
|
|
146
|
+
|
|
147
|
+
params: Joi.object({
|
|
148
|
+
account: accountIdSchema.required()
|
|
149
|
+
}),
|
|
150
|
+
|
|
151
|
+
payload: Joi.object({
|
|
152
|
+
path: Joi.array()
|
|
153
|
+
.items(Joi.string().max(256))
|
|
154
|
+
.single()
|
|
155
|
+
.example(['Parent folder', 'Subfolder'])
|
|
156
|
+
.description('Mailbox path as an array or a string. If account is namespaced then namespace prefix is added by default.')
|
|
157
|
+
.label('MailboxPath')
|
|
158
|
+
}).label('CreateMailbox')
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
response: {
|
|
162
|
+
schema: Joi.object({
|
|
163
|
+
path: Joi.string().required().example('Kalender/S&APw-nnip&AOQ-evad').description('Full path to mailbox').label('MailboxPath'),
|
|
164
|
+
mailboxId: Joi.string().example('1439876283476').description('Mailbox ID (if server has support)').label('MailboxId'),
|
|
165
|
+
created: Joi.boolean().example(true).description('Was the mailbox created')
|
|
166
|
+
}).label('CreateMailboxResponse'),
|
|
167
|
+
failAction: 'log'
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
server.route({
|
|
173
|
+
method: 'PUT',
|
|
174
|
+
path: '/v1/account/{account}/mailbox',
|
|
175
|
+
|
|
176
|
+
async handler(request) {
|
|
177
|
+
let accountObject = new Account({
|
|
178
|
+
redis,
|
|
179
|
+
account: request.params.account,
|
|
180
|
+
call,
|
|
181
|
+
secret: await getSecret(),
|
|
182
|
+
timeout: request.headers['x-ee-timeout']
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
return await accountObject.modifyMailbox(request.payload.path, request.payload.newPath, request.payload.subscribed);
|
|
187
|
+
} catch (err) {
|
|
188
|
+
request.logger.error({ msg: 'API request failed', err });
|
|
189
|
+
if (Boom.isBoom(err)) {
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
193
|
+
if (err.code) {
|
|
194
|
+
error.output.payload.code = err.code;
|
|
195
|
+
}
|
|
196
|
+
if (err.info) {
|
|
197
|
+
error.output.payload.details = err.info;
|
|
198
|
+
}
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
options: {
|
|
204
|
+
description: 'Modify mailbox',
|
|
205
|
+
notes: 'Modify an existing mailbox folder (rename or change subscription status)',
|
|
206
|
+
tags: ['api', 'Mailbox'],
|
|
207
|
+
|
|
208
|
+
plugins: {},
|
|
209
|
+
|
|
210
|
+
auth: {
|
|
211
|
+
strategy: 'api-token',
|
|
212
|
+
mode: 'required'
|
|
213
|
+
},
|
|
214
|
+
cors: CORS_CONFIG,
|
|
215
|
+
|
|
216
|
+
validate: {
|
|
217
|
+
options: {
|
|
218
|
+
stripUnknown: false,
|
|
219
|
+
abortEarly: false,
|
|
220
|
+
convert: true
|
|
221
|
+
},
|
|
222
|
+
failAction,
|
|
223
|
+
|
|
224
|
+
params: Joi.object({
|
|
225
|
+
account: accountIdSchema.required()
|
|
226
|
+
}),
|
|
227
|
+
|
|
228
|
+
payload: Joi.object({
|
|
229
|
+
path: Joi.string().required().example('Folder Name').description('Mailbox folder path to modify').label('ExistingMailboxPath'),
|
|
230
|
+
newPath: Joi.array()
|
|
231
|
+
.items(Joi.string().max(256))
|
|
232
|
+
.single()
|
|
233
|
+
.example(['Parent folder', 'Subfolder'])
|
|
234
|
+
.description('New mailbox path as an array or a string. If account is namespaced then namespace prefix is added by default. Optional.')
|
|
235
|
+
.label('TargetMailboxPath'),
|
|
236
|
+
subscribed: Joi.boolean()
|
|
237
|
+
.example(true)
|
|
238
|
+
.description('Change mailbox subscription status. Only applies to IMAP accounts, ignored for Gmail and Outlook.')
|
|
239
|
+
.label('SubscriptionStatus')
|
|
240
|
+
})
|
|
241
|
+
.or('newPath', 'subscribed')
|
|
242
|
+
.label('ModifyMailbox')
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
response: {
|
|
246
|
+
schema: Joi.object({
|
|
247
|
+
path: Joi.string().required().example('Mail').description('Mailbox folder path').label('ExistingMailboxPath'),
|
|
248
|
+
newPath: Joi.string().example('Kalender/S&APw-nnip&AOQ-evad').description('Full path to mailbox if renamed').label('NewMailboxPath'),
|
|
249
|
+
renamed: Joi.boolean().example(true).description('Was the mailbox renamed'),
|
|
250
|
+
subscribed: Joi.boolean().example(true).description('Subscription status after modification')
|
|
251
|
+
}).label('ModifyMailboxResponse'),
|
|
252
|
+
failAction: 'log'
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
server.route({
|
|
258
|
+
method: 'DELETE',
|
|
259
|
+
path: '/v1/account/{account}/mailbox',
|
|
260
|
+
|
|
261
|
+
async handler(request) {
|
|
262
|
+
let accountObject = new Account({
|
|
263
|
+
redis,
|
|
264
|
+
account: request.params.account,
|
|
265
|
+
call,
|
|
266
|
+
secret: await getSecret(),
|
|
267
|
+
timeout: request.headers['x-ee-timeout']
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
return await accountObject.deleteMailbox(request.query.path);
|
|
272
|
+
} catch (err) {
|
|
273
|
+
handleError(request, err);
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
options: {
|
|
278
|
+
description: 'Delete mailbox',
|
|
279
|
+
notes: 'Delete existing mailbox folder',
|
|
280
|
+
tags: ['api', 'Mailbox'],
|
|
281
|
+
|
|
282
|
+
plugins: {},
|
|
283
|
+
|
|
284
|
+
auth: {
|
|
285
|
+
strategy: 'api-token',
|
|
286
|
+
mode: 'required'
|
|
287
|
+
},
|
|
288
|
+
cors: CORS_CONFIG,
|
|
289
|
+
|
|
290
|
+
validate: {
|
|
291
|
+
options: {
|
|
292
|
+
stripUnknown: false,
|
|
293
|
+
abortEarly: false,
|
|
294
|
+
convert: true
|
|
295
|
+
},
|
|
296
|
+
failAction,
|
|
297
|
+
|
|
298
|
+
params: Joi.object({
|
|
299
|
+
account: accountIdSchema.required()
|
|
300
|
+
}),
|
|
301
|
+
|
|
302
|
+
query: Joi.object({
|
|
303
|
+
path: Joi.string().required().example('My Outdated Mail').description('Mailbox folder path to delete').label('MailboxPath')
|
|
304
|
+
}).label('DeleteMailbox')
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
response: {
|
|
308
|
+
schema: Joi.object({
|
|
309
|
+
path: Joi.string().required().example('Kalender/S&APw-nnip&AOQ-evad').description('Full path to mailbox').label('MailboxPath'),
|
|
310
|
+
deleted: Joi.boolean().example(true).description('Was the mailbox deleted')
|
|
311
|
+
}).label('DeleteMailboxResponse'),
|
|
312
|
+
failAction: 'log'
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
module.exports = init;
|
|
@@ -4,9 +4,9 @@ const { redis } = require('../db');
|
|
|
4
4
|
const { Account } = require('../account');
|
|
5
5
|
const getSecret = require('../get-secret');
|
|
6
6
|
const settings = require('../settings');
|
|
7
|
-
const Boom = require('@hapi/boom');
|
|
8
7
|
const Joi = require('joi');
|
|
9
8
|
const { failAction } = require('../tools');
|
|
9
|
+
const { handleError } = require('./route-helpers');
|
|
10
10
|
|
|
11
11
|
const {
|
|
12
12
|
accountIdSchema,
|
|
@@ -44,15 +44,7 @@ async function init(args) {
|
|
|
44
44
|
const response = await accountObject.getRawMessage(request.params.message);
|
|
45
45
|
return h.response(response);
|
|
46
46
|
} catch (err) {
|
|
47
|
-
|
|
48
|
-
if (Boom.isBoom(err)) {
|
|
49
|
-
throw err;
|
|
50
|
-
}
|
|
51
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
52
|
-
if (err.code) {
|
|
53
|
-
error.output.payload.code = err.code;
|
|
54
|
-
}
|
|
55
|
-
throw error;
|
|
47
|
+
handleError(request, err);
|
|
56
48
|
}
|
|
57
49
|
},
|
|
58
50
|
options: {
|
|
@@ -106,15 +98,7 @@ async function init(args) {
|
|
|
106
98
|
try {
|
|
107
99
|
return await accountObject.getMessage(request.params.message, request.query);
|
|
108
100
|
} catch (err) {
|
|
109
|
-
|
|
110
|
-
if (Boom.isBoom(err)) {
|
|
111
|
-
throw err;
|
|
112
|
-
}
|
|
113
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
114
|
-
if (err.code) {
|
|
115
|
-
error.output.payload.code = err.code;
|
|
116
|
-
}
|
|
117
|
-
throw error;
|
|
101
|
+
handleError(request, err);
|
|
118
102
|
}
|
|
119
103
|
},
|
|
120
104
|
options: {
|
|
@@ -213,15 +197,7 @@ async function init(args) {
|
|
|
213
197
|
try {
|
|
214
198
|
return await accountObject.uploadMessage(request.payload);
|
|
215
199
|
} catch (err) {
|
|
216
|
-
|
|
217
|
-
if (Boom.isBoom(err)) {
|
|
218
|
-
throw err;
|
|
219
|
-
}
|
|
220
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
221
|
-
if (err.code) {
|
|
222
|
-
error.output.payload.code = err.code;
|
|
223
|
-
}
|
|
224
|
-
throw error;
|
|
200
|
+
handleError(request, err);
|
|
225
201
|
}
|
|
226
202
|
},
|
|
227
203
|
options: {
|
|
@@ -390,15 +366,7 @@ async function init(args) {
|
|
|
390
366
|
try {
|
|
391
367
|
return await accountObject.updateMessage(request.params.message, request.payload);
|
|
392
368
|
} catch (err) {
|
|
393
|
-
|
|
394
|
-
if (Boom.isBoom(err)) {
|
|
395
|
-
throw err;
|
|
396
|
-
}
|
|
397
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
398
|
-
if (err.code) {
|
|
399
|
-
error.output.payload.code = err.code;
|
|
400
|
-
}
|
|
401
|
-
throw error;
|
|
369
|
+
handleError(request, err);
|
|
402
370
|
}
|
|
403
371
|
},
|
|
404
372
|
options: {
|
|
@@ -464,15 +432,7 @@ async function init(args) {
|
|
|
464
432
|
try {
|
|
465
433
|
return await accountObject.updateMessages(request.query.path, request.payload.search, request.payload.update);
|
|
466
434
|
} catch (err) {
|
|
467
|
-
|
|
468
|
-
if (Boom.isBoom(err)) {
|
|
469
|
-
throw err;
|
|
470
|
-
}
|
|
471
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
472
|
-
if (err.code) {
|
|
473
|
-
error.output.payload.code = err.code;
|
|
474
|
-
}
|
|
475
|
-
throw error;
|
|
435
|
+
handleError(request, err);
|
|
476
436
|
}
|
|
477
437
|
},
|
|
478
438
|
options: {
|
|
@@ -548,15 +508,7 @@ async function init(args) {
|
|
|
548
508
|
}
|
|
549
509
|
return await accountObject.moveMessage(request.params.message, { path: request.payload.path }, { source: sourceOption });
|
|
550
510
|
} catch (err) {
|
|
551
|
-
|
|
552
|
-
if (Boom.isBoom(err)) {
|
|
553
|
-
throw err;
|
|
554
|
-
}
|
|
555
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
556
|
-
if (err.code) {
|
|
557
|
-
error.output.payload.code = err.code;
|
|
558
|
-
}
|
|
559
|
-
throw error;
|
|
511
|
+
handleError(request, err);
|
|
560
512
|
}
|
|
561
513
|
},
|
|
562
514
|
options: {
|
|
@@ -626,15 +578,7 @@ async function init(args) {
|
|
|
626
578
|
try {
|
|
627
579
|
return await accountObject.moveMessages(request.query.path, request.payload.search, { path: request.payload.path });
|
|
628
580
|
} catch (err) {
|
|
629
|
-
|
|
630
|
-
if (Boom.isBoom(err)) {
|
|
631
|
-
throw err;
|
|
632
|
-
}
|
|
633
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
634
|
-
if (err.code) {
|
|
635
|
-
error.output.payload.code = err.code;
|
|
636
|
-
}
|
|
637
|
-
throw error;
|
|
581
|
+
handleError(request, err);
|
|
638
582
|
}
|
|
639
583
|
},
|
|
640
584
|
options: {
|
|
@@ -709,15 +653,7 @@ async function init(args) {
|
|
|
709
653
|
try {
|
|
710
654
|
return await accountObject.deleteMessage(request.params.message, request.query.force);
|
|
711
655
|
} catch (err) {
|
|
712
|
-
|
|
713
|
-
if (Boom.isBoom(err)) {
|
|
714
|
-
throw err;
|
|
715
|
-
}
|
|
716
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
717
|
-
if (err.code) {
|
|
718
|
-
error.output.payload.code = err.code;
|
|
719
|
-
}
|
|
720
|
-
throw error;
|
|
656
|
+
handleError(request, err);
|
|
721
657
|
}
|
|
722
658
|
},
|
|
723
659
|
options: {
|
|
@@ -787,15 +723,7 @@ async function init(args) {
|
|
|
787
723
|
try {
|
|
788
724
|
return await accountObject.deleteMessages(request.query.path, request.payload.search, request.query.force);
|
|
789
725
|
} catch (err) {
|
|
790
|
-
|
|
791
|
-
if (Boom.isBoom(err)) {
|
|
792
|
-
throw err;
|
|
793
|
-
}
|
|
794
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
795
|
-
if (err.code) {
|
|
796
|
-
error.output.payload.code = err.code;
|
|
797
|
-
}
|
|
798
|
-
throw error;
|
|
726
|
+
handleError(request, err);
|
|
799
727
|
}
|
|
800
728
|
},
|
|
801
729
|
options: {
|
|
@@ -881,15 +809,7 @@ async function init(args) {
|
|
|
881
809
|
try {
|
|
882
810
|
return await accountObject.listMessages(request.query);
|
|
883
811
|
} catch (err) {
|
|
884
|
-
|
|
885
|
-
if (Boom.isBoom(err)) {
|
|
886
|
-
throw err;
|
|
887
|
-
}
|
|
888
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
889
|
-
if (err.code) {
|
|
890
|
-
error.output.payload.code = err.code;
|
|
891
|
-
}
|
|
892
|
-
throw error;
|
|
812
|
+
handleError(request, err);
|
|
893
813
|
}
|
|
894
814
|
},
|
|
895
815
|
options: {
|
|
@@ -988,15 +908,7 @@ async function init(args) {
|
|
|
988
908
|
try {
|
|
989
909
|
return await accountObject.searchMessages(Object.assign(request.query, request.payload));
|
|
990
910
|
} catch (err) {
|
|
991
|
-
|
|
992
|
-
if (Boom.isBoom(err)) {
|
|
993
|
-
throw err;
|
|
994
|
-
}
|
|
995
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
996
|
-
if (err.code) {
|
|
997
|
-
error.output.payload.code = err.code;
|
|
998
|
-
}
|
|
999
|
-
throw error;
|
|
911
|
+
handleError(request, err);
|
|
1000
912
|
}
|
|
1001
913
|
},
|
|
1002
914
|
options: {
|
|
@@ -1059,7 +971,7 @@ async function init(args) {
|
|
|
1059
971
|
.truthy('Y', 'true', '1')
|
|
1060
972
|
.falsy('N', 'false', 0)
|
|
1061
973
|
.description(
|
|
1062
|
-
'MS Graph only. If enabled, uses the $search parameter for MS Graph search queries instead of $filter. This allows searching the "to", "cc", "bcc", "larger", "smaller", "body", "before", "sentBefore", "since", and the "sentSince" fields. Note that $search returns up to 1,000 results, does not indicate the total number of matching results or pages, and returns results sorted by relevance rather than date.'
|
|
974
|
+
'MS Graph only. If enabled, uses the $search parameter for MS Graph search queries instead of $filter. This allows searching the "to", "cc", "bcc", "larger", "smaller", "body", "before", "sentBefore", "since", and the "sentSince" fields. Note that $search returns up to 1,000 results, does not indicate the total number of matching results or pages, and returns results sorted by relevance rather than date. The "labels" filter is not available in this mode - leave this option disabled to filter by category.'
|
|
1063
975
|
)
|
|
1064
976
|
.label('useOutlookSearch')
|
|
1065
977
|
.optional(),
|
|
@@ -1102,7 +1014,11 @@ async function init(args) {
|
|
|
1102
1014
|
header: {
|
|
1103
1015
|
'Message-ID': '<12345@example.com>'
|
|
1104
1016
|
},
|
|
1105
|
-
gmailRaw: 'has:attachment in:unread'
|
|
1017
|
+
gmailRaw: 'has:attachment in:unread',
|
|
1018
|
+
labels: {
|
|
1019
|
+
has: ['Important'],
|
|
1020
|
+
not: ['Horizon']
|
|
1021
|
+
}
|
|
1106
1022
|
}
|
|
1107
1023
|
})
|
|
1108
1024
|
},
|
|
@@ -1152,15 +1068,7 @@ async function init(args) {
|
|
|
1152
1068
|
try {
|
|
1153
1069
|
return await accountObject.searchMessages(Object.assign({ documentStore: true }, request.query, request.payload), { unified: true });
|
|
1154
1070
|
} catch (err) {
|
|
1155
|
-
|
|
1156
|
-
if (Boom.isBoom(err)) {
|
|
1157
|
-
throw err;
|
|
1158
|
-
}
|
|
1159
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
1160
|
-
if (err.code) {
|
|
1161
|
-
error.output.payload.code = err.code;
|
|
1162
|
-
}
|
|
1163
|
-
throw error;
|
|
1071
|
+
handleError(request, err);
|
|
1164
1072
|
}
|
|
1165
1073
|
},
|
|
1166
1074
|
options: {
|
|
@@ -1243,15 +1151,7 @@ async function init(args) {
|
|
|
1243
1151
|
try {
|
|
1244
1152
|
return await accountObject.getText(request.params.text, request.query);
|
|
1245
1153
|
} catch (err) {
|
|
1246
|
-
|
|
1247
|
-
if (Boom.isBoom(err)) {
|
|
1248
|
-
throw err;
|
|
1249
|
-
}
|
|
1250
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
1251
|
-
if (err.code) {
|
|
1252
|
-
error.output.payload.code = err.code;
|
|
1253
|
-
}
|
|
1254
|
-
throw error;
|
|
1154
|
+
handleError(request, err);
|
|
1255
1155
|
}
|
|
1256
1156
|
},
|
|
1257
1157
|
options: {
|
|
@@ -1329,15 +1229,7 @@ async function init(args) {
|
|
|
1329
1229
|
try {
|
|
1330
1230
|
return await accountObject.getAttachment(request.params.attachment);
|
|
1331
1231
|
} catch (err) {
|
|
1332
|
-
|
|
1333
|
-
if (Boom.isBoom(err)) {
|
|
1334
|
-
throw err;
|
|
1335
|
-
}
|
|
1336
|
-
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
1337
|
-
if (err.code) {
|
|
1338
|
-
error.output.payload.code = err.code;
|
|
1339
|
-
}
|
|
1340
|
-
throw error;
|
|
1232
|
+
handleError(request, err);
|
|
1341
1233
|
}
|
|
1342
1234
|
},
|
|
1343
1235
|
options: {
|