@nocobase/plugin-workflow-mailer 2.3.0-beta.12 → 2.3.0-beta.14

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
@@ -0,0 +1,344 @@
1
+ import http from 'node:http';
2
+ import https from 'node:https';
3
+ import * as urllib from '../shared/url.js';
4
+ import zlib from 'node:zlib';
5
+ import { PassThrough } from 'node:stream';
6
+ import Cookies from './cookies.js';
7
+ import * as packageData from '../package-info.js';
8
+ import net from 'node:net';
9
+ import * as errors from '../errors.js';
10
+ import { isProtoKey } from '../shared/objects.js';
11
+ const MAX_REDIRECTS = 5;
12
+ // a stalled server would otherwise hold the request, and whatever waits on it, open forever
13
+ const DEFAULT_TIMEOUT = 60 * 1000;
14
+ // the body is usually buffered in memory by the caller, so an unbounded download is refused
15
+ const DEFAULT_MAX_BYTES = 64 * 1024 * 1024;
16
+ // Only genuine TLS settings are taken from options.tls. That object reaches us straight
17
+ // from a user supplied attachment (content.tls), so keys like host, port, path, socketPath
18
+ // or lookup would otherwise repoint the request at a destination that never went through
19
+ // the URL checks below.
20
+ //
21
+ // The source of truth is the tls.connect() option list in the Node docs. A key missing
22
+ // here is dropped silently, so extend this list rather than working around it.
23
+ const TLS_OPTION_KEYS = [
24
+ 'ALPNProtocols',
25
+ 'ca',
26
+ 'cert',
27
+ 'checkServerIdentity',
28
+ 'ciphers',
29
+ 'crl',
30
+ 'dhparam',
31
+ 'ecdhCurve',
32
+ 'honorCipherOrder',
33
+ 'key',
34
+ 'maxVersion',
35
+ 'minVersion',
36
+ 'passphrase',
37
+ 'pfx',
38
+ 'rejectUnauthorized',
39
+ 'secureContext',
40
+ 'secureOptions',
41
+ 'secureProtocol',
42
+ 'servername',
43
+ 'sessionIdContext',
44
+ 'sigalgs'
45
+ ];
46
+ /**
47
+ * Resolves a URL only if it is one this module is willing to request.
48
+ *
49
+ * urllib.parse throws for a host that contains forbidden bytes, and it is called for
50
+ * every URL that reaches nmfetch, including ones that arrive from a message attachment
51
+ * or from a redirect Location header. An uncaught throw here takes the process down,
52
+ * so a URL that does not parse is reported the same way as one with a scheme we refuse.
53
+ *
54
+ * @param url URL to parse
55
+ * @returns Parsed URL, or false if it is not a usable http(s) URL
56
+ */
57
+ function parseFetchUrl(url) {
58
+ let parsed;
59
+ try {
60
+ parsed = urllib.parse(url);
61
+ }
62
+ catch (_err) {
63
+ return false;
64
+ }
65
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
66
+ return false;
67
+ }
68
+ return parsed;
69
+ }
70
+ function nmfetch(url, options) {
71
+ options = options || {};
72
+ options.fetchRes = options.fetchRes || new PassThrough();
73
+ options.cookies = options.cookies || new Cookies();
74
+ options.redirects = options.redirects || 0;
75
+ options.maxRedirects = isNaN(options.maxRedirects) ? MAX_REDIRECTS : options.maxRedirects;
76
+ const fetchRes = options.fetchRes;
77
+ const parsed = parseFetchUrl(url);
78
+ if (!parsed) {
79
+ // Only http(s) URLs can be fetched. Any other scheme (file:, gopher:, a
80
+ // protocol-relative redirect target etc.) would otherwise be silently served over
81
+ // plain HTTP, possibly against an unintended host. Bail out before the cookie jar
82
+ // is touched so a refused URL can not seed it, and release a caller supplied body:
83
+ // this is the one exit that runs before the error handler below is attached to it,
84
+ // so an error on that stream would have nowhere to go and the fd or socket behind
85
+ // it would never be released.
86
+ if (options.body && typeof options.body.destroy === 'function') {
87
+ options.body.on('error', () => false);
88
+ options.body.destroy();
89
+ }
90
+ setImmediate(() => {
91
+ const err = new Error('Unsupported protocol for URL ' + url);
92
+ err.code = errors.EFETCH;
93
+ err.sourceUrl = url;
94
+ fetchRes.emit('error', err);
95
+ });
96
+ return fetchRes;
97
+ }
98
+ if (options.cookie) {
99
+ [].concat(options.cookie || []).forEach(cookie => {
100
+ options.cookies.set(cookie, url);
101
+ });
102
+ options.cookie = false;
103
+ }
104
+ let method = (options.method || '').toString().trim().toUpperCase() || 'GET';
105
+ let finished = false;
106
+ let cookies;
107
+ let body;
108
+ const handler = parsed.protocol === 'https:' ? https : http;
109
+ const headers = {
110
+ 'accept-encoding': 'gzip,deflate',
111
+ 'user-agent': 'nodemailer/' + packageData.version
112
+ };
113
+ Object.keys(options.headers || {}).forEach(key => {
114
+ // options.headers is the caller's httpHeaders, straight off an attachment
115
+ if (isProtoKey(key.toLowerCase().trim())) {
116
+ return;
117
+ }
118
+ headers[key.toLowerCase().trim()] = options.headers[key];
119
+ });
120
+ if (options.userAgent) {
121
+ headers['user-agent'] = options.userAgent;
122
+ }
123
+ if (parsed.auth) {
124
+ headers.Authorization = 'Basic ' + Buffer.from(parsed.auth).toString('base64');
125
+ }
126
+ if ((cookies = options.cookies.get(url))) {
127
+ headers.cookie = cookies;
128
+ }
129
+ if (options.body) {
130
+ if (options.contentType !== false) {
131
+ headers['Content-Type'] = options.contentType || 'application/x-www-form-urlencoded';
132
+ }
133
+ if (typeof options.body.pipe === 'function') {
134
+ // it's a stream
135
+ headers['Transfer-Encoding'] = 'chunked';
136
+ body = options.body;
137
+ body.on('error', (err) => {
138
+ if (finished) {
139
+ return;
140
+ }
141
+ finished = true;
142
+ err.code = errors.EFETCH;
143
+ err.sourceUrl = url;
144
+ fetchRes.emit('error', err);
145
+ });
146
+ }
147
+ else {
148
+ if (options.body instanceof Buffer) {
149
+ body = options.body;
150
+ }
151
+ else if (typeof options.body === 'object') {
152
+ try {
153
+ // encodeURIComponent can fail on invalid input (partial emoji etc.)
154
+ body = Buffer.from(Object.keys(options.body)
155
+ .map(key => {
156
+ const value = options.body[key].toString().trim();
157
+ return encodeURIComponent(key) + '=' + encodeURIComponent(value);
158
+ })
159
+ .join('&'));
160
+ }
161
+ catch (E) {
162
+ // the caller attaches its error listener once nmfetch has returned, so
163
+ // the error is emitted on the next tick and the stream is handed back
164
+ // the way every other failure is reported
165
+ finished = true;
166
+ E.code = errors.EFETCH;
167
+ E.sourceUrl = url;
168
+ setImmediate(() => fetchRes.emit('error', E));
169
+ return fetchRes;
170
+ }
171
+ }
172
+ else {
173
+ body = Buffer.from(options.body.toString().trim());
174
+ }
175
+ headers['Content-Type'] = options.contentType || 'application/x-www-form-urlencoded';
176
+ headers['Content-Length'] = body.length;
177
+ }
178
+ // if method is not provided, use POST instead of GET
179
+ method = (options.method || '').toString().trim().toUpperCase() || 'POST';
180
+ }
181
+ let req;
182
+ const reqOptions = {
183
+ method,
184
+ host: parsed.hostname,
185
+ path: parsed.path,
186
+ port: parsed.port ? parsed.port : parsed.protocol === 'https:' ? 443 : 80,
187
+ headers,
188
+ // Validate TLS certificates by default. Callers that genuinely need to
189
+ // reach a self-signed/internal host opt out explicitly with
190
+ // options.tls = { rejectUnauthorized: false }.
191
+ rejectUnauthorized: true,
192
+ agent: false
193
+ };
194
+ if (options.tls) {
195
+ // see TLS_OPTION_KEYS
196
+ Object.keys(options.tls).forEach(key => {
197
+ if (TLS_OPTION_KEYS.includes(key)) {
198
+ reqOptions[key] = options.tls[key];
199
+ }
200
+ });
201
+ }
202
+ if (parsed.protocol === 'https:' &&
203
+ parsed.hostname &&
204
+ parsed.hostname !== reqOptions.host &&
205
+ !net.isIP(parsed.hostname) &&
206
+ !reqOptions.servername) {
207
+ reqOptions.servername = parsed.hostname;
208
+ }
209
+ try {
210
+ req = handler.request(reqOptions);
211
+ }
212
+ catch (E) {
213
+ finished = true;
214
+ setImmediate(() => {
215
+ E.code = errors.EFETCH;
216
+ E.sourceUrl = url;
217
+ fetchRes.emit('error', E);
218
+ });
219
+ return fetchRes;
220
+ }
221
+ // reports the first failure of this request on fetchRes and releases the request
222
+ const fail = (err, sourceUrl = url) => {
223
+ if (finished) {
224
+ return;
225
+ }
226
+ finished = true;
227
+ err.code = errors.EFETCH;
228
+ err.sourceUrl = sourceUrl;
229
+ fetchRes.emit('error', err);
230
+ req.abort();
231
+ };
232
+ const timeout = typeof options.timeout === 'number' && options.timeout >= 0 ? options.timeout : DEFAULT_TIMEOUT;
233
+ if (timeout) {
234
+ req.setTimeout(timeout, () => fail(new Error('Request Timeout')));
235
+ }
236
+ req.on('error', (err) => fail(err));
237
+ req.on('response', res => {
238
+ let inflate;
239
+ if (finished) {
240
+ return;
241
+ }
242
+ switch (res.headers['content-encoding']) {
243
+ case 'gzip':
244
+ case 'deflate':
245
+ inflate = zlib.createUnzip();
246
+ break;
247
+ }
248
+ if (res.headers['set-cookie']) {
249
+ [].concat(res.headers['set-cookie'] || []).forEach(cookie => {
250
+ options.cookies.set(cookie, url);
251
+ });
252
+ }
253
+ if ([301, 302, 303, 307, 308].includes(res.statusCode) && res.headers.location) {
254
+ // redirect
255
+ options.redirects++;
256
+ if (options.redirects > options.maxRedirects) {
257
+ return fail(new Error('Maximum redirect count exceeded'));
258
+ }
259
+ // redirect does not include POST body
260
+ options.method = 'GET';
261
+ options.body = false;
262
+ let redirectUrl;
263
+ try {
264
+ redirectUrl = urllib.resolve(url, res.headers.location);
265
+ }
266
+ catch (_err) {
267
+ // the legacy resolver throws on a Location the WHATWG parser also refused,
268
+ // so fall through to the check below with what the server actually sent
269
+ redirectUrl = res.headers.location;
270
+ }
271
+ const redirectParsed = parseFetchUrl(redirectUrl);
272
+ if (!redirectParsed) {
273
+ // Refuse the redirect target here rather than leaving it to the recursive
274
+ // call: that call gets its own `finished` flag and no handle on this
275
+ // request, so this one would stay open and could emit a second error on
276
+ // the shared fetchRes once it times out. Callers listen with req.once().
277
+ return fail(new Error('Unsupported protocol for URL ' + redirectUrl), redirectUrl);
278
+ }
279
+ // Do not forward credentials when the redirect leaves the original
280
+ // security context: a different host, or a downgrade from https to
281
+ // http (which would otherwise put them on the wire in cleartext).
282
+ // Strip sensitive request headers so an attacker who controls the
283
+ // redirect target cannot harvest them.
284
+ const crossHost = redirectParsed.hostname !== parsed.hostname;
285
+ const downgrade = parsed.protocol === 'https:' && redirectParsed.protocol === 'http:';
286
+ if (options.headers && (crossHost || downgrade)) {
287
+ const sensitive = ['authorization', 'cookie', 'proxy-authorization'];
288
+ Object.keys(options.headers).forEach(key => {
289
+ if (sensitive.includes(key.toLowerCase())) {
290
+ delete options.headers[key];
291
+ }
292
+ });
293
+ }
294
+ // this request is done with, release it so its socket and timeout do not
295
+ // outlive it and report a late error on the shared fetchRes
296
+ finished = true;
297
+ res.resume();
298
+ req.abort();
299
+ return nmfetch(redirectUrl, options);
300
+ }
301
+ fetchRes.statusCode = res.statusCode;
302
+ fetchRes.headers = res.headers;
303
+ if (res.statusCode >= 300 && !options.allowErrorResponse) {
304
+ return fail(new Error('Invalid status code ' + res.statusCode));
305
+ }
306
+ res.on('error', (err) => fail(err));
307
+ const maxBytes = typeof options.maxBytes === 'number' && options.maxBytes > 0 ? options.maxBytes : DEFAULT_MAX_BYTES;
308
+ const source = inflate || res;
309
+ let received = 0;
310
+ source.on('data', (chunk) => {
311
+ received += chunk.length;
312
+ if (received <= maxBytes || finished) {
313
+ return;
314
+ }
315
+ source.unpipe(fetchRes);
316
+ fail(new Error('Response size exceeds the allowed ' + maxBytes + ' bytes'));
317
+ });
318
+ if (inflate) {
319
+ res.pipe(inflate).pipe(fetchRes);
320
+ inflate.on('error', (err) => fail(err));
321
+ }
322
+ else {
323
+ res.pipe(fetchRes);
324
+ }
325
+ });
326
+ setImmediate(() => {
327
+ if (body) {
328
+ try {
329
+ if (typeof body.pipe === 'function') {
330
+ return body.pipe(req);
331
+ }
332
+ req.write(body);
333
+ }
334
+ catch (err) {
335
+ return fail(err);
336
+ }
337
+ }
338
+ req.end();
339
+ });
340
+ return fetchRes;
341
+ }
342
+ nmfetch.Cookies = Cookies;
343
+ nmfetch.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
344
+ export default nmfetch;
@@ -0,0 +1,64 @@
1
+ import type { Logger } from '../shared/index.js';
2
+ import type { MimeNodeEnvelope } from '../mime-node/index.js';
3
+ import type MailMessage from '../mailer/mail-message.js';
4
+ import type { default as Mail, SentMessageInfo, SendMailOptions, TransportOptions } from '../mailer/index.js';
5
+ /**
6
+ * Options for the JSON transport
7
+ */
8
+ export interface JSONTransportOptions extends TransportOptions {
9
+ /** Selects this transport in createTransport */
10
+ jsonTransport?: boolean | undefined;
11
+ /** If true, the message is returned as an object instead of a JSON string */
12
+ skipEncoding?: boolean | undefined;
13
+ }
14
+ /**
15
+ * The value the JSON transport hands to the send callback. M is the type of the message
16
+ * field: a JSON string by default, the message object itself when skipEncoding is set
17
+ */
18
+ export interface JSONSentMessageInfo<M = string> extends SentMessageInfo {
19
+ /** The envelope the message was generated with */
20
+ envelope: MimeNodeEnvelope;
21
+ /** Message-ID value of the message */
22
+ messageId: string;
23
+ /** The normalized message as a JSON string, or as the object itself when skipEncoding is set */
24
+ message: M;
25
+ }
26
+ /**
27
+ * The value the JSON transport hands to the send callback when skipEncoding is set: the
28
+ * message field holds the message object. Typed loosely so that a transporter created with
29
+ * skipEncoding still fits a variable declared with the plain result type
30
+ */
31
+ export type JSONSentMessageObjectInfo = JSONSentMessageInfo<any>;
32
+ /**
33
+ * Generates a Transport object to generate JSON output
34
+ *
35
+ * @constructor
36
+ * @param optional config parameter
37
+ */
38
+ declare class JSONTransport {
39
+ mailer: Mail<JSONSentMessageInfo>;
40
+ options: JSONTransportOptions;
41
+ name: string;
42
+ version: string;
43
+ logger: Logger;
44
+ constructor(options?: JSONTransportOptions);
45
+ /**
46
+ * <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
47
+ *
48
+ * @param mail MailComposer object
49
+ * @param done Callback function to run when the sending is completed
50
+ */
51
+ send(mail: MailMessage<JSONSentMessageInfo>, done: (err: Error | null, info?: JSONSentMessageInfo) => void): void;
52
+ }
53
+ /**
54
+ * Type aliases in the layout of @types/nodemailer, so `JSONTransport.Options` style references keep working
55
+ */
56
+ declare namespace JSONTransport {
57
+ type Options = JSONTransportOptions;
58
+ type MailOptions = SendMailOptions;
59
+ type SentMessageInfo = JSONSentMessageInfo;
60
+ type SentMessageObjectInfo = JSONSentMessageObjectInfo;
61
+ }
62
+ /** The same aliases as module level exports, for `import * as JSONTransport` and `import JSONTransport = require()` */
63
+ export type { JSONTransportOptions as Options, SendMailOptions as MailOptions, JSONSentMessageInfo as SentMessageInfo, JSONSentMessageObjectInfo as SentMessageObjectInfo };
64
+ export default JSONTransport;
@@ -0,0 +1,62 @@
1
+ import * as packageData from '../package-info.js';
2
+ import * as shared from '../shared/index.js';
3
+ /**
4
+ * Generates a Transport object to generate JSON output
5
+ *
6
+ * @constructor
7
+ * @param optional config parameter
8
+ */
9
+ class JSONTransport {
10
+ constructor(options) {
11
+ options = options || {};
12
+ this.options = options;
13
+ this.name = 'JSONTransport';
14
+ this.version = packageData.version;
15
+ this.logger = shared.getLogger(this.options, {
16
+ component: this.options.component || 'json-transport'
17
+ });
18
+ }
19
+ /**
20
+ * <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
21
+ *
22
+ * @param mail MailComposer object
23
+ * @param done Callback function to run when the sending is completed
24
+ */
25
+ send(mail, done) {
26
+ // Sendmail strips this header line by itself. send() runs after the message was
27
+ // compiled, so mail.message is set
28
+ mail.message.keepBcc = true;
29
+ const envelope = mail.message.getEnvelope();
30
+ const messageId = mail.message.messageId();
31
+ const recipients = [].concat(envelope.to || []);
32
+ if (recipients.length > 3) {
33
+ recipients.push('...and ' + recipients.splice(2).length + ' more');
34
+ }
35
+ this.logger.info({
36
+ tnx: 'send',
37
+ messageId
38
+ }, 'Composing JSON structure of %s to <%s>', messageId, recipients.join(', '));
39
+ setImmediate(() => {
40
+ mail.normalize((err, data) => {
41
+ if (err) {
42
+ this.logger.error({
43
+ err,
44
+ tnx: 'send',
45
+ messageId
46
+ }, 'Failed building JSON structure for %s. %s', messageId, err.message);
47
+ return done(err);
48
+ }
49
+ delete data.envelope;
50
+ delete data.normalizedHeaders;
51
+ // the message field is the object itself with skipEncoding, the
52
+ // createTransport overload for that option types the result accordingly
53
+ return done(null, {
54
+ envelope,
55
+ messageId,
56
+ message: this.options.skipEncoding ? data : JSON.stringify(data)
57
+ });
58
+ });
59
+ });
60
+ }
61
+ }
62
+ export default JSONTransport;
@@ -0,0 +1,174 @@
1
+ import MimeNode, { type MimeNodeAddressInput, type MimeNodeContent, type MimeNodeEnvelopeInput, type MimeNodeHeaders, type MimeNodeOptions } from '../mime-node/index.js';
2
+ import type { Readable } from 'node:stream';
3
+ import type { OutgoingHttpHeaders } from 'node:http';
4
+ /**
5
+ * A content element, the shape of the text, html, watchHtml, amp and alternatives values.
6
+ * The content is either given in `content`, read from `path` or `href`, or `raw` supplies
7
+ * a pregenerated MIME part
8
+ */
9
+ export interface MailComposerAlternative {
10
+ /** The content itself: a string, a Buffer, a readable stream or a content descriptor */
11
+ content?: MimeNodeContent | undefined;
12
+ /** File path, data URI or http(s) URL to read the content from */
13
+ path?: string | false | undefined;
14
+ /** URL or data URI to fetch the content from */
15
+ href?: string | false | undefined;
16
+ /** Request headers for a URL fetch */
17
+ httpHeaders?: OutgoingHttpHeaders | undefined;
18
+ /** TLS settings for a URL fetch, see nmfetch */
19
+ tls?: {
20
+ [key: string]: any;
21
+ } | undefined;
22
+ /** Encoding of a string `content`, decoded into a Buffer unless it is utf8 or ascii */
23
+ encoding?: string | undefined;
24
+ /** Pregenerated MIME part, used as is instead of building the node */
25
+ raw?: MimeNodeContent | undefined;
26
+ /** Content type, detected from the filename, path or URL when not set */
27
+ contentType?: string | undefined;
28
+ /** Content-Transfer-Encoding for the node, false leaves the choice to the node */
29
+ contentTransferEncoding?: string | false | undefined;
30
+ /** Filename for the node, false suppresses the generated one */
31
+ filename?: string | false | undefined;
32
+ /** Additional headers for the node */
33
+ headers?: MimeNodeHeaders | undefined;
34
+ }
35
+ /**
36
+ * An attachment, the shape of the attachments entries
37
+ */
38
+ export interface MailComposerAttachment extends MailComposerAlternative {
39
+ /** Content-Disposition for the node, 'attachment' by default and 'inline' for a message node or an image with a cid */
40
+ contentDisposition?: string | undefined;
41
+ /** Content-Id for an embedded image, moves the attachment into the multipart/related node beside the html */
42
+ cid?: string | undefined;
43
+ }
44
+ /**
45
+ * The icalEvent value as an object
46
+ */
47
+ export interface MailComposerIcalEvent extends MailComposerAlternative {
48
+ /** iCalendar method, PUBLISH by default */
49
+ method?: string | undefined;
50
+ }
51
+ /**
52
+ * The attachments as sorted by getAttachments
53
+ */
54
+ export interface MailComposerAttachments {
55
+ /** Attachments for the multipart/mixed node, the icalEvent attachment included */
56
+ attached: MailComposerAttachment[];
57
+ /** Attachments with a cid, embedded in the multipart/related node beside the html */
58
+ related: MailComposerAttachment[];
59
+ }
60
+ /**
61
+ * A List-* header entry, a bare url or an url with a comment
62
+ */
63
+ export type MailComposerListHeaderEntry = string | {
64
+ url: string;
65
+ comment?: string | undefined;
66
+ };
67
+ /**
68
+ * The list value: List-* headers keyed by the part after "List-" (help, unsubscribe,
69
+ * subscribe, post, owner, archive, id). An array emits one header per entry, an entry that
70
+ * is itself an array joins its values into one header
71
+ */
72
+ export interface MailComposerListHeaders {
73
+ [key: string]: MailComposerListHeaderEntry | (MailComposerListHeaderEntry | MailComposerListHeaderEntry[])[];
74
+ }
75
+ /**
76
+ * Encoding for the non-ascii header values: quoted-printable ('Q', the default) or base64
77
+ * ('B'). Only the first letter is read, so the short forms work as well
78
+ */
79
+ export type MailComposerTextEncoding = 'quoted-printable' | 'base64' | 'Q' | 'B';
80
+ /**
81
+ * Mail options, the message data MailComposer builds the MIME tree from. The address
82
+ * fields, subject, messageId, date, inReplyTo and references become headers of the root
83
+ * node. Some fields are read by the mailer that hands the data to MailComposer rather than
84
+ * by MailComposer itself, these are marked as such
85
+ */
86
+ export interface MailComposerOptions {
87
+ from?: MimeNodeAddressInput | undefined;
88
+ sender?: MimeNodeAddressInput | undefined;
89
+ to?: MimeNodeAddressInput | undefined;
90
+ cc?: MimeNodeAddressInput | undefined;
91
+ bcc?: MimeNodeAddressInput | undefined;
92
+ replyTo?: MimeNodeAddressInput | undefined;
93
+ inReplyTo?: string | undefined;
94
+ references?: string | string[] | undefined;
95
+ subject?: string | undefined;
96
+ /** Message-ID header value, generated when missing */
97
+ messageId?: string | undefined;
98
+ /** Date header value, the current time when missing */
99
+ date?: Date | string | undefined;
100
+ /** Plaintext version of the message */
101
+ text?: string | Buffer | Readable | MailComposerAlternative | undefined;
102
+ /** HTML version of the message */
103
+ html?: string | Buffer | Readable | MailComposerAlternative | undefined;
104
+ /** Apple Watch specific HTML version of the message */
105
+ watchHtml?: string | Buffer | Readable | MailComposerAlternative | undefined;
106
+ /** AMP4EMAIL version of the message */
107
+ amp?: string | Buffer | Readable | MailComposerAlternative | undefined;
108
+ /** iCalendar event, included both as a text/calendar alternative and as an application/ics attachment */
109
+ icalEvent?: string | Buffer | Readable | MailComposerIcalEvent | undefined;
110
+ attachments?: MailComposerAttachment[] | undefined;
111
+ /** Further alternatives for the multipart/alternative node, after text, watchHtml, amp, html and the calendar event */
112
+ alternatives?: MailComposerAlternative[] | undefined;
113
+ /** Custom headers for the root node, the standard headers above override them */
114
+ headers?: MimeNodeHeaders | undefined;
115
+ /** List-* headers, read by the mailer */
116
+ list?: MailComposerListHeaders | undefined;
117
+ /** SMTP envelope to use instead of the one generated from the headers */
118
+ envelope?: MimeNodeEnvelopeInput | undefined;
119
+ /** Content-Transfer-Encoding to force for the text/* nodes that do not set their own */
120
+ encoding?: string | undefined;
121
+ /** Header string encoding, 'Q' (the default) or 'B', 'quoted-printable' and 'base64' are accepted as well */
122
+ textEncoding?: MailComposerTextEncoding | undefined;
123
+ /** Pregenerated rfc822 message, used as is instead of building one */
124
+ raw?: MimeNodeContent | undefined;
125
+ /** Reject content that points to a URL */
126
+ disableUrlAccess?: boolean | undefined;
127
+ /** Reject content that points to a file path */
128
+ disableFileAccess?: boolean | undefined;
129
+ /** Convert data: images in the html into embedded attachments, read by the mailer */
130
+ attachDataUrls?: boolean | undefined;
131
+ /** Prefix for the generated multipart boundaries */
132
+ boundaryPrefix?: string | undefined;
133
+ /** Shared part of the unique multipart boundary */
134
+ baseBoundary?: string | undefined;
135
+ /** 'win' for CRLF and 'linux' for LF line breaks in the generated message, kept as is when not set */
136
+ newline?: string | undefined;
137
+ /** Method to normalize header keys for custom caseing */
138
+ normalizeHeaderKey?: MimeNodeOptions['normalizeHeaderKey'] | undefined;
139
+ /** 'high', 'normal' or 'low', sets the priority headers, read by the mailer */
140
+ priority?: string | undefined;
141
+ /** X-Mailer header value, false leaves the header out, read by the mailer */
142
+ xMailer?: string | false | undefined;
143
+ }
144
+ declare class MailComposer {
145
+ mail: MailComposerOptions;
146
+ message: MimeNode | false;
147
+ constructor(mail?: MailComposerOptions);
148
+ /**
149
+ * Builds MimeNode instance
150
+ */
151
+ compile(): MimeNode;
152
+ /**
153
+ * List all attachments. Resulting attachment objects can be used as input for MimeNode nodes
154
+ *
155
+ * @param findRelated If true separate related attachments from attached ones
156
+ * @returns An object of arrays (`related` and `attached`)
157
+ */
158
+ getAttachments(findRelated?: boolean): MailComposerAttachments;
159
+ /**
160
+ * List alternatives. Resulting objects can be used as input for MimeNode nodes
161
+ *
162
+ * @returns An array of alternative elements. Includes the `text` and `html` values as well
163
+ */
164
+ getAlternatives(): MailComposerAlternative[];
165
+ }
166
+ /**
167
+ * Type alias in the layout of the other modules (@types/nodemailer had no namespace for MailComposer)
168
+ */
169
+ declare namespace MailComposer {
170
+ type Options = MailComposerOptions;
171
+ }
172
+ /** The same alias as a module level export, for `import * as MailComposer` and `import MailComposer = require()` */
173
+ export type { MailComposerOptions as Options };
174
+ export default MailComposer;