@mavogel/awscdk-rootmail 0.1.8 → 0.1.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 (167) hide show
  1. package/.jsii +10 -10
  2. package/lib/rootmail.js +1 -1
  3. package/lib/ses-receive.js +1 -1
  4. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-cjs/index.js +5 -5
  5. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-es/schemas/schemas_0.js +4 -4
  6. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/DescribeDeliveryDestinationsCommand.d.ts +1 -0
  7. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/GetDeliveryDestinationCommand.d.ts +1 -0
  8. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/PutAccountPolicyCommand.d.ts +4 -1
  9. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/PutDeliveryDestinationCommand.d.ts +2 -0
  10. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/models/models_0.d.ts +80 -36
  11. package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/ts3.4/models/models_0.d.ts +2 -0
  12. package/node_modules/@aws-sdk/client-cloudwatch-logs/package.json +1 -1
  13. package/node_modules/@aws-sdk/client-route-53/dist-cjs/index.js +1 -1
  14. package/node_modules/@aws-sdk/client-route-53/package.json +1 -1
  15. package/node_modules/@aws-sdk/client-s3/dist-cjs/index.js +2 -1
  16. package/node_modules/@aws-sdk/client-s3/dist-es/models/enums.js +1 -0
  17. package/node_modules/@aws-sdk/client-s3/dist-types/commands/GetBucketInventoryConfigurationCommand.d.ts +1 -1
  18. package/node_modules/@aws-sdk/client-s3/dist-types/commands/ListBucketInventoryConfigurationsCommand.d.ts +1 -1
  19. package/node_modules/@aws-sdk/client-s3/dist-types/commands/PutBucketInventoryConfigurationCommand.d.ts +1 -1
  20. package/node_modules/@aws-sdk/client-s3/dist-types/models/enums.d.ts +1 -0
  21. package/node_modules/@aws-sdk/client-s3/dist-types/ts3.4/models/enums.d.ts +1 -0
  22. package/node_modules/@aws-sdk/client-s3/package.json +2 -2
  23. package/node_modules/@aws-sdk/client-ses/dist-cjs/index.js +1 -1
  24. package/node_modules/@aws-sdk/client-ses/package.json +1 -1
  25. package/node_modules/@aws-sdk/client-ssm/dist-cjs/index.js +9 -3
  26. package/node_modules/@aws-sdk/client-ssm/dist-es/models/enums.js +4 -0
  27. package/node_modules/@aws-sdk/client-ssm/dist-es/schemas/schemas_0.js +3 -2
  28. package/node_modules/@aws-sdk/client-ssm/dist-types/commands/DeleteResourcePolicyCommand.d.ts +6 -0
  29. package/node_modules/@aws-sdk/client-ssm/dist-types/commands/PutResourcePolicyCommand.d.ts +12 -0
  30. package/node_modules/@aws-sdk/client-ssm/dist-types/models/enums.d.ts +12 -0
  31. package/node_modules/@aws-sdk/client-ssm/dist-types/models/models_0.d.ts +20 -1
  32. package/node_modules/@aws-sdk/client-ssm/dist-types/models/models_1.d.ts +2 -2
  33. package/node_modules/@aws-sdk/client-ssm/dist-types/ts3.4/models/enums.d.ts +5 -0
  34. package/node_modules/@aws-sdk/client-ssm/dist-types/ts3.4/models/models_0.d.ts +2 -0
  35. package/node_modules/@aws-sdk/client-ssm/package.json +1 -1
  36. package/node_modules/@zone-eu/mailsplit/lib/flowed-decoder.js +1 -5
  37. package/node_modules/@zone-eu/mailsplit/lib/headers.js +35 -25
  38. package/node_modules/@zone-eu/mailsplit/lib/message-splitter.js +126 -79
  39. package/node_modules/@zone-eu/mailsplit/lib/mime-node.js +27 -5
  40. package/node_modules/@zone-eu/mailsplit/lib/node-rewriter.js +3 -2
  41. package/node_modules/@zone-eu/mailsplit/lib/types.d.ts +0 -3
  42. package/node_modules/@zone-eu/mailsplit/package.json +5 -5
  43. package/node_modules/libbase64/.github/workflows/release.yaml +12 -10
  44. package/node_modules/libbase64/.ncurc.js +7 -1
  45. package/node_modules/libbase64/CHANGELOG.md +7 -0
  46. package/node_modules/libbase64/lib/libbase64.js +27 -0
  47. package/node_modules/libbase64/package.json +4 -4
  48. package/node_modules/libmime/CHANGELOG.md +14 -0
  49. package/node_modules/libmime/lib/libmime.js +41 -21
  50. package/node_modules/libmime/package.json +3 -3
  51. package/node_modules/libqp/.github/workflows/release.yaml +12 -10
  52. package/node_modules/libqp/CHANGELOG.md +7 -0
  53. package/node_modules/libqp/lib/libqp.js +6 -4
  54. package/node_modules/libqp/package.json +2 -2
  55. package/node_modules/libqp/test/libqp-test.js +71 -14
  56. package/node_modules/mailparser/.release-please-manifest.json +1 -1
  57. package/node_modules/mailparser/CHANGELOG.md +42 -0
  58. package/node_modules/mailparser/README.md +5 -0
  59. package/node_modules/mailparser/lib/mail-parser.js +107 -32
  60. package/node_modules/mailparser/lib/simple-parser.js +12 -0
  61. package/node_modules/mailparser/lib/stream-hash.js +1 -1
  62. package/node_modules/mailparser/package.json +6 -6
  63. package/node_modules/nodemailer/CHANGELOG.md +38 -0
  64. package/node_modules/nodemailer/README.md +1 -1
  65. package/node_modules/nodemailer/dist/cjs/addressparser/index.d.ts +16 -2
  66. package/node_modules/nodemailer/dist/cjs/addressparser/index.js +147 -28
  67. package/node_modules/nodemailer/dist/cjs/base64/index.js +2 -1
  68. package/node_modules/nodemailer/dist/cjs/dkim/index.d.ts +13 -1
  69. package/node_modules/nodemailer/dist/cjs/dkim/index.js +25 -8
  70. package/node_modules/nodemailer/dist/cjs/dkim/message-parser.d.ts +10 -1
  71. package/node_modules/nodemailer/dist/cjs/dkim/message-parser.js +28 -4
  72. package/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.d.ts +10 -1
  73. package/node_modules/nodemailer/dist/cjs/dkim/sign.d.ts +3 -0
  74. package/node_modules/nodemailer/dist/cjs/dkim/sign.js +18 -1
  75. package/node_modules/nodemailer/dist/cjs/errors.d.ts +3 -2
  76. package/node_modules/nodemailer/dist/cjs/fetch/cookies.d.ts +12 -1
  77. package/node_modules/nodemailer/dist/cjs/fetch/index.d.ts +15 -1
  78. package/node_modules/nodemailer/dist/cjs/fetch/index.js +39 -64
  79. package/node_modules/nodemailer/dist/cjs/json-transport/index.d.ts +14 -4
  80. package/node_modules/nodemailer/dist/cjs/json-transport/index.js +2 -0
  81. package/node_modules/nodemailer/dist/cjs/mail-composer/index.d.ts +8 -3
  82. package/node_modules/nodemailer/dist/cjs/mailer/index.d.ts +43 -25
  83. package/node_modules/nodemailer/dist/cjs/mailer/mail-message.d.ts +11 -4
  84. package/node_modules/nodemailer/dist/cjs/mime-funcs/index.d.ts +7 -3
  85. package/node_modules/nodemailer/dist/cjs/mime-funcs/index.js +198 -84
  86. package/node_modules/nodemailer/dist/cjs/mime-node/index.d.ts +5 -2
  87. package/node_modules/nodemailer/dist/cjs/mime-node/index.js +2 -1
  88. package/node_modules/nodemailer/dist/cjs/nodemailer.d.ts +38 -16
  89. package/node_modules/nodemailer/dist/cjs/nodemailer.js +1 -0
  90. package/node_modules/nodemailer/dist/cjs/package-info.d.ts +1 -1
  91. package/node_modules/nodemailer/dist/cjs/package-info.js +1 -1
  92. package/node_modules/nodemailer/dist/cjs/punycode/index.js +1 -0
  93. package/node_modules/nodemailer/dist/cjs/qp/index.d.ts +2 -0
  94. package/node_modules/nodemailer/dist/cjs/qp/index.js +10 -1
  95. package/node_modules/nodemailer/dist/cjs/sendmail-transport/index.d.ts +2 -0
  96. package/node_modules/nodemailer/dist/cjs/ses-transport/index.d.ts +39 -2
  97. package/node_modules/nodemailer/dist/cjs/shared/index.d.ts +43 -7
  98. package/node_modules/nodemailer/dist/cjs/shared/index.js +5 -2
  99. package/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.d.ts +2 -1
  100. package/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.js +32 -24
  101. package/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.d.ts +13 -5
  102. package/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.js +23 -11
  103. package/node_modules/nodemailer/dist/cjs/smtp-connection/index.d.ts +59 -24
  104. package/node_modules/nodemailer/dist/cjs/smtp-connection/index.js +156 -75
  105. package/node_modules/nodemailer/dist/cjs/smtp-pool/index.d.ts +12 -4
  106. package/node_modules/nodemailer/dist/cjs/smtp-pool/index.js +39 -11
  107. package/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.js +27 -31
  108. package/node_modules/nodemailer/dist/cjs/smtp-transport/index.d.ts +19 -6
  109. package/node_modules/nodemailer/dist/cjs/smtp-transport/index.js +25 -33
  110. package/node_modules/nodemailer/dist/cjs/stream-transport/index.d.ts +2 -0
  111. package/node_modules/nodemailer/dist/cjs/well-known/services.js +6 -0
  112. package/node_modules/nodemailer/dist/cjs/xoauth2/index.d.ts +13 -3
  113. package/node_modules/nodemailer/dist/cjs/xoauth2/index.js +25 -13
  114. package/node_modules/nodemailer/dist/esm/addressparser/index.d.ts +16 -2
  115. package/node_modules/nodemailer/dist/esm/addressparser/index.js +147 -27
  116. package/node_modules/nodemailer/dist/esm/base64/index.js +2 -1
  117. package/node_modules/nodemailer/dist/esm/dkim/index.d.ts +13 -1
  118. package/node_modules/nodemailer/dist/esm/dkim/index.js +25 -8
  119. package/node_modules/nodemailer/dist/esm/dkim/message-parser.d.ts +10 -1
  120. package/node_modules/nodemailer/dist/esm/dkim/message-parser.js +30 -5
  121. package/node_modules/nodemailer/dist/esm/dkim/relaxed-body.d.ts +10 -1
  122. package/node_modules/nodemailer/dist/esm/dkim/relaxed-body.js +2 -1
  123. package/node_modules/nodemailer/dist/esm/dkim/sign.d.ts +3 -0
  124. package/node_modules/nodemailer/dist/esm/dkim/sign.js +18 -1
  125. package/node_modules/nodemailer/dist/esm/errors.d.ts +3 -2
  126. package/node_modules/nodemailer/dist/esm/fetch/cookies.d.ts +12 -1
  127. package/node_modules/nodemailer/dist/esm/fetch/cookies.js +2 -1
  128. package/node_modules/nodemailer/dist/esm/fetch/index.d.ts +15 -1
  129. package/node_modules/nodemailer/dist/esm/fetch/index.js +39 -64
  130. package/node_modules/nodemailer/dist/esm/json-transport/index.d.ts +14 -4
  131. package/node_modules/nodemailer/dist/esm/json-transport/index.js +2 -0
  132. package/node_modules/nodemailer/dist/esm/mail-composer/index.d.ts +8 -3
  133. package/node_modules/nodemailer/dist/esm/mailer/index.d.ts +43 -25
  134. package/node_modules/nodemailer/dist/esm/mailer/mail-message.d.ts +11 -4
  135. package/node_modules/nodemailer/dist/esm/mime-funcs/index.d.ts +7 -3
  136. package/node_modules/nodemailer/dist/esm/mime-funcs/index.js +198 -84
  137. package/node_modules/nodemailer/dist/esm/mime-node/index.d.ts +5 -2
  138. package/node_modules/nodemailer/dist/esm/mime-node/index.js +2 -1
  139. package/node_modules/nodemailer/dist/esm/nodemailer.d.ts +38 -16
  140. package/node_modules/nodemailer/dist/esm/package-info.d.ts +1 -1
  141. package/node_modules/nodemailer/dist/esm/package-info.js +1 -1
  142. package/node_modules/nodemailer/dist/esm/punycode/index.js +1 -0
  143. package/node_modules/nodemailer/dist/esm/qp/index.d.ts +2 -0
  144. package/node_modules/nodemailer/dist/esm/qp/index.js +10 -1
  145. package/node_modules/nodemailer/dist/esm/sendmail-transport/index.d.ts +2 -0
  146. package/node_modules/nodemailer/dist/esm/ses-transport/index.d.ts +39 -2
  147. package/node_modules/nodemailer/dist/esm/shared/index.d.ts +43 -7
  148. package/node_modules/nodemailer/dist/esm/shared/index.js +5 -2
  149. package/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.d.ts +2 -1
  150. package/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.js +32 -24
  151. package/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.d.ts +13 -5
  152. package/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.js +23 -11
  153. package/node_modules/nodemailer/dist/esm/smtp-connection/index.d.ts +59 -24
  154. package/node_modules/nodemailer/dist/esm/smtp-connection/index.js +156 -75
  155. package/node_modules/nodemailer/dist/esm/smtp-pool/index.d.ts +12 -4
  156. package/node_modules/nodemailer/dist/esm/smtp-pool/index.js +39 -11
  157. package/node_modules/nodemailer/dist/esm/smtp-pool/pool-resource.js +27 -31
  158. package/node_modules/nodemailer/dist/esm/smtp-transport/index.d.ts +19 -6
  159. package/node_modules/nodemailer/dist/esm/smtp-transport/index.js +25 -33
  160. package/node_modules/nodemailer/dist/esm/stream-transport/index.d.ts +2 -0
  161. package/node_modules/nodemailer/dist/esm/well-known/services.js +6 -0
  162. package/node_modules/nodemailer/dist/esm/xoauth2/index.d.ts +13 -3
  163. package/node_modules/nodemailer/dist/esm/xoauth2/index.js +25 -13
  164. package/node_modules/nodemailer/dist/well-known/services.json +7 -0
  165. package/node_modules/nodemailer/package.json +16 -12
  166. package/package.json +16 -16
  167. package/renovate.json5 +1 -0
