node_modules: update (#322)

Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com>
This commit is contained in:
Dawid Dziurla
2026-09-15 13:00:32 +02:00
committed by GitHub
parent 4a3d0f9ca3
commit 67ce3558d6
174 changed files with 25661 additions and 5540 deletions
+14
View File
@@ -0,0 +1,14 @@
import { Transform, type TransformOptions } from 'node:stream';
/**
* Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
* Also makes sure that only <CR><LF> sequences are used for linebreaks
*
* @param options Stream options
*/
export default class DataStream extends Transform {
options: TransformOptions;
inByteCount: number;
outByteCount: number;
lastByte: number | false;
constructor(options?: TransformOptions);
}
+100
View File
@@ -0,0 +1,100 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const node_stream_1 = require("node:stream");
/**
* Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
* Also makes sure that only <CR><LF> sequences are used for linebreaks
*
* @param options Stream options
*/
class DataStream extends node_stream_1.Transform {
constructor(options) {
super(options);
this.options = options || {};
this.inByteCount = 0;
this.outByteCount = 0;
this.lastByte = false;
}
/**
* Escapes dots
* @internal
*/
_transform(chunk, encoding, done) {
const chunks = [];
let chunklen = 0;
let i, len, lastPos = 0;
let buf;
if (!chunk || !chunk.length) {
return done();
}
if (typeof chunk === 'string') {
chunk = Buffer.from(chunk);
}
this.inByteCount += chunk.length;
for (i = 0, len = chunk.length; i < len; i++) {
if (chunk[i] === 0x2e) {
// .
if ((i && chunk[i - 1] === 0x0a) || (!i && (!this.lastByte || this.lastByte === 0x0a))) {
buf = chunk.slice(lastPos, i + 1);
chunks.push(buf);
chunks.push(Buffer.from('.'));
chunklen += buf.length + 1;
lastPos = i + 1;
}
}
else if (chunk[i] === 0x0a) {
// \n
if ((i && chunk[i - 1] !== 0x0d) || (!i && this.lastByte !== 0x0d)) {
if (i > lastPos) {
buf = chunk.slice(lastPos, i);
chunks.push(buf);
chunklen += buf.length + 2;
}
else {
chunklen += 2;
}
chunks.push(Buffer.from('\r\n'));
lastPos = i + 1;
}
}
}
if (chunklen) {
// add last piece
if (lastPos < chunk.length) {
buf = chunk.slice(lastPos);
chunks.push(buf);
chunklen += buf.length;
}
this.outByteCount += chunklen;
this.push(Buffer.concat(chunks, chunklen));
}
else {
this.outByteCount += chunk.length;
this.push(chunk);
}
this.lastByte = chunk[chunk.length - 1];
done();
}
/**
* Finalizes the stream with a dot on a single line
* @internal
*/
_flush(done) {
let buf;
if (this.lastByte === 0x0a) {
buf = Buffer.from('.\r\n');
}
else if (this.lastByte === 0x0d) {
buf = Buffer.from('\n.\r\n');
}
else {
buf = Buffer.from('\r\n.\r\n');
}
this.outByteCount += buf.length;
this.push(buf);
done();
}
}
exports.default = DataStream;
module.exports = exports.default;
Object.defineProperty(module.exports, 'default', { value: exports.default, enumerable: false, writable: true, configurable: true });
@@ -0,0 +1,39 @@
/**
* Minimal HTTP/S proxy client
*/
import net from 'node:net';
import type { NodemailerError } from '../errors.js';
/**
* TLS options for connecting to an HTTPS proxy
*/
export interface HttpProxyClientOptions {
/** Set to false to accept a proxy certificate that fails validation (e.g. self-signed) */
rejectUnauthorized?: boolean | undefined;
}
/**
* Receives the proxied socket once the CONNECT handshake has succeeded, or the error that prevented it
*/
export type HttpProxyClientCallback = (err: NodemailerError | null, socket?: net.Socket) => void;
/**
* Establishes proxied connection to destinationPort
*
* httpProxyClient("http://localhost:3128/", 80, "google.com", function(err, socket){
* socket.write("GET / HTTP/1.0\r\n\r\n");
* });
*
* @param proxyUrl proxy configuration, etg "http://proxy.host:3128/"
* @param destinationPort Port to open in destination host
* @param destinationHost Destination hostname
* @param [tlsOptions] Optional TLS options for an HTTPS proxy (e.g. { rejectUnauthorized: false })
* @param callback Callback to run with the rocket object once connection is established
*/
declare function httpProxyClient(proxyUrl: string, destinationPort: number | string, destinationHost: string, callback: HttpProxyClientCallback): void;
declare function httpProxyClient(proxyUrl: string, destinationPort: number | string, destinationHost: string, tlsOptions: HttpProxyClientOptions | undefined, callback: HttpProxyClientCallback): void;
/**
* Socket timeout in milliseconds while the CONNECT handshake is in progress, defaults to 30 seconds.
* Settable on the function itself, the same way the CommonJS module exposed it.
*/
declare namespace httpProxyClient {
let timeout: number | undefined;
}
export default httpProxyClient;
+177
View File
@@ -0,0 +1,177 @@
"use strict";
/**
* Minimal HTTP/S proxy client
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_net_1 = __importDefault(require("node:net"));
const node_tls_1 = __importDefault(require("node:tls"));
const urllib = __importStar(require("../shared/url.js"));
const errors = __importStar(require("../errors.js"));
// Cap the CONNECT response we buffer before the header terminator, so a proxy that
// never sends \r\n\r\n cannot grow memory unboundedly before the socket times out.
const MAX_RESPONSE_HEADER_BYTES = 64 * 1024;
function httpProxyClient(proxyUrl, destinationPort, destinationHost, tlsOptions, callback) {
if (typeof tlsOptions === 'function') {
callback = tlsOptions;
tlsOptions = {};
}
tlsOptions = tlsOptions || {};
// Reject CRLF in the destination before it reaches the CONNECT request line
// and Host header. A tainted host/port could otherwise inject additional
// request headers into the proxy connection (HTTP request splitting).
destinationPort = Number(destinationPort) || 0;
if (!destinationPort || /[\r\n]/.test(destinationHost)) {
const err = new Error('Invalid proxy destination');
err.code = errors.EPROXY;
setImmediate(() => callback(err));
return;
}
const proxy = urllib.parse(proxyUrl);
const connectOptions = {
host: proxy.hostname,
port: Number(proxy.port) ? Number(proxy.port) : proxy.protocol === 'https:' ? 443 : 80
};
let connect;
if (proxy.protocol === 'https:') {
// Validate the proxy's TLS certificate by default. A caller that uses a
// self-signed proxy (e.g. integration tests) opts out explicitly with
// tls.rejectUnauthorized === false.
connectOptions.rejectUnauthorized = tlsOptions.rejectUnauthorized !== false;
connect = node_tls_1.default.connect.bind(node_tls_1.default);
}
else {
connect = node_net_1.default.connect.bind(node_net_1.default);
}
let socket;
// Error harness for initial connection. Once connection is established, the responsibility
// to handle errors is passed to whoever uses this socket
let finished = false;
const tempSocketErr = (err) => {
if (finished) {
return;
}
finished = true;
try {
socket.destroy();
}
catch (_E) {
// ignore
}
callback(err);
};
const timeoutErr = () => {
const err = new Error('Proxy socket timed out');
err.code = 'ETIMEDOUT';
tempSocketErr(err);
};
socket = connect(connectOptions, () => {
if (finished) {
return;
}
const reqHeaders = {
Host: destinationHost + ':' + destinationPort,
Connection: 'close'
};
if (proxy.auth) {
reqHeaders['Proxy-Authorization'] = 'Basic ' + Buffer.from(proxy.auth).toString('base64');
}
socket.write(
// HTTP method
'CONNECT ' +
destinationHost +
':' +
destinationPort +
' HTTP/1.1\r\n' +
// HTTP request headers
Object.keys(reqHeaders)
.map(key => key + ': ' + reqHeaders[key])
.join('\r\n') +
// End request
'\r\n\r\n');
let headers = '';
const onSocketData = (chunk) => {
let match;
let remainder;
if (finished) {
return;
}
headers += chunk.toString('binary');
if ((match = headers.match(/\r\n\r\n/))) {
socket.removeListener('data', onSocketData);
remainder = headers.substr(match.index + match[0].length);
headers = headers.substr(0, match.index);
if (remainder) {
socket.unshift(Buffer.from(remainder, 'binary'));
}
// proxy connection is now established
finished = true;
// check response code
match = headers.match(/^HTTP\/\d+\.\d+ (\d+)/i);
if (!match || (match[1] || '').charAt(0) !== '2') {
try {
socket.destroy();
}
catch (_E) {
// ignore
}
const err = new Error('Invalid response from proxy' + ((match && ': ' + match[1]) || ''));
err.code = errors.EPROXY;
return callback(err);
}
socket.removeListener('error', tempSocketErr);
socket.removeListener('timeout', timeoutErr);
socket.setTimeout(0);
return callback(null, socket);
}
if (headers.length > MAX_RESPONSE_HEADER_BYTES) {
socket.removeListener('data', onSocketData);
const err = new Error('Proxy response headers too large');
err.code = errors.EPROXY;
return tempSocketErr(err);
}
};
socket.on('data', onSocketData);
});
socket.setTimeout(httpProxyClient.timeout || 30 * 1000);
socket.on('timeout', timeoutErr);
socket.once('error', tempSocketErr);
}
exports.default = httpProxyClient;
module.exports = exports.default;
Object.defineProperty(module.exports, 'default', { value: exports.default, enumerable: false, writable: true, configurable: true });
+378
View File
@@ -0,0 +1,378 @@
import { EventEmitter } from 'node:events';
import net from 'node:net';
import tls from 'node:tls';
import { type Readable } from 'node:stream';
import * as shared from '../shared/index.js';
import type { NodemailerError } from '../errors.js';
import type XOAuth2 from '../xoauth2/index.js';
/**
* Custom authentication handlers keyed by (case insensitive) SASL method name
*/
export type SMTPConnectionCustomAuthHandlers = {
[method: string]: SMTPConnectionCustomAuthHandler;
};
/**
* Options for the SMTP connection, see the SMTPConnection class description
*/
export interface SMTPConnectionOptions {
/** Port to connect to, defaults to 587, or to 465 when secure is set */
port?: number | string | undefined;
/** Hostname or IP address to connect to, defaults to 'localhost' */
host?: string | undefined;
/** Use TLS from the start */
secure?: boolean | undefined;
/** Marks the provided socket as already upgraded to TLS */
secured?: boolean | undefined;
/** Server name for SNI, defaults to host when that is not an IP address */
servername?: string | undefined;
/** Ignore STARTTLS even when the server advertises it */
ignoreTLS?: boolean | undefined;
/** Force STARTTLS, fail when the server does not support it */
requireTLS?: boolean | undefined;
/** Continue unencrypted when the STARTTLS upgrade fails */
opportunisticTLS?: boolean | undefined;
/** Name of the client server, sent with EHLO/HELO, CRLF is stripped */
name?: string | undefined;
/** Outbound address to bind to */
localAddress?: string | undefined;
/** Time to wait in ms for the connection to establish, defaults to 2 minutes */
connectionTimeout?: number | undefined;
/** Time to wait in ms until the greeting is received, defaults to 30 seconds */
greetingTimeout?: number | undefined;
/** Time of inactivity in ms until the connection is closed, defaults to 10 minutes */
socketTimeout?: number | undefined;
/** Time to wait in ms for the DNS requests to be resolved, defaults to 30 seconds */
dnsTimeout?: number | undefined;
/** Use LMTP instead of SMTP */
lmtp?: boolean | undefined;
/** Bunyan compatible logger interface, true for the default console logger */
logger?: shared.ExternalLogger | boolean | undefined;
/** Pass SMTP traffic, including the message data, to the logger */
debug?: boolean | undefined;
/** Pass SMTP commands and responses to the logger */
transactionLog?: boolean | undefined;
/** Options for tls.connect */
tls?: tls.ConnectionOptions | undefined;
/** Existing socket to use instead of creating a new one, not connected yet */
socket?: net.Socket | undefined;
/** Already opened connection to use instead of creating a new one */
connection?: net.Socket | undefined;
/** Count loopback interfaces when checking which address families are usable */
allowInternalNetworkInterfaces?: boolean | undefined;
/** Logger component name, defaults to 'smtp-connection' */
component?: string | undefined;
/** Custom authentication handlers keyed by method name */
customAuth?: SMTPConnectionCustomAuthHandlers | undefined;
}
/**
* User and password credentials resolved for a SASL mechanism
*/
export interface SMTPConnectionCredentials {
user?: string | undefined;
pass?: string | undefined;
/** Extra options for the authentication method, copied from the auth object */
options?: {
[key: string]: any;
} | undefined;
}
/**
* Authentication data for login()
*/
export interface SMTPConnectionAuth {
/** Authentication type, informational */
type?: string | undefined;
/** SASL method to use, false or unset picks the first supported one (PLAIN if none is advertised) */
method?: string | false | undefined;
user?: string | undefined;
pass?: string | undefined;
/** Extra options for the authentication method */
options?: {
[key: string]: any;
} | undefined;
/** XOAuth2 token generator, selects XOAUTH2 when no method is set */
oauth2?: XOAuth2 | undefined;
/** Credentials for the SASL mechanism, filled in from user and pass when missing */
credentials?: SMTPConnectionCredentials | undefined;
/** Custom authentication handlers receive the auth object as is, so it may carry any other value */
[key: string]: any;
}
/**
* A parsed server reply, handed to the sendCommand callback of a custom authentication handler
*/
export interface SMTPConnectionCustomAuthResponse {
/** The command that was sent */
command: string;
/** Raw server response */
response: string;
/** Numeric status code, 0 if the response did not start with one */
status: number;
/** Enhanced status code, if any */
code?: string | undefined;
/** Response text without the status codes */
text: string;
}
/**
* Callback for a command sent by a custom authentication handler
*/
export type SMTPConnectionCustomAuthCommandCallback = (err: Error | null, data: SMTPConnectionCustomAuthResponse) => void;
/**
* The object a custom authentication handler is run with
*/
export interface SMTPConnectionCustomAuthContext {
/** The auth object handed to login() */
auth: SMTPConnectionAuth;
/** Selected authentication method name */
method: string;
/** SMTP extensions the server advertised */
extensions: string[];
/** SASL methods the server advertised */
authMethods: string[];
/** Maximum message size the server accepts, false when not advertised */
maxAllowedSize: number | false;
/** Sends a command to the server. Returns a promise when no callback is given */
sendCommand(cmd: string, done?: SMTPConnectionCustomAuthCommandCallback): Promise<SMTPConnectionCustomAuthResponse> | undefined;
/** Marks the user as authenticated */
resolve(): void;
/** Fails the authentication with an error */
reject(err: Error | string): void;
}
/**
* A custom authentication handler. Calls resolve() or reject() on the context, or returns a promise
*/
export type SMTPConnectionCustomAuthHandler = (ctx: SMTPConnectionCustomAuthContext) => void | Promise<unknown>;
/**
* An envelope address, either a plain string or an object with an address property
*/
export interface SMTPEnvelopeAddress {
address?: string | undefined;
name?: string | undefined;
}
/**
* DSN parameters for the envelope (RFC 3461)
*/
export interface SMTPEnvelopeDsn {
/** Return either 'HDRS' (headers) or 'FULL' (body) with the notification */
ret?: string | null | undefined;
/** Alias of ret */
return?: string | undefined;
/** Envelope identifier, sent as ENVID */
envid?: string | null | undefined;
/** Alias of envid */
id?: string | undefined;
/** When to notify: 'NEVER', or any combination of 'SUCCESS', 'FAILURE' and 'DELAY' */
notify?: string | string[] | null | undefined;
/** Original recipient, sent as ORCPT */
recipient?: string | undefined;
/** Alias of recipient, in the 'rfc822;address' form */
orcpt?: string | null | undefined;
}
/**
* Envelope object accepted by send()
*/
export interface SMTPEnvelope {
/** Sender address */
from?: string | SMTPEnvelopeAddress | undefined;
/** Recipient address or addresses */
to?: string | SMTPEnvelopeAddress | Array<string | SMTPEnvelopeAddress> | undefined;
/** Message size in bytes, sent as the SIZE parameter when the server supports it */
size?: number | string | undefined;
/** DSN parameters, sent when the server supports the DSN extension */
dsn?: SMTPEnvelopeDsn | undefined;
/** Declare BODY=8BITMIME when the server supports it */
use8BitMime?: boolean | undefined;
/** RFC 8689: send the REQUIRETLS parameter, requires a TLS connection and server support */
requireTLSExtensionEnabled?: boolean | undefined;
}
/**
* The envelope as tracked by the connection while a message is being sent. The from and to
* values are normalized to strings and the recipient bookkeeping is added by _setEnvelope
*/
export interface SMTPConnectionEnvelope extends SMTPEnvelope {
from?: string | undefined;
to?: string[] | undefined;
/** Recipients still waiting for RCPT TO */
rcptQueue: string[];
/** Recipients the server rejected */
rejected: string[];
/** Errors for the rejected recipients */
rejectedErrors: NodemailerError[];
/** Recipients the server accepted */
accepted: string[];
}
/**
* Result of a sent message
*/
export interface SMTPConnectionSendInfo {
/** Recipients the server accepted */
accepted: string[];
/** Recipients the server rejected */
rejected: string[];
/** EHLO response lines, without the greeting line */
ehlo?: string[] | undefined;
/** Errors for the rejected recipients */
rejectedErrors?: NodemailerError[] | undefined;
/** Time in ms spent on the envelope commands */
envelopeTime?: number | undefined;
/** Time in ms spent on streaming the message */
messageTime?: number | undefined;
/** Size of the encoded message in bytes */
messageSize?: number | undefined;
/** Final server response for the message */
response?: string | undefined;
}
/**
* Callback for send()
*/
export type SMTPConnectionSendCallback = (err: NodemailerError | null, info?: SMTPConnectionSendInfo) => void;
/**
* Callback for login() and reset(), the result is true on success
*/
export type SMTPConnectionCallback = (err: NodemailerError | null, result?: boolean) => void;
/**
* Callback for the message data response, yields the server response text
*/
export type SMTPConnectionResponseCallback = (err: NodemailerError | null, response?: string) => void;
/**
* Callback for connect(), run once the SMTP handshake is finished
*/
export type SMTPConnectionConnectCallback = (err?: NodemailerError) => void;
/**
* Options handed to net.connect or tls.connect, resolved hostname values are merged in
*/
export interface SMTPConnectionConnectOptions extends tls.ConnectionOptions {
port: number;
host: string;
/** Outbound address to bind to */
localAddress?: string | undefined;
/** Count loopback interfaces when resolving the hostname */
allowInternalNetworkInterfaces?: boolean | undefined;
/** DNS lookup timeout in ms */
timeout?: number | undefined;
}
/**
* A queued handler for the next server response
*/
export type SMTPConnectionResponseAction = (str: string) => void;
/**
* Generates a SMTP connection object
*
* Optional options object takes the following possible properties:
*
* * **port** - is the port to connect to (defaults to 587 or 465)
* * **host** - is the hostname or IP address to connect to (defaults to 'localhost')
* * **secure** - use SSL
* * **ignoreTLS** - ignore server support for STARTTLS
* * **requireTLS** - forces the client to use STARTTLS
* * **name** - the name of the client server
* * **localAddress** - outbound address to bind to (see: http://nodejs.org/api/net.html#net_net_connect_options_connectionlistener)
* * **greetingTimeout** - Time to wait in ms until greeting message is received from the server (defaults to 30 seconds)
* * **connectionTimeout** - how many milliseconds to wait for the connection to establish (defaults to 2 minutes)
* * **socketTimeout** - Time of inactivity until the connection is closed (defaults to 10 minutes)
* * **dnsTimeout** - Time to wait in ms for the DNS requests to be resolved (defaults to 30 seconds)
* * **lmtp** - if true, uses LMTP instead of SMTP protocol
* * **logger** - bunyan compatible logger interface
* * **debug** - if true pass SMTP traffic to the logger
* * **tls** - options for createCredentials
* * **socket** - existing socket to use instead of creating a new one (see: http://nodejs.org/api/net.html#net_class_net_socket)
* * **secured** - boolean indicates that the provided socket has already been upgraded to tls
*
* @constructor
* @namespace SMTP Client module
* @param [options] Option properties
*/
declare class SMTPConnection extends EventEmitter {
id: string;
stage: string;
options: SMTPConnectionOptions;
secureConnection: boolean;
alreadySecured: boolean;
port: number;
host: string;
servername: string | false;
allowInternalNetworkInterfaces: boolean;
name: string;
logger: shared.Logger;
customAuth: Map<string, SMTPConnectionCustomAuthHandler>;
/**
* Expose version nr, just for the reference
*/
version: string;
/**
* If true, then the user is authenticated
*/
authenticated: boolean;
/**
* If set to true, this instance is no longer active
* @private
*/
destroyed: boolean;
/**
* Defines if the current connection is secure or not. If not,
* STARTTLS can be used if available
* @private
*/
secure: boolean;
lastServerResponse: string | false;
/**
* The socket connecting to the server
* @public
*/
_socket: net.Socket | false | null;
/**
* Set to true, if EHLO response includes "AUTH".
* If false then authentication is not tried
*/
allowsAuth: boolean;
/**
* True while the STARTTLS upgrade is in progress
* @private
*/
upgrading?: boolean | undefined;
constructor(options?: SMTPConnectionOptions);
/**
* Creates a connection to a SMTP server and sets up connection
* listener
*/
connect(connectCallback?: SMTPConnectionConnectCallback): void;
/**
* Sends QUIT
*/
quit(): void;
/**
* Closes the connection to the server
*/
close(): void;
/**
* Authenticate user
*/
login(authData: SMTPConnectionAuth | undefined, callback: SMTPConnectionCallback): void;
/**
* Sends a message
*
* @param envelope Envelope object, {from: addr, to: [addr]}
* @param message String, Buffer or a Stream
* @param callback Callback to return once sending is completed
*/
send(envelope: SMTPEnvelope, message: string | Buffer | Readable, done: SMTPConnectionSendCallback): void;
/**
* Resets connection state
*
* @param callback Callback to return once connection is reset
*/
reset(callback: SMTPConnectionCallback): void;
}
/**
* Type aliases in the layout of @types/nodemailer, so `SMTPConnection.Options` style references keep working
*/
declare namespace SMTPConnection {
type Options = SMTPConnectionOptions;
type AuthenticationType = SMTPConnectionAuth;
type Credentials = SMTPConnectionCredentials;
type Envelope = SMTPEnvelope;
type DSNOptions = SMTPEnvelopeDsn;
type SentMessageInfo = SMTPConnectionSendInfo;
type CustomAuthenticationContext = SMTPConnectionCustomAuthContext;
type CustomAuthenticationResponse = SMTPConnectionCustomAuthResponse;
type CustomAuthenticationHandlers = SMTPConnectionCustomAuthHandlers;
}
export default SMTPConnection;
File diff suppressed because it is too large Load Diff