@nocobase/plugin-workflow-mailer 2.3.0-beta.9 → 2.4.0-alpha.10

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 (187) hide show
  1. package/dist/externalVersion.js +6 -6
  2. package/dist/node_modules/joi/dist/joi-browser.min.js +1 -1
  3. package/dist/node_modules/joi/lib/index.js +1 -1
  4. package/dist/node_modules/joi/lib/messages.js +35 -6
  5. package/dist/node_modules/joi/lib/types/keys.js +18 -1
  6. package/dist/node_modules/joi/lib/types/link.js +18 -2
  7. package/dist/node_modules/joi/lib/types/string.js +2 -2
  8. package/dist/node_modules/joi/package.json +1 -1
  9. package/dist/node_modules/nodemailer/dist/cjs/addressparser/index.d.ts +59 -0
  10. package/dist/node_modules/nodemailer/dist/cjs/addressparser/index.js +790 -0
  11. package/dist/node_modules/nodemailer/dist/cjs/base64/index.d.ts +36 -0
  12. package/dist/node_modules/nodemailer/dist/cjs/base64/index.js +119 -0
  13. package/dist/node_modules/nodemailer/dist/cjs/dkim/index.d.ts +52 -0
  14. package/dist/node_modules/nodemailer/dist/cjs/dkim/index.js +228 -0
  15. package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.d.ts +48 -0
  16. package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.js +180 -0
  17. package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.d.ts +36 -0
  18. package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.js +148 -0
  19. package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.d.ts +52 -0
  20. package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.js +165 -0
  21. package/dist/node_modules/nodemailer/dist/cjs/errors.d.ts +96 -0
  22. package/dist/node_modules/nodemailer/dist/cjs/errors.js +70 -0
  23. package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.d.ts +107 -0
  24. package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.js +282 -0
  25. package/dist/node_modules/nodemailer/dist/cjs/fetch/index.d.ts +65 -0
  26. package/dist/node_modules/nodemailer/dist/cjs/fetch/index.js +384 -0
  27. package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.d.ts +64 -0
  28. package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.js +99 -0
  29. package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.d.ts +174 -0
  30. package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.js +613 -0
  31. package/dist/node_modules/nodemailer/dist/cjs/mailer/index.d.ts +237 -0
  32. package/dist/node_modules/nodemailer/dist/cjs/mailer/index.js +415 -0
  33. package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.d.ts +97 -0
  34. package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.js +342 -0
  35. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.d.ts +161 -0
  36. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.js +787 -0
  37. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.d.ts +2 -0
  38. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.js +2103 -0
  39. package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.d.ts +333 -0
  40. package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.js +1493 -0
  41. package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.d.ts +5 -0
  42. package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.js +32 -0
  43. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.d.ts +9 -0
  44. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.js +40 -0
  45. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.d.ts +10 -0
  46. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.js +47 -0
  47. package/dist/node_modules/nodemailer/dist/cjs/nodemailer.d.ts +124 -0
  48. package/dist/node_modules/nodemailer/dist/cjs/nodemailer.js +1 -0
  49. package/dist/node_modules/nodemailer/dist/cjs/package-info.d.ts +3 -0
  50. package/dist/node_modules/nodemailer/dist/cjs/package-info.js +7 -0
  51. package/dist/node_modules/nodemailer/dist/cjs/package.json +3 -0
  52. package/dist/node_modules/nodemailer/dist/cjs/punycode/index.d.ts +73 -0
  53. package/dist/node_modules/nodemailer/{lib → dist/cjs}/punycode/index.js +63 -112
  54. package/dist/node_modules/nodemailer/dist/cjs/qp/index.d.ts +32 -0
  55. package/dist/node_modules/nodemailer/dist/cjs/qp/index.js +207 -0
  56. package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.d.ts +69 -0
  57. package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.js +210 -0
  58. package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.d.ts +112 -0
  59. package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.js +252 -0
  60. package/dist/node_modules/nodemailer/dist/cjs/shared/index.d.ts +260 -0
  61. package/dist/node_modules/nodemailer/dist/cjs/shared/index.js +680 -0
  62. package/dist/node_modules/nodemailer/dist/cjs/shared/objects.d.ts +23 -0
  63. package/dist/node_modules/nodemailer/dist/cjs/shared/objects.js +43 -0
  64. package/dist/node_modules/nodemailer/dist/cjs/shared/url.d.ts +21 -0
  65. package/dist/node_modules/nodemailer/dist/cjs/shared/url.js +255 -0
  66. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.d.ts +15 -0
  67. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.js +108 -0
  68. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.d.ts +47 -0
  69. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.js +189 -0
  70. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.d.ts +416 -0
  71. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.js +1837 -0
  72. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.d.ts +133 -0
  73. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.js +569 -0
  74. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.d.ts +62 -0
  75. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.js +257 -0
  76. package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.d.ts +156 -0
  77. package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.js +371 -0
  78. package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.d.ts +65 -0
  79. package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.js +146 -0
  80. package/dist/node_modules/nodemailer/dist/cjs/well-known/index.d.ts +35 -0
  81. package/dist/node_modules/nodemailer/dist/cjs/well-known/index.js +41 -0
  82. package/dist/node_modules/nodemailer/dist/cjs/well-known/services.d.ts +2 -0
  83. package/dist/node_modules/nodemailer/dist/cjs/well-known/services.js +674 -0
  84. package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.d.ts +201 -0
  85. package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.js +426 -0
  86. package/dist/node_modules/nodemailer/dist/esm/addressparser/index.d.ts +59 -0
  87. package/dist/node_modules/nodemailer/dist/esm/addressparser/index.js +786 -0
  88. package/dist/node_modules/nodemailer/dist/esm/base64/index.d.ts +36 -0
  89. package/dist/node_modules/nodemailer/{lib → dist/esm}/base64/index.js +39 -68
  90. package/dist/node_modules/nodemailer/dist/esm/dkim/index.d.ts +52 -0
  91. package/dist/node_modules/nodemailer/{lib → dist/esm}/dkim/index.js +62 -92
  92. package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.d.ts +48 -0
  93. package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.js +176 -0
  94. package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.d.ts +36 -0
  95. package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.js +141 -0
  96. package/dist/node_modules/nodemailer/dist/esm/dkim/sign.d.ts +52 -0
  97. package/dist/node_modules/nodemailer/dist/esm/dkim/sign.js +125 -0
  98. package/dist/node_modules/nodemailer/dist/esm/errors.d.ts +96 -0
  99. package/dist/node_modules/nodemailer/dist/esm/errors.js +67 -0
  100. package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.d.ts +107 -0
  101. package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.js +242 -0
  102. package/dist/node_modules/nodemailer/dist/esm/fetch/index.d.ts +65 -0
  103. package/dist/node_modules/nodemailer/dist/esm/fetch/index.js +344 -0
  104. package/dist/node_modules/nodemailer/dist/esm/json-transport/index.d.ts +64 -0
  105. package/dist/node_modules/nodemailer/dist/esm/json-transport/index.js +62 -0
  106. package/dist/node_modules/nodemailer/dist/esm/mail-composer/index.d.ts +174 -0
  107. package/dist/node_modules/nodemailer/{lib → dist/esm}/mail-composer/index.js +283 -275
  108. package/dist/node_modules/nodemailer/dist/esm/mailer/index.d.ts +237 -0
  109. package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/index.js +151 -205
  110. package/dist/node_modules/nodemailer/dist/esm/mailer/mail-message.d.ts +97 -0
  111. package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/mail-message.js +111 -125
  112. package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.d.ts +161 -0
  113. package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.js +738 -0
  114. package/dist/node_modules/nodemailer/dist/esm/mime-funcs/mime-types.d.ts +2 -0
  115. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-funcs/mime-types.js +43 -49
  116. package/dist/node_modules/nodemailer/dist/esm/mime-node/index.d.ts +333 -0
  117. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/index.js +576 -437
  118. package/dist/node_modules/nodemailer/dist/esm/mime-node/last-newline.d.ts +5 -0
  119. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/last-newline.js +4 -10
  120. package/dist/node_modules/nodemailer/dist/esm/mime-node/le-unix.d.ts +9 -0
  121. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-unix.js +7 -15
  122. package/dist/node_modules/nodemailer/dist/esm/mime-node/le-windows.d.ts +10 -0
  123. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-windows.js +6 -16
  124. package/dist/node_modules/nodemailer/dist/esm/nodemailer.d.ts +124 -0
  125. package/dist/node_modules/nodemailer/dist/esm/nodemailer.js +166 -0
  126. package/dist/node_modules/nodemailer/dist/esm/package-info.d.ts +3 -0
  127. package/dist/node_modules/nodemailer/dist/esm/package-info.js +4 -0
  128. package/dist/node_modules/nodemailer/dist/esm/package.json +3 -0
  129. package/dist/node_modules/nodemailer/dist/esm/punycode/index.d.ts +73 -0
  130. package/dist/node_modules/nodemailer/dist/esm/punycode/index.js +405 -0
  131. package/dist/node_modules/nodemailer/dist/esm/qp/index.d.ts +32 -0
  132. package/dist/node_modules/nodemailer/{lib → dist/esm}/qp/index.js +59 -77
  133. package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.d.ts +69 -0
  134. package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.js +170 -0
  135. package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.d.ts +112 -0
  136. package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.js +212 -0
  137. package/dist/node_modules/nodemailer/dist/esm/shared/index.d.ts +260 -0
  138. package/dist/node_modules/nodemailer/dist/esm/shared/index.js +631 -0
  139. package/dist/node_modules/nodemailer/dist/esm/shared/objects.d.ts +23 -0
  140. package/dist/node_modules/nodemailer/dist/esm/shared/objects.js +38 -0
  141. package/dist/node_modules/nodemailer/dist/esm/shared/url.d.ts +21 -0
  142. package/dist/node_modules/nodemailer/dist/esm/shared/url.js +214 -0
  143. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.d.ts +15 -0
  144. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.js +103 -0
  145. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.d.ts +47 -0
  146. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.js +149 -0
  147. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.d.ts +416 -0
  148. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.js +1797 -0
  149. package/dist/node_modules/nodemailer/dist/esm/smtp-pool/index.d.ts +133 -0
  150. package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/index.js +195 -314
  151. package/dist/node_modules/nodemailer/dist/esm/smtp-pool/pool-resource.d.ts +62 -0
  152. package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/pool-resource.js +70 -107
  153. package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.d.ts +156 -0
  154. package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.js +331 -0
  155. package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.d.ts +65 -0
  156. package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.js +106 -0
  157. package/dist/node_modules/nodemailer/dist/esm/well-known/index.d.ts +35 -0
  158. package/dist/node_modules/nodemailer/{lib → dist/esm}/well-known/index.js +12 -23
  159. package/dist/node_modules/nodemailer/dist/esm/well-known/services.d.ts +2 -0
  160. package/dist/node_modules/nodemailer/dist/esm/well-known/services.js +671 -0
  161. package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.d.ts +201 -0
  162. package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.js +386 -0
  163. package/dist/node_modules/nodemailer/dist/well-known/services.json +640 -0
  164. package/dist/node_modules/nodemailer/package.json +1 -1
  165. package/package.json +4 -4
  166. package/dist/node_modules/nodemailer/.gitattributes +0 -6
  167. package/dist/node_modules/nodemailer/.ncurc.js +0 -7
  168. package/dist/node_modules/nodemailer/.prettierrc.js +0 -8
  169. package/dist/node_modules/nodemailer/lib/addressparser/index.js +0 -313
  170. package/dist/node_modules/nodemailer/lib/dkim/message-parser.js +0 -155
  171. package/dist/node_modules/nodemailer/lib/dkim/relaxed-body.js +0 -154
  172. package/dist/node_modules/nodemailer/lib/dkim/sign.js +0 -117
  173. package/dist/node_modules/nodemailer/lib/fetch/cookies.js +0 -281
  174. package/dist/node_modules/nodemailer/lib/fetch/index.js +0 -274
  175. package/dist/node_modules/nodemailer/lib/json-transport/index.js +0 -82
  176. package/dist/node_modules/nodemailer/lib/mime-funcs/index.js +0 -625
  177. package/dist/node_modules/nodemailer/lib/nodemailer.js +0 -1
  178. package/dist/node_modules/nodemailer/lib/sendmail-transport/index.js +0 -210
  179. package/dist/node_modules/nodemailer/lib/ses-transport/index.js +0 -349
  180. package/dist/node_modules/nodemailer/lib/shared/index.js +0 -688
  181. package/dist/node_modules/nodemailer/lib/smtp-connection/data-stream.js +0 -108
  182. package/dist/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +0 -143
  183. package/dist/node_modules/nodemailer/lib/smtp-connection/index.js +0 -1825
  184. package/dist/node_modules/nodemailer/lib/smtp-transport/index.js +0 -416
  185. package/dist/node_modules/nodemailer/lib/stream-transport/index.js +0 -135
  186. package/dist/node_modules/nodemailer/lib/well-known/services.json +0 -343
  187. package/dist/node_modules/nodemailer/lib/xoauth2/index.js +0 -376
