mirror of
https://github.com/dawidd6/action-send-mail.git
synced 2026-10-23 06:55:45 +07:00
node_modules: update (#352)
Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com>
This commit is contained in:
1 parent
4026a70a6b
commit
47af4a10b5
53 files changed
+630
-217
No files matched your search
+1
-1
@@ -9,7 +9,7 @@ import * as errors from '../errors.js';
|
||||
// never sends \r\n\r\n cannot grow memory unboundedly before the socket times out.
|
||||
const MAX_RESPONSE_HEADER_BYTES = 64 * 1024;
|
||||
// URL hostnames keep the brackets around an IPv6 literal, socket options and net.isIPv6 take it without
|
||||
const unbracket = (host) => typeof host === 'string' && host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host;
|
||||
const unbracket = (host) => (typeof host === 'string' && host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host);
|
||||
function httpProxyClient(proxyUrl, destinationPort, destinationHost, tlsOptions, callback) {
|
||||
if (typeof tlsOptions === 'function') {
|
||||
callback = tlsOptions;
|
||||
|
||||
+6
@@ -245,6 +245,12 @@ export interface SMTPConnectionSendInfo extends SMTPConnectionEnvelopeInfo {
|
||||
messageSize: number;
|
||||
/** Final server response for the message */
|
||||
response: string;
|
||||
/**
|
||||
* Message-ID the server gave the message, with angle brackets, when its final reply names
|
||||
* one in a known format (Microsoft 365 and Outlook.com, Amazon SES). Such a server replaces
|
||||
* the Message-ID header, so the delivered copy carries this id instead of messageId
|
||||
*/
|
||||
serverMessageId?: string | undefined;
|
||||
}
|
||||
/**
|
||||
* Callback for send(), receives the result once the server accepted the message. The error
|
||||
|
||||
+16
-13
@@ -7,7 +7,8 @@ import crypto from 'node:crypto';
|
||||
import DataStream from './data-stream.js';
|
||||
import { PassThrough } from 'node:stream';
|
||||
import * as shared from '../shared/index.js';
|
||||
import { ERR_ACCESS_DENIED, isTransientError } from '../errors.js';
|
||||
import { parseServerMessageId } from './server-message-id.js';
|
||||
import { ERR_ACCESS_DENIED, isPermanentResponseCode, isTransientError } from '../errors.js';
|
||||
// default timeout values in ms
|
||||
const CONNECTION_TIMEOUT = 2 * 60 * 1000; // how much to wait for the connection to be established
|
||||
const SOCKET_TIMEOUT = 10 * 60 * 1000; // how much to wait for socket inactivity before disconnecting the client
|
||||
@@ -361,9 +362,7 @@ class SMTPConnection extends EventEmitter {
|
||||
if (this._destroyed || this._closing) {
|
||||
return;
|
||||
}
|
||||
const connectFn = secure
|
||||
? tls.connect
|
||||
: net.connect;
|
||||
const connectFn = secure ? tls.connect : net.connect;
|
||||
try {
|
||||
this._socket = connectFn(opts, () => this._onConnect());
|
||||
this._setupConnectionHandlers();
|
||||
@@ -701,6 +700,16 @@ class SMTPConnection extends EventEmitter {
|
||||
result.messageTime = Date.now() - envelopeTime;
|
||||
result.messageSize = stream.outByteCount;
|
||||
result.response = str;
|
||||
const serverMessageId = parseServerMessageId(result.response, this.options.host);
|
||||
if (serverMessageId) {
|
||||
result.serverMessageId = serverMessageId;
|
||||
}
|
||||
// an LMTP server answers the message once per recipient, so recipients can be
|
||||
// refused after the envelope info was built without any rejected errors on it
|
||||
const rejectedErrors = this._envelope?.rejectedErrors;
|
||||
if (!result.rejectedErrors && rejectedErrors && rejectedErrors.length) {
|
||||
result.rejectedErrors = rejectedErrors;
|
||||
}
|
||||
return callback(null, result);
|
||||
});
|
||||
if (typeof message.pipe === 'function') {
|
||||
@@ -928,6 +937,7 @@ class SMTPConnection extends EventEmitter {
|
||||
const responseCode = (typeof response === 'string' && Number((response.match(/^\d+/) || [])[0])) || false;
|
||||
if (responseCode) {
|
||||
err.responseCode = responseCode;
|
||||
err.permanent = isPermanentResponseCode(responseCode);
|
||||
}
|
||||
if (command) {
|
||||
err.command = command;
|
||||
@@ -970,12 +980,7 @@ class SMTPConnection extends EventEmitter {
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
if (!failureResponse &&
|
||||
this.stage === 'connected' &&
|
||||
!this._responseActions.length &&
|
||||
!this._pendingSend &&
|
||||
!this._destroyed &&
|
||||
!this._closing) {
|
||||
if (!failureResponse && this.stage === 'connected' && !this._responseActions.length && !this._pendingSend && !this._destroyed && !this._closing) {
|
||||
// nothing was waiting for the server, so this is the server ending an idle session
|
||||
// (usually after its idle timeout), not a failure
|
||||
this.logger.info({
|
||||
@@ -1196,9 +1201,7 @@ class SMTPConnection extends EventEmitter {
|
||||
const args = [];
|
||||
let useSmtpUtf8 = false;
|
||||
this._envelope = (envelope || {});
|
||||
this._envelope.from = ((this._envelope.from && this._envelope.from.address) || this._envelope.from || '')
|
||||
.toString()
|
||||
.trim();
|
||||
this._envelope.from = ((this._envelope.from && this._envelope.from.address) || this._envelope.from || '').toString().trim();
|
||||
this._envelope.to = []
|
||||
.concat(this._envelope.to || [])
|
||||
.map(to => ((to && to.address) || to || '').toString().trim());
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Reads the Message-ID a receiving server gave the message out of its final 250 reply. Some
|
||||
* servers replace the Message-ID header of a submitted message with one of their own, and
|
||||
* the copy the recipients and the sent folder get carries that one instead of the id the
|
||||
* message was built with. Only replies in a format known to carry such an id are read.
|
||||
*/
|
||||
/**
|
||||
* Reads the server assigned Message-ID out of the final reply to a message
|
||||
*
|
||||
* @param response Final server reply for the message
|
||||
* @param [host] Hostname the connection was made to, SES replies are only read for an SES host
|
||||
* @returns The Message-ID with its angle brackets, or undefined when the reply names none
|
||||
*/
|
||||
export declare function parseServerMessageId(response: string | undefined, host?: string): string | undefined;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Reads the Message-ID a receiving server gave the message out of its final 250 reply. Some
|
||||
* servers replace the Message-ID header of a submitted message with one of their own, and
|
||||
* the copy the recipients and the sent folder get carries that one instead of the id the
|
||||
* message was built with. Only replies in a format known to carry such an id are read.
|
||||
*/
|
||||
// Microsoft 365 and Outlook.com: "250 2.0.0 OK <id@host.prod.outlook.com> [Hostname=...]"
|
||||
const OUTLOOK_REPLY = /^250 2\.0\.0 OK (<[^<>\s]+\.prod\.outlook\.com>)/i;
|
||||
// Amazon SES: "250 Ok 0100018b5c3c0a4f-...-000000", the local part of the Message-ID it sets
|
||||
const SES_REPLY = /^250 Ok ([0-9a-f]+(?:-[0-9a-f]+)+)$/i;
|
||||
// an AWS region name such as us-east-1 or ap-southeast-2
|
||||
const AWS_REGION = /^[a-z]{2}(?:-[a-z]+)+-\d+$/;
|
||||
/**
|
||||
* Finds the AWS region an SES SMTP endpoint is in from its hostname, such as
|
||||
* email-smtp.eu-west-1.amazonaws.com or a VPC endpoint name under it
|
||||
*
|
||||
* @param host SMTP hostname
|
||||
* @returns Region name, or undefined for a host outside amazonaws.com and awsapps.com
|
||||
*/
|
||||
function sesRegion(host) {
|
||||
const labels = host.toLowerCase().replace(/\.$/, '').split('.');
|
||||
const domain = labels.slice(-2).join('.');
|
||||
if (domain !== 'amazonaws.com' && domain !== 'awsapps.com') {
|
||||
return undefined;
|
||||
}
|
||||
return labels.slice(0, -2).find(label => AWS_REGION.test(label));
|
||||
}
|
||||
/**
|
||||
* Reads the server assigned Message-ID out of the final reply to a message
|
||||
*
|
||||
* @param response Final server reply for the message
|
||||
* @param [host] Hostname the connection was made to, SES replies are only read for an SES host
|
||||
* @returns The Message-ID with its angle brackets, or undefined when the reply names none
|
||||
*/
|
||||
export function parseServerMessageId(response, host) {
|
||||
const reply = (response || '').toString().trim();
|
||||
const outlook = reply.match(OUTLOOK_REPLY);
|
||||
if (outlook) {
|
||||
return outlook[1];
|
||||
}
|
||||
const ses = reply.match(SES_REPLY);
|
||||
if (ses && host) {
|
||||
const region = sesRegion(host);
|
||||
if (region) {
|
||||
// the SES Message-ID domain is email.amazonses.com in us-east-1 and the region elsewhere
|
||||
return '<' + ses[1].toLowerCase() + '@' + (region === 'us-east-1' ? 'email' : region) + '.amazonses.com>';
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
Reference in new issue
Block a user