polikolog 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. package/.idea/5lab.iml +12 -0
  2. package/.idea/inspectionProfiles/Project_Default.xml +10 -0
  3. package/.idea/jsLibraryMappings.xml +6 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/vcs.xml +6 -0
  6. package/06-02.js +48 -0
  7. package/06-03.js +22 -0
  8. package/06-04.js +22 -0
  9. package/index.html +41 -0
  10. package/m0603.js +28 -0
  11. package/mypackage/m0603.js +28 -0
  12. package/mypackage/node_modules/.package-lock.json +24 -0
  13. package/mypackage/node_modules/nodemailer/.gitattributes +6 -0
  14. package/mypackage/node_modules/nodemailer/.prettierrc.js +8 -0
  15. package/mypackage/node_modules/nodemailer/CHANGELOG.md +725 -0
  16. package/mypackage/node_modules/nodemailer/CODE_OF_CONDUCT.md +76 -0
  17. package/mypackage/node_modules/nodemailer/CONTRIBUTING.md +67 -0
  18. package/mypackage/node_modules/nodemailer/LICENSE +16 -0
  19. package/mypackage/node_modules/nodemailer/README.md +97 -0
  20. package/mypackage/node_modules/nodemailer/SECURITY.txt +22 -0
  21. package/mypackage/node_modules/nodemailer/lib/addressparser/index.js +313 -0
  22. package/mypackage/node_modules/nodemailer/lib/base64/index.js +142 -0
  23. package/mypackage/node_modules/nodemailer/lib/dkim/index.js +251 -0
  24. package/mypackage/node_modules/nodemailer/lib/dkim/message-parser.js +155 -0
  25. package/mypackage/node_modules/nodemailer/lib/dkim/relaxed-body.js +154 -0
  26. package/mypackage/node_modules/nodemailer/lib/dkim/sign.js +117 -0
  27. package/mypackage/node_modules/nodemailer/lib/fetch/cookies.js +281 -0
  28. package/mypackage/node_modules/nodemailer/lib/fetch/index.js +274 -0
  29. package/mypackage/node_modules/nodemailer/lib/json-transport/index.js +82 -0
  30. package/mypackage/node_modules/nodemailer/lib/mail-composer/index.js +558 -0
  31. package/mypackage/node_modules/nodemailer/lib/mailer/index.js +427 -0
  32. package/mypackage/node_modules/nodemailer/lib/mailer/mail-message.js +315 -0
  33. package/mypackage/node_modules/nodemailer/lib/mime-funcs/index.js +625 -0
  34. package/mypackage/node_modules/nodemailer/lib/mime-funcs/mime-types.js +2102 -0
  35. package/mypackage/node_modules/nodemailer/lib/mime-node/index.js +1290 -0
  36. package/mypackage/node_modules/nodemailer/lib/mime-node/last-newline.js +33 -0
  37. package/mypackage/node_modules/nodemailer/lib/mime-node/le-unix.js +43 -0
  38. package/mypackage/node_modules/nodemailer/lib/mime-node/le-windows.js +52 -0
  39. package/mypackage/node_modules/nodemailer/lib/nodemailer.js +143 -0
  40. package/mypackage/node_modules/nodemailer/lib/qp/index.js +219 -0
  41. package/mypackage/node_modules/nodemailer/lib/sendmail-transport/index.js +210 -0
  42. package/mypackage/node_modules/nodemailer/lib/ses-transport/index.js +349 -0
  43. package/mypackage/node_modules/nodemailer/lib/shared/index.js +638 -0
  44. package/mypackage/node_modules/nodemailer/lib/smtp-connection/data-stream.js +108 -0
  45. package/mypackage/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +143 -0
  46. package/mypackage/node_modules/nodemailer/lib/smtp-connection/index.js +1796 -0
  47. package/mypackage/node_modules/nodemailer/lib/smtp-pool/index.js +648 -0
  48. package/mypackage/node_modules/nodemailer/lib/smtp-pool/pool-resource.js +253 -0
  49. package/mypackage/node_modules/nodemailer/lib/smtp-transport/index.js +416 -0
  50. package/mypackage/node_modules/nodemailer/lib/stream-transport/index.js +135 -0
  51. package/mypackage/node_modules/nodemailer/lib/well-known/index.js +47 -0
  52. package/mypackage/node_modules/nodemailer/lib/well-known/services.json +286 -0
  53. package/mypackage/node_modules/nodemailer/lib/xoauth2/index.js +376 -0
  54. package/mypackage/node_modules/nodemailer/package.json +46 -0
  55. package/mypackage/node_modules/nodemailer/postinstall.js +101 -0
  56. package/mypackage/package.json +15 -0
  57. package/package.json +15 -0
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ const packageData = require('../../package.json');
4
+ const shared = require('../shared');
5
+
6
+ /**
7
+ * Generates a Transport object to generate JSON output
8
+ *
9
+ * @constructor
10
+ * @param {Object} optional config parameter
11
+ */
12
+ class JSONTransport {
13
+ constructor(options) {
14
+ options = options || {};
15
+
16
+ this.options = options || {};
17
+
18
+ this.name = 'JSONTransport';
19
+ this.version = packageData.version;
20
+
21
+ this.logger = shared.getLogger(this.options, {
22
+ component: this.options.component || 'json-transport'
23
+ });
24
+ }
25
+
26
+ /**
27
+ * <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
28
+ *
29
+ * @param {Object} emailMessage MailComposer object
30
+ * @param {Function} callback Callback function to run when the sending is completed
31
+ */
32
+ send(mail, done) {
33
+ // Sendmail strips this header line by itself
34
+ mail.message.keepBcc = true;
35
+
36
+ let envelope = mail.data.envelope || mail.message.getEnvelope();
37
+ let messageId = mail.message.messageId();
38
+
39
+ let recipients = [].concat(envelope.to || []);
40
+ if (recipients.length > 3) {
41
+ recipients.push('...and ' + recipients.splice(2).length + ' more');
42
+ }
43
+ this.logger.info(
44
+ {
45
+ tnx: 'send',
46
+ messageId
47
+ },
48
+ 'Composing JSON structure of %s to <%s>',
49
+ messageId,
50
+ recipients.join(', ')
51
+ );
52
+
53
+ setImmediate(() => {
54
+ mail.normalize((err, data) => {
55
+ if (err) {
56
+ this.logger.error(
57
+ {
58
+ err,
59
+ tnx: 'send',
60
+ messageId
61
+ },
62
+ 'Failed building JSON structure for %s. %s',
63
+ messageId,
64
+ err.message
65
+ );
66
+ return done(err);
67
+ }
68
+
69
+ delete data.envelope;
70
+ delete data.normalizedHeaders;
71
+
72
+ return done(null, {
73
+ envelope,
74
+ messageId,
75
+ message: this.options.skipEncoding ? data : JSON.stringify(data)
76
+ });
77
+ });
78
+ });
79
+ }
80
+ }
81
+
82
+ module.exports = JSONTransport;
@@ -0,0 +1,558 @@
1
+ /* eslint no-undefined: 0 */
2
+
3
+ 'use strict';
4
+
5
+ const MimeNode = require('../mime-node');
6
+ const mimeFuncs = require('../mime-funcs');
7
+
8
+ /**
9
+ * Creates the object for composing a MimeNode instance out from the mail options
10
+ *
11
+ * @constructor
12
+ * @param {Object} mail Mail options
13
+ */
14
+ class MailComposer {
15
+ constructor(mail) {
16
+ this.mail = mail || {};
17
+ this.message = false;
18
+ }
19
+
20
+ /**
21
+ * Builds MimeNode instance
22
+ */
23
+ compile() {
24
+ this._alternatives = this.getAlternatives();
25
+ this._htmlNode = this._alternatives.filter(alternative => /^text\/html\b/i.test(alternative.contentType)).pop();
26
+ this._attachments = this.getAttachments(!!this._htmlNode);
27
+
28
+ this._useRelated = !!(this._htmlNode && this._attachments.related.length);
29
+ this._useAlternative = this._alternatives.length > 1;
30
+ this._useMixed = this._attachments.attached.length > 1 || (this._alternatives.length && this._attachments.attached.length === 1);
31
+
32
+ // Compose MIME tree
33
+ if (this.mail.raw) {
34
+ this.message = new MimeNode('message/rfc822', { newline: this.mail.newline }).setRaw(this.mail.raw);
35
+ } else if (this._useMixed) {
36
+ this.message = this._createMixed();
37
+ } else if (this._useAlternative) {
38
+ this.message = this._createAlternative();
39
+ } else if (this._useRelated) {
40
+ this.message = this._createRelated();
41
+ } else {
42
+ this.message = this._createContentNode(
43
+ false,
44
+ []
45
+ .concat(this._alternatives || [])
46
+ .concat(this._attachments.attached || [])
47
+ .shift() || {
48
+ contentType: 'text/plain',
49
+ content: ''
50
+ }
51
+ );
52
+ }
53
+
54
+ // Add custom headers
55
+ if (this.mail.headers) {
56
+ this.message.addHeader(this.mail.headers);
57
+ }
58
+
59
+ // Add headers to the root node, always overrides custom headers
60
+ ['from', 'sender', 'to', 'cc', 'bcc', 'reply-to', 'in-reply-to', 'references', 'subject', 'message-id', 'date'].forEach(header => {
61
+ let key = header.replace(/-(\w)/g, (o, c) => c.toUpperCase());
62
+ if (this.mail[key]) {
63
+ this.message.setHeader(header, this.mail[key]);
64
+ }
65
+ });
66
+
67
+ // Sets custom envelope
68
+ if (this.mail.envelope) {
69
+ this.message.setEnvelope(this.mail.envelope);
70
+ }
71
+
72
+ // ensure Message-Id value
73
+ this.message.messageId();
74
+
75
+ return this.message;
76
+ }
77
+
78
+ /**
79
+ * List all attachments. Resulting attachment objects can be used as input for MimeNode nodes
80
+ *
81
+ * @param {Boolean} findRelated If true separate related attachments from attached ones
82
+ * @returns {Object} An object of arrays (`related` and `attached`)
83
+ */
84
+ getAttachments(findRelated) {
85
+ let icalEvent, eventObject;
86
+ let attachments = [].concat(this.mail.attachments || []).map((attachment, i) => {
87
+ let data;
88
+ let isMessageNode = /^message\//i.test(attachment.contentType);
89
+
90
+ if (/^data:/i.test(attachment.path || attachment.href)) {
91
+ attachment = this._processDataUrl(attachment);
92
+ }
93
+
94
+ data = {
95
+ contentType: attachment.contentType || mimeFuncs.detectMimeType(attachment.filename || attachment.path || attachment.href || 'bin'),
96
+ contentDisposition: attachment.contentDisposition || (isMessageNode ? 'inline' : 'attachment'),
97
+ contentTransferEncoding: 'contentTransferEncoding' in attachment ? attachment.contentTransferEncoding : 'base64'
98
+ };
99
+
100
+ if (attachment.filename) {
101
+ data.filename = attachment.filename;
102
+ } else if (!isMessageNode && attachment.filename !== false) {
103
+ data.filename = (attachment.path || attachment.href || '').split('/').pop().split('?').shift() || 'attachment-' + (i + 1);
104
+ if (data.filename.indexOf('.') < 0) {
105
+ data.filename += '.' + mimeFuncs.detectExtension(data.contentType);
106
+ }
107
+ }
108
+
109
+ if (/^https?:\/\//i.test(attachment.path)) {
110
+ attachment.href = attachment.path;
111
+ attachment.path = undefined;
112
+ }
113
+
114
+ if (attachment.cid) {
115
+ data.cid = attachment.cid;
116
+ }
117
+
118
+ if (attachment.raw) {
119
+ data.raw = attachment.raw;
120
+ } else if (attachment.path) {
121
+ data.content = {
122
+ path: attachment.path
123
+ };
124
+ } else if (attachment.href) {
125
+ data.content = {
126
+ href: attachment.href,
127
+ httpHeaders: attachment.httpHeaders
128
+ };
129
+ } else {
130
+ data.content = attachment.content || '';
131
+ }
132
+
133
+ if (attachment.encoding) {
134
+ data.encoding = attachment.encoding;
135
+ }
136
+
137
+ if (attachment.headers) {
138
+ data.headers = attachment.headers;
139
+ }
140
+
141
+ return data;
142
+ });
143
+
144
+ if (this.mail.icalEvent) {
145
+ if (
146
+ typeof this.mail.icalEvent === 'object' &&
147
+ (this.mail.icalEvent.content || this.mail.icalEvent.path || this.mail.icalEvent.href || this.mail.icalEvent.raw)
148
+ ) {
149
+ icalEvent = this.mail.icalEvent;
150
+ } else {
151
+ icalEvent = {
152
+ content: this.mail.icalEvent
153
+ };
154
+ }
155
+
156
+ eventObject = {};
157
+ Object.keys(icalEvent).forEach(key => {
158
+ eventObject[key] = icalEvent[key];
159
+ });
160
+
161
+ eventObject.contentType = 'application/ics';
162
+ if (!eventObject.headers) {
163
+ eventObject.headers = {};
164
+ }
165
+ eventObject.filename = eventObject.filename || 'invite.ics';
166
+ eventObject.headers['Content-Disposition'] = 'attachment';
167
+ eventObject.headers['Content-Transfer-Encoding'] = 'base64';
168
+ }
169
+
170
+ if (!findRelated) {
171
+ return {
172
+ attached: attachments.concat(eventObject || []),
173
+ related: []
174
+ };
175
+ } else {
176
+ return {
177
+ attached: attachments.filter(attachment => !attachment.cid).concat(eventObject || []),
178
+ related: attachments.filter(attachment => !!attachment.cid)
179
+ };
180
+ }
181
+ }
182
+
183
+ /**
184
+ * List alternatives. Resulting objects can be used as input for MimeNode nodes
185
+ *
186
+ * @returns {Array} An array of alternative elements. Includes the `text` and `html` values as well
187
+ */
188
+ getAlternatives() {
189
+ let alternatives = [],
190
+ text,
191
+ html,
192
+ watchHtml,
193
+ amp,
194
+ icalEvent,
195
+ eventObject;
196
+
197
+ if (this.mail.text) {
198
+ if (typeof this.mail.text === 'object' && (this.mail.text.content || this.mail.text.path || this.mail.text.href || this.mail.text.raw)) {
199
+ text = this.mail.text;
200
+ } else {
201
+ text = {
202
+ content: this.mail.text
203
+ };
204
+ }
205
+ text.contentType = 'text/plain; charset=utf-8';
206
+ }
207
+
208
+ if (this.mail.watchHtml) {
209
+ if (
210
+ typeof this.mail.watchHtml === 'object' &&
211
+ (this.mail.watchHtml.content || this.mail.watchHtml.path || this.mail.watchHtml.href || this.mail.watchHtml.raw)
212
+ ) {
213
+ watchHtml = this.mail.watchHtml;
214
+ } else {
215
+ watchHtml = {
216
+ content: this.mail.watchHtml
217
+ };
218
+ }
219
+ watchHtml.contentType = 'text/watch-html; charset=utf-8';
220
+ }
221
+
222
+ if (this.mail.amp) {
223
+ if (typeof this.mail.amp === 'object' && (this.mail.amp.content || this.mail.amp.path || this.mail.amp.href || this.mail.amp.raw)) {
224
+ amp = this.mail.amp;
225
+ } else {
226
+ amp = {
227
+ content: this.mail.amp
228
+ };
229
+ }
230
+ amp.contentType = 'text/x-amp-html; charset=utf-8';
231
+ }
232
+
233
+ // NB! when including attachments with a calendar alternative you might end up in a blank screen on some clients
234
+ if (this.mail.icalEvent) {
235
+ if (
236
+ typeof this.mail.icalEvent === 'object' &&
237
+ (this.mail.icalEvent.content || this.mail.icalEvent.path || this.mail.icalEvent.href || this.mail.icalEvent.raw)
238
+ ) {
239
+ icalEvent = this.mail.icalEvent;
240
+ } else {
241
+ icalEvent = {
242
+ content: this.mail.icalEvent
243
+ };
244
+ }
245
+
246
+ eventObject = {};
247
+ Object.keys(icalEvent).forEach(key => {
248
+ eventObject[key] = icalEvent[key];
249
+ });
250
+
251
+ if (eventObject.content && typeof eventObject.content === 'object') {
252
+ // we are going to have the same attachment twice, so mark this to be
253
+ // resolved just once
254
+ eventObject.content._resolve = true;
255
+ }
256
+
257
+ eventObject.filename = false;
258
+ eventObject.contentType = 'text/calendar; charset=utf-8; method=' + (eventObject.method || 'PUBLISH').toString().trim().toUpperCase();
259
+ if (!eventObject.headers) {
260
+ eventObject.headers = {};
261
+ }
262
+ }
263
+
264
+ if (this.mail.html) {
265
+ if (typeof this.mail.html === 'object' && (this.mail.html.content || this.mail.html.path || this.mail.html.href || this.mail.html.raw)) {
266
+ html = this.mail.html;
267
+ } else {
268
+ html = {
269
+ content: this.mail.html
270
+ };
271
+ }
272
+ html.contentType = 'text/html; charset=utf-8';
273
+ }
274
+
275
+ []
276
+ .concat(text || [])
277
+ .concat(watchHtml || [])
278
+ .concat(amp || [])
279
+ .concat(html || [])
280
+ .concat(eventObject || [])
281
+ .concat(this.mail.alternatives || [])
282
+ .forEach(alternative => {
283
+ let data;
284
+
285
+ if (/^data:/i.test(alternative.path || alternative.href)) {
286
+ alternative = this._processDataUrl(alternative);
287
+ }
288
+
289
+ data = {
290
+ contentType: alternative.contentType || mimeFuncs.detectMimeType(alternative.filename || alternative.path || alternative.href || 'txt'),
291
+ contentTransferEncoding: alternative.contentTransferEncoding
292
+ };
293
+
294
+ if (alternative.filename) {
295
+ data.filename = alternative.filename;
296
+ }
297
+
298
+ if (/^https?:\/\//i.test(alternative.path)) {
299
+ alternative.href = alternative.path;
300
+ alternative.path = undefined;
301
+ }
302
+
303
+ if (alternative.raw) {
304
+ data.raw = alternative.raw;
305
+ } else if (alternative.path) {
306
+ data.content = {
307
+ path: alternative.path
308
+ };
309
+ } else if (alternative.href) {
310
+ data.content = {
311
+ href: alternative.href
312
+ };
313
+ } else {
314
+ data.content = alternative.content || '';
315
+ }
316
+
317
+ if (alternative.encoding) {
318
+ data.encoding = alternative.encoding;
319
+ }
320
+
321
+ if (alternative.headers) {
322
+ data.headers = alternative.headers;
323
+ }
324
+
325
+ alternatives.push(data);
326
+ });
327
+
328
+ return alternatives;
329
+ }
330
+
331
+ /**
332
+ * Builds multipart/mixed node. It should always contain different type of elements on the same level
333
+ * eg. text + attachments
334
+ *
335
+ * @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
336
+ * @returns {Object} MimeNode node element
337
+ */
338
+ _createMixed(parentNode) {
339
+ let node;
340
+
341
+ if (!parentNode) {
342
+ node = new MimeNode('multipart/mixed', {
343
+ baseBoundary: this.mail.baseBoundary,
344
+ textEncoding: this.mail.textEncoding,
345
+ boundaryPrefix: this.mail.boundaryPrefix,
346
+ disableUrlAccess: this.mail.disableUrlAccess,
347
+ disableFileAccess: this.mail.disableFileAccess,
348
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
349
+ newline: this.mail.newline
350
+ });
351
+ } else {
352
+ node = parentNode.createChild('multipart/mixed', {
353
+ disableUrlAccess: this.mail.disableUrlAccess,
354
+ disableFileAccess: this.mail.disableFileAccess,
355
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
356
+ newline: this.mail.newline
357
+ });
358
+ }
359
+
360
+ if (this._useAlternative) {
361
+ this._createAlternative(node);
362
+ } else if (this._useRelated) {
363
+ this._createRelated(node);
364
+ }
365
+
366
+ []
367
+ .concat((!this._useAlternative && this._alternatives) || [])
368
+ .concat(this._attachments.attached || [])
369
+ .forEach(element => {
370
+ // if the element is a html node from related subpart then ignore it
371
+ if (!this._useRelated || element !== this._htmlNode) {
372
+ this._createContentNode(node, element);
373
+ }
374
+ });
375
+
376
+ return node;
377
+ }
378
+
379
+ /**
380
+ * Builds multipart/alternative node. It should always contain same type of elements on the same level
381
+ * eg. text + html view of the same data
382
+ *
383
+ * @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
384
+ * @returns {Object} MimeNode node element
385
+ */
386
+ _createAlternative(parentNode) {
387
+ let node;
388
+
389
+ if (!parentNode) {
390
+ node = new MimeNode('multipart/alternative', {
391
+ baseBoundary: this.mail.baseBoundary,
392
+ textEncoding: this.mail.textEncoding,
393
+ boundaryPrefix: this.mail.boundaryPrefix,
394
+ disableUrlAccess: this.mail.disableUrlAccess,
395
+ disableFileAccess: this.mail.disableFileAccess,
396
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
397
+ newline: this.mail.newline
398
+ });
399
+ } else {
400
+ node = parentNode.createChild('multipart/alternative', {
401
+ disableUrlAccess: this.mail.disableUrlAccess,
402
+ disableFileAccess: this.mail.disableFileAccess,
403
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
404
+ newline: this.mail.newline
405
+ });
406
+ }
407
+
408
+ this._alternatives.forEach(alternative => {
409
+ if (this._useRelated && this._htmlNode === alternative) {
410
+ this._createRelated(node);
411
+ } else {
412
+ this._createContentNode(node, alternative);
413
+ }
414
+ });
415
+
416
+ return node;
417
+ }
418
+
419
+ /**
420
+ * Builds multipart/related node. It should always contain html node with related attachments
421
+ *
422
+ * @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
423
+ * @returns {Object} MimeNode node element
424
+ */
425
+ _createRelated(parentNode) {
426
+ let node;
427
+
428
+ if (!parentNode) {
429
+ node = new MimeNode('multipart/related; type="text/html"', {
430
+ baseBoundary: this.mail.baseBoundary,
431
+ textEncoding: this.mail.textEncoding,
432
+ boundaryPrefix: this.mail.boundaryPrefix,
433
+ disableUrlAccess: this.mail.disableUrlAccess,
434
+ disableFileAccess: this.mail.disableFileAccess,
435
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
436
+ newline: this.mail.newline
437
+ });
438
+ } else {
439
+ node = parentNode.createChild('multipart/related; type="text/html"', {
440
+ disableUrlAccess: this.mail.disableUrlAccess,
441
+ disableFileAccess: this.mail.disableFileAccess,
442
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
443
+ newline: this.mail.newline
444
+ });
445
+ }
446
+
447
+ this._createContentNode(node, this._htmlNode);
448
+
449
+ this._attachments.related.forEach(alternative => this._createContentNode(node, alternative));
450
+
451
+ return node;
452
+ }
453
+
454
+ /**
455
+ * Creates a regular node with contents
456
+ *
457
+ * @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
458
+ * @param {Object} element Node data
459
+ * @returns {Object} MimeNode node element
460
+ */
461
+ _createContentNode(parentNode, element) {
462
+ element = element || {};
463
+ element.content = element.content || '';
464
+
465
+ let node;
466
+ let encoding = (element.encoding || 'utf8')
467
+ .toString()
468
+ .toLowerCase()
469
+ .replace(/[-_\s]/g, '');
470
+
471
+ if (!parentNode) {
472
+ node = new MimeNode(element.contentType, {
473
+ filename: element.filename,
474
+ baseBoundary: this.mail.baseBoundary,
475
+ textEncoding: this.mail.textEncoding,
476
+ boundaryPrefix: this.mail.boundaryPrefix,
477
+ disableUrlAccess: this.mail.disableUrlAccess,
478
+ disableFileAccess: this.mail.disableFileAccess,
479
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
480
+ newline: this.mail.newline
481
+ });
482
+ } else {
483
+ node = parentNode.createChild(element.contentType, {
484
+ filename: element.filename,
485
+ textEncoding: this.mail.textEncoding,
486
+ disableUrlAccess: this.mail.disableUrlAccess,
487
+ disableFileAccess: this.mail.disableFileAccess,
488
+ normalizeHeaderKey: this.mail.normalizeHeaderKey,
489
+ newline: this.mail.newline
490
+ });
491
+ }
492
+
493
+ // add custom headers
494
+ if (element.headers) {
495
+ node.addHeader(element.headers);
496
+ }
497
+
498
+ if (element.cid) {
499
+ node.setHeader('Content-Id', '<' + element.cid.replace(/[<>]/g, '') + '>');
500
+ }
501
+
502
+ if (element.contentTransferEncoding) {
503
+ node.setHeader('Content-Transfer-Encoding', element.contentTransferEncoding);
504
+ } else if (this.mail.encoding && /^text\//i.test(element.contentType)) {
505
+ node.setHeader('Content-Transfer-Encoding', this.mail.encoding);
506
+ }
507
+
508
+ if (!/^text\//i.test(element.contentType) || element.contentDisposition) {
509
+ node.setHeader('Content-Disposition', element.contentDisposition || (element.cid ? 'inline' : 'attachment'));
510
+ }
511
+
512
+ if (typeof element.content === 'string' && !['utf8', 'usascii', 'ascii'].includes(encoding)) {
513
+ element.content = Buffer.from(element.content, encoding);
514
+ }
515
+
516
+ // prefer pregenerated raw content
517
+ if (element.raw) {
518
+ node.setRaw(element.raw);
519
+ } else {
520
+ node.setContent(element.content);
521
+ }
522
+
523
+ return node;
524
+ }
525
+
526
+ /**
527
+ * Parses data uri and converts it to a Buffer
528
+ *
529
+ * @param {Object} element Content element
530
+ * @return {Object} Parsed element
531
+ */
532
+ _processDataUrl(element) {
533
+ let parts = (element.path || element.href).match(/^data:((?:[^;]*;)*(?:[^,]*)),(.*)$/i);
534
+ if (!parts) {
535
+ return element;
536
+ }
537
+
538
+ element.content = /\bbase64$/i.test(parts[1]) ? Buffer.from(parts[2], 'base64') : Buffer.from(decodeURIComponent(parts[2]));
539
+
540
+ if ('path' in element) {
541
+ element.path = false;
542
+ }
543
+
544
+ if ('href' in element) {
545
+ element.href = false;
546
+ }
547
+
548
+ parts[1].split(';').forEach(item => {
549
+ if (/^\w+\/[^/]+$/i.test(item)) {
550
+ element.contentType = element.contentType || item.toLowerCase();
551
+ }
552
+ });
553
+
554
+ return element;
555
+ }
556
+ }
557
+
558
+ module.exports = MailComposer;