@@ -1,188 +1,185 @@
1
- 'use strict';
2
-
3
- const shared = require('../shared');
4
- const MimeNode = require('../mime-node');
5
- const mimeFuncs = require('../mime-funcs');
6
-
7
- class MailMessage {
1
+ import * as shared from '../shared/index.js';
2
+ import MimeNode from '../mime-node/index.js';
3
+ import * as mimeFuncs from '../mime-funcs/index.js';
4
+ // Only an own key counts as already set. `key in obj` also matches every member of
5
+ // Object.prototype, which silently drops a transporter default legitimately named
6
+ // toString or constructor.
7
+ const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
8
+ export default class MailMessage {
8
9
  constructor(mailer, data) {
9
10
  this.mailer = mailer;
10
11
  this.data = {};
11
12
  this.message = null;
12
-
13
13
  data = data || {};
14
- let options = mailer.options || {};
15
- let defaults = mailer._defaults || {};
16
-
17
- Object.keys(data).forEach(key => {
18
- this.data[key] = data[key];
19
- });
20
-
14
+ const options = mailer.options || {};
15
+ const defaults = mailer._defaults || {};
16
+ shared.copyOwnKeys(this.data, data);
21
17
  this.data.headers = this.data.headers || {};
22
-
23
- // apply defaults
24
- Object.keys(defaults).forEach(key => {
25
- if (!(key in this.data)) {
26
- this.data[key] = defaults[key];
27
- } else if (key === 'headers') {
28
- // headers is a special case. Allow setting individual default headers
29
- Object.keys(defaults.headers).forEach(key => {
30
- if (!(key in this.data.headers)) {
31
- this.data.headers[key] = defaults.headers[key];
32
- }
33
- });
34
- }
35
- });
36
-
18
+ // Apply defaults. `_defaults` is caller supplied too, it is the second argument of
19
+ // createTransport, so it needs the same treatment as `data` above
20
+ shared.copyOwnKeys(this.data, defaults, key => hasOwn(this.data, key));
21
+ // headers is a special case. Allow setting individual default headers
22
+ shared.copyOwnKeys(this.data.headers, defaults.headers, key => hasOwn(this.data.headers, key));
37
23
  // force specific keys from transporter options
38
- ['disableFileAccess', 'disableUrlAccess', 'normalizeHeaderKey'].forEach(key => {
24
+ ['disableFileAccess', 'disableUrlAccess', 'normalizeHeaderKey', 'maxRecipients'].forEach(key => {
39
25
  if (key in options) {
40
26
  this.data[key] = options[key];
41
27
  }
42
28
  });
29
+ // The access flags are a sandbox rather than a message field, so `defaults` counts as
30
+ // transporter configuration for them. For a transporter plugin it is the only channel
31
+ // there is, createTransport leaves `options` undefined for one, and the defaults copy
32
+ // above yields to anything the message already set, which let message data switch the
33
+ // sandbox back off. Closing is one way here, same as in resolveContent below: either
34
+ // side may switch a flag on, neither can switch off what the other closed.
35
+ ['disableFileAccess', 'disableUrlAccess'].forEach(key => {
36
+ if (!(key in options) && hasOwn(defaults, key)) {
37
+ this.data[key] = this.data[key] || defaults[key];
38
+ }
39
+ });
43
40
  }
44
-
45
- resolveContent(...args) {
46
- return shared.resolveContent(...args);
41
+ resolveContent(data, key, options, callback) {
42
+ // Most plugins call this with the legacy (data, key, callback) signature, which carries
43
+ // no access policy. The policy belongs to the message, so apply it here. Explicit
44
+ // options may only tighten it, never reopen what the transporter closed.
45
+ if (!callback && typeof options === 'function') {
46
+ callback = options;
47
+ options = false;
48
+ }
49
+ options = options || {};
50
+ const policy = {
51
+ disableFileAccess: this.data.disableFileAccess || options.disableFileAccess,
52
+ disableUrlAccess: this.data.disableUrlAccess || options.disableUrlAccess
53
+ };
54
+ return shared.resolveContent(data, key, policy, callback);
47
55
  }
48
-
49
56
  resolveAll(callback) {
50
- let keys = [
57
+ const keys = [
51
58
  [this.data, 'html'],
52
59
  [this.data, 'text'],
53
60
  [this.data, 'watchHtml'],
54
61
  [this.data, 'amp'],
55
62
  [this.data, 'icalEvent']
56
63
  ];
57
-
58
64
  if (this.data.alternatives && this.data.alternatives.length) {
59
65
  this.data.alternatives.forEach((alternative, i) => {
60
66
  keys.push([this.data.alternatives, i]);
61
67
  });
62
68
  }
63
-
64
69
  if (this.data.attachments && this.data.attachments.length) {
65
70
  this.data.attachments.forEach((attachment, i) => {
66
71
  if (!attachment.filename) {
67
- attachment.filename = (attachment.path || attachment.href || '').split('/').pop().split('?').shift() || 'attachment-' + (i + 1);
72
+ // a backslash separates as well, so a Windows path does not put the sender's directories in the headers
73
+ attachment.filename =
74
+ (attachment.path || attachment.href || '').split(/[/\\]/).pop().split('?').shift() ||
75
+ 'attachment-' + (i + 1);
68
76
  if (attachment.filename.indexOf('.') < 0) {
69
77
  attachment.filename += '.' + mimeFuncs.detectExtension(attachment.contentType);
70
78
  }
71
79
  }
72
-
73
80
  if (!attachment.contentType) {
74
81
  attachment.contentType = mimeFuncs.detectMimeType(attachment.filename || attachment.path || attachment.href || 'bin');
75
82
  }
76
-
77
83
  keys.push([this.data.attachments, i]);
78
84
  });
79
85
  }
80
-
81
- let mimeNode = new MimeNode();
82
-
83
- let addressKeys = ['from', 'to', 'cc', 'bcc', 'sender', 'replyTo'];
84
-
86
+ const mimeNode = new MimeNode();
87
+ const addressKeys = ['from', 'to', 'cc', 'bcc', 'sender', 'replyTo'];
85
88
  addressKeys.forEach(address => {
86
89
  let value;
87
90
  if (this.message) {
88
91
  value = [].concat(mimeNode._parseAddresses(this.message.getHeader(address === 'replyTo' ? 'reply-to' : address)) || []);
89
- } else if (this.data[address]) {
92
+ }
93
+ else if (this.data[address]) {
90
94
  value = [].concat(mimeNode._parseAddresses(this.data[address]) || []);
91
95
  }
92
96
  if (value && value.length) {
93
97
  this.data[address] = value;
94
- } else if (address in this.data) {
98
+ }
99
+ else if (address in this.data) {
95
100
  this.data[address] = null;
96
101
  }
97
102
  });
98
-
99
- let singleKeys = ['from', 'sender'];
103
+ const singleKeys = ['from', 'sender'];
100
104
  singleKeys.forEach(address => {
101
105
  if (this.data[address]) {
102
106
  this.data[address] = this.data[address].shift();
103
107
  }
104
108
  });
105
-
106
109
  let pos = 0;
107
- let resolveNext = () => {
110
+ const resolveNext = () => {
108
111
  if (pos >= keys.length) {
109
112
  return callback(null, this.data);
110
113
  }
111
- let args = keys[pos++];
114
+ const args = keys[pos++];
112
115
  if (!args[0] || !args[0][args[1]]) {
113
116
  return resolveNext();
114
117
  }
115
- shared.resolveContent(...args, (err, value) => {
118
+ shared.resolveContent(...args, { disableFileAccess: this.data.disableFileAccess, disableUrlAccess: this.data.disableUrlAccess }, (err, value) => {
116
119
  if (err) {
117
120
  return callback(err);
118
121
  }
119
-
120
- let node = {
122
+ const node = {
121
123
  content: value
122
124
  };
123
125
  if (args[0][args[1]] && typeof args[0][args[1]] === 'object' && !Buffer.isBuffer(args[0][args[1]])) {
124
- Object.keys(args[0][args[1]]).forEach(key => {
125
- if (!(key in node) && !['content', 'path', 'href', 'raw'].includes(key)) {
126
- node[key] = args[0][args[1]][key];
127
- }
128
- });
126
+ // The keys are the caller's, so copying them takes the same "__proto__"
127
+ // rule as the constructor. `key in node` stays as the already-set test
128
+ // here, unlike for the defaults: it also skips the Object.prototype
129
+ // member names, and letting message data land a `toString` string on a
130
+ // node only buys a TypeError the first time something stringifies it.
131
+ shared.copyOwnKeys(node, args[0][args[1]], key => key in node || ['content', 'path', 'href', 'raw'].includes(key));
129
132
  }
130
-
131
133
  args[0][args[1]] = node;
132
134
  resolveNext();
133
135
  });
134
136
  };
135
-
136
137
  setImmediate(() => resolveNext());
137
138
  }
138
-
139
139
  normalize(callback) {
140
- let envelope = this.data.envelope || this.message.getEnvelope();
141
- let messageId = this.message.messageId();
142
-
140
+ const envelope = this.message.getEnvelope();
141
+ const messageId = this.message.messageId();
143
142
  this.resolveAll((err, data) => {
144
143
  if (err) {
145
144
  return callback(err);
146
145
  }
147
-
148
146
  data.envelope = envelope;
149
147
  data.messageId = messageId;
150
-
151
148
  ['html', 'text', 'watchHtml', 'amp'].forEach(key => {
152
149
  if (data[key] && data[key].content) {
153
150
  if (typeof data[key].content === 'string') {
154
151
  data[key] = data[key].content;
155
- } else if (Buffer.isBuffer(data[key].content)) {
152
+ }
153
+ else if (Buffer.isBuffer(data[key].content)) {
156
154
  data[key] = data[key].content.toString();
157
155
  }
158
156
  }
159
157
  });
160
-
161
158
  if (data.icalEvent && Buffer.isBuffer(data.icalEvent.content)) {
162
159
  data.icalEvent.content = data.icalEvent.content.toString('base64');
163
160
  data.icalEvent.encoding = 'base64';
164
161
  }
165
-
166
162
  if (data.alternatives && data.alternatives.length) {
167
- data.alternatives.forEach(alternative => {
163
+ data.alternatives.forEach((alternative) => {
168
164
  if (alternative && alternative.content && Buffer.isBuffer(alternative.content)) {
169
165
  alternative.content = alternative.content.toString('base64');
170
166
  alternative.encoding = 'base64';
171
167
  }
172
168
  });
173
169
  }
174
-
175
170
  if (data.attachments && data.attachments.length) {
176
- data.attachments.forEach(attachment => {
171
+ data.attachments.forEach((attachment) => {
177
172
  if (attachment && attachment.content && Buffer.isBuffer(attachment.content)) {
178
173
  attachment.content = attachment.content.toString('base64');
179
174
  attachment.encoding = 'base64';
180
175
  }
181
176
  });
182
177
  }
183
-
184
178
  data.normalizedHeaders = {};
185
179
  Object.keys(data.headers || {}).forEach(key => {
180
+ if (shared.isProtoKey(key)) {
181
+ return;
182
+ }
186
183
  let value = [].concat(data.headers[key] || []).shift();
187
184
  value = (value && value.value) || value;
188
185
  if (value) {
@@ -192,33 +189,27 @@ class MailMessage {
192
189
  data.normalizedHeaders[key] = value;
193
190
  }
194
191
  });
195
-
196
192
  if (data.list && typeof data.list === 'object') {
197
- let listHeaders = this._getListHeaders(data.list);
193
+ const listHeaders = this._getListHeaders(data.list);
198
194
  listHeaders.forEach(entry => {
199
195
  data.normalizedHeaders[entry.key] = entry.value.map(val => (val && val.value) || val).join(', ');
200
196
  });
201
197
  }
202
-
203
198
  if (data.references) {
204
199
  data.normalizedHeaders.references = this.message._encodeHeaderValue('references', data.references);
205
200
  }
206
-
207
201
  if (data.inReplyTo) {
208
202
  data.normalizedHeaders['in-reply-to'] = this.message._encodeHeaderValue('in-reply-to', data.inReplyTo);
209
203
  }
210
-
211
204
  return callback(null, data);
212
205
  });
213
206
  }
214
-
215
207
  setMailerHeader() {
216
208
  if (!this.message || !this.data.xMailer) {
217
209
  return;
218
210
  }
219
211
  this.message.setHeader('X-Mailer', this.data.xMailer);
220
212
  }
221
-
222
213
  setPriorityHeaders() {
223
214
  if (!this.message || !this.data.priority) {
224
215
  return;
@@ -238,21 +229,18 @@ class MailMessage {
238
229
  // do not add anything, since all messages are 'Normal' by default
239
230
  }
240
231
  }
241
-
242
232
  setListHeaders() {
243
233
  if (!this.message || !this.data.list || typeof this.data.list !== 'object') {
244
234
  return;
245
235
  }
246
236
  // add optional List-* headers
247
- if (this.data.list && typeof this.data.list === 'object') {
248
- this._getListHeaders(this.data.list).forEach(listHeader => {
249
- listHeader.value.forEach(value => {
250
- this.message.addHeader(listHeader.key, value);
251
- });
237
+ this._getListHeaders(this.data.list).forEach(listHeader => {
238
+ listHeader.value.forEach(value => {
239
+ this.message.addHeader(listHeader.key, value);
252
240
  });
253
- }
241
+ });
254
242
  }
255
-
243
+ /** @internal */
256
244
  _getListHeaders(listData) {
257
245
  // make sure an url looks like <protocol:url>
258
246
  return Object.keys(listData).map(key => ({
@@ -263,53 +251,51 @@ class MailMessage {
263
251
  value: []
264
252
  .concat(value || [])
265
253
  .map(value => {
266
- if (typeof value === 'string') {
267
- value = {
268
- url: value
269
- };
270
- }
271
-
272
- if (value && value.url) {
273
- if (key.toLowerCase().trim() === 'id') {
274
- // List-ID: "comment" <domain>
275
- let comment = value.comment || '';
276
- if (mimeFuncs.isPlainText(comment)) {
277
- comment = '"' + comment + '"';
278
- } else {
279
- comment = mimeFuncs.encodeWord(comment);
280
- }
281
-
282
- return (value.comment ? comment + ' ' : '') + this._formatListUrl(value.url).replace(/^<[^:]+\/{,2}/, '');
283
- }
284
-
285
- // List-*: <http://domain> (comment)
286
- let comment = value.comment || '';
287
- if (!mimeFuncs.isPlainText(comment)) {
288
- comment = mimeFuncs.encodeWord(comment);
289
- }
290
-
291
- return this._formatListUrl(value.url) + (value.comment ? ' (' + comment + ')' : '');
254
+ if (typeof value === 'string') {
255
+ value = {
256
+ url: value
257
+ };
258
+ }
259
+ if (value && value.url) {
260
+ // strip CR/LF so a comment can't inject extra header lines. DEL is neither
261
+ // qtext nor ctext, so it can not be carried literally by either construct
262
+ // and has to become an encoded word like any other non-plaintext value
263
+ let comment = (value.comment || '').toString().replace(/\r?\n|\r/g, ' ');
264
+ const needsEncoding = !mimeFuncs.isPlainText(comment) || /\x7f/.test(comment);
265
+ if (key.toLowerCase().trim() === 'id') {
266
+ // List-ID: "comment" <domain>, where an unescaped quote or a trailing
267
+ // backslash in the comment would swallow the <domain> behind it
268
+ comment = needsEncoding ? mimeFuncs.encodeWord(comment) : mimeFuncs.quoteString(comment);
269
+ // List-ID expects a bare domain-like identifier, so strip the
270
+ // scheme prefix that _formatListUrl adds or passes through
271
+ return ((value.comment ? comment + ' ' : '') + this._formatListUrl(value.url).replace(/^<[^:]+:\/{0,2}/, '<'));
292
272
  }
293
-
294
- return '';
295
- })
273
+ // List-*: <http://domain> (comment)
274
+ // the ctext specials go out as quoted-pairs, otherwise a ")" closes the
275
+ // comment early and leaves the rest as junk, an unpaired "(" opens a
276
+ // nested comment that never closes, and a trailing backslash escapes
277
+ // the closing ")" so the comment swallows whatever follows it
278
+ comment = needsEncoding ? mimeFuncs.encodeWord(comment) : comment.replace(/[()\\]/g, '\\$&');
279
+ return this._formatListUrl(value.url) + (value.comment ? ' (' + comment + ')' : '');
280
+ }
281
+ return '';
282
+ })
296
283
  .filter(value => value)
297
284
  .join(', ')
298
285
  }))
299
286
  }));
300
287
  }
301
-
288
+ /** @internal */
302
289
  _formatListUrl(url) {
303
- url = url.replace(/[\s<]+|[\s>]+/g, '');
290
+ // a url has no way to carry a control char or DEL, and the angle brackets around it
291
+ // are not a quoting construct, so anything left here lands in the header raw
292
+ url = url.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, '').replace(/[\s<]+|[\s>]+/g, '');
304
293
  if (/^(https?|mailto|ftp):/.test(url)) {
305
294
  return '<' + url + '>';
306
295
  }
307
296
  if (/^[^@]+@[^@]+$/.test(url)) {
308
297
  return '<mailto:' + url + '>';
309
298
  }
310
-
311
299
  return '<http://' + url + '>';
312
300
  }
313
301
  }
314
-
315
- module.exports = MailMessage;
@@ -0,0 +1,161 @@
1
+ /**
2
+ * A header value split into the value token and its parameters, the result of parseHeaderValue
3
+ */
4
+ export interface ParsedHeaderValue {
5
+ /** The value ahead of the parameters, for example the content type, an empty string when there is none */
6
+ value: string;
7
+ /** Parameter values keyed by lowercase parameter name */
8
+ params: Record<string, string>;
9
+ }
10
+ /**
11
+ * Header value structure accepted by buildHeaderValue
12
+ */
13
+ export interface StructuredHeaderValue {
14
+ /** The value ahead of the parameters, for example the content type */
15
+ value: string | false;
16
+ /** Parameter values keyed by parameter name */
17
+ params?: Record<string, string> | undefined;
18
+ }
19
+ /**
20
+ * A single key=value pair of an rfc2231 encoded header parameter
21
+ */
22
+ export interface EncodedHeaderParam {
23
+ /** Parameter name with the continuation suffix, for example title*0* */
24
+ key: string;
25
+ /** Parameter value of this part */
26
+ value: string;
27
+ }
28
+ /** The names @types/nodemailer used for the two types above */
29
+ export type HeaderValue = StructuredHeaderValue;
30
+ export type ParsedHeaderParam = EncodedHeaderParam;
31
+ /**
32
+ * Checks if a value is plaintext string (uses only printable 7bit chars)
33
+ *
34
+ * When isParam is set the value is destined for a header parameter, so HT, CR and LF
35
+ * are not plaintext either: a header parameter has no way to carry them. HT is a valid
36
+ * fold point, so folding and unfolding a header would rewrite it as a space, and CR/LF
37
+ * cannot appear in a header value at all. DEL is neither a token character nor qtext,
38
+ * so it can not be carried bare or quoted. Such values have to go through the rfc2231
39
+ * parameter continuation encoding instead, the same way a quote already does.
40
+ *
41
+ * @param value String to be tested
42
+ * @param [isParam] Set to true if the value is a header parameter value
43
+ * @returns true if it is a plaintext string
44
+ */
45
+ export declare function isPlainText(value: unknown, isParam?: boolean): boolean;
46
+ /**
47
+ * Wraps a value into a quoted-string. Inside one a quote would end the string early
48
+ * and a backslash would escape whatever follows it, so both go out as quoted-pairs.
49
+ *
50
+ * @param value String to be quoted
51
+ * @returns The value as a quoted-string, quotes included
52
+ */
53
+ export declare function quoteString(value?: string): string;
54
+ /**
55
+ * Checks if a multi line string containes lines longer than the selected value.
56
+ *
57
+ * Useful when detecting if a mail message needs any processing at all:
58
+ * if only plaintext characters are used and lines are short, then there is
59
+ * no need to encode the values in any way. If the value is plaintext but has
60
+ * longer lines then allowed, then use format=flowed
61
+ *
62
+ * @param str Multi line string to check
63
+ * @param lineLength Max line length to check for
64
+ * @returns Returns true if there is at least one line longer than lineLength chars
65
+ */
66
+ export declare function hasLongerLines(str: string, lineLength: number): boolean;
67
+ /**
68
+ * Encodes a string or an Buffer to an UTF-8 MIME Word (rfc2047)
69
+ *
70
+ * @param data String to be encoded
71
+ * @param mimeWordEncoding='Q' Encoding for the mime word, either Q or B
72
+ * @param [maxLength=0] If set, split mime words into several chunks if needed
73
+ * @return Single or several mime words joined together
74
+ */
75
+ export declare function encodeWord(data: string | Buffer, mimeWordEncoding?: string, maxLength?: number): string;
76
+ /**
77
+ * Finds word sequences with non ascii text and converts these to mime words
78
+ *
79
+ * @param value String to be encoded
80
+ * @param mimeWordEncoding='Q' Encoding for the mime word, either Q or B
81
+ * @param [maxLength=0] If set, split mime words into several chunks if needed
82
+ * @param [encodeAll=false] If true and the value needs encoding then encodes entire string, not just the smallest match
83
+ * @return String with possible mime words
84
+ */
85
+ export declare function encodeWords(value: string, mimeWordEncoding?: string, maxLength?: number, encodeAll?: boolean): string;
86
+ /**
87
+ * Joins parsed header value together as 'value; param1=value1; param2=value2'
88
+ * PS: We are following RFC 822 for the list of special characters that we need to keep in quotes.
89
+ * Refer: https://www.w3.org/Protocols/rfc1341/4_Content-Type.html
90
+ * @param structured Parsed header value
91
+ * @return joined header value
92
+ */
93
+ export declare function buildHeaderValue(structured: StructuredHeaderValue): string;
94
+ /**
95
+ * Encodes a string or an Buffer to an UTF-8 Parameter Value Continuation encoding (rfc2231)
96
+ * Useful for splitting long parameter values.
97
+ *
98
+ * For example
99
+ * title="unicode string"
100
+ * becomes
101
+ * title*0*=utf-8''unicode
102
+ * title*1*=%20string
103
+ *
104
+ * @param key Parameter name the generated keys are built from, for example title
105
+ * @param data String to be encoded
106
+ * @param [maxLength=50] Max length for generated chunks
107
+ * @return A list of encoded keys and headers
108
+ */
109
+ export declare function buildHeaderParam(key: string, data: string | Buffer, maxLength?: number): EncodedHeaderParam[];
110
+ /**
111
+ * Parses a header value with key=value arguments into a structured
112
+ * object.
113
+ *
114
+ * parseHeaderValue('content-type: text/plain; CHARSET='UTF-8'') ->
115
+ * {
116
+ * 'value': 'text/plain',
117
+ * 'params': {
118
+ * 'charset': 'UTF-8'
119
+ * }
120
+ * }
121
+ *
122
+ * @param str Header value
123
+ * @return Header value as a parsed structure
124
+ */
125
+ export declare function parseHeaderValue(str: string): ParsedHeaderValue;
126
+ /**
127
+ * Returns file extension for a content type string. If no suitable extensions
128
+ * are found, 'bin' is used as the default extension
129
+ *
130
+ * @param mimeType Content type to be checked for
131
+ * @return File extension
132
+ */
133
+ export declare function detectExtension(mimeType?: string | false): string;
134
+ /**
135
+ * Returns content type for a file extension. If no suitable content types
136
+ * are found, 'application/octet-stream' is used as the default content type
137
+ *
138
+ * @param extension Extension to be checked for
139
+ * @return File extension
140
+ */
141
+ export declare function detectMimeType(extension?: string | false): string;
142
+ /**
143
+ * Folds long lines, useful for folding header lines (afterSpace=false) and
144
+ * flowed text (afterSpace=true)
145
+ *
146
+ * @param str String to be folded
147
+ * @param [lineLength=76] Maximum length of a line
148
+ * @param afterSpace If true, leave a space in th end of a line
149
+ * @return String with folded lines
150
+ */
151
+ export declare function foldLines(str: string, lineLength?: number, afterSpace?: boolean): string;
152
+ /**
153
+ * Splits a mime encoded string. Needed for dividing mime words into smaller chunks
154
+ *
155
+ * @param str Mime encoded string to be split up
156
+ * @param maxlen Maximum length of characters for one part (minimum 12)
157
+ * @return Split string
158
+ */
159
+ export declare function splitMimeEncodedString(str: string, maxlen?: number): string[];
160
+ export declare function encodeURICharComponent(chr: string): string;
161
+ export declare function safeEncodeURIComponent(str: string): string;