mirror of https://github.com/eleith/emailjs.git
Compare commits
No commits in common. "99bdf2fb14c8bde0c61f687ef4a0421a42282968" and "c1c4d0b81b0ddeab7b177deec701afefe6255ae0" have entirely different histories.
99bdf2fb14
...
c1c4d0b81b
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -4,18 +4,6 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [3.4.0] - 2020-12-01
|
||||
### Added
|
||||
- `SMTPClient#sendAsync` API [#267](https://github.com/eleith/emailjs/issues/267)
|
||||
- `isRFC2822Date` API
|
||||
|
||||
### Changed
|
||||
- use `WeakSet` instead of `WeakMap` for greylist tracking
|
||||
|
||||
### Fixed
|
||||
- use camelCase style for internal function names
|
||||
- use correct types in jsdoc comments
|
||||
|
||||
## [3.3.0] - 2020-08-08
|
||||
### Added
|
||||
- greylist support [#202](https://github.com/eleith/emailjs/issues/202)
|
||||
|
|
27
README.md
27
README.md
|
@ -50,33 +50,6 @@ client.send(
|
|||
);
|
||||
```
|
||||
|
||||
## EXAMPLE USAGE - using async/await
|
||||
|
||||
```js
|
||||
// assuming top-level await for brevity
|
||||
import { SMTPClient } from 'emailjs';
|
||||
|
||||
const client = new SMTPClient({
|
||||
user: 'user',
|
||||
password: 'password',
|
||||
host: 'smtp.your-email.com',
|
||||
ssl: true,
|
||||
});
|
||||
|
||||
try {
|
||||
const message = await client.sendAsync({
|
||||
text: 'i hope this works',
|
||||
from: 'you <username@your-email.com>',
|
||||
to: 'someone <someone@your-email.com>, another <another@your-email.com>',
|
||||
cc: 'else <else@your-email.com>',
|
||||
subject: 'testing emailjs',
|
||||
});
|
||||
console.log(message);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
```
|
||||
|
||||
## EXAMPLE USAGE - html emails and attachments
|
||||
|
||||
```js
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "emailjs",
|
||||
"description": "send text/html emails and attachments (files, streams and strings) from node.js to any smtp server",
|
||||
"version": "3.4.0",
|
||||
"version": "3.3.0",
|
||||
"author": "eleith",
|
||||
"contributors": [
|
||||
"izuzak",
|
||||
|
|
197
rollup/email.cjs
197
rollup/email.cjs
|
@ -256,19 +256,6 @@ function getRFC2822DateUTC(date = new Date()) {
|
|||
dates.push('+0000');
|
||||
return dates.join(' ');
|
||||
}
|
||||
/**
|
||||
* RFC 2822 regex
|
||||
* @see https://tools.ietf.org/html/rfc2822#section-3.3
|
||||
* @see https://github.com/moment/moment/blob/a831fc7e2694281ce31e4f090bbcf90a690f0277/src/lib/create/from-string.js#L101
|
||||
*/
|
||||
const rfc2822re = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/.compile();
|
||||
/**
|
||||
* @param {string} [date] a string to check for conformance to the [rfc2822](https://tools.ietf.org/html/rfc2822#section-3.3) standard
|
||||
* @returns {boolean} the result of the conformance check
|
||||
*/
|
||||
function isRFC2822Date(date) {
|
||||
return rfc2822re.test(date);
|
||||
}
|
||||
|
||||
// adapted from https://github.com/emailjs/emailjs-mime-codec/blob/6909c706b9f09bc0e5c3faf48f723cca53e5b352/src/mimecodec.js
|
||||
const encoder = new util.TextEncoder();
|
||||
|
@ -471,7 +458,7 @@ const MIME64CHUNK = (MIMECHUNK * 6);
|
|||
*/
|
||||
const BUFFERSIZE = (MIMECHUNK * 24 * 7);
|
||||
let counter = 0;
|
||||
function generateBoundary() {
|
||||
function generate_boundary() {
|
||||
let text = '';
|
||||
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'()+_,-./:=?";
|
||||
for (let i = 0; i < 69; i++) {
|
||||
|
@ -610,7 +597,7 @@ class Message {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @returns {MessageStream} a stream of the current message
|
||||
* @returns {*} a stream of the current message
|
||||
*/
|
||||
stream() {
|
||||
return new MessageStream(this);
|
||||
|
@ -630,7 +617,7 @@ class Message {
|
|||
}
|
||||
class MessageStream extends stream.Stream {
|
||||
/**
|
||||
* @param {Message} message the message to stream
|
||||
* @param {*} message the message to stream
|
||||
*/
|
||||
constructor(message) {
|
||||
super();
|
||||
|
@ -683,7 +670,7 @@ class MessageStream extends stream.Stream {
|
|||
* @param {MessageAttachment} [attachment] the attachment whose headers you would like to output
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputAttachmentHeaders = (attachment) => {
|
||||
const output_attachment_headers = (attachment) => {
|
||||
let data = [];
|
||||
const headers = {
|
||||
'content-type': attachment.type +
|
||||
|
@ -715,7 +702,7 @@ class MessageStream extends stream.Stream {
|
|||
* @param {function(): void} [callback] the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputBase64 = (data, callback) => {
|
||||
const output_base64 = (data, callback) => {
|
||||
const loops = Math.ceil(data.length / MIMECHUNK);
|
||||
let loop = 0;
|
||||
while (loop < loops) {
|
||||
|
@ -726,7 +713,7 @@ class MessageStream extends stream.Stream {
|
|||
callback();
|
||||
}
|
||||
};
|
||||
const outputFile = (attachment, next) => {
|
||||
const output_file = (attachment, next) => {
|
||||
const chunk = MIME64CHUNK * 16;
|
||||
const buffer = Buffer.alloc(chunk);
|
||||
const closed = (fd) => fs.closeSync(fd);
|
||||
|
@ -752,7 +739,7 @@ class MessageStream extends stream.Stream {
|
|||
encoding = 'base64';
|
||||
}
|
||||
// guaranteed to be encoded without padding unless it is our last read
|
||||
outputBase64(buffer.toString(encoding, 0, bytes), () => {
|
||||
output_base64(buffer.toString(encoding, 0, bytes), () => {
|
||||
if (bytes == chunk) {
|
||||
// we read a full chunk, there might be more
|
||||
fs.read(fd, buffer, 0, chunk, null, read);
|
||||
|
@ -781,13 +768,13 @@ class MessageStream extends stream.Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputStream = (attachment, callback) => {
|
||||
const output_stream = (attachment, callback) => {
|
||||
const { stream } = attachment;
|
||||
if (stream === null || stream === void 0 ? void 0 : stream.readable) {
|
||||
let previous = Buffer.alloc(0);
|
||||
stream.resume();
|
||||
stream.on('end', () => {
|
||||
outputBase64(previous.toString('base64'), callback);
|
||||
output_base64(previous.toString('base64'), callback);
|
||||
this.removeListener('pause', stream.pause);
|
||||
this.removeListener('resume', stream.resume);
|
||||
this.removeListener('error', stream.resume);
|
||||
|
@ -805,7 +792,7 @@ class MessageStream extends stream.Stream {
|
|||
// copy dangling bytes into previous buffer
|
||||
buffer.copy(previous, 0, buffer.length - padded);
|
||||
}
|
||||
outputBase64(buffer.toString('base64', 0, buffer.length - padded));
|
||||
output_base64(buffer.toString('base64', 0, buffer.length - padded));
|
||||
});
|
||||
this.on('pause', stream.pause);
|
||||
this.on('resume', stream.resume);
|
||||
|
@ -815,13 +802,13 @@ class MessageStream extends stream.Stream {
|
|||
this.emit('error', { message: 'stream not readable' });
|
||||
}
|
||||
};
|
||||
const outputAttachment = (attachment, callback) => {
|
||||
const output_attachment = (attachment, callback) => {
|
||||
const build = attachment.path
|
||||
? outputFile
|
||||
? output_file
|
||||
: attachment.stream
|
||||
? outputStream
|
||||
: outputData;
|
||||
outputAttachmentHeaders(attachment);
|
||||
? output_stream
|
||||
: output_data;
|
||||
output_attachment_headers(attachment);
|
||||
build(attachment, callback);
|
||||
};
|
||||
/**
|
||||
|
@ -831,14 +818,14 @@ class MessageStream extends stream.Stream {
|
|||
* @param {function(): void} callback the function to call if index is greater than upper bound
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputMessage = (boundary, list, index, callback) => {
|
||||
const output_message = (boundary, list, index, callback) => {
|
||||
if (index < list.length) {
|
||||
output(`--${boundary}${CRLF}`);
|
||||
if (list[index].related) {
|
||||
outputRelated(list[index], () => outputMessage(boundary, list, index + 1, callback));
|
||||
output_related(list[index], () => output_message(boundary, list, index + 1, callback));
|
||||
}
|
||||
else {
|
||||
outputAttachment(list[index], () => outputMessage(boundary, list, index + 1, callback));
|
||||
output_attachment(list[index], () => output_message(boundary, list, index + 1, callback));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -846,17 +833,17 @@ class MessageStream extends stream.Stream {
|
|||
callback();
|
||||
}
|
||||
};
|
||||
const outputMixed = () => {
|
||||
const boundary = generateBoundary();
|
||||
const output_mixed = () => {
|
||||
const boundary = generate_boundary();
|
||||
output(`Content-Type: multipart/mixed; boundary="${boundary}"${CRLF}${CRLF}--${boundary}${CRLF}`);
|
||||
if (this.message.alternative == null) {
|
||||
outputText(this.message);
|
||||
outputMessage(boundary, this.message.attachments, 0, close);
|
||||
output_text(this.message);
|
||||
output_message(boundary, this.message.attachments, 0, close);
|
||||
}
|
||||
else {
|
||||
outputAlternative(
|
||||
output_alternative(
|
||||
// typescript bug; should narrow to { alternative: MessageAttachment }
|
||||
this.message, () => outputMessage(boundary, this.message.attachments, 0, close));
|
||||
this.message, () => output_message(boundary, this.message.attachments, 0, close));
|
||||
}
|
||||
};
|
||||
/**
|
||||
|
@ -864,16 +851,16 @@ class MessageStream extends stream.Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputData = (attachment, callback) => {
|
||||
const output_data = (attachment, callback) => {
|
||||
var _a, _b;
|
||||
outputBase64(attachment.encoded
|
||||
output_base64(attachment.encoded
|
||||
? (_a = attachment.data) !== null && _a !== void 0 ? _a : '' : Buffer.from((_b = attachment.data) !== null && _b !== void 0 ? _b : '').toString('base64'), callback);
|
||||
};
|
||||
/**
|
||||
* @param {Message} message the message to output
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputText = (message) => {
|
||||
const output_text = (message) => {
|
||||
let data = [];
|
||||
data = data.concat([
|
||||
'Content-Type:',
|
||||
|
@ -891,12 +878,12 @@ class MessageStream extends stream.Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputRelated = (message, callback) => {
|
||||
const boundary = generateBoundary();
|
||||
const output_related = (message, callback) => {
|
||||
const boundary = generate_boundary();
|
||||
output(`Content-Type: multipart/related; boundary="${boundary}"${CRLF}${CRLF}--${boundary}${CRLF}`);
|
||||
outputAttachment(message, () => {
|
||||
output_attachment(message, () => {
|
||||
var _a;
|
||||
outputMessage(boundary, (_a = message.related) !== null && _a !== void 0 ? _a : [], 0, () => {
|
||||
output_message(boundary, (_a = message.related) !== null && _a !== void 0 ? _a : [], 0, () => {
|
||||
output(`${CRLF}--${boundary}--${CRLF}${CRLF}`);
|
||||
callback();
|
||||
});
|
||||
|
@ -907,10 +894,10 @@ class MessageStream extends stream.Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputAlternative = (message, callback) => {
|
||||
const boundary = generateBoundary();
|
||||
const output_alternative = (message, callback) => {
|
||||
const boundary = generate_boundary();
|
||||
output(`Content-Type: multipart/alternative; boundary="${boundary}"${CRLF}${CRLF}--${boundary}${CRLF}`);
|
||||
outputText(message);
|
||||
output_text(message);
|
||||
output(`--${boundary}${CRLF}`);
|
||||
/**
|
||||
* @returns {void}
|
||||
|
@ -920,10 +907,10 @@ class MessageStream extends stream.Stream {
|
|||
callback();
|
||||
};
|
||||
if (message.alternative.related) {
|
||||
outputRelated(message.alternative, finish);
|
||||
output_related(message.alternative, finish);
|
||||
}
|
||||
else {
|
||||
outputAttachment(message.alternative, finish);
|
||||
output_attachment(message.alternative, finish);
|
||||
}
|
||||
};
|
||||
const close = (err) => {
|
||||
|
@ -947,20 +934,20 @@ class MessageStream extends stream.Stream {
|
|||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputHeaderData = () => {
|
||||
const output_header_data = () => {
|
||||
if (this.message.attachments.length || this.message.alternative) {
|
||||
output(`MIME-Version: 1.0${CRLF}`);
|
||||
outputMixed();
|
||||
output_mixed();
|
||||
} // you only have a text message!
|
||||
else {
|
||||
outputText(this.message);
|
||||
output_text(this.message);
|
||||
close();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputHeader = () => {
|
||||
const output_header = () => {
|
||||
let data = [];
|
||||
for (const header in this.message.header) {
|
||||
// do not output BCC in the headers (regex) nor custom Object.prototype functions...
|
||||
|
@ -975,10 +962,10 @@ class MessageStream extends stream.Stream {
|
|||
}
|
||||
}
|
||||
output(data.join(''));
|
||||
outputHeaderData();
|
||||
output_header_data();
|
||||
};
|
||||
this.once('destroy', close);
|
||||
process.nextTick(outputHeader);
|
||||
process.nextTick(output_header);
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
|
@ -1149,7 +1136,7 @@ const CRLF$1 = '\r\n';
|
|||
const GREYLIST_DELAY = 300;
|
||||
let DEBUG = 0;
|
||||
/**
|
||||
* @param {...any[]} args the message(s) to log
|
||||
* @param {...any} args the message(s) to log
|
||||
* @returns {void}
|
||||
*/
|
||||
const log = (...args) => {
|
||||
|
@ -1162,8 +1149,8 @@ const log = (...args) => {
|
|||
}
|
||||
};
|
||||
/**
|
||||
* @param {function(...any[]): void} callback the function to call
|
||||
* @param {...any[]} args the arguments to apply to the function
|
||||
* @param {function(...*): void} callback the function to call
|
||||
* @param {...*} args the arguments to apply to the function
|
||||
* @returns {void}
|
||||
*/
|
||||
const caller = (callback, ...args) => {
|
||||
|
@ -1200,7 +1187,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
this.host = 'localhost';
|
||||
this.ssl = false;
|
||||
this.tls = false;
|
||||
this.greylistResponseTracker = new WeakSet();
|
||||
this.greylistResponseTracker = new WeakMap();
|
||||
if (Array.isArray(authentication)) {
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
@ -1263,7 +1250,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
* NOTE: `host` is trimmed before being used to establish a connection; however, the original untrimmed value will still be visible in configuration.
|
||||
*
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {number} [port] the port to use for the connection
|
||||
* @param {string} [host] the hostname to use for the connection
|
||||
* @param {ConnectOptions} [options={}] the options
|
||||
|
@ -1345,7 +1332,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
/**
|
||||
* @public
|
||||
* @param {string} str the string to send
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {*} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
send(str, callback) {
|
||||
|
@ -1372,7 +1359,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
/**
|
||||
* @public
|
||||
* @param {string} cmd command to issue
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {(number[] | number)} [codes=[250]] array codes
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1393,8 +1380,8 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
else if ((code === 450 || code === 451) &&
|
||||
msg.message.toLowerCase().includes('greylist') &&
|
||||
this.greylistResponseTracker.has(response) === false) {
|
||||
this.greylistResponseTracker.add(response);
|
||||
this.greylistResponseTracker.get(response) === false) {
|
||||
this.greylistResponseTracker.set(response, true);
|
||||
setTimeout(() => {
|
||||
this.send(cmd + CRLF$1, response);
|
||||
}, GREYLIST_DELAY);
|
||||
|
@ -1406,7 +1393,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
}
|
||||
};
|
||||
this.greylistResponseTracker.delete(response);
|
||||
this.greylistResponseTracker.set(response, false);
|
||||
this.send(cmd + CRLF$1, response);
|
||||
}
|
||||
/**
|
||||
|
@ -1419,7 +1406,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
* As this command was deprecated by rfc2821, it should only be used for compatibility with non-compliant servers.
|
||||
* @see https://tools.ietf.org/html/rfc2821#appendix-F.3
|
||||
*
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} domain the domain to associate with the 'helo' request
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1436,7 +1423,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
starttls(callback) {
|
||||
|
@ -1491,7 +1478,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} domain the domain to associate with the 'ehlo' request
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1524,7 +1511,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
/**
|
||||
* @public
|
||||
* @description SMTP 'help' command, returns text from the server
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} domain the domain to associate with the 'help' request
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1533,7 +1520,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
rset(callback) {
|
||||
|
@ -1541,7 +1528,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
noop(callback) {
|
||||
|
@ -1549,7 +1536,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} from the sender
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1558,7 +1545,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} to the receiver
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1567,7 +1554,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
data(callback) {
|
||||
|
@ -1575,7 +1562,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
data_end(callback) {
|
||||
|
@ -1595,7 +1582,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
* @public
|
||||
* @description SMTP 'verify' command -- checks for address validity.
|
||||
* @param {string} address the address to validate
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
verify(address, callback) {
|
||||
|
@ -1605,7 +1592,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
* @public
|
||||
* @description SMTP 'expn' command -- expands a mailing list.
|
||||
* @param {string} address the mailing list to expand
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
expn(address, callback) {
|
||||
|
@ -1618,7 +1605,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
* If there has been no previous EHLO or HELO command self session, self
|
||||
* method tries ESMTP EHLO first.
|
||||
*
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} [domain] the domain to associate with the command
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1646,7 +1633,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
*
|
||||
* This method will return normally if the authentication was successful.
|
||||
*
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} [user] the username to authenticate with
|
||||
* @param {string} [password] the password for the authentication
|
||||
* @param {{ method: string, domain: string }} [options] login options
|
||||
|
@ -1671,7 +1658,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
* @param {string} challenge challenge
|
||||
* @returns {string} base64 cram hash
|
||||
*/
|
||||
const encodeCramMd5 = (challenge) => {
|
||||
const encode_cram_md5 = (challenge) => {
|
||||
const hmac = crypto.createHmac('md5', login.password());
|
||||
hmac.update(Buffer.from(challenge, 'base64').toString('ascii'));
|
||||
return Buffer.from(`${login.user()} ${hmac.digest('hex')}`).toString('base64');
|
||||
|
@ -1679,12 +1666,12 @@ class SMTPConnection extends events.EventEmitter {
|
|||
/**
|
||||
* @returns {string} base64 login/password
|
||||
*/
|
||||
const encodePlain = () => Buffer.from(`\u0000${login.user()}\u0000${login.password()}`).toString('base64');
|
||||
const encode_plain = () => Buffer.from(`\u0000${login.user()}\u0000${login.password()}`).toString('base64');
|
||||
/**
|
||||
* @see https://developers.google.com/gmail/xoauth2_protocol
|
||||
* @returns {string} base64 xoauth2 auth token
|
||||
*/
|
||||
const encodeXoauth2 = () => Buffer.from(`user=${login.user()}\u0001auth=Bearer ${login.password()}\u0001\u0001`).toString('base64');
|
||||
const encode_xoauth2 = () => Buffer.from(`user=${login.user()}\u0001auth=Bearer ${login.password()}\u0001\u0001`).toString('base64');
|
||||
// List of authentication methods we support: from preferred to
|
||||
// less preferred methods.
|
||||
if (!method) {
|
||||
|
@ -1703,7 +1690,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
/**
|
||||
* handle bad responses from command differently
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @returns {void}
|
||||
*/
|
||||
const failed = (err, data) => {
|
||||
|
@ -1713,7 +1700,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
};
|
||||
/**
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @returns {void}
|
||||
*/
|
||||
const response = (err, data) => {
|
||||
|
@ -1727,7 +1714,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
};
|
||||
/**
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @param {string} msg msg
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1737,7 +1724,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
else {
|
||||
if (method === AUTH_METHODS['CRAM-MD5']) {
|
||||
this.command(encodeCramMd5(msg), response, [235, 503]);
|
||||
this.command(encode_cram_md5(msg), response, [235, 503]);
|
||||
}
|
||||
else if (method === AUTH_METHODS.LOGIN) {
|
||||
this.command(Buffer.from(login.password()).toString('base64'), response, [235, 503]);
|
||||
|
@ -1746,11 +1733,11 @@ class SMTPConnection extends events.EventEmitter {
|
|||
};
|
||||
/**
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @param {string} msg msg
|
||||
* @returns {void}
|
||||
*/
|
||||
const attemptUser = (err, data) => {
|
||||
const attempt_user = (err, data) => {
|
||||
if (err) {
|
||||
failed(err, data);
|
||||
}
|
||||
|
@ -1765,16 +1752,18 @@ class SMTPConnection extends events.EventEmitter {
|
|||
this.command(`AUTH ${AUTH_METHODS['CRAM-MD5']}`, attempt, [334]);
|
||||
break;
|
||||
case AUTH_METHODS.LOGIN:
|
||||
this.command(`AUTH ${AUTH_METHODS.LOGIN}`, attemptUser, [334]);
|
||||
this.command(`AUTH ${AUTH_METHODS.LOGIN}`, attempt_user, [334]);
|
||||
break;
|
||||
case AUTH_METHODS.PLAIN:
|
||||
this.command(`AUTH ${AUTH_METHODS.PLAIN} ${encodePlain()}`, response, [235, 503]);
|
||||
this.command(`AUTH ${AUTH_METHODS.PLAIN} ${encode_plain()}`, response, [235, 503]);
|
||||
break;
|
||||
case AUTH_METHODS.XOAUTH2:
|
||||
this.command(`AUTH ${AUTH_METHODS.XOAUTH2} ${encodeXoauth2()}`, response, [235, 503]);
|
||||
this.command(`AUTH ${AUTH_METHODS.XOAUTH2} ${encode_xoauth2()}`, response, [235, 503]);
|
||||
break;
|
||||
default:
|
||||
caller(callback, SMTPError.create('no form of authorization supported', SMTPErrorStates.AUTHNOTSUPPORTED, null, data));
|
||||
const msg = 'no form of authorization supported';
|
||||
const err = SMTPError.create(msg, SMTPErrorStates.AUTHNOTSUPPORTED, null, data);
|
||||
caller(callback, err);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -1808,7 +1797,7 @@ class SMTPConnection extends events.EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} [callback] function to call after response
|
||||
* @param {function(...*): void} [callback] function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
quit(callback) {
|
||||
|
@ -1864,23 +1853,6 @@ class SMTPClient {
|
|||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {Message} msg the message to send
|
||||
* @returns {Promise<Message>} a promise that resolves to the fully processed message
|
||||
*/
|
||||
sendAsync(msg) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.send(msg, (err, msg) => {
|
||||
if (err != null) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
* @description Converts a message to the raw object used by the internal stack.
|
||||
|
@ -1994,8 +1966,8 @@ class SMTPClient {
|
|||
}
|
||||
/**
|
||||
* @protected
|
||||
* @param {MessageAttachment | MessageAttachment[]} attachment attachment
|
||||
* @returns {boolean} whether the attachment contains inlined html
|
||||
* @param {*} attachment attachment
|
||||
* @returns {*} whether the attachment contains inlined html
|
||||
*/
|
||||
_containsInlinedHtml(attachment) {
|
||||
if (Array.isArray(attachment)) {
|
||||
|
@ -2116,7 +2088,6 @@ exports.SMTPState = SMTPState;
|
|||
exports.addressparser = addressparser;
|
||||
exports.getRFC2822Date = getRFC2822Date;
|
||||
exports.getRFC2822DateUTC = getRFC2822DateUTC;
|
||||
exports.isRFC2822Date = isRFC2822Date;
|
||||
exports.mimeEncode = mimeEncode;
|
||||
exports.mimeWordEncode = mimeWordEncode;
|
||||
//# sourceMappingURL=email.cjs.map
|
||||
|
|
File diff suppressed because one or more lines are too long
198
rollup/email.mjs
198
rollup/email.mjs
|
@ -252,19 +252,6 @@ function getRFC2822DateUTC(date = new Date()) {
|
|||
dates.push('+0000');
|
||||
return dates.join(' ');
|
||||
}
|
||||
/**
|
||||
* RFC 2822 regex
|
||||
* @see https://tools.ietf.org/html/rfc2822#section-3.3
|
||||
* @see https://github.com/moment/moment/blob/a831fc7e2694281ce31e4f090bbcf90a690f0277/src/lib/create/from-string.js#L101
|
||||
*/
|
||||
const rfc2822re = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/.compile();
|
||||
/**
|
||||
* @param {string} [date] a string to check for conformance to the [rfc2822](https://tools.ietf.org/html/rfc2822#section-3.3) standard
|
||||
* @returns {boolean} the result of the conformance check
|
||||
*/
|
||||
function isRFC2822Date(date) {
|
||||
return rfc2822re.test(date);
|
||||
}
|
||||
|
||||
// adapted from https://github.com/emailjs/emailjs-mime-codec/blob/6909c706b9f09bc0e5c3faf48f723cca53e5b352/src/mimecodec.js
|
||||
const encoder = new TextEncoder();
|
||||
|
@ -467,7 +454,7 @@ const MIME64CHUNK = (MIMECHUNK * 6);
|
|||
*/
|
||||
const BUFFERSIZE = (MIMECHUNK * 24 * 7);
|
||||
let counter = 0;
|
||||
function generateBoundary() {
|
||||
function generate_boundary() {
|
||||
let text = '';
|
||||
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'()+_,-./:=?";
|
||||
for (let i = 0; i < 69; i++) {
|
||||
|
@ -606,7 +593,7 @@ class Message {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @returns {MessageStream} a stream of the current message
|
||||
* @returns {*} a stream of the current message
|
||||
*/
|
||||
stream() {
|
||||
return new MessageStream(this);
|
||||
|
@ -626,7 +613,7 @@ class Message {
|
|||
}
|
||||
class MessageStream extends Stream {
|
||||
/**
|
||||
* @param {Message} message the message to stream
|
||||
* @param {*} message the message to stream
|
||||
*/
|
||||
constructor(message) {
|
||||
super();
|
||||
|
@ -679,7 +666,7 @@ class MessageStream extends Stream {
|
|||
* @param {MessageAttachment} [attachment] the attachment whose headers you would like to output
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputAttachmentHeaders = (attachment) => {
|
||||
const output_attachment_headers = (attachment) => {
|
||||
let data = [];
|
||||
const headers = {
|
||||
'content-type': attachment.type +
|
||||
|
@ -711,7 +698,7 @@ class MessageStream extends Stream {
|
|||
* @param {function(): void} [callback] the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputBase64 = (data, callback) => {
|
||||
const output_base64 = (data, callback) => {
|
||||
const loops = Math.ceil(data.length / MIMECHUNK);
|
||||
let loop = 0;
|
||||
while (loop < loops) {
|
||||
|
@ -722,7 +709,7 @@ class MessageStream extends Stream {
|
|||
callback();
|
||||
}
|
||||
};
|
||||
const outputFile = (attachment, next) => {
|
||||
const output_file = (attachment, next) => {
|
||||
const chunk = MIME64CHUNK * 16;
|
||||
const buffer = Buffer.alloc(chunk);
|
||||
const closed = (fd) => fs.closeSync(fd);
|
||||
|
@ -748,7 +735,7 @@ class MessageStream extends Stream {
|
|||
encoding = 'base64';
|
||||
}
|
||||
// guaranteed to be encoded without padding unless it is our last read
|
||||
outputBase64(buffer.toString(encoding, 0, bytes), () => {
|
||||
output_base64(buffer.toString(encoding, 0, bytes), () => {
|
||||
if (bytes == chunk) {
|
||||
// we read a full chunk, there might be more
|
||||
fs.read(fd, buffer, 0, chunk, null, read);
|
||||
|
@ -777,13 +764,13 @@ class MessageStream extends Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputStream = (attachment, callback) => {
|
||||
const output_stream = (attachment, callback) => {
|
||||
const { stream } = attachment;
|
||||
if (stream === null || stream === void 0 ? void 0 : stream.readable) {
|
||||
let previous = Buffer.alloc(0);
|
||||
stream.resume();
|
||||
stream.on('end', () => {
|
||||
outputBase64(previous.toString('base64'), callback);
|
||||
output_base64(previous.toString('base64'), callback);
|
||||
this.removeListener('pause', stream.pause);
|
||||
this.removeListener('resume', stream.resume);
|
||||
this.removeListener('error', stream.resume);
|
||||
|
@ -801,7 +788,7 @@ class MessageStream extends Stream {
|
|||
// copy dangling bytes into previous buffer
|
||||
buffer.copy(previous, 0, buffer.length - padded);
|
||||
}
|
||||
outputBase64(buffer.toString('base64', 0, buffer.length - padded));
|
||||
output_base64(buffer.toString('base64', 0, buffer.length - padded));
|
||||
});
|
||||
this.on('pause', stream.pause);
|
||||
this.on('resume', stream.resume);
|
||||
|
@ -811,13 +798,13 @@ class MessageStream extends Stream {
|
|||
this.emit('error', { message: 'stream not readable' });
|
||||
}
|
||||
};
|
||||
const outputAttachment = (attachment, callback) => {
|
||||
const output_attachment = (attachment, callback) => {
|
||||
const build = attachment.path
|
||||
? outputFile
|
||||
? output_file
|
||||
: attachment.stream
|
||||
? outputStream
|
||||
: outputData;
|
||||
outputAttachmentHeaders(attachment);
|
||||
? output_stream
|
||||
: output_data;
|
||||
output_attachment_headers(attachment);
|
||||
build(attachment, callback);
|
||||
};
|
||||
/**
|
||||
|
@ -827,14 +814,14 @@ class MessageStream extends Stream {
|
|||
* @param {function(): void} callback the function to call if index is greater than upper bound
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputMessage = (boundary, list, index, callback) => {
|
||||
const output_message = (boundary, list, index, callback) => {
|
||||
if (index < list.length) {
|
||||
output(`--${boundary}${CRLF}`);
|
||||
if (list[index].related) {
|
||||
outputRelated(list[index], () => outputMessage(boundary, list, index + 1, callback));
|
||||
output_related(list[index], () => output_message(boundary, list, index + 1, callback));
|
||||
}
|
||||
else {
|
||||
outputAttachment(list[index], () => outputMessage(boundary, list, index + 1, callback));
|
||||
output_attachment(list[index], () => output_message(boundary, list, index + 1, callback));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -842,17 +829,17 @@ class MessageStream extends Stream {
|
|||
callback();
|
||||
}
|
||||
};
|
||||
const outputMixed = () => {
|
||||
const boundary = generateBoundary();
|
||||
const output_mixed = () => {
|
||||
const boundary = generate_boundary();
|
||||
output(`Content-Type: multipart/mixed; boundary="${boundary}"${CRLF}${CRLF}--${boundary}${CRLF}`);
|
||||
if (this.message.alternative == null) {
|
||||
outputText(this.message);
|
||||
outputMessage(boundary, this.message.attachments, 0, close);
|
||||
output_text(this.message);
|
||||
output_message(boundary, this.message.attachments, 0, close);
|
||||
}
|
||||
else {
|
||||
outputAlternative(
|
||||
output_alternative(
|
||||
// typescript bug; should narrow to { alternative: MessageAttachment }
|
||||
this.message, () => outputMessage(boundary, this.message.attachments, 0, close));
|
||||
this.message, () => output_message(boundary, this.message.attachments, 0, close));
|
||||
}
|
||||
};
|
||||
/**
|
||||
|
@ -860,16 +847,16 @@ class MessageStream extends Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputData = (attachment, callback) => {
|
||||
const output_data = (attachment, callback) => {
|
||||
var _a, _b;
|
||||
outputBase64(attachment.encoded
|
||||
output_base64(attachment.encoded
|
||||
? (_a = attachment.data) !== null && _a !== void 0 ? _a : '' : Buffer.from((_b = attachment.data) !== null && _b !== void 0 ? _b : '').toString('base64'), callback);
|
||||
};
|
||||
/**
|
||||
* @param {Message} message the message to output
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputText = (message) => {
|
||||
const output_text = (message) => {
|
||||
let data = [];
|
||||
data = data.concat([
|
||||
'Content-Type:',
|
||||
|
@ -887,12 +874,12 @@ class MessageStream extends Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputRelated = (message, callback) => {
|
||||
const boundary = generateBoundary();
|
||||
const output_related = (message, callback) => {
|
||||
const boundary = generate_boundary();
|
||||
output(`Content-Type: multipart/related; boundary="${boundary}"${CRLF}${CRLF}--${boundary}${CRLF}`);
|
||||
outputAttachment(message, () => {
|
||||
output_attachment(message, () => {
|
||||
var _a;
|
||||
outputMessage(boundary, (_a = message.related) !== null && _a !== void 0 ? _a : [], 0, () => {
|
||||
output_message(boundary, (_a = message.related) !== null && _a !== void 0 ? _a : [], 0, () => {
|
||||
output(`${CRLF}--${boundary}--${CRLF}${CRLF}`);
|
||||
callback();
|
||||
});
|
||||
|
@ -903,10 +890,10 @@ class MessageStream extends Stream {
|
|||
* @param {function(): void} callback the function to call after output is finished
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputAlternative = (message, callback) => {
|
||||
const boundary = generateBoundary();
|
||||
const output_alternative = (message, callback) => {
|
||||
const boundary = generate_boundary();
|
||||
output(`Content-Type: multipart/alternative; boundary="${boundary}"${CRLF}${CRLF}--${boundary}${CRLF}`);
|
||||
outputText(message);
|
||||
output_text(message);
|
||||
output(`--${boundary}${CRLF}`);
|
||||
/**
|
||||
* @returns {void}
|
||||
|
@ -916,10 +903,10 @@ class MessageStream extends Stream {
|
|||
callback();
|
||||
};
|
||||
if (message.alternative.related) {
|
||||
outputRelated(message.alternative, finish);
|
||||
output_related(message.alternative, finish);
|
||||
}
|
||||
else {
|
||||
outputAttachment(message.alternative, finish);
|
||||
output_attachment(message.alternative, finish);
|
||||
}
|
||||
};
|
||||
const close = (err) => {
|
||||
|
@ -943,20 +930,20 @@ class MessageStream extends Stream {
|
|||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputHeaderData = () => {
|
||||
const output_header_data = () => {
|
||||
if (this.message.attachments.length || this.message.alternative) {
|
||||
output(`MIME-Version: 1.0${CRLF}`);
|
||||
outputMixed();
|
||||
output_mixed();
|
||||
} // you only have a text message!
|
||||
else {
|
||||
outputText(this.message);
|
||||
output_text(this.message);
|
||||
close();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
const outputHeader = () => {
|
||||
const output_header = () => {
|
||||
let data = [];
|
||||
for (const header in this.message.header) {
|
||||
// do not output BCC in the headers (regex) nor custom Object.prototype functions...
|
||||
|
@ -971,10 +958,10 @@ class MessageStream extends Stream {
|
|||
}
|
||||
}
|
||||
output(data.join(''));
|
||||
outputHeaderData();
|
||||
output_header_data();
|
||||
};
|
||||
this.once('destroy', close);
|
||||
process.nextTick(outputHeader);
|
||||
process.nextTick(output_header);
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
|
@ -1145,7 +1132,7 @@ const CRLF$1 = '\r\n';
|
|||
const GREYLIST_DELAY = 300;
|
||||
let DEBUG = 0;
|
||||
/**
|
||||
* @param {...any[]} args the message(s) to log
|
||||
* @param {...any} args the message(s) to log
|
||||
* @returns {void}
|
||||
*/
|
||||
const log = (...args) => {
|
||||
|
@ -1158,8 +1145,8 @@ const log = (...args) => {
|
|||
}
|
||||
};
|
||||
/**
|
||||
* @param {function(...any[]): void} callback the function to call
|
||||
* @param {...any[]} args the arguments to apply to the function
|
||||
* @param {function(...*): void} callback the function to call
|
||||
* @param {...*} args the arguments to apply to the function
|
||||
* @returns {void}
|
||||
*/
|
||||
const caller = (callback, ...args) => {
|
||||
|
@ -1196,7 +1183,7 @@ class SMTPConnection extends EventEmitter {
|
|||
this.host = 'localhost';
|
||||
this.ssl = false;
|
||||
this.tls = false;
|
||||
this.greylistResponseTracker = new WeakSet();
|
||||
this.greylistResponseTracker = new WeakMap();
|
||||
if (Array.isArray(authentication)) {
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
@ -1259,7 +1246,7 @@ class SMTPConnection extends EventEmitter {
|
|||
* NOTE: `host` is trimmed before being used to establish a connection; however, the original untrimmed value will still be visible in configuration.
|
||||
*
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {number} [port] the port to use for the connection
|
||||
* @param {string} [host] the hostname to use for the connection
|
||||
* @param {ConnectOptions} [options={}] the options
|
||||
|
@ -1341,7 +1328,7 @@ class SMTPConnection extends EventEmitter {
|
|||
/**
|
||||
* @public
|
||||
* @param {string} str the string to send
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {*} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
send(str, callback) {
|
||||
|
@ -1368,7 +1355,7 @@ class SMTPConnection extends EventEmitter {
|
|||
/**
|
||||
* @public
|
||||
* @param {string} cmd command to issue
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {(number[] | number)} [codes=[250]] array codes
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1389,8 +1376,8 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
else if ((code === 450 || code === 451) &&
|
||||
msg.message.toLowerCase().includes('greylist') &&
|
||||
this.greylistResponseTracker.has(response) === false) {
|
||||
this.greylistResponseTracker.add(response);
|
||||
this.greylistResponseTracker.get(response) === false) {
|
||||
this.greylistResponseTracker.set(response, true);
|
||||
setTimeout(() => {
|
||||
this.send(cmd + CRLF$1, response);
|
||||
}, GREYLIST_DELAY);
|
||||
|
@ -1402,7 +1389,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
}
|
||||
};
|
||||
this.greylistResponseTracker.delete(response);
|
||||
this.greylistResponseTracker.set(response, false);
|
||||
this.send(cmd + CRLF$1, response);
|
||||
}
|
||||
/**
|
||||
|
@ -1415,7 +1402,7 @@ class SMTPConnection extends EventEmitter {
|
|||
* As this command was deprecated by rfc2821, it should only be used for compatibility with non-compliant servers.
|
||||
* @see https://tools.ietf.org/html/rfc2821#appendix-F.3
|
||||
*
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} domain the domain to associate with the 'helo' request
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1432,7 +1419,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
starttls(callback) {
|
||||
|
@ -1487,7 +1474,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} domain the domain to associate with the 'ehlo' request
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1520,7 +1507,7 @@ class SMTPConnection extends EventEmitter {
|
|||
/**
|
||||
* @public
|
||||
* @description SMTP 'help' command, returns text from the server
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} domain the domain to associate with the 'help' request
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1529,7 +1516,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
rset(callback) {
|
||||
|
@ -1537,7 +1524,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
noop(callback) {
|
||||
|
@ -1545,7 +1532,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} from the sender
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1554,7 +1541,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} to the receiver
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1563,7 +1550,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
data(callback) {
|
||||
|
@ -1571,7 +1558,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
data_end(callback) {
|
||||
|
@ -1591,7 +1578,7 @@ class SMTPConnection extends EventEmitter {
|
|||
* @public
|
||||
* @description SMTP 'verify' command -- checks for address validity.
|
||||
* @param {string} address the address to validate
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
verify(address, callback) {
|
||||
|
@ -1601,7 +1588,7 @@ class SMTPConnection extends EventEmitter {
|
|||
* @public
|
||||
* @description SMTP 'expn' command -- expands a mailing list.
|
||||
* @param {string} address the mailing list to expand
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
expn(address, callback) {
|
||||
|
@ -1614,7 +1601,7 @@ class SMTPConnection extends EventEmitter {
|
|||
* If there has been no previous EHLO or HELO command self session, self
|
||||
* method tries ESMTP EHLO first.
|
||||
*
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} [domain] the domain to associate with the command
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1642,7 +1629,7 @@ class SMTPConnection extends EventEmitter {
|
|||
*
|
||||
* This method will return normally if the authentication was successful.
|
||||
*
|
||||
* @param {function(...any[]): void} callback function to call after response
|
||||
* @param {function(...*): void} callback function to call after response
|
||||
* @param {string} [user] the username to authenticate with
|
||||
* @param {string} [password] the password for the authentication
|
||||
* @param {{ method: string, domain: string }} [options] login options
|
||||
|
@ -1667,7 +1654,7 @@ class SMTPConnection extends EventEmitter {
|
|||
* @param {string} challenge challenge
|
||||
* @returns {string} base64 cram hash
|
||||
*/
|
||||
const encodeCramMd5 = (challenge) => {
|
||||
const encode_cram_md5 = (challenge) => {
|
||||
const hmac = createHmac('md5', login.password());
|
||||
hmac.update(Buffer.from(challenge, 'base64').toString('ascii'));
|
||||
return Buffer.from(`${login.user()} ${hmac.digest('hex')}`).toString('base64');
|
||||
|
@ -1675,12 +1662,12 @@ class SMTPConnection extends EventEmitter {
|
|||
/**
|
||||
* @returns {string} base64 login/password
|
||||
*/
|
||||
const encodePlain = () => Buffer.from(`\u0000${login.user()}\u0000${login.password()}`).toString('base64');
|
||||
const encode_plain = () => Buffer.from(`\u0000${login.user()}\u0000${login.password()}`).toString('base64');
|
||||
/**
|
||||
* @see https://developers.google.com/gmail/xoauth2_protocol
|
||||
* @returns {string} base64 xoauth2 auth token
|
||||
*/
|
||||
const encodeXoauth2 = () => Buffer.from(`user=${login.user()}\u0001auth=Bearer ${login.password()}\u0001\u0001`).toString('base64');
|
||||
const encode_xoauth2 = () => Buffer.from(`user=${login.user()}\u0001auth=Bearer ${login.password()}\u0001\u0001`).toString('base64');
|
||||
// List of authentication methods we support: from preferred to
|
||||
// less preferred methods.
|
||||
if (!method) {
|
||||
|
@ -1699,7 +1686,7 @@ class SMTPConnection extends EventEmitter {
|
|||
/**
|
||||
* handle bad responses from command differently
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @returns {void}
|
||||
*/
|
||||
const failed = (err, data) => {
|
||||
|
@ -1709,7 +1696,7 @@ class SMTPConnection extends EventEmitter {
|
|||
};
|
||||
/**
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @returns {void}
|
||||
*/
|
||||
const response = (err, data) => {
|
||||
|
@ -1723,7 +1710,7 @@ class SMTPConnection extends EventEmitter {
|
|||
};
|
||||
/**
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @param {string} msg msg
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -1733,7 +1720,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
else {
|
||||
if (method === AUTH_METHODS['CRAM-MD5']) {
|
||||
this.command(encodeCramMd5(msg), response, [235, 503]);
|
||||
this.command(encode_cram_md5(msg), response, [235, 503]);
|
||||
}
|
||||
else if (method === AUTH_METHODS.LOGIN) {
|
||||
this.command(Buffer.from(login.password()).toString('base64'), response, [235, 503]);
|
||||
|
@ -1742,11 +1729,11 @@ class SMTPConnection extends EventEmitter {
|
|||
};
|
||||
/**
|
||||
* @param {Error} err err
|
||||
* @param {unknown} data data
|
||||
* @param {*} data data
|
||||
* @param {string} msg msg
|
||||
* @returns {void}
|
||||
*/
|
||||
const attemptUser = (err, data) => {
|
||||
const attempt_user = (err, data) => {
|
||||
if (err) {
|
||||
failed(err, data);
|
||||
}
|
||||
|
@ -1761,16 +1748,18 @@ class SMTPConnection extends EventEmitter {
|
|||
this.command(`AUTH ${AUTH_METHODS['CRAM-MD5']}`, attempt, [334]);
|
||||
break;
|
||||
case AUTH_METHODS.LOGIN:
|
||||
this.command(`AUTH ${AUTH_METHODS.LOGIN}`, attemptUser, [334]);
|
||||
this.command(`AUTH ${AUTH_METHODS.LOGIN}`, attempt_user, [334]);
|
||||
break;
|
||||
case AUTH_METHODS.PLAIN:
|
||||
this.command(`AUTH ${AUTH_METHODS.PLAIN} ${encodePlain()}`, response, [235, 503]);
|
||||
this.command(`AUTH ${AUTH_METHODS.PLAIN} ${encode_plain()}`, response, [235, 503]);
|
||||
break;
|
||||
case AUTH_METHODS.XOAUTH2:
|
||||
this.command(`AUTH ${AUTH_METHODS.XOAUTH2} ${encodeXoauth2()}`, response, [235, 503]);
|
||||
this.command(`AUTH ${AUTH_METHODS.XOAUTH2} ${encode_xoauth2()}`, response, [235, 503]);
|
||||
break;
|
||||
default:
|
||||
caller(callback, SMTPError.create('no form of authorization supported', SMTPErrorStates.AUTHNOTSUPPORTED, null, data));
|
||||
const msg = 'no form of authorization supported';
|
||||
const err = SMTPError.create(msg, SMTPErrorStates.AUTHNOTSUPPORTED, null, data);
|
||||
caller(callback, err);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -1804,7 +1793,7 @@ class SMTPConnection extends EventEmitter {
|
|||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {function(...any[]): void} [callback] function to call after response
|
||||
* @param {function(...*): void} [callback] function to call after response
|
||||
* @returns {void}
|
||||
*/
|
||||
quit(callback) {
|
||||
|
@ -1860,23 +1849,6 @@ class SMTPClient {
|
|||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
* @param {Message} msg the message to send
|
||||
* @returns {Promise<Message>} a promise that resolves to the fully processed message
|
||||
*/
|
||||
sendAsync(msg) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.send(msg, (err, msg) => {
|
||||
if (err != null) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
* @description Converts a message to the raw object used by the internal stack.
|
||||
|
@ -1990,8 +1962,8 @@ class SMTPClient {
|
|||
}
|
||||
/**
|
||||
* @protected
|
||||
* @param {MessageAttachment | MessageAttachment[]} attachment attachment
|
||||
* @returns {boolean} whether the attachment contains inlined html
|
||||
* @param {*} attachment attachment
|
||||
* @returns {*} whether the attachment contains inlined html
|
||||
*/
|
||||
_containsInlinedHtml(attachment) {
|
||||
if (Array.isArray(attachment)) {
|
||||
|
@ -2097,5 +2069,5 @@ class SMTPClient {
|
|||
}
|
||||
}
|
||||
|
||||
export { AUTH_METHODS, BUFFERSIZE, DEFAULT_TIMEOUT, MIME64CHUNK, MIMECHUNK, Message, SMTPClient, SMTPConnection, SMTPError, SMTPErrorStates, SMTPResponseMonitor, SMTPState, addressparser, getRFC2822Date, getRFC2822DateUTC, isRFC2822Date, mimeEncode, mimeWordEncode };
|
||||
export { AUTH_METHODS, BUFFERSIZE, DEFAULT_TIMEOUT, MIME64CHUNK, MIMECHUNK, Message, SMTPClient, SMTPConnection, SMTPError, SMTPErrorStates, SMTPResponseMonitor, SMTPState, addressparser, getRFC2822Date, getRFC2822DateUTC, mimeEncode, mimeWordEncode };
|
||||
//# sourceMappingURL=email.mjs.map
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue