@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
@@ -0,0 +1,36 @@
1
+ import { Transform } from 'node:stream';
2
+ /**
3
+ * Encodes a Buffer into a base64 encoded string
4
+ *
5
+ * @param buffer Buffer to convert
6
+ * @returns base64 encoded string
7
+ */
8
+ export declare function encode(buffer: Buffer | string): string;
9
+ /**
10
+ * Adds soft line breaks to a base64 string
11
+ *
12
+ * @param str base64 encoded string that might need line wrapping
13
+ * @param [lineLength=76] Maximum allowed length for a line
14
+ * @returns Soft-wrapped base64 encoded string
15
+ */
16
+ export declare function wrap(str: string, lineLength?: number | false): string;
17
+ /**
18
+ * Options for the base64 encoder stream
19
+ */
20
+ export interface EncoderOptions {
21
+ /** Maximum length for lines, set to false to disable wrapping */
22
+ lineLength?: number | false | undefined;
23
+ }
24
+ /**
25
+ * Creates a transform stream for encoding data to base64 encoding
26
+ *
27
+ * @constructor
28
+ * @param options Stream options
29
+ * @param [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
30
+ */
31
+ export declare class Encoder extends Transform {
32
+ options: EncoderOptions;
33
+ inputBytes: number;
34
+ outputBytes: number;
35
+ constructor(options?: EncoderOptions);
36
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Encoder = void 0;
4
+ exports.encode = encode;
5
+ exports.wrap = wrap;
6
+ const node_stream_1 = require("node:stream");
7
+ /**
8
+ * Encodes a Buffer into a base64 encoded string
9
+ *
10
+ * @param buffer Buffer to convert
11
+ * @returns base64 encoded string
12
+ */
13
+ function encode(buffer) {
14
+ if (typeof buffer === 'string') {
15
+ buffer = Buffer.from(buffer, 'utf-8');
16
+ }
17
+ return buffer.toString('base64');
18
+ }
19
+ /**
20
+ * Adds soft line breaks to a base64 string
21
+ *
22
+ * @param str base64 encoded string that might need line wrapping
23
+ * @param [lineLength=76] Maximum allowed length for a line
24
+ * @returns Soft-wrapped base64 encoded string
25
+ */
26
+ function wrap(str, lineLength) {
27
+ str = (str || '').toString();
28
+ // a negative length would step backwards through the input and never finish
29
+ lineLength = Math.max(Number(lineLength) || 76, 1);
30
+ if (str.length <= lineLength) {
31
+ return str;
32
+ }
33
+ const result = [];
34
+ let pos = 0;
35
+ const chunkLength = lineLength * 1024;
36
+ const wrapRegex = new RegExp('.{' + lineLength + '}', 'g');
37
+ while (pos < str.length) {
38
+ const wrappedLines = str.substr(pos, chunkLength).replace(wrapRegex, '$&\r\n').trim();
39
+ result.push(wrappedLines);
40
+ pos += chunkLength;
41
+ }
42
+ return result.join('\r\n').trim();
43
+ }
44
+ /**
45
+ * Creates a transform stream for encoding data to base64 encoding
46
+ *
47
+ * @constructor
48
+ * @param options Stream options
49
+ * @param [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
50
+ */
51
+ class Encoder extends node_stream_1.Transform {
52
+ constructor(options) {
53
+ super();
54
+ this.options = options || {};
55
+ if (this.options.lineLength !== false) {
56
+ this.options.lineLength = this.options.lineLength || 76;
57
+ }
58
+ this._curLine = '';
59
+ this._remainingBytes = false;
60
+ this.inputBytes = 0;
61
+ this.outputBytes = 0;
62
+ }
63
+ /** @internal */
64
+ _transform(chunk, encoding, done) {
65
+ let buf = encoding !== 'buffer' ? Buffer.from(chunk, encoding) : chunk;
66
+ if (!buf || !buf.length) {
67
+ setImmediate(done);
68
+ return;
69
+ }
70
+ this.inputBytes += buf.length;
71
+ if (this._remainingBytes && this._remainingBytes.length) {
72
+ buf = Buffer.concat([this._remainingBytes, buf], this._remainingBytes.length + buf.length);
73
+ this._remainingBytes = false;
74
+ }
75
+ if (buf.length % 3) {
76
+ this._remainingBytes = buf.slice(buf.length - (buf.length % 3));
77
+ buf = buf.slice(0, buf.length - (buf.length % 3));
78
+ }
79
+ else {
80
+ this._remainingBytes = false;
81
+ }
82
+ let b64 = this._curLine + encode(buf);
83
+ if (this.options.lineLength) {
84
+ b64 = wrap(b64, this.options.lineLength);
85
+ // remove last line as it is still most probably incomplete
86
+ const lastLF = b64.lastIndexOf('\n');
87
+ if (lastLF < 0) {
88
+ this._curLine = b64;
89
+ b64 = '';
90
+ }
91
+ else if (lastLF === b64.length - 1) {
92
+ this._curLine = '';
93
+ }
94
+ else {
95
+ this._curLine = b64.substring(lastLF + 1);
96
+ b64 = b64.substring(0, lastLF + 1);
97
+ }
98
+ }
99
+ if (b64) {
100
+ this.outputBytes += b64.length;
101
+ this.push(Buffer.from(b64, 'ascii'));
102
+ }
103
+ setImmediate(done);
104
+ }
105
+ /** @internal */
106
+ _flush(done) {
107
+ if (this._remainingBytes && this._remainingBytes.length) {
108
+ this._curLine += encode(this._remainingBytes);
109
+ }
110
+ if (this._curLine) {
111
+ this._curLine = wrap(this._curLine, this.options.lineLength);
112
+ this.outputBytes += this._curLine.length;
113
+ this.push(Buffer.from(this._curLine, 'ascii'));
114
+ this._curLine = '';
115
+ }
116
+ done();
117
+ }
118
+ }
119
+ exports.Encoder = Encoder;
@@ -0,0 +1,52 @@
1
+ import { type DKIMKey, type DKIMPrivateKey, type DKIMSignOptions } from './sign.js';
2
+ import { PassThrough, type Readable } from 'node:stream';
3
+ /**
4
+ * A single DKIM signing key
5
+ */
6
+ export type { DKIMKey, DKIMPrivateKey, DKIMSignOptions };
7
+ /**
8
+ * Options for the DKIM signer
9
+ */
10
+ export interface DKIMOptions extends DKIMSignOptions {
11
+ /** One or more signing keys, used instead of the domainName, keySelector and privateKey options */
12
+ keys?: DKIMKey | DKIMKey[] | undefined;
13
+ /** Directory for buffering large message bodies to disk, no buffering when not set */
14
+ cacheDir?: string | false | undefined;
15
+ /** Body size in bytes from which the body is buffered to cacheDir, defaults to 10 MB */
16
+ cacheTreshold?: number | undefined;
17
+ /** Hash algorithm for the body hash and the signature, defaults to sha256 */
18
+ hashAlgo?: string | undefined;
19
+ }
20
+ /**
21
+ * The signed message as returned by DKIM#sign
22
+ */
23
+ export interface DKIMSignedStream extends PassThrough {
24
+ /** true if the message body was buffered to cacheDir while signing */
25
+ usingCache: boolean;
26
+ }
27
+ declare class DKIM {
28
+ options: DKIMOptions;
29
+ keys: DKIMKey[];
30
+ constructor(options: DKIMOptions);
31
+ sign(input: Readable | Buffer | string, extraOptions?: DKIMOptions): DKIMSignedStream;
32
+ }
33
+ /** The signer options without any key material */
34
+ export type DKIMOptionalOptions = Omit<DKIMOptions, 'keys' | 'domainName' | 'keySelector' | 'privateKey'>;
35
+ /** The signer options for a single key given as domainName, keySelector and privateKey */
36
+ export type DKIMSingleKeyOptions = Omit<DKIMOptions, 'keys'>;
37
+ /** The signer options for one or more keys given through `keys` */
38
+ export type DKIMMultipleKeysOptions = DKIMOptionalOptions & {
39
+ keys: DKIMKey | DKIMKey[];
40
+ };
41
+ /**
42
+ * Type aliases in the layout of @types/nodemailer, so `DKIM.Options` style references keep working
43
+ */
44
+ declare namespace DKIM {
45
+ type Options = DKIMOptions;
46
+ type OptionalOptions = DKIMOptionalOptions;
47
+ type SingleKeyOptions = DKIMSingleKeyOptions;
48
+ type MultipleKeysOptions = DKIMMultipleKeysOptions;
49
+ }
50
+ /** The same aliases as module level exports, for `import * as DKIM` and `import DKIM = require()` */
51
+ export type { DKIMOptions as Options, DKIMOptionalOptions as OptionalOptions, DKIMSingleKeyOptions as SingleKeyOptions, DKIMMultipleKeysOptions as MultipleKeysOptions };
52
+ export default DKIM;
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ // FIXME:
3
+ // replace this Transform mess with a method that pipes input argument to output argument
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const message_parser_js_1 = __importDefault(require("./message-parser.js"));
9
+ const relaxed_body_js_1 = __importDefault(require("./relaxed-body.js"));
10
+ const sign_js_1 = __importDefault(require("./sign.js"));
11
+ const node_stream_1 = require("node:stream");
12
+ const node_fs_1 = __importDefault(require("node:fs"));
13
+ const node_path_1 = __importDefault(require("node:path"));
14
+ const node_crypto_1 = __importDefault(require("node:crypto"));
15
+ const objects_js_1 = require("../shared/objects.js");
16
+ const DKIM_ALGO = 'sha256';
17
+ const MAX_MESSAGE_SIZE = 10 * 1024 * 1024; // buffer messages larger than this to disk
18
+ class DKIMSigner {
19
+ constructor(options, keys, input, output) {
20
+ this.options = options || {};
21
+ this.keys = keys;
22
+ this.cacheTreshold = Number(this.options.cacheTreshold) || MAX_MESSAGE_SIZE;
23
+ this.hashAlgo = this.options.hashAlgo || DKIM_ALGO;
24
+ this.cacheDir = this.options.cacheDir || false;
25
+ this.chunks = [];
26
+ this.chunklen = 0;
27
+ this.readPos = 0;
28
+ this.cachePath = this.cacheDir
29
+ ? node_path_1.default.join(this.cacheDir, 'message.' + Date.now() + '-' + node_crypto_1.default.randomBytes(14).toString('hex'))
30
+ : false;
31
+ this.cache = false;
32
+ this.headers = false;
33
+ this.bodyHash = false;
34
+ this.parser = false;
35
+ this.relaxedBody = false;
36
+ this.input = input;
37
+ this.output = output;
38
+ this.output.usingCache = false;
39
+ this.hasErrored = false;
40
+ this.input.on('error', err => {
41
+ this.hasErrored = true;
42
+ this.cleanup();
43
+ output.emit('error', err);
44
+ });
45
+ }
46
+ cleanup() {
47
+ if (!this.cache || !this.cachePath) {
48
+ return;
49
+ }
50
+ node_fs_1.default.unlink(this.cachePath, () => false);
51
+ }
52
+ createReadCache() {
53
+ // pipe remainings to cache file
54
+ this.cache = node_fs_1.default.createReadStream(this.cachePath);
55
+ this.cache.once('error', err => {
56
+ this.cleanup();
57
+ this.output.emit('error', err);
58
+ });
59
+ this.cache.once('close', () => {
60
+ this.cleanup();
61
+ });
62
+ this.cache.pipe(this.output);
63
+ }
64
+ sendNextChunk() {
65
+ if (this.hasErrored) {
66
+ return;
67
+ }
68
+ if (this.readPos >= this.chunks.length) {
69
+ if (!this.cache) {
70
+ this.output.end();
71
+ return;
72
+ }
73
+ return this.createReadCache();
74
+ }
75
+ const chunk = this.chunks[this.readPos++];
76
+ if (this.output.write(chunk) === false) {
77
+ this.output.once('drain', () => {
78
+ this.sendNextChunk();
79
+ });
80
+ return;
81
+ }
82
+ setImmediate(() => this.sendNextChunk());
83
+ }
84
+ sendSignedOutput() {
85
+ let keyPos = 0;
86
+ const signNextKey = () => {
87
+ if (keyPos >= this.keys.length) {
88
+ this.output.write(this.parser.rawHeaders);
89
+ setImmediate(() => this.sendNextChunk());
90
+ return;
91
+ }
92
+ const key = this.keys[keyPos++];
93
+ let dkimField;
94
+ try {
95
+ dkimField = (0, sign_js_1.default)(this.headers, this.hashAlgo, this.bodyHash, {
96
+ domainName: key.domainName,
97
+ keySelector: key.keySelector,
98
+ privateKey: key.privateKey,
99
+ headerFieldNames: this.options.headerFieldNames,
100
+ skipFields: this.options.skipFields
101
+ });
102
+ }
103
+ catch (err) {
104
+ this.hasErrored = true;
105
+ this.cleanup();
106
+ this.output.emit('error', err);
107
+ return;
108
+ }
109
+ if (dkimField) {
110
+ this.output.write(Buffer.from(dkimField + '\r\n'));
111
+ }
112
+ setImmediate(signNextKey);
113
+ };
114
+ if (this.bodyHash && this.headers) {
115
+ return signNextKey();
116
+ }
117
+ this.output.write(this.parser.rawHeaders);
118
+ this.sendNextChunk();
119
+ }
120
+ createWriteCache() {
121
+ this.output.usingCache = true;
122
+ // pipe remainings to cache file
123
+ this.cache = node_fs_1.default.createWriteStream(this.cachePath);
124
+ this.cache.once('error', err => {
125
+ this.cleanup();
126
+ // drain input
127
+ this.relaxedBody.unpipe(this.cache);
128
+ this.relaxedBody.on('readable', () => {
129
+ while (this.relaxedBody.read() !== null) {
130
+ // do nothing
131
+ }
132
+ });
133
+ this.hasErrored = true;
134
+ // emit error
135
+ this.output.emit('error', err);
136
+ });
137
+ this.cache.once('close', () => {
138
+ this.sendSignedOutput();
139
+ });
140
+ this.relaxedBody.removeAllListeners('readable');
141
+ this.relaxedBody.pipe(this.cache);
142
+ }
143
+ signStream() {
144
+ this.parser = new message_parser_js_1.default();
145
+ this.relaxedBody = new relaxed_body_js_1.default({
146
+ hashAlgo: this.hashAlgo
147
+ });
148
+ this.parser.on('headers', value => {
149
+ this.headers = value;
150
+ });
151
+ this.relaxedBody.on('hash', value => {
152
+ this.bodyHash = value;
153
+ });
154
+ this.relaxedBody.on('readable', () => {
155
+ let chunk;
156
+ if (this.cache) {
157
+ return;
158
+ }
159
+ while ((chunk = this.relaxedBody.read()) !== null) {
160
+ this.chunks.push(chunk);
161
+ this.chunklen += chunk.length;
162
+ if (this.chunklen >= this.cacheTreshold && this.cachePath) {
163
+ return this.createWriteCache();
164
+ }
165
+ }
166
+ });
167
+ this.relaxedBody.on('end', () => {
168
+ if (this.cache) {
169
+ return;
170
+ }
171
+ this.sendSignedOutput();
172
+ });
173
+ this.parser.pipe(this.relaxedBody);
174
+ setImmediate(() => this.input.pipe(this.parser));
175
+ }
176
+ }
177
+ class DKIM {
178
+ constructor(options) {
179
+ this.options = options || {};
180
+ this.keys = [].concat(this.options.keys || {
181
+ domainName: options.domainName,
182
+ keySelector: options.keySelector,
183
+ privateKey: options.privateKey
184
+ });
185
+ }
186
+ sign(input, extraOptions) {
187
+ const output = new node_stream_1.PassThrough();
188
+ let inputStream = input;
189
+ let writeValue = false;
190
+ if (Buffer.isBuffer(input)) {
191
+ writeValue = input;
192
+ inputStream = new node_stream_1.PassThrough();
193
+ }
194
+ else if (typeof input === 'string') {
195
+ writeValue = Buffer.from(input);
196
+ inputStream = new node_stream_1.PassThrough();
197
+ }
198
+ let options = this.options;
199
+ if (extraOptions && Object.keys(extraOptions).length) {
200
+ // extraOptions is mail.data._dkim, caller supplied message data. An own
201
+ // "__proto__" key there would let every option this signer reads and the
202
+ // transport did not set, such as skipFields, answer from the caller
203
+ options = (0, objects_js_1.copyOwnKeys)({}, extraOptions);
204
+ (0, objects_js_1.copyOwnKeys)(options, this.options);
205
+ }
206
+ const signer = new DKIMSigner(options, this.keys, inputStream, output);
207
+ setImmediate(() => {
208
+ try {
209
+ signer.signStream();
210
+ }
211
+ catch (_E) {
212
+ // the body hash is created here, an unknown hashAlgo throws inside this timer
213
+ // where nothing else could catch it
214
+ output.emit('error', sign_js_1.default.unsupportedHashAlgoError(signer.hashAlgo));
215
+ return;
216
+ }
217
+ if (writeValue) {
218
+ setImmediate(() => {
219
+ inputStream.end(writeValue);
220
+ });
221
+ }
222
+ });
223
+ return output;
224
+ }
225
+ }
226
+ exports.default = DKIM;
227
+ module.exports = exports.default;
228
+ Object.defineProperty(module.exports, 'default', { value: exports.default, enumerable: false, writable: true, configurable: true });
@@ -0,0 +1,48 @@
1
+ import { Transform, type TransformOptions } from 'node:stream';
2
+ /**
3
+ * A header line as emitted with the 'headers' event
4
+ */
5
+ export interface MessageParserHeaderLine {
6
+ /** Lowercase header field name */
7
+ key: string;
8
+ /** Full header line, folded continuation lines included, one character per byte ('binary' encoding) */
9
+ line: string;
10
+ }
11
+ /**
12
+ * MessageParser instance is a transform stream that separates message headers
13
+ * from the rest of the body. Headers are emitted with the 'headers' event. Message
14
+ * body is passed on as the resulting stream.
15
+ */
16
+ declare class MessageParser extends Transform {
17
+ lastBytes: Buffer;
18
+ headersParsed: boolean;
19
+ headerBytes: number;
20
+ headerChunks: Buffer[] | null;
21
+ rawHeaders: Buffer | false;
22
+ bodySize: number;
23
+ constructor(options?: TransformOptions);
24
+ /**
25
+ * Keeps count of the last 4 bytes in order to detect line breaks on chunk boundaries
26
+ *
27
+ * @param data Next data chunk from the stream
28
+ */
29
+ updateLastBytes(data: Buffer): void;
30
+ /**
31
+ * Finds and removes message headers from the remaining body. We want to keep
32
+ * headers separated until final delivery to be able to modify these
33
+ *
34
+ * @param data Next chunk of data
35
+ * @return Returns true if headers are already found or false otherwise
36
+ */
37
+ checkHeaders(data: Buffer): boolean;
38
+ parseHeaders(): MessageParserHeaderLine[];
39
+ }
40
+ /**
41
+ * Type aliases in the layout of @types/nodemailer, so `MessageParser.Header` style references keep working
42
+ */
43
+ declare namespace MessageParser {
44
+ type Header = MessageParserHeaderLine;
45
+ }
46
+ /** The same alias as a module level export, for `import * as MessageParser` and `import MessageParser = require()` */
47
+ export type { MessageParserHeaderLine as Header };
48
+ export default MessageParser;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_stream_1 = require("node:stream");
4
+ /**
5
+ * Drops the SP and HTAB from both ends of a field name.
6
+ *
7
+ * An index scan rather than `/^[ \t]+|[ \t]+$/g`, which retries the trailing branch at
8
+ * every offset of a blank run that is followed by other text: the run is consumed greedily,
9
+ * `$` fails, and the engine gives the characters back one at a time before moving on to
10
+ * start the same walk one offset further in. A field name carrying a 128 KiB run of spaces
11
+ * between two atoms took about 6.7 seconds to trim, and the cost grows with its square.
12
+ *
13
+ * Not `.trim()`, which takes the other Unicode spaces along: an NBSP in front of a field
14
+ * name would come off and select the name into the signed set, where the relaxed
15
+ * canonicalization in sign.ts deliberately leaves everything but SP and HTAB alone.
16
+ *
17
+ * @param str Field name to trim
18
+ * @return The field name without the surrounding SP and HTAB
19
+ */
20
+ function _trimFieldName(str) {
21
+ let start = 0;
22
+ let end = str.length;
23
+ while (start < end && (str.charCodeAt(start) === 0x20 || str.charCodeAt(start) === 0x09)) {
24
+ start++;
25
+ }
26
+ while (end > start && (str.charCodeAt(end - 1) === 0x20 || str.charCodeAt(end - 1) === 0x09)) {
27
+ end--;
28
+ }
29
+ return str.slice(start, end);
30
+ }
31
+ /**
32
+ * MessageParser instance is a transform stream that separates message headers
33
+ * from the rest of the body. Headers are emitted with the 'headers' event. Message
34
+ * body is passed on as the resulting stream.
35
+ */
36
+ class MessageParser extends node_stream_1.Transform {
37
+ constructor(options) {
38
+ super(options);
39
+ this.lastBytes = Buffer.alloc(4);
40
+ this.headersParsed = false;
41
+ this.headerBytes = 0;
42
+ this.headerChunks = [];
43
+ this.rawHeaders = false;
44
+ this.bodySize = 0;
45
+ }
46
+ /**
47
+ * Keeps count of the last 4 bytes in order to detect line breaks on chunk boundaries
48
+ *
49
+ * @param data Next data chunk from the stream
50
+ */
51
+ updateLastBytes(data) {
52
+ const lblen = this.lastBytes.length;
53
+ const nblen = Math.min(data.length, lblen);
54
+ // shift existing bytes
55
+ for (let i = 0, len = lblen - nblen; i < len; i++) {
56
+ this.lastBytes[i] = this.lastBytes[i + nblen];
57
+ }
58
+ // add new bytes
59
+ for (let i = 1; i <= nblen; i++) {
60
+ this.lastBytes[lblen - i] = data[data.length - i];
61
+ }
62
+ }
63
+ /**
64
+ * Finds and removes message headers from the remaining body. We want to keep
65
+ * headers separated until final delivery to be able to modify these
66
+ *
67
+ * @param data Next chunk of data
68
+ * @return Returns true if headers are already found or false otherwise
69
+ */
70
+ checkHeaders(data) {
71
+ if (this.headersParsed) {
72
+ return true;
73
+ }
74
+ const lblen = this.lastBytes.length;
75
+ let headerPos = 0;
76
+ for (let i = 0, len = this.lastBytes.length + data.length; i < len; i++) {
77
+ let chr;
78
+ if (i < lblen) {
79
+ chr = this.lastBytes[i];
80
+ }
81
+ else {
82
+ chr = data[i - lblen];
83
+ }
84
+ if (chr === 0x0a && i) {
85
+ const pr1 = i - 1 < lblen ? this.lastBytes[i - 1] : data[i - 1 - lblen];
86
+ const pr2 = i > 1 ? (i - 2 < lblen ? this.lastBytes[i - 2] : data[i - 2 - lblen]) : false;
87
+ if (pr1 === 0x0a) {
88
+ this.headersParsed = true;
89
+ headerPos = i - lblen + 1;
90
+ this.headerBytes += headerPos;
91
+ break;
92
+ }
93
+ else if (pr1 === 0x0d && pr2 === 0x0a) {
94
+ this.headersParsed = true;
95
+ headerPos = i - lblen + 1;
96
+ this.headerBytes += headerPos;
97
+ break;
98
+ }
99
+ }
100
+ }
101
+ if (this.headersParsed) {
102
+ this.headerChunks.push(data.slice(0, headerPos));
103
+ this.rawHeaders = Buffer.concat(this.headerChunks, this.headerBytes);
104
+ this.headerChunks = null;
105
+ this.emit('headers', this.parseHeaders());
106
+ if (data.length > headerPos) {
107
+ const chunk = data.slice(headerPos);
108
+ this.bodySize += chunk.length;
109
+ // this would be the first chunk of data sent downstream
110
+ setImmediate(() => this.push(chunk));
111
+ }
112
+ return false;
113
+ }
114
+ this.headerBytes += data.length;
115
+ this.headerChunks.push(data);
116
+ // store last 4 bytes to catch header break
117
+ this.updateLastBytes(data);
118
+ return false;
119
+ }
120
+ /** @internal */
121
+ _transform(chunk, encoding, callback) {
122
+ if (!chunk || !chunk.length) {
123
+ return callback();
124
+ }
125
+ if (typeof chunk === 'string') {
126
+ chunk = Buffer.from(chunk, encoding);
127
+ }
128
+ let headersFound;
129
+ try {
130
+ headersFound = this.checkHeaders(chunk);
131
+ }
132
+ catch (E) {
133
+ return callback(E);
134
+ }
135
+ if (headersFound) {
136
+ this.bodySize += chunk.length;
137
+ this.push(chunk);
138
+ }
139
+ setImmediate(callback);
140
+ }
141
+ /** @internal */
142
+ _flush(callback) {
143
+ if (this.headerChunks) {
144
+ // no empty line was seen, so the message consists of headers only
145
+ this.rawHeaders = Buffer.concat(this.headerChunks, this.headerBytes);
146
+ this.headerChunks = null;
147
+ this.emit('headers', this.parseHeaders());
148
+ }
149
+ callback();
150
+ }
151
+ parseHeaders() {
152
+ // the header bytes are kept as they are, one character per byte, so the
153
+ // signature covers exactly the bytes the receiving side canonicalizes
154
+ // Only SP and HTAB fold a line, and only they are trimmed from the field name, the
155
+ // same whitespace the relaxed canonicalization in sign.ts works with
156
+ const rawLines = (this.rawHeaders || Buffer.alloc(0)).toString('binary').split(/\r?\n/);
157
+ // Unfold in a single forward pass and only ever test a freshly split line for the
158
+ // continuation prefix. Testing an already merged line instead would rescan a string
159
+ // that grows with every continuation line, so a header folded into many continuation
160
+ // lines (a large recipient list, for example) would take quadratic time to unfold
161
+ const lines = [];
162
+ for (const rawLine of rawLines) {
163
+ if (lines.length && /^[ \t]/.test(rawLine)) {
164
+ lines[lines.length - 1] += '\n' + rawLine;
165
+ }
166
+ else {
167
+ lines.push(rawLine);
168
+ }
169
+ }
170
+ return lines
171
+ .filter(line => /[^ \t\r]/.test(line))
172
+ .map(line => ({
173
+ key: _trimFieldName(line.substr(0, line.indexOf(':'))).toLowerCase(),
174
+ line
175
+ }));
176
+ }
177
+ }
178
+ exports.default = MessageParser;
179
+ module.exports = exports.default;
180
+ Object.defineProperty(module.exports, 'default', { value: exports.default, enumerable: false, writable: true, configurable: true });