@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
|
@@ -74,12 +74,14 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
74
74
|
constructor(options, logger) {
|
|
75
75
|
super();
|
|
76
76
|
this.options = options || {};
|
|
77
|
+
this.configError = false;
|
|
77
78
|
if (options && options.serviceClient) {
|
|
78
79
|
if (!options.privateKey || !options.user) {
|
|
80
|
+
// reported through getToken() rather than an 'error' event: the transports forward
|
|
81
|
+
// that event up to the Mail object, where nothing may be listening
|
|
79
82
|
const err = new Error('Options "privateKey" and "user" are required for service account!');
|
|
80
83
|
err.code = errors.EOAUTH2;
|
|
81
|
-
|
|
82
|
-
return;
|
|
84
|
+
this.configError = err;
|
|
83
85
|
}
|
|
84
86
|
const serviceRequestTimeout = Math.min(Math.max(Number(this.options.serviceRequestTimeout) || 0, 0), 3600);
|
|
85
87
|
this.options.serviceRequestTimeout = serviceRequestTimeout || 5 * 60;
|
|
@@ -111,6 +113,11 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
111
113
|
* @param callback Callback function with error object and token string
|
|
112
114
|
*/
|
|
113
115
|
getToken(renew, callback) {
|
|
116
|
+
// the error paths hand over the error alone
|
|
117
|
+
const done = callback;
|
|
118
|
+
if (this.configError) {
|
|
119
|
+
return done(this.configError);
|
|
120
|
+
}
|
|
114
121
|
if (!renew && this.accessToken && (!this.expires || this.expires > Date.now())) {
|
|
115
122
|
this.logger.debug({
|
|
116
123
|
tnx: 'OAUTH2',
|
|
@@ -136,11 +143,11 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
136
143
|
}, 'Cannot renew access token for %s: No refresh mechanism available', this.options.user);
|
|
137
144
|
const err = new Error("Can't create new access token for user");
|
|
138
145
|
err.code = errors.EOAUTH2;
|
|
139
|
-
return
|
|
146
|
+
return done(err);
|
|
140
147
|
}
|
|
141
148
|
// If renewal already in progress, queue this request instead of starting another
|
|
142
149
|
if (this.renewing) {
|
|
143
|
-
this.renewalQueue.push({ renew, callback });
|
|
150
|
+
this.renewalQueue.push({ renew, callback: done });
|
|
144
151
|
return;
|
|
145
152
|
}
|
|
146
153
|
this.renewing = true;
|
|
@@ -165,7 +172,7 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
165
172
|
}, 'Generated new Access Token for %s', this.options.user);
|
|
166
173
|
}
|
|
167
174
|
// Complete original request
|
|
168
|
-
|
|
175
|
+
done(err, accessToken);
|
|
169
176
|
};
|
|
170
177
|
if (this.provisionCallback) {
|
|
171
178
|
this.provisionCallback(this.options.user, !!renew, (err, accessToken, expires) => {
|
|
@@ -204,6 +211,8 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
204
211
|
* @param callback Callback function with error object and token string
|
|
205
212
|
*/
|
|
206
213
|
generateToken(callback) {
|
|
214
|
+
// the error paths hand over the error alone
|
|
215
|
+
const done = callback;
|
|
207
216
|
let urlOptions;
|
|
208
217
|
let loggedUrlOptions;
|
|
209
218
|
if (this.options.serviceClient) {
|
|
@@ -224,7 +233,7 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
224
233
|
catch (_err) {
|
|
225
234
|
const err = new Error("Can't generate token. Check your auth options");
|
|
226
235
|
err.code = errors.EOAUTH2;
|
|
227
|
-
return
|
|
236
|
+
return done(err);
|
|
228
237
|
}
|
|
229
238
|
urlOptions = {
|
|
230
239
|
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
@@ -239,7 +248,7 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
239
248
|
if (!this.options.refreshToken) {
|
|
240
249
|
const err = new Error("Can't create new access token for user");
|
|
241
250
|
err.code = errors.EOAUTH2;
|
|
242
|
-
return
|
|
251
|
+
return done(err);
|
|
243
252
|
}
|
|
244
253
|
// web app - https://developers.google.com/identity/protocols/OAuth2WebServer
|
|
245
254
|
urlOptions = {
|
|
@@ -265,13 +274,13 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
265
274
|
this.postRequest(this.options.accessUrl, urlOptions, this.options, (error, body) => {
|
|
266
275
|
let data;
|
|
267
276
|
if (error) {
|
|
268
|
-
return
|
|
277
|
+
return done(error);
|
|
269
278
|
}
|
|
270
279
|
try {
|
|
271
280
|
data = JSON.parse(body.toString());
|
|
272
281
|
}
|
|
273
282
|
catch (E) {
|
|
274
|
-
return
|
|
283
|
+
return done(E);
|
|
275
284
|
}
|
|
276
285
|
if (!data || typeof data !== 'object') {
|
|
277
286
|
this.logger.debug({
|
|
@@ -281,7 +290,7 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
281
290
|
}, 'Response: %s', (body || '').toString());
|
|
282
291
|
const err = new Error('Invalid authentication response');
|
|
283
292
|
err.code = errors.EOAUTH2;
|
|
284
|
-
return
|
|
293
|
+
return done(err);
|
|
285
294
|
}
|
|
286
295
|
const logData = Object.assign({}, data);
|
|
287
296
|
if (logData.access_token) {
|
|
@@ -303,7 +312,7 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
303
312
|
}
|
|
304
313
|
const err = new Error(errorMessage);
|
|
305
314
|
err.code = errors.EOAUTH2;
|
|
306
|
-
return
|
|
315
|
+
return done(err);
|
|
307
316
|
}
|
|
308
317
|
if (data.access_token) {
|
|
309
318
|
this.updateToken(data.access_token, data.expires_in);
|
|
@@ -311,7 +320,7 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
311
320
|
}
|
|
312
321
|
const err = new Error('No access token');
|
|
313
322
|
err.code = errors.EOAUTH2;
|
|
314
|
-
return
|
|
323
|
+
return done(err);
|
|
315
324
|
});
|
|
316
325
|
}
|
|
317
326
|
/**
|
|
@@ -345,7 +354,10 @@ class XOAuth2 extends node_stream_1.Stream {
|
|
|
345
354
|
method: 'post',
|
|
346
355
|
headers: params.customHeaders,
|
|
347
356
|
body: payload,
|
|
348
|
-
allowErrorResponse: true
|
|
357
|
+
allowErrorResponse: true,
|
|
358
|
+
// unset falls back to the fetch default, a stalled token endpoint would otherwise keep
|
|
359
|
+
// `renewing` set and queue every later request
|
|
360
|
+
timeout: params.requestTimeout
|
|
349
361
|
};
|
|
350
362
|
// OAuth2 token endpoints are credential-bearing. src/fetch already
|
|
351
363
|
// validates certs by default; pin rejectUnauthorized:true here so the
|
|
@@ -39,7 +39,21 @@ export type Address = MailboxAddress | GroupAddress;
|
|
|
39
39
|
*
|
|
40
40
|
* @param str Address field
|
|
41
41
|
* @param options Optional options object
|
|
42
|
-
* @param options._depth Internal recursion depth counter (do not set manually)
|
|
43
42
|
* @return An array of address objects
|
|
44
43
|
*/
|
|
45
|
-
|
|
44
|
+
declare function addressparser(str: string | null | undefined, options: AddressParserOptions & {
|
|
45
|
+
flatten: true;
|
|
46
|
+
}): MailboxAddress[];
|
|
47
|
+
declare function addressparser(str?: string | null, options?: AddressParserOptions): Address[];
|
|
48
|
+
/**
|
|
49
|
+
* Type aliases in the layout of @types/nodemailer, so `addressparser.Address` style references keep working
|
|
50
|
+
*/
|
|
51
|
+
type AddressEntry = Address;
|
|
52
|
+
declare namespace addressparser {
|
|
53
|
+
type Address = MailboxAddress;
|
|
54
|
+
type Group = GroupAddress;
|
|
55
|
+
type AddressOrGroup = AddressEntry;
|
|
56
|
+
}
|
|
57
|
+
/** The names @types/nodemailer used for the group entry and for the union of both entry types */
|
|
58
|
+
export type { GroupAddress as Group, Address as AddressOrGroup };
|
|
59
|
+
export default addressparser;
|
|
@@ -240,6 +240,81 @@ function _recoverAddrSpec(data) {
|
|
|
240
240
|
.filter(part => part)
|
|
241
241
|
.join(' ');
|
|
242
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Takes the RFC 5322 comments out of the contents of an angle-addr.
|
|
245
|
+
*
|
|
246
|
+
* The tokenizer tracks a single open operator, so once '<' is open a '(' is plain text and
|
|
247
|
+
* a comment inside the brackets reached the address verbatim: 'Name <user@example.com(x)evil.com>'
|
|
248
|
+
* put 'user@example.com(x)evil.com' into the envelope, a value that is no mailbox and that a
|
|
249
|
+
* receiver stripping the comment reads as 'user@example.comevil.com' (GHSA-g73g-hqqh-jr95).
|
|
250
|
+
* A comment is folding whitespace, so it is read as a space that splits two atoms and as
|
|
251
|
+
* nothing next to an '@', the same rule the token walk applies outside the brackets. Quoted
|
|
252
|
+
* strings and domain literals are copied through untouched, a '(' in there is not a comment.
|
|
253
|
+
*
|
|
254
|
+
* @param address Contents of the angle brackets
|
|
255
|
+
* @return The address with the comments removed, and the text of the comments
|
|
256
|
+
*/
|
|
257
|
+
function _stripAddressComments(address) {
|
|
258
|
+
const comments = [];
|
|
259
|
+
let result = '';
|
|
260
|
+
let comment = '';
|
|
261
|
+
let depth = 0;
|
|
262
|
+
let closer = '';
|
|
263
|
+
// carried along rather than read back off the growing result, which would flatten it on
|
|
264
|
+
// every comment (see lastChars in _handleAddress)
|
|
265
|
+
let lastChar = '';
|
|
266
|
+
for (let i = 0, len = address.length; i < len; i++) {
|
|
267
|
+
const chr = address.charAt(i);
|
|
268
|
+
if (depth) {
|
|
269
|
+
if (chr === '\\' && i < len - 1) {
|
|
270
|
+
comment += address.charAt(++i);
|
|
271
|
+
}
|
|
272
|
+
else if (chr === '(') {
|
|
273
|
+
depth++;
|
|
274
|
+
comment += chr;
|
|
275
|
+
}
|
|
276
|
+
else if (chr === ')' && !--depth) {
|
|
277
|
+
comments.push(comment.trim());
|
|
278
|
+
comment = '';
|
|
279
|
+
if (lastChar !== '@' && address.charAt(i + 1) !== '@') {
|
|
280
|
+
result += ' ';
|
|
281
|
+
lastChar = ' ';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
comment += chr;
|
|
286
|
+
}
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (closer) {
|
|
290
|
+
if (chr === '\\' && closer === '"' && i < len - 1) {
|
|
291
|
+
result += chr + address.charAt(++i);
|
|
292
|
+
lastChar = address.charAt(i);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (chr === closer) {
|
|
296
|
+
closer = '';
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else if (chr === '"') {
|
|
300
|
+
closer = '"';
|
|
301
|
+
}
|
|
302
|
+
else if (chr === '[') {
|
|
303
|
+
closer = ']';
|
|
304
|
+
}
|
|
305
|
+
else if (chr === '(') {
|
|
306
|
+
depth = 1;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
result += chr;
|
|
310
|
+
lastChar = chr;
|
|
311
|
+
}
|
|
312
|
+
if (depth) {
|
|
313
|
+
// an unterminated comment runs to the end of the address
|
|
314
|
+
comments.push(comment.trim());
|
|
315
|
+
}
|
|
316
|
+
return { address: result.trim(), comments: comments.filter(text => text) };
|
|
317
|
+
}
|
|
243
318
|
/**
|
|
244
319
|
* Converts tokens for a single address into an address object
|
|
245
320
|
*
|
|
@@ -351,7 +426,7 @@ function _handleAddress(tokens, depth) {
|
|
|
351
426
|
// Parse group members, but flatten any nested groups (RFC 5322 doesn't allow nesting)
|
|
352
427
|
let groupMembers = [];
|
|
353
428
|
if (data.group.length) {
|
|
354
|
-
const parsedGroup =
|
|
429
|
+
const parsedGroup = _parseAddressList(data.group.join(','), depth + 1);
|
|
355
430
|
parsedGroup.forEach(member => {
|
|
356
431
|
if (member.group) {
|
|
357
432
|
groupMembers = groupMembers.concat(member.group);
|
|
@@ -367,6 +442,24 @@ function _handleAddress(tokens, depth) {
|
|
|
367
442
|
});
|
|
368
443
|
}
|
|
369
444
|
else {
|
|
445
|
+
// Comments come out of the angle-addr before anything asks whether one was found, so
|
|
446
|
+
// that brackets holding nothing but a comment read the same as empty ones
|
|
447
|
+
const addressComments = [];
|
|
448
|
+
const addressParts = [];
|
|
449
|
+
for (const part of data.address) {
|
|
450
|
+
if (part.indexOf('(') < 0) {
|
|
451
|
+
addressParts.push(part);
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
const stripped = _stripAddressComments(part);
|
|
455
|
+
for (const comment of stripped.comments) {
|
|
456
|
+
addressComments.push(comment);
|
|
457
|
+
}
|
|
458
|
+
if (stripped.address) {
|
|
459
|
+
addressParts.push(stripped.address);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
data.address = addressParts;
|
|
370
463
|
// If no address was found, try to detect one from regular text
|
|
371
464
|
if (!data.address.length && data.text.length) {
|
|
372
465
|
for (let i = data.text.length - 1; i >= 0; i--) {
|
|
@@ -420,7 +513,13 @@ function _handleAddress(tokens, depth) {
|
|
|
420
513
|
// Join values with spaces
|
|
421
514
|
data.text = data.text.join(' ');
|
|
422
515
|
data.address = data.address.join(' ');
|
|
423
|
-
if (addressFromQuotedText && data.text) {
|
|
516
|
+
if (addressFromQuotedText && data.text.indexOf('@') >= 0) {
|
|
517
|
+
// A quoted run with no '@' in it is a display name and nothing else, so it stays
|
|
518
|
+
// where it is. Moving it over anyway made a comment the mailbox was read from:
|
|
519
|
+
// '"Display Name" <(a comment)>' handed on 'Display Name' as the address with the
|
|
520
|
+
// comment as the name, and a quoted name holding a ',' or a ';' became an address
|
|
521
|
+
// that reads as two recipients once a consumer writes it back into a header.
|
|
522
|
+
//
|
|
424
523
|
// The mailbox is still sitting in the text, so it moves over here and is quoted
|
|
425
524
|
// before the recovery below rather than after it. Anything else the text holds
|
|
426
525
|
// came along with it: a comment ends the domain but leaves the atoms behind it in
|
|
@@ -433,6 +532,10 @@ function _handleAddress(tokens, depth) {
|
|
|
433
532
|
data.text = '';
|
|
434
533
|
}
|
|
435
534
|
_recoverAddrSpec(data);
|
|
535
|
+
// a comment names the mailbox only when nothing else does, as one outside the brackets
|
|
536
|
+
if (!data.text && addressComments.length) {
|
|
537
|
+
data.text = addressComments.join(' ');
|
|
538
|
+
}
|
|
436
539
|
const address = {
|
|
437
540
|
address: data.address || data.text || '',
|
|
438
541
|
name: data.text || data.address || ''
|
|
@@ -463,6 +566,7 @@ class Tokenizer {
|
|
|
463
566
|
this.node = null;
|
|
464
567
|
this.escaped = false;
|
|
465
568
|
this.inDomainLiteral = false;
|
|
569
|
+
this.afterAt = false;
|
|
466
570
|
this.list = [];
|
|
467
571
|
/**
|
|
468
572
|
* Operator tokens and which tokens are expected to end the sequence
|
|
@@ -506,17 +610,23 @@ class Tokenizer {
|
|
|
506
610
|
* Checks if a character is an operator or text and acts accordingly
|
|
507
611
|
*
|
|
508
612
|
* @param chr Character from the address field
|
|
613
|
+
* @param nextChr Character following chr, null at the end of the field
|
|
509
614
|
*/
|
|
510
615
|
checkChar(chr, nextChr) {
|
|
511
|
-
// Track RFC 5322 domain-literals ("[" *dtext "]").
|
|
512
|
-
//
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
//
|
|
516
|
-
//
|
|
517
|
-
//
|
|
616
|
+
// Track RFC 5322 domain-literals ("[" *dtext "]"). The ":" of an IPv6
|
|
617
|
+
// address-literal (user@[IPv6:2001:db8::1]) is dtext and must not be treated as
|
|
618
|
+
// the group delimiter while inside the brackets. That is the only operator the
|
|
619
|
+
// literal hides: letting it hide the others as well meant a "[" could turn the
|
|
620
|
+
// comment, quoted string or angle-addr after it into text and pick a different
|
|
621
|
+
// mailbox, '[ ( ] <a@victim.com> ) <b@evil.com>' yielded a@victim.com where
|
|
622
|
+
// RFC 5322 reads b@evil.com. A "[" also only opens a literal right after the "@"
|
|
623
|
+
// of an addr-spec, so the group delimiter of a display name holding one stays
|
|
624
|
+
// intact. Quoted strings and comments are handled separately via
|
|
625
|
+
// operatorExpecting, so only enter this state when no operator is open. The list
|
|
626
|
+
// separators "," and ";" always end the literal (and split the address list) so
|
|
627
|
+
// that an unclosed "[" cannot swallow later recipients.
|
|
518
628
|
if (!this.escaped && !this.operatorExpecting) {
|
|
519
|
-
if (!this.inDomainLiteral && chr === '[') {
|
|
629
|
+
if (!this.inDomainLiteral && chr === '[' && this.afterAt) {
|
|
520
630
|
this.inDomainLiteral = true;
|
|
521
631
|
}
|
|
522
632
|
else if (this.inDomainLiteral && (chr === ']' || chr === ',' || chr === ';')) {
|
|
@@ -536,17 +646,24 @@ class Tokenizer {
|
|
|
536
646
|
}
|
|
537
647
|
this.list.push(this.node);
|
|
538
648
|
this.node = null;
|
|
649
|
+
if (chr !== ')') {
|
|
650
|
+
// a comment is folding whitespace, it does not part the "@" from the "["
|
|
651
|
+
this.afterAt = false;
|
|
652
|
+
}
|
|
539
653
|
this.operatorExpecting = '';
|
|
540
654
|
this.escaped = false;
|
|
541
655
|
return;
|
|
542
656
|
}
|
|
543
|
-
else if (!this.operatorExpecting && !this.inDomainLiteral && chr in this.operators) {
|
|
657
|
+
else if (!this.operatorExpecting && !(this.inDomainLiteral && chr === ':') && chr in this.operators) {
|
|
544
658
|
this.node = {
|
|
545
659
|
type: 'operator',
|
|
546
660
|
value: chr
|
|
547
661
|
};
|
|
548
662
|
this.list.push(this.node);
|
|
549
663
|
this.node = null;
|
|
664
|
+
if (chr !== '(') {
|
|
665
|
+
this.afterAt = false;
|
|
666
|
+
}
|
|
550
667
|
this.operatorExpecting = this.operators[chr];
|
|
551
668
|
this.escaped = false;
|
|
552
669
|
return;
|
|
@@ -570,6 +687,11 @@ class Tokenizer {
|
|
|
570
687
|
if (chr.charCodeAt(0) >= 0x21 || [' ', '\t'].includes(chr)) {
|
|
571
688
|
// skip command bytes
|
|
572
689
|
this.node.value += chr;
|
|
690
|
+
// text inside a quoted string or a comment is not part of an addr-spec. Tracked
|
|
691
|
+
// as it goes rather than read back off the value (see lastChars in _handleAddress)
|
|
692
|
+
if (!this.operatorExpecting && chr !== ' ' && chr !== '\t') {
|
|
693
|
+
this.afterAt = chr === '@';
|
|
694
|
+
}
|
|
573
695
|
}
|
|
574
696
|
this.escaped = false;
|
|
575
697
|
}
|
|
@@ -581,24 +703,18 @@ class Tokenizer {
|
|
|
581
703
|
*/
|
|
582
704
|
const MAX_NESTED_GROUP_DEPTH = 50;
|
|
583
705
|
/**
|
|
584
|
-
* Parses
|
|
585
|
-
*
|
|
586
|
-
* Example:
|
|
706
|
+
* Parses an address list, recursing into the groups it holds.
|
|
587
707
|
*
|
|
588
|
-
*
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
* [{name: 'Name', address: 'address@domain'}]
|
|
708
|
+
* The depth is threaded through the calls rather than carried in an options object, so a
|
|
709
|
+
* caller supplied one can not seed it and lift the recursion limit: `{ _depth: -1e9 }`
|
|
710
|
+
* bought a billion levels of nesting and turned the guard below into the stack overflow it
|
|
711
|
+
* is there to prevent.
|
|
593
712
|
*
|
|
594
713
|
* @param str Address field
|
|
595
|
-
* @param
|
|
596
|
-
* @param options._depth Internal recursion depth counter (do not set manually)
|
|
714
|
+
* @param depth Current recursion depth for nested group protection
|
|
597
715
|
* @return An array of address objects
|
|
598
716
|
*/
|
|
599
|
-
|
|
600
|
-
options = options || {};
|
|
601
|
-
const depth = options._depth || 0;
|
|
717
|
+
function _parseAddressList(str, depth) {
|
|
602
718
|
// Prevent stack overflow from deeply nested groups (DoS protection)
|
|
603
719
|
if (depth > MAX_NESTED_GROUP_DEPTH) {
|
|
604
720
|
return [];
|
|
@@ -607,7 +723,7 @@ export default function addressparser(str, options) {
|
|
|
607
723
|
const tokens = tokenizer.tokenize();
|
|
608
724
|
const addresses = [];
|
|
609
725
|
let address = [];
|
|
610
|
-
|
|
726
|
+
const parsedAddresses = [];
|
|
611
727
|
tokens.forEach(token => {
|
|
612
728
|
if (token.type === 'operator' && (token.value === ',' || token.value === ';')) {
|
|
613
729
|
if (address.length) {
|
|
@@ -648,8 +764,11 @@ export default function addressparser(str, options) {
|
|
|
648
764
|
}
|
|
649
765
|
}
|
|
650
766
|
mergedAddresses.reverse();
|
|
651
|
-
|
|
652
|
-
|
|
767
|
+
return mergedAddresses;
|
|
768
|
+
}
|
|
769
|
+
function addressparser(str, options) {
|
|
770
|
+
const parsedAddresses = _parseAddressList(str, 0);
|
|
771
|
+
if (options?.flatten) {
|
|
653
772
|
const flatAddresses = [];
|
|
654
773
|
const walkAddressList = (list) => {
|
|
655
774
|
list.forEach(entry => {
|
|
@@ -664,3 +783,4 @@ export default function addressparser(str, options) {
|
|
|
664
783
|
}
|
|
665
784
|
return parsedAddresses;
|
|
666
785
|
}
|
|
786
|
+
export default addressparser;
|
|
@@ -20,7 +20,8 @@ export function encode(buffer) {
|
|
|
20
20
|
*/
|
|
21
21
|
export function wrap(str, lineLength) {
|
|
22
22
|
str = (str || '').toString();
|
|
23
|
-
|
|
23
|
+
// a negative length would step backwards through the input and never finish
|
|
24
|
+
lineLength = Math.max(Number(lineLength) || 76, 1);
|
|
24
25
|
if (str.length <= lineLength) {
|
|
25
26
|
return str;
|
|
26
27
|
}
|
|
@@ -30,11 +30,23 @@ declare class DKIM {
|
|
|
30
30
|
constructor(options: DKIMOptions);
|
|
31
31
|
sign(input: Readable | Buffer | string, extraOptions?: DKIMOptions): DKIMSignedStream;
|
|
32
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
|
+
};
|
|
33
41
|
/**
|
|
34
42
|
* Type aliases in the layout of @types/nodemailer, so `DKIM.Options` style references keep working
|
|
35
43
|
*/
|
|
36
44
|
declare namespace DKIM {
|
|
37
45
|
type Options = DKIMOptions;
|
|
38
|
-
type
|
|
46
|
+
type OptionalOptions = DKIMOptionalOptions;
|
|
47
|
+
type SingleKeyOptions = DKIMSingleKeyOptions;
|
|
48
|
+
type MultipleKeysOptions = DKIMMultipleKeysOptions;
|
|
39
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 };
|
|
40
52
|
export default DKIM;
|
|
@@ -85,13 +85,22 @@ class DKIMSigner {
|
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
87
|
const key = this.keys[keyPos++];
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
let dkimField;
|
|
89
|
+
try {
|
|
90
|
+
dkimField = sign(this.headers, this.hashAlgo, this.bodyHash, {
|
|
91
|
+
domainName: key.domainName,
|
|
92
|
+
keySelector: key.keySelector,
|
|
93
|
+
privateKey: key.privateKey,
|
|
94
|
+
headerFieldNames: this.options.headerFieldNames,
|
|
95
|
+
skipFields: this.options.skipFields
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
this.hasErrored = true;
|
|
100
|
+
this.cleanup();
|
|
101
|
+
this.output.emit('error', err);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
95
104
|
if (dkimField) {
|
|
96
105
|
this.output.write(Buffer.from(dkimField + '\r\n'));
|
|
97
106
|
}
|
|
@@ -191,7 +200,15 @@ class DKIM {
|
|
|
191
200
|
}
|
|
192
201
|
const signer = new DKIMSigner(options, this.keys, inputStream, output);
|
|
193
202
|
setImmediate(() => {
|
|
194
|
-
|
|
203
|
+
try {
|
|
204
|
+
signer.signStream();
|
|
205
|
+
}
|
|
206
|
+
catch (_E) {
|
|
207
|
+
// the body hash is created here, an unknown hashAlgo throws inside this timer
|
|
208
|
+
// where nothing else could catch it
|
|
209
|
+
output.emit('error', sign.unsupportedHashAlgoError(signer.hashAlgo));
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
195
212
|
if (writeValue) {
|
|
196
213
|
setImmediate(() => {
|
|
197
214
|
inputStream.end(writeValue);
|
|
@@ -13,7 +13,7 @@ export interface MessageParserHeaderLine {
|
|
|
13
13
|
* from the rest of the body. Headers are emitted with the 'headers' event. Message
|
|
14
14
|
* body is passed on as the resulting stream.
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
declare class MessageParser extends Transform {
|
|
17
17
|
lastBytes: Buffer;
|
|
18
18
|
headersParsed: boolean;
|
|
19
19
|
headerBytes: number;
|
|
@@ -37,3 +37,12 @@ export default class MessageParser extends Transform {
|
|
|
37
37
|
checkHeaders(data: Buffer): boolean;
|
|
38
38
|
parseHeaders(): MessageParserHeaderLine[];
|
|
39
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;
|
|
@@ -1,10 +1,37 @@
|
|
|
1
1
|
import { Transform } from 'node:stream';
|
|
2
|
+
/**
|
|
3
|
+
* Drops the SP and HTAB from both ends of a field name.
|
|
4
|
+
*
|
|
5
|
+
* An index scan rather than `/^[ \t]+|[ \t]+$/g`, which retries the trailing branch at
|
|
6
|
+
* every offset of a blank run that is followed by other text: the run is consumed greedily,
|
|
7
|
+
* `$` fails, and the engine gives the characters back one at a time before moving on to
|
|
8
|
+
* start the same walk one offset further in. A field name carrying a 128 KiB run of spaces
|
|
9
|
+
* between two atoms took about 6.7 seconds to trim, and the cost grows with its square.
|
|
10
|
+
*
|
|
11
|
+
* Not `.trim()`, which takes the other Unicode spaces along: an NBSP in front of a field
|
|
12
|
+
* name would come off and select the name into the signed set, where the relaxed
|
|
13
|
+
* canonicalization in sign.ts deliberately leaves everything but SP and HTAB alone.
|
|
14
|
+
*
|
|
15
|
+
* @param str Field name to trim
|
|
16
|
+
* @return The field name without the surrounding SP and HTAB
|
|
17
|
+
*/
|
|
18
|
+
function _trimFieldName(str) {
|
|
19
|
+
let start = 0;
|
|
20
|
+
let end = str.length;
|
|
21
|
+
while (start < end && (str.charCodeAt(start) === 0x20 || str.charCodeAt(start) === 0x09)) {
|
|
22
|
+
start++;
|
|
23
|
+
}
|
|
24
|
+
while (end > start && (str.charCodeAt(end - 1) === 0x20 || str.charCodeAt(end - 1) === 0x09)) {
|
|
25
|
+
end--;
|
|
26
|
+
}
|
|
27
|
+
return str.slice(start, end);
|
|
28
|
+
}
|
|
2
29
|
/**
|
|
3
30
|
* MessageParser instance is a transform stream that separates message headers
|
|
4
31
|
* from the rest of the body. Headers are emitted with the 'headers' event. Message
|
|
5
32
|
* body is passed on as the resulting stream.
|
|
6
33
|
*/
|
|
7
|
-
|
|
34
|
+
class MessageParser extends Transform {
|
|
8
35
|
constructor(options) {
|
|
9
36
|
super(options);
|
|
10
37
|
this.lastBytes = Buffer.alloc(4);
|
|
@@ -141,11 +168,9 @@ export default class MessageParser extends Transform {
|
|
|
141
168
|
return lines
|
|
142
169
|
.filter(line => /[^ \t\r]/.test(line))
|
|
143
170
|
.map(line => ({
|
|
144
|
-
key: line
|
|
145
|
-
.substr(0, line.indexOf(':'))
|
|
146
|
-
.replace(/^[ \t]+|[ \t]+$/g, '')
|
|
147
|
-
.toLowerCase(),
|
|
171
|
+
key: _trimFieldName(line.substr(0, line.indexOf(':'))).toLowerCase(),
|
|
148
172
|
line
|
|
149
173
|
}));
|
|
150
174
|
}
|
|
151
175
|
}
|
|
176
|
+
export default MessageParser;
|
|
@@ -17,7 +17,7 @@ export interface RelaxedBodyOptions {
|
|
|
17
17
|
* a non-empty body always ends with CRLF. Bytes are canonicalized as they arrive,
|
|
18
18
|
* so a line of any length costs constant memory.
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
declare class RelaxedBody extends Transform {
|
|
21
21
|
bodyHash: crypto.Hash;
|
|
22
22
|
/** Bytes of the original body seen so far */
|
|
23
23
|
byteLength: number;
|
|
@@ -25,3 +25,12 @@ export default class RelaxedBody extends Transform {
|
|
|
25
25
|
constructor(options?: RelaxedBodyOptions);
|
|
26
26
|
updateHash(chunk: Buffer, final?: boolean): void;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Type aliases in the layout of @types/nodemailer, so `RelaxedBody.Options` style references keep working
|
|
30
|
+
*/
|
|
31
|
+
declare namespace RelaxedBody {
|
|
32
|
+
type Options = RelaxedBodyOptions;
|
|
33
|
+
}
|
|
34
|
+
/** The same alias as a module level export, for `import * as RelaxedBody` and `import RelaxedBody = require()` */
|
|
35
|
+
export type { RelaxedBodyOptions as Options };
|
|
36
|
+
export default RelaxedBody;
|
|
@@ -16,7 +16,7 @@ const EMPTY_LINES = Buffer.alloc(4096, CRLF);
|
|
|
16
16
|
* a non-empty body always ends with CRLF. Bytes are canonicalized as they arrive,
|
|
17
17
|
* so a line of any length costs constant memory.
|
|
18
18
|
*/
|
|
19
|
-
|
|
19
|
+
class RelaxedBody extends Transform {
|
|
20
20
|
constructor(options) {
|
|
21
21
|
super();
|
|
22
22
|
options = options || {};
|
|
@@ -138,3 +138,4 @@ export default class RelaxedBody extends Transform {
|
|
|
138
138
|
callback();
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
+
export default RelaxedBody;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
+
import type { NodemailerError } from '../errors.js';
|
|
2
3
|
import type { MessageParserHeaderLine } from './message-parser.js';
|
|
3
4
|
/**
|
|
4
5
|
* Private key accepted by crypto.Sign#sign: a PEM string, a Buffer, a KeyObject or an
|
|
@@ -35,6 +36,7 @@ export interface DKIMRelaxedHeaders {
|
|
|
35
36
|
* Returns DKIM signature header line
|
|
36
37
|
*
|
|
37
38
|
* @param headers Parsed headers object from MessageParser
|
|
39
|
+
* @param hashAlgo Hash algorithm the body hash was calculated with, for example "sha256"
|
|
38
40
|
* @param bodyHash Base64 encoded hash of the message
|
|
39
41
|
* @param options DKIM options
|
|
40
42
|
* @param options.domainName Domain name to be signed for
|
|
@@ -45,5 +47,6 @@ export interface DKIMRelaxedHeaders {
|
|
|
45
47
|
declare function sign(headers: MessageParserHeaderLine[], hashAlgo: string, bodyHash: string, options?: DKIMSignOptions): string | false;
|
|
46
48
|
declare namespace sign {
|
|
47
49
|
var relaxedHeaders: (headers: MessageParserHeaderLine[], fieldNames?: string, skipFields?: string) => DKIMRelaxedHeaders;
|
|
50
|
+
var unsupportedHashAlgoError: (hashAlgo: string) => NodemailerError;
|
|
48
51
|
}
|
|
49
52
|
export default sign;
|