@@ -4,8 +4,8 @@ import DKIM, { type DKIMOptions } from '../dkim/index.js';
4
4
  import MailMessage, { type MailDefaults, type SendMailOptions } from './mail-message.js';
5
5
  import net from 'node:net';
6
6
  import type { ConnectionOptions } from 'node:tls';
7
- import type { MailComposerAlternative, MailComposerAttachment, MailComposerIcalEvent, MailComposerListHeaderEntry, MailComposerListHeaders } from '../mail-composer/index.js';
8
- import type { NodemailerError, ResultCallback } from '../errors.js';
7
+ import type { MailComposerAlternative, MailComposerAttachment, MailComposerIcalEvent, MailComposerListHeaderEntry, MailComposerListHeaders, MailComposerTextEncoding } from '../mail-composer/index.js';
8
+ import type { Callback, NodemailerError, ResultCallback } from '../errors.js';
9
9
  import type { ParsedUrl } from '../shared/url.js';
10
10
  import type { MimeNodeAddress, MimeNodeEnvelope, MimeNodeEnvelopeInput, MimeNodeHeaders, MimeNodeOptions } from '../mime-node/index.js';
11
11
  import type { XOAuth2ProvisionCallback } from '../xoauth2/index.js';
@@ -15,9 +15,10 @@ export type { default as MailMessage } from './mail-message.js';
15
15
  * The base shape of the object a transport hands back for a sent message. Every bundled
