@mavogel/awscdk-rootmail 0.1.7 → 0.1.9
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.
- package/.jsii +10 -10
- package/lib/rootmail.js +1 -1
- package/lib/ses-receive.js +1 -1
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-cjs/index.js +5 -5
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-es/schemas/schemas_0.js +4 -4
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/DescribeDeliveryDestinationsCommand.d.ts +1 -0
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/GetDeliveryDestinationCommand.d.ts +1 -0
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/PutAccountPolicyCommand.d.ts +4 -1
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/commands/PutDeliveryDestinationCommand.d.ts +2 -0
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/models/models_0.d.ts +80 -36
- package/node_modules/@aws-sdk/client-cloudwatch-logs/dist-types/ts3.4/models/models_0.d.ts +2 -0
- package/node_modules/@aws-sdk/client-cloudwatch-logs/package.json +1 -1
- package/node_modules/@aws-sdk/client-route-53/dist-cjs/index.js +1 -1
- package/node_modules/@aws-sdk/client-route-53/package.json +1 -1
- package/node_modules/@aws-sdk/client-s3/dist-cjs/index.js +2 -1
- package/node_modules/@aws-sdk/client-s3/dist-es/models/enums.js +1 -0
- package/node_modules/@aws-sdk/client-s3/dist-types/commands/GetBucketInventoryConfigurationCommand.d.ts +1 -1
- package/node_modules/@aws-sdk/client-s3/dist-types/commands/ListBucketInventoryConfigurationsCommand.d.ts +1 -1
- package/node_modules/@aws-sdk/client-s3/dist-types/commands/PutBucketInventoryConfigurationCommand.d.ts +1 -1
- package/node_modules/@aws-sdk/client-s3/dist-types/models/enums.d.ts +1 -0
- package/node_modules/@aws-sdk/client-s3/dist-types/ts3.4/models/enums.d.ts +1 -0
- package/node_modules/@aws-sdk/client-s3/package.json +2 -2
- package/node_modules/@aws-sdk/client-ses/dist-cjs/index.js +1 -1
- package/node_modules/@aws-sdk/client-ses/package.json +1 -1
- package/node_modules/@aws-sdk/client-ssm/dist-cjs/index.js +9 -3
- package/node_modules/@aws-sdk/client-ssm/dist-es/models/enums.js +4 -0
- package/node_modules/@aws-sdk/client-ssm/dist-es/schemas/schemas_0.js +3 -2
- package/node_modules/@aws-sdk/client-ssm/dist-types/commands/DeleteResourcePolicyCommand.d.ts +6 -0
- package/node_modules/@aws-sdk/client-ssm/dist-types/commands/PutResourcePolicyCommand.d.ts +12 -0
- package/node_modules/@aws-sdk/client-ssm/dist-types/models/enums.d.ts +12 -0
- package/node_modules/@aws-sdk/client-ssm/dist-types/models/models_0.d.ts +20 -1
- package/node_modules/@aws-sdk/client-ssm/dist-types/models/models_1.d.ts +2 -2
- package/node_modules/@aws-sdk/client-ssm/dist-types/ts3.4/models/enums.d.ts +5 -0
- package/node_modules/@aws-sdk/client-ssm/dist-types/ts3.4/models/models_0.d.ts +2 -0
- package/node_modules/@aws-sdk/client-ssm/package.json +1 -1
- package/node_modules/@zone-eu/mailsplit/lib/flowed-decoder.js +1 -5
- package/node_modules/@zone-eu/mailsplit/lib/headers.js +35 -25
- package/node_modules/@zone-eu/mailsplit/lib/message-splitter.js +126 -79
- package/node_modules/@zone-eu/mailsplit/lib/mime-node.js +27 -5
- package/node_modules/@zone-eu/mailsplit/lib/node-rewriter.js +3 -2
- package/node_modules/@zone-eu/mailsplit/lib/types.d.ts +0 -3
- package/node_modules/@zone-eu/mailsplit/package.json +5 -5
- package/node_modules/libbase64/.github/workflows/release.yaml +12 -10
- package/node_modules/libbase64/.ncurc.js +7 -1
- package/node_modules/libbase64/CHANGELOG.md +7 -0
- package/node_modules/libbase64/lib/libbase64.js +27 -0
- package/node_modules/libbase64/package.json +4 -4
- package/node_modules/libmime/CHANGELOG.md +14 -0
- package/node_modules/libmime/lib/libmime.js +41 -21
- package/node_modules/libmime/package.json +3 -3
- package/node_modules/libqp/.github/workflows/release.yaml +12 -10
- package/node_modules/libqp/CHANGELOG.md +7 -0
- package/node_modules/libqp/lib/libqp.js +6 -4
- package/node_modules/libqp/package.json +2 -2
- package/node_modules/libqp/test/libqp-test.js +71 -14
- package/node_modules/mailparser/.release-please-manifest.json +1 -1
- package/node_modules/mailparser/CHANGELOG.md +42 -0
- package/node_modules/mailparser/README.md +5 -0
- package/node_modules/mailparser/lib/mail-parser.js +107 -32
- package/node_modules/mailparser/lib/simple-parser.js +12 -0
- package/node_modules/mailparser/lib/stream-hash.js +1 -1
- package/node_modules/mailparser/package.json +6 -6
- package/node_modules/nodemailer/CHANGELOG.md +38 -0
- package/node_modules/nodemailer/README.md +1 -1
- package/node_modules/nodemailer/dist/cjs/addressparser/index.d.ts +16 -2
- package/node_modules/nodemailer/dist/cjs/addressparser/index.js +147 -28
- package/node_modules/nodemailer/dist/cjs/base64/index.js +2 -1
- package/node_modules/nodemailer/dist/cjs/dkim/index.d.ts +13 -1
- package/node_modules/nodemailer/dist/cjs/dkim/index.js +25 -8
- package/node_modules/nodemailer/dist/cjs/dkim/message-parser.d.ts +10 -1
- package/node_modules/nodemailer/dist/cjs/dkim/message-parser.js +28 -4
- package/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.d.ts +10 -1
- package/node_modules/nodemailer/dist/cjs/dkim/sign.d.ts +3 -0
- package/node_modules/nodemailer/dist/cjs/dkim/sign.js +18 -1
- package/node_modules/nodemailer/dist/cjs/errors.d.ts +3 -2
- package/node_modules/nodemailer/dist/cjs/fetch/cookies.d.ts +12 -1
- package/node_modules/nodemailer/dist/cjs/fetch/index.d.ts +15 -1
- package/node_modules/nodemailer/dist/cjs/fetch/index.js +39 -64
- package/node_modules/nodemailer/dist/cjs/json-transport/index.d.ts +14 -4
- package/node_modules/nodemailer/dist/cjs/json-transport/index.js +2 -0
- package/node_modules/nodemailer/dist/cjs/mail-composer/index.d.ts +8 -3
- package/node_modules/nodemailer/dist/cjs/mailer/index.d.ts +43 -25
- package/node_modules/nodemailer/dist/cjs/mailer/mail-message.d.ts +11 -4
- package/node_modules/nodemailer/dist/cjs/mime-funcs/index.d.ts +7 -3
- package/node_modules/nodemailer/dist/cjs/mime-funcs/index.js +198 -84
- package/node_modules/nodemailer/dist/cjs/mime-node/index.d.ts +5 -2
- package/node_modules/nodemailer/dist/cjs/mime-node/index.js +2 -1
- package/node_modules/nodemailer/dist/cjs/nodemailer.d.ts +38 -16
- package/node_modules/nodemailer/dist/cjs/nodemailer.js +1 -0
- package/node_modules/nodemailer/dist/cjs/package-info.d.ts +1 -1
- package/node_modules/nodemailer/dist/cjs/package-info.js +1 -1
- package/node_modules/nodemailer/dist/cjs/punycode/index.js +1 -0
- package/node_modules/nodemailer/dist/cjs/qp/index.d.ts +2 -0
- package/node_modules/nodemailer/dist/cjs/qp/index.js +10 -1
- package/node_modules/nodemailer/dist/cjs/sendmail-transport/index.d.ts +2 -0
- package/node_modules/nodemailer/dist/cjs/ses-transport/index.d.ts +39 -2
- package/node_modules/nodemailer/dist/cjs/shared/index.d.ts +43 -7
- package/node_modules/nodemailer/dist/cjs/shared/index.js +5 -2
- package/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.d.ts +2 -1
- package/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.js +32 -24
- package/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.d.ts +13 -5
- package/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.js +23 -11
- package/node_modules/nodemailer/dist/cjs/smtp-connection/index.d.ts +59 -24
- package/node_modules/nodemailer/dist/cjs/smtp-connection/index.js +156 -75
- package/node_modules/nodemailer/dist/cjs/smtp-pool/index.d.ts +12 -4
- package/node_modules/nodemailer/dist/cjs/smtp-pool/index.js +39 -11
- package/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.js +27 -31
- package/node_modules/nodemailer/dist/cjs/smtp-transport/index.d.ts +19 -6
- package/node_modules/nodemailer/dist/cjs/smtp-transport/index.js +25 -33
- package/node_modules/nodemailer/dist/cjs/stream-transport/index.d.ts +2 -0
- package/node_modules/nodemailer/dist/cjs/well-known/services.js +6 -0
- package/node_modules/nodemailer/dist/cjs/xoauth2/index.d.ts +13 -3
- package/node_modules/nodemailer/dist/cjs/xoauth2/index.js +25 -13
- package/node_modules/nodemailer/dist/esm/addressparser/index.d.ts +16 -2
- package/node_modules/nodemailer/dist/esm/addressparser/index.js +147 -27
- package/node_modules/nodemailer/dist/esm/base64/index.js +2 -1
- package/node_modules/nodemailer/dist/esm/dkim/index.d.ts +13 -1
- package/node_modules/nodemailer/dist/esm/dkim/index.js +25 -8
- package/node_modules/nodemailer/dist/esm/dkim/message-parser.d.ts +10 -1
- package/node_modules/nodemailer/dist/esm/dkim/message-parser.js +30 -5
- package/node_modules/nodemailer/dist/esm/dkim/relaxed-body.d.ts +10 -1
- package/node_modules/nodemailer/dist/esm/dkim/relaxed-body.js +2 -1
- package/node_modules/nodemailer/dist/esm/dkim/sign.d.ts +3 -0
- package/node_modules/nodemailer/dist/esm/dkim/sign.js +18 -1
- package/node_modules/nodemailer/dist/esm/errors.d.ts +3 -2
- package/node_modules/nodemailer/dist/esm/fetch/cookies.d.ts +12 -1
- package/node_modules/nodemailer/dist/esm/fetch/cookies.js +2 -1
- package/node_modules/nodemailer/dist/esm/fetch/index.d.ts +15 -1
- package/node_modules/nodemailer/dist/esm/fetch/index.js +39 -64
- package/node_modules/nodemailer/dist/esm/json-transport/index.d.ts +14 -4
- package/node_modules/nodemailer/dist/esm/json-transport/index.js +2 -0
- package/node_modules/nodemailer/dist/esm/mail-composer/index.d.ts +8 -3
- package/node_modules/nodemailer/dist/esm/mailer/index.d.ts +43 -25
- package/node_modules/nodemailer/dist/esm/mailer/mail-message.d.ts +11 -4
- package/node_modules/nodemailer/dist/esm/mime-funcs/index.d.ts +7 -3
- package/node_modules/nodemailer/dist/esm/mime-funcs/index.js +198 -84
- package/node_modules/nodemailer/dist/esm/mime-node/index.d.ts +5 -2
- package/node_modules/nodemailer/dist/esm/mime-node/index.js +2 -1
- package/node_modules/nodemailer/dist/esm/nodemailer.d.ts +38 -16
- package/node_modules/nodemailer/dist/esm/package-info.d.ts +1 -1
- package/node_modules/nodemailer/dist/esm/package-info.js +1 -1
- package/node_modules/nodemailer/dist/esm/punycode/index.js +1 -0
- package/node_modules/nodemailer/dist/esm/qp/index.d.ts +2 -0
- package/node_modules/nodemailer/dist/esm/qp/index.js +10 -1
- package/node_modules/nodemailer/dist/esm/sendmail-transport/index.d.ts +2 -0
- package/node_modules/nodemailer/dist/esm/ses-transport/index.d.ts +39 -2
- package/node_modules/nodemailer/dist/esm/shared/index.d.ts +43 -7
- package/node_modules/nodemailer/dist/esm/shared/index.js +5 -2
- package/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.d.ts +2 -1
- package/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.js +32 -24
- package/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.d.ts +13 -5
- package/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.js +23 -11
- package/node_modules/nodemailer/dist/esm/smtp-connection/index.d.ts +59 -24
- package/node_modules/nodemailer/dist/esm/smtp-connection/index.js +156 -75
- package/node_modules/nodemailer/dist/esm/smtp-pool/index.d.ts +12 -4
- package/node_modules/nodemailer/dist/esm/smtp-pool/index.js +39 -11
- package/node_modules/nodemailer/dist/esm/smtp-pool/pool-resource.js +27 -31
- package/node_modules/nodemailer/dist/esm/smtp-transport/index.d.ts +19 -6
- package/node_modules/nodemailer/dist/esm/smtp-transport/index.js +25 -33
- package/node_modules/nodemailer/dist/esm/stream-transport/index.d.ts +2 -0
- package/node_modules/nodemailer/dist/esm/well-known/services.js +6 -0
- package/node_modules/nodemailer/dist/esm/xoauth2/index.d.ts +13 -3
- package/node_modules/nodemailer/dist/esm/xoauth2/index.js +25 -13
- package/node_modules/nodemailer/dist/well-known/services.json +7 -0
- package/node_modules/nodemailer/package.json +16 -12
- package/package.json +18 -16
- package/renovate.json5 +59 -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,
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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?:
|
|
37
|
+
message?: any;
|
|
37
38
|
/** Transport specific fields */
|
|
38
|
-
[key: string]:
|
|
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 =
|
|
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 |
|
|
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,
|
|
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:
|
|
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:
|
|
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?:
|
|
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
|
-
* @
|
|
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
|
|
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
|
-
|
|
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
|
|
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:
|
|
429
|
+
value: '',
|
|
406
430
|
params: {}
|
|
407
431
|
};
|
|
408
|
-
//
|
|
409
|
-
//
|
|
410
|
-
//
|
|
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
|
-
|
|
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
|
|
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 (
|
|
493
|
+
if (stage === 'key') {
|
|
425
494
|
if (chr === '=') {
|
|
426
|
-
key =
|
|
427
|
-
|
|
428
|
-
|
|
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
|
-
|
|
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
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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
|
-
|
|
546
|
+
addChr(chr);
|
|
459
547
|
}
|
|
460
548
|
escaped = false;
|
|
461
549
|
}
|
|
462
550
|
}
|
|
463
|
-
if (
|
|
464
|
-
|
|
465
|
-
response.value = value.trim();
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
setParam(key, value.trim());
|
|
469
|
-
}
|
|
551
|
+
if (stage === 'value') {
|
|
552
|
+
storeValue();
|
|
470
553
|
}
|
|
471
|
-
else
|
|
472
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
479
|
-
if (
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
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;
|