test-smtp-server
Version:
The test-smtp-server package allows internal testing of projects needing an SMTP server.
145 lines • 4.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.testSmtpServer = exports.eMail = void 0;
const smtp_server_1 = require("smtp-server");
const mailparser_1 = require("mailparser");
const stream_1 = require("stream");
/**
* Class to describe an email. The `envelope` contains the SMTP routing
* information. This may not match the `to/cc/bcc` information in the
* email contaents. The buffer contains the raw email content. To easily
* access parts of the email, `getParsed` should be used.
*/
class eMail {
constructor(envelope, buffer) {
this.buffer = null;
this.length = 0;
this.envelope = envelope;
this.buffer = buffer;
}
/**
* Return a parsed email as formatted by `simpleParser`.
*
* @returns Promise<ParsedMail> See
* https://nodemailer.com/extras/mailparser/ for the structure.
*/
async getParsed() {
if (this.buffer) {
const stream = stream_1.Readable.from(this.buffer);
const options = {
skipHtmlToText: true,
skipTextLinks: true,
skipTextToHtml: true,
};
return (0, mailparser_1.simpleParser)(stream, options);
}
else {
throw new Error("Empty email buffer");
}
}
}
exports.eMail = eMail;
/**
* Create a testSmtpServer. This provides a wrapper to SMTPServer that
* can be used for testing. The emails are stored in an array that
* can be examined to validate the content.
*/
class testSmtpServer {
constructor(options) {
this.debug = (_message, ..._optionalParams) => { };
this.emails = [];
this.isDebugging = false;
this.localhostOnly = true;
this.port = 1025;
if (options) {
if (options.smtpPort) {
this.port = options.smtpPort;
}
if (options.localhostOnly) {
this.localhostOnly = options.localhostOnly;
}
if (options.debug) {
this.debug = options.debug;
}
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this; // preserve for use in other objects
this.server = new smtp_server_1.SMTPServer({
authOptional: true,
onConnect(session, callback) {
// 172.17 prefix is a linux docker container
if (that.localhostOnly && !session.remoteAddress.match(/^172.17|127.0.0.1|::1$/)) {
return callback(new Error("Only connections from localhost allowed"));
}
return callback(); // Accept the connection
},
onAuth(auth, _session, callback) {
that.debug(`SMTP login for user: ${auth.username}`);
callback(null, { user: auth.username });
},
onData(stream, session, callback) {
const buffers = [];
const writer = new stream_1.Writable({
write(data, _encoding, writerCallback) {
buffers.push(data);
writerCallback();
},
});
stream.pipe(writer);
stream.on("end", () => {
const buffer = Buffer.concat(buffers);
const email = new eMail(session.envelope, buffer);
that.emails.push(email);
if (that.isDebugging) {
that.debug(JSON.stringify(email, (key, value) => {
if ("buffer" === key) {
return buffer.toString();
}
else {
return value;
}
}, 2));
}
callback();
});
},
secure: true,
});
}
/**
* Clear the set of emails.
*
* @returns number of emails deleted
*/
clearEmails() {
const count = this.emails.length;
this.emails.length = 0;
return count;
}
/**
* Retrieve the set of emails in order from oldest to most recent.
*
* @returns array of eMail objects
*/
getEmails() {
return this.emails;
}
/**
* Query for the port number used by the server.
*
* @returns the port number being used
*/
getPort() {
return this.port;
}
/** Start the server */
startServer() {
this.server.listen(this.port);
}
/** Stop the server */
stopServer() {
this.server.close();
}
}
exports.testSmtpServer = testSmtpServer;
//# sourceMappingURL=test-smtp-server.js.map