16
16
  * transport sets the envelope and the Message-ID, the rest depends on the transport.
17
17
  *
18
- * The index signature keeps a transport specific field readable through this type, and it
19
- * is also what a result type has to inherit to stay assignable to it, so the result type
20
- * of a transport outside this package has to extend this interface rather than restate it
18
+ * The index signature keeps a transport specific field readable through this type, the way
19
+ * the `any` typed result of @types/nodemailer was, and it is also what a result type has
20
+ * to inherit to stay assignable to it, so the result type of a transport outside this
21
+ * package has to extend this interface rather than restate it
21
22
  */
22
23
  export interface SentMessageInfo {
23
24
  /** The envelope the message was sent with */
@@ -33,9 +34,9 @@ export interface SentMessageInfo {
33
34
  /** Last response from the server */
34
35
  response?: string | undefined;
35
36
  /** The generated message, for the transports that hand it back instead of sending it */
36
- message?: unknown;
37
+ message?: any;
37
38
  /** Transport specific fields */
38
- [key: string]: unknown;
39
+ [key: string]: any;
39
40
  }
40
41
  /**
41
42
  * Callback for sendMail, receives the transport result once the transport has taken the
@@ -43,9 +44,11 @@ export interface SentMessageInfo {
43
44
  */
44
45
  export type SendMailCallback<T = SentMessageInfo> = (err: NodemailerError | null, info: T) => void;
45
46
  /**
46
- * Callback for verify(), success is true once the transport accepted the configuration
47
+ * Callback for verify(), success is true once the transport accepted the configuration.
48
+ * Declared with a required success value, the way @types/nodemailer declared it, the
49
+ * error path hands over the error alone
47
50
  */
48
- export type VerifyCallback = (err: NodemailerError | null, success?: true) => void;
51
+ export type VerifyCallback = Callback<true>;
49
52
  /**
50
53
  * Callback a plugin calls once it is done, an error aborts the send
51
54
  */
@@ -60,21 +63,23 @@ export type PluginFunction<T = SentMessageInfo> = (mail: MailMessage<T>, callbac
60
63
  */
61
64
  export interface GetSocketOptions {
62
65
  host?: string | undefined;
63
- port?: number | string | undefined;
66
+ port?: number | undefined;
64
67
  [key: string]: any;
65
68
  }
66
69
  /**
67
- * The result of a getSocket handler, the socket to use for the connection
70
+ * The result of a getSocket handler, the socket to use for the connection. The object is
71
+ * merged into the connection options, so it may carry any of those as well
68
72
  */
69
73
  export interface SocketOptions {
70
74
  /** An established socket, the proxied connection */
71
75
  connection?: net.Socket | undefined;
76
+ [key: string]: any;
72
77
  }
73
78
  /**
74
- * Receives the socket options from a getSocket handler, or the error that prevented the
75
- * connection
79
+ * Receives the socket options from a getSocket handler, false when a new socket should be
80
+ * opened, or the error that prevented the connection
76
81
  */
77
- export type GetSocketCallback = (err: NodemailerError | null, socketOptions?: SocketOptions) => void;
82
+ export type GetSocketCallback = (err: Error | null, socketOptions?: SocketOptions | false) => void;
78
83
  /**
79
84
  * A socket handler. Mail sets one on the transport as getSocket when a proxy is configured,
80
85
  * the SMTP transports call it to get a proxied socket instead of connecting directly
@@ -101,9 +106,12 @@ export interface MailMeta {
101
106
  /**
102
107
  * A transport as consumed by Mail: any object with a name, a version and a send method
103
108
  * works, the rest is optional. Mail forwards its close, isIdle and verify calls to the
104
- * methods of the same name as they are, so their arguments are up to the transport
109
+ * methods of the same name as they are, so their arguments are up to the transport.
110
+ *
111
+ * D is the options type of the transport, the second type parameter @types/nodemailer
112
+ * declared on Transport, Transporter and Mail
105
113
  */
106
- export interface Transport<T = SentMessageInfo> {
114
+ export interface Transport<T = SentMessageInfo, D extends TransportOptions = TransportOptions> {
107
115
  /** Transport name, used for logging */
108
116
  name: string;
109
117
  /** Transport version, used for logging */
@@ -119,7 +127,7 @@ export interface Transport<T = SentMessageInfo> {
119
127
  /** Registers an event listener, the transport may emit 'log', 'error', 'idle' and 'clear' */
120
128
  on?(event: string | symbol, listener: (...args: any[]) => void): this;
121
129
  /** The Mail object the transport belongs to, set by Mail */
122
- mailer?: Mail<T> | undefined;
130
+ mailer?: Mail<T, D> | undefined;
123
131
  /** Socket handler for a proxied connection, set by Mail when a proxy is configured */
124
132
  getSocket?: GetSocketHandler | undefined;
125
133
  }
@@ -150,22 +158,23 @@ export interface TransportOptions {
150
158
  attachDataUrls?: boolean | undefined;
151
159
  }
152
160
  /**
153
- * The transporter object createTransport returns, a Mail instance wrapping a transport
161
+ * The transporter object createTransport returns, a Mail instance wrapping a transport. D
162
+ * is the options type of the transport, it types the options field of the transporter
154
163
  */
155
- export type Transporter<T = SentMessageInfo> = Mail<T>;
164
+ export type Transporter<T = SentMessageInfo, D extends TransportOptions = TransportOptions> = Mail<T, D>;
156
165
  /**
157
166
  * Creates an object for exposing the Mail API
158
167
  *
159
168
  * @constructor
160
169
  * @param transporter Transport object instance to pass the mails to
161
170
  */
162
- declare class Mail<out T = SentMessageInfo> extends EventEmitter {
163
- options: TransportOptions;
171
+ declare class Mail<out T = SentMessageInfo, out D extends TransportOptions = TransportOptions> extends EventEmitter {
172
+ options: D;
164
173
  /** Message defaults given to createTransport, kept public because the DefinitelyTyped typings declared it */
165
174
  _defaults: MailDefaults;
166
175
  meta: Map<string, any>;
167
176
  dkim: DKIM | false;
168
- transporter: Transport<T>;
177
+ transporter: Transport<T, D>;
169
178
  logger: shared.Logger;
170
179
  /** Closes the transport, the pooled SMTP transport closes its connections */
171
180
  close: () => void;
@@ -178,15 +187,21 @@ declare class Mail<out T = SentMessageInfo> extends EventEmitter {
178
187
  };
179
188
  /** Socket handler for a proxied connection, set by setupProxy and handed to the transport on the next send */
180
189
  getSocket?: GetSocketHandler | false | undefined;
181
- constructor(transporter: Transport<T>, options?: TransportOptions, defaults?: MailDefaults);
190
+ constructor(transporter: Transport<T, D>, options?: D, defaults?: MailDefaults);
182
191
  use(step: string, plugin: PluginFunction<T>): this;
183
192
  /**
184
193
  * Sends an email using the preselected transport object
185
194
  *
186
195
  * @param data E-data description
187
- * @param callback Callback to run once the sending succeeded or failed
196
+ * @returns Promise that resolves with the result of the send
188
197
  */
189
198
  sendMail(data: SendMailOptions): Promise<T>;
199
+ /**
200
+ * Sends an email using the preselected transport object
201
+ *
202
+ * @param data E-data description
203
+ * @param callback Callback to run once the sending succeeded or failed
204
+ */
190
205
  sendMail(data: SendMailOptions, callback: SendMailCallback<T>): void;
191
206
  getVersionString(): string;
192
207
  /**
@@ -213,7 +228,10 @@ declare namespace Mail {
213
228
  type ListHeader = MailComposerListHeaderEntry;
214
229
  type ListHeaders = MailComposerListHeaders;
215
230
  type Envelope = MimeNodeEnvelopeInput;
216
- type TextEncoding = NonNullable<SendMailOptions['textEncoding']>;
231
+ type Connection = SocketOptions;
232
+ type TextEncoding = MailComposerTextEncoding;
217
233
  type PluginFunction<T = SentMessageInfo> = MailPluginFunction<T>;
218
234
  }
235
+ /** The same aliases as module level exports, for `import * as Mail` and `import Mail = require()` */
236
+ export type { SendMailOptions as Options, MimeNodeAddress as Address, MailComposerAttachment as Attachment, MailComposerAlternative as AttachmentLike, MailComposerAlternative as AmpAttachment, MailComposerIcalEvent as IcalAttachment, MimeNodeHeaders as Headers, MailComposerListHeaderEntry as ListHeader, MailComposerListHeaders as ListHeaders, MimeNodeEnvelopeInput as Envelope, SocketOptions as Connection, MailComposerTextEncoding as TextEncoding };
219
237
  export default Mail;
@@ -3,6 +3,7 @@ import type { MailComposerOptions } from '../mail-composer/index.js';
3
3
  import type { DKIMOptions } from '../dkim/index.js';
4
4
  import type { SMTPEnvelopeDsn } from '../smtp-connection/index.js';
5
5
  import type { SMTPTransportAuthOptions } from '../smtp-transport/index.js';
6
+ import type { SESSendEmailRequest } from '../ses-transport/index.js';
6
7
  import type { NodemailerError } from '../errors.js';
7
8
  import type { ResolveContentOptions } from '../shared/index.js';
8
9
  import type Mail from './index.js';
@@ -14,6 +15,8 @@ import type { SentMessageInfo } from './index.js';
14
15
  export interface SendMailOptions extends MailComposerOptions {
15
16
  /** DKIM signing options for this message, used instead of the ones of the transporter */
16
17
  dkim?: DKIMOptions | undefined;
18
+ /** Extra DKIM options for this message, merged over the options of the signer. The SES transport sets skipFields here, the option is not meant for callers */
19
+ _dkim?: DKIMOptions | undefined;
17
20
  /** Recipients allowed on this message, 0 disables the limit, defaults to 100000 */
18
21
  maxRecipients?: number | undefined;
19
22
  /** SMTP transports: DSN parameters for the envelope, sent when the server supports the DSN extension */
@@ -23,9 +26,7 @@ export interface SendMailOptions extends MailComposerOptions {
23
26
  /** SMTP transports: per-message authentication settings, used instead of the transport level auth */
24
27
  auth?: SMTPTransportAuthOptions | undefined;
25
28
  /** SES transport: extra SendEmailCommand parameters merged into the API call */
26
- ses?: {
27
- [key: string]: unknown;
28
- } | undefined;
29
+ ses?: SESSendEmailRequest | undefined;
29
30
  }
30
31
  /**
31
32
  * Default message fields, the third argument of createTransport. Applied to every message
@@ -71,7 +72,13 @@ export interface MailMessageListHeader {
71
72
  export default class MailMessage<T = SentMessageInfo> {
72
73
  mailer: Mail<T>;
73
74
  data: MailMessageData;
74
- message: MimeNode | null;
75
+ /**
76
+ * The compiled MIME tree. Set once the compile step is done, so it is null while the
77
+ * 'compile' plugins run and set by the time the 'stream' plugins and the transport see
78
+ * the message. Declared as always set, the way @types/nodemailer declared it, since the
79
+ * plugins that read it are the ones that run after it is set
80
+ */
81
+ message: MimeNode;
75
82
  constructor(mailer: Mail<T>, data?: SendMailOptions);
76
83
  resolveContent(data: {
77
84
  [key: string]: any;
@@ -2,8 +2,8 @@
2
2
  * A header value split into the value token and its parameters, the result of parseHeaderValue
3
3
  */
4
4
  export interface ParsedHeaderValue {
5
- /** The value ahead of the parameters, for example the content type */
6
- value: string | false;
5
+ /** The value ahead of the parameters, for example the content type, an empty string when there is none */
6
+ value: string;
7
7
  /** Parameter values keyed by lowercase parameter name */
8
8
  params: Record<string, string>;
9
9
  }
@@ -25,6 +25,9 @@ export interface EncodedHeaderParam {
25
25
  /** Parameter value of this part */
26
26
  value: string;
27
27
  }
28
+ /** The names @types/nodemailer used for the two types above */
29
+ export type HeaderValue = StructuredHeaderValue;
30
+ export type ParsedHeaderParam = EncodedHeaderParam;
28
31
  /**
29
32
  * Checks if a value is plaintext string (uses only printable 7bit chars)
30
33
  *
@@ -56,6 +59,7 @@ export declare function quoteString(value?: string): string;
56
59
  * no need to encode the values in any way. If the value is plaintext but has
57
60
  * longer lines then allowed, then use format=flowed
58
61
  *
62
+ * @param str Multi line string to check
59
63
  * @param lineLength Max line length to check for
60
64
  * @returns Returns true if there is at least one line longer than lineLength chars
61
65
  */
@@ -97,9 +101,9 @@ export declare function buildHeaderValue(structured: StructuredHeaderValue): str
97
101
  * title*0*=utf-8''unicode
98
102
  * title*1*=%20string
99
103
  *
104
+ * @param key Parameter name the generated keys are built from, for example title
100
105
  * @param data String to be encoded
101
106
  * @param [maxLength=50] Max length for generated chunks
102
- * @param [fromCharset='UTF-8'] Source sharacter set
103
107
  * @return A list of encoded keys and headers
104
108
  */
105
109
  export declare function buildHeaderParam(key: string, data: string | Buffer, maxLength?: number): EncodedHeaderParam[];
@@ -88,6 +88,7 @@ function quoteString(value) {
88
88
  * no need to encode the values in any way. If the value is plaintext but has
89
89
  * longer lines then allowed, then use format=flowed
90
90
  *
91
+ * @param str Multi line string to check
91
92
  * @param lineLength Max line length to check for
92
93
  * @returns Returns true if there is at least one line longer than lineLength chars
93
94
  */
@@ -234,7 +235,10 @@ function buildHeaderValue(structured) {
234
235
  }
235
236
  });
236
237
  }
237
- else if (/[\s'"\\;:/=(),<>@[\]?]|^-/.test(value)) {
238
+ else if (!value.length || /[\s'"\\;:/=(),<>@[\]?]|^-/.test(value)) {
239
+ // a parameter value is a token or a quoted-string and a token is never empty, so
240
+ // a valueless parameter such as the 'flag' of 'multipart/mixed; flag; boundary=b'
241
+ // goes out as 'flag=""' rather than as the 'flag=' that parses as neither
238
242
  paramsArray.push(param + '=' + JSON.stringify(value));
239
243
  }
240
244
  else {
@@ -256,9 +260,9 @@ function buildHeaderValue(structured) {
256
260
  * title*0*=utf-8''unicode
257
261
  * title*1*=%20string
258
262
  *
263
+ * @param key Parameter name the generated keys are built from, for example title
259
264
  * @param data String to be encoded
260
265
  * @param [maxLength=50] Max length for generated chunks
261
- * @param [fromCharset='UTF-8'] Source sharacter set
262
266
  * @return A list of encoded keys and headers
263
267
  */
264
268
  function buildHeaderParam(key, data, maxLength) {
@@ -385,6 +389,26 @@ function buildHeaderParam(key, data, maxLength) {
385
389
  value: item.line
386
390
  }));
387
391
  }
392
+ /**
393
+ * An RFC 2045 token: printable ASCII without SPACE, the control characters, DEL and the
394
+ * tspecials. A charset name is one, and the name a continuation carries is written into
395
+ * the encoded word the parameter value becomes, so it is checked against this before it
396
+ * goes in. Whitespace used to come off it only because the value was trimmed first.
397
+ */
398
+ const TOKEN = /^[^\x00-\x20\x7f()<>@,;:\\"/[\]?=]+$/;
399
+ /**
400
+ * Whether a string can be a header parameter name.
401
+ *
402
+ * A parameter name is a token, so it is never empty. A "__proto__" name would target the
403
+ * prototype chain of the params object instead of an own property of it and read back as
404
+ * Object.prototype, so it is no name either.
405
+ *
406
+ * @param name Candidate parameter name, already lowercased
407
+ * @return true when the name can be used
408
+ */
409
+ function _isParamName(name) {
410
+ return !!name && !(0, objects_js_1.isProtoKey)(name);
411
+ }
388
412
  /**
389
413
  * Parses a header value with key=value arguments into a structured
390
414
  * object.
@@ -402,137 +426,227 @@ function buildHeaderParam(key, data, maxLength) {
402
426
  */
403
427
  function parseHeaderValue(str) {
404
428
  const response = {
405
- value: false,
429
+ value: '',
406
430
  params: {}
407
431
  };
408
- // Parameter names come from a caller supplied contentType/contentDisposition. A
409
- // "__proto__" name would target the prototype chain of the params object instead of
410
- // an own property of it, and read back as Object.prototype, so it is dropped.
432
+ // A duplicated parameter resolves to its first occurrence, the way a duplicated header
433
+ // does. Letting the last one win disagrees with the receivers that take the first, and
434
+ // the two readings of 'boundary="b"; boundary="c"' name different delimiters. The
435
+ // continuation join below is the only writer of the name it builds, so it tests the
436
+ // name with _isParamName directly rather than taking that rule along from here.
411
437
  const setParam = (name, value) => {
412
- if (!(0, objects_js_1.isProtoKey)(name)) {
438
+ name = name.toLowerCase();
439
+ if (_isParamName(name) && !Object.prototype.hasOwnProperty.call(response.params, name)) {
413
440
  response.params[name] = value;
414
441
  }
415
442
  };
416
443
  let key = false;
417
444
  let value = '';
418
- let type = 'value';
445
+ let stage = 'value';
419
446
  let quote = false;
420
447
  let escaped = false;
421
448
  let chr;
449
+ // Whitespace seen outside a quoted string is held back until a significant character
450
+ // follows it, so the whitespace around a value is dropped without trimming spaces the
451
+ // sender quoted on purpose. Trimming the stored value instead loses the trailing space
452
+ // of 'filename*0="Annual Report "', which the next continuation section is appended to.
453
+ let pendingSpace = '';
454
+ let quoteClosed = false;
455
+ // Whitespace ahead of the first character of a value is padding and is dropped, the
456
+ // whitespace between two characters of it is content
457
+ const flushSpace = () => {
458
+ if (value.length) {
459
+ value += pendingSpace;
460
+ }
461
+ pendingSpace = '';
462
+ };
463
+ const addChr = (c) => {
464
+ flushSpace();
465
+ value += c;
466
+ };
467
+ const takeValue = () => {
468
+ const taken = value;
469
+ value = '';
470
+ pendingSpace = '';
471
+ quoteClosed = false;
472
+ return taken;
473
+ };
474
+ const storeValue = () => {
475
+ const taken = takeValue();
476
+ if (key === false) {
477
+ response.value = taken;
478
+ }
479
+ else {
480
+ setParam(key, taken);
481
+ }
482
+ };
483
+ // A parameter name with no '=' is a valueless parameter, not the start of the next one.
484
+ // Without this the name keeps growing across the ';' and swallows whatever follows, which
485
+ // is how 'multipart/mixed; flag; boundary="AAA"' lost its boundary to a parameter named
486
+ // 'flag; boundary' and left the node declaring the generated boundary beside the asked
487
+ // for one, so a receiver reading the first of the two found no delimiter it matched.
488
+ const storeEmptyKey = () => {
489
+ setParam(takeValue().trim(), '');
490
+ };
422
491
  for (let i = 0, len = str.length; i < len; i++) {
423
492
  chr = str.charAt(i);
424
- if (type === 'key') {
493
+ if (stage === 'key') {
425
494
  if (chr === '=') {
426
- key = value.trim().toLowerCase();
427
- type = 'value';
428
- value = '';
495
+ key = takeValue().trim();
496
+ stage = 'value';
497
+ continue;
498
+ }
499
+ if (chr === ';') {
500
+ storeEmptyKey();
429
501
  continue;
430
502
  }
431
503
  value += chr;
432
504
  }
433
505
  else {
506
+ if (quoteClosed && chr !== ';') {
507
+ // Nothing behind a closed quoted string reaches the value. RFC 2045 says a
508
+ // parameter value is a token or a quoted string and not both, so what follows
509
+ // one is junk and only the ';' that ends the parameter still counts. Tested
510
+ // ahead of the branches rather than beside the append at the foot of them,
511
+ // where each branch above was a way around it: a second '"' reopened quoting
512
+ // and swallowed the rest of the header, so 'boundary="AAA" "; boundary=BBB"'
513
+ // read as a single boundary of 'AAA ', and the junk of
514
+ // 'boundary="AAA" (unterminated comment' still joined the declared boundary
515
+ // through the escape branch. quoteClosed is only ever set while no quote is
516
+ // open, and this is what keeps one from being opened afterwards.
517
+ escaped = false;
518
+ continue;
519
+ }
434
520
  if (escaped) {
435
- value += chr;
521
+ addChr(chr);
436
522
  }
437
- else if (chr === '\\') {
523
+ else if (quote && chr === '\\') {
524
+ // a backslash only escapes inside a quoted string, everywhere else it is an
525
+ // ordinary character. Treating it as an escape turns the parameter value
526
+ // 'C:\Users\me\report.txt' into 'C:Usersmereport.txt'
438
527
  escaped = true;
439
528
  continue;
440
529
  }
441
530
  else if (quote && chr === quote) {
442
531
  quote = false;
532
+ quoteClosed = true;
443
533
  }
444
534
  else if (!quote && chr === '"') {
445
535
  quote = chr;
536
+ flushSpace();
446
537
  }
447
538
  else if (!quote && chr === ';') {
448
- if (key === false) {
449
- response.value = value.trim();
450
- }
451
- else {
452
- setParam(key, value.trim());
453
- }
454
- type = 'key';
455
- value = '';
539
+ storeValue();
540
+ stage = 'key';
541
+ }
542
+ else if (!quote && (chr === ' ' || chr === '\t')) {
543
+ pendingSpace += chr;
456
544
  }
457
545
  else {
458
- value += chr;
546
+ addChr(chr);
459
547
  }
460
548
  escaped = false;
461
549
  }
462
550
  }
463
- if (type === 'value') {
464
- if (key === false) {
465
- response.value = value.trim();
466
- }
467
- else {
468
- setParam(key, value.trim());
469
- }
551
+ if (stage === 'value') {
552
+ storeValue();
470
553
  }
471
- else if (value.trim()) {
472
- setParam(value.trim().toLowerCase(), '');
554
+ else {
555
+ // a key with no value, as in 'Header-Key: somevalue; key=value; emptykey'
556
+ storeEmptyKey();
473
557
  }
474
558
  // handle parameter value continuations
475
559
  // https://tools.ietf.org/html/rfc2231#section-3
476
- // preprocess values
560
+ // Sections are collected in a list and ordered below rather than written into an array
561
+ // at their own section number. An index write makes the array as long as the number the
562
+ // header asked for, and the join that follows walks all of it, so the 55 byte value
563
+ // "attachment; filename*0*=utf-8''a; filename*4000000000=b" held a core for over two
564
+ // minutes.
565
+ const continuations = new Map();
477
566
  Object.keys(response.params).forEach(key => {
478
- let actualKey, nr, match, value;
479
- if ((match = key.match(/(\*(\d+)|\*(\d+)\*|\*)$/))) {
480
- actualKey = key.substr(0, match.index);
481
- nr = Number(match[2] || match[3]) || 0;
482
- if ((0, objects_js_1.isProtoKey)(actualKey)) {
483
- // see setParam. Reading it back would yield Object.prototype, which is
484
- // an object, so the initializer below would be skipped and the write
485
- // that follows would throw out of a header build the caller can not catch
486
- delete response.params[key];
487
- return;
488
- }
489
- if (!response.params[actualKey] || typeof response.params[actualKey] !== 'object') {
490
- response.params[actualKey] = {
491
- charset: false,
492
- values: []
493
- };
494
- }
495
- value = response.params[key];
496
- if (nr === 0 && match[0].substr(-1) === '*' && (match = value.match(/^([^']*)'[^']*'(.*)$/))) {
497
- response.params[actualKey].charset = match[1] || 'iso-8859-1';
498
- value = match[2];
499
- }
500
- response.params[actualKey].values[nr] = value;
501
- // remove the old reference
502
- delete response.params[key];
567
+ const match = key.match(/(\*(\d+)|\*(\d+)\*|\*)$/);
568
+ if (!match) {
569
+ // not a continuation parameter, there is nothing to join
570
+ return;
571
+ }
572
+ const actualKey = key.substr(0, match.index);
573
+ const nr = Number(match[2] || match[3]) || 0;
574
+ // RFC 2231 section 4.1: only a section whose name ends in '*' is percent encoded
575
+ const encoded = match[0].substr(-1) === '*';
576
+ // remove the old reference
577
+ let value = response.params[key];
578
+ delete response.params[key];
579
+ if (!_isParamName(actualKey)) {
580
+ // the joined value can not be written back under this name. It is empty when the
581
+ // continuation suffix was all there was of it, as in the bare '*' of 'text/plain; a;*'
582
+ return;
583
+ }
584
+ let continuation = continuations.get(actualKey);
585
+ if (!continuation) {
586
+ continuation = { charset: false, sections: [] };
587
+ continuations.set(actualKey, continuation);
588
+ }
589
+ const charsetMatch = nr === 0 && encoded ? value.match(/^([^']*)'[^']*'(.*)$/) : null;
590
+ if (charsetMatch) {
591
+ // the charset is a token, and anything else named as one is no charset a consumer
592
+ // could resolve, so it reads as the unnamed case rather than being carried into
593
+ // the encoded word below. A "\r\n" of a prefix would otherwise reach a consumer
594
+ // of the parsed value as the charset of a word that no decoder can act on
595
+ continuation.charset = TOKEN.test(charsetMatch[1]) ? charsetMatch[1] : 'iso-8859-1';
596
+ value = charsetMatch[2];
503
597
  }
598
+ continuation.sections.push({ nr, value, encoded });
504
599
  });
505
600
  // concatenate split rfc2231 strings and convert encoded strings to mime encoded words
506
- Object.keys(response.params).forEach(key => {
507
- let value;
508
- if (response.params[key] && Array.isArray(response.params[key].values)) {
509
- value = response.params[key].values.map((val) => val || '').join('');
510
- if (response.params[key].charset) {
511
- // convert "%AB" to "=?charset?Q?=AB?="
512
- response.params[key] =
513
- '=?' +
514
- response.params[key].charset +
515
- '?Q?' +
516
- value
517
- // fix invalidly encoded chars
518
- .replace(/[=?_\s]/g, s => {
519
- const c = s.charCodeAt(0).toString(16);
520
- if (s === ' ') {
521
- return '_';
522
- }
523
- return '%' + (c.length < 2 ? '0' : '') + c;
524
- })
525
- // change from urlencoding to percent encoding
526
- .replace(/%/g, '=') +
527
- '?=';
528
- }
529
- else {
530
- response.params[key] = value;
531
- }
601
+ continuations.forEach((continuation, key) => {
602
+ if (Object.prototype.hasOwnProperty.call(response.params, key)) {
603
+ // The same name was also given as a plain parameter, which the starred keys were
604
+ // just deleted from around, so this write would be the only one in the function
605
+ // to override a name already taken. 'filename=plain.txt; filename*0=evil.txt'
606
+ // resolves to the plain parameter either way round, so the reading does not come
607
+ // down to which of the two spellings the sender put first
608
+ return;
609
+ }
610
+ continuation.sections.sort((a, b) => a.nr - b.nr);
611
+ if (!continuation.charset) {
612
+ // nothing said which charset the percent escapes of an encoded section are in,
613
+ // so every section is passed on as the text it already is
614
+ response.params[key] = continuation.sections.map(section => section.value).join('');
615
+ return;
532
616
  }
617
+ // convert "%AB" to "=?charset?Q?=AB?="
618
+ response.params[key] = '=?' + continuation.charset + '?Q?' + continuation.sections.map(_encodeContinuationSection).join('') + '?=';
533
619
  });
534
620
  return response;
535
621
  }
622
+ /**
623
+ * Renders one parameter value continuation section as the payload of a Q encoded word.
624
+ *
625
+ * A section whose name ends in '*' is percent encoded and its escapes carry the bytes of
626
+ * the value, so they only have to be rewritten into the "=AB" spelling a Q encoded word
627
+ * uses. A section without the '*' is literal text (RFC 2231 section 4.1), so its '%' is a
628
+ * '%' and is escaped along with the characters a Q encoded word can not carry bare.
629
+ * Decoding a literal section invents bytes that never appeared on the wire: it is how the
630
+ * value 'filename*0*=utf-8''safe; filename*1=%2F..%2F..%2Fetc%2Fpasswd' was emitted as a
631
+ * filename every receiving client reads back as 'safe/../../etc/passwd'.
632
+ *
633
+ * @param section One collected continuation section
634
+ * @return The section as Q encoded word payload
635
+ */
636
+ function _encodeContinuationSection(section) {
637
+ const specials = section.encoded ? /[=?_\s]/g : /[=?_\s%]/g;
638
+ return (section.value
639
+ // fix invalidly encoded chars
640
+ .replace(specials, s => {
641
+ const c = s.charCodeAt(0).toString(16);
642
+ if (s === ' ') {
643
+ return '_';
644
+ }
645
+ return '%' + (c.length < 2 ? '0' : '') + c;
646
+ })
647
+ // change from urlencoding to percent encoding
648
+ .replace(/%/g, '='));
649
+ }
536
650
  /**
537
651
  * Returns file extension for a content type string. If no suitable extensions
538
652
  * are found, 'bin' is used as the default extension
@@ -108,10 +108,11 @@ export interface MimeNodeEnvelope {
108
108
  }
109
109
  /**
110
110
  * Envelope as accepted by setEnvelope. Recipients are collected from to, cc and bcc, any
111
- * other field is copied to the envelope as is
111
+ * other field is copied to the envelope as is. A `from` of false is the null sender of a
112
+ * bounce message, it is sent as MAIL FROM:<>
112
113
  */
113
114
  export interface MimeNodeEnvelopeInput {
114
- from?: MimeNodeAddressInput | undefined;
115
+ from?: MimeNodeAddressInput | false | undefined;
115
116
  to?: MimeNodeAddressInput | undefined;
116
117
  cc?: MimeNodeAddressInput | undefined;
117
118
  bcc?: MimeNodeAddressInput | undefined;
@@ -327,4 +328,6 @@ declare namespace MimeNode {
327
328
  type Addresses = MimeNodeAddresses;
328
329
  type Envelope = MimeNodeEnvelope;
329
330
  }
331
+ /** The same aliases as module level exports, for `import * as MimeNode` and `import MimeNode = require()` */
332
+ export type { MimeNodeOptions as Options, MimeNodeAddresses as Addresses, MimeNodeEnvelope as Envelope };
330
333
  export default MimeNode;