test-smtp-server 0.9.6 → 0.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,77 +1,77 @@
1
- # Test SMTP Server
2
-
3
- Test SMTP Server is a lightweight wrapper for
4
- [smtp-server](<https://nodemailer.com/extras/smtp-server/>).
5
- It is primarily intended for development and testing. The test code can start the server, run email tests and then validate the email contents. It can replace the use of external fake SMTP services which may have availablility issues.
6
-
7
- All received emails are stored in an array in the order received. The emails
8
- may be viewed as raw data or a parsed object that is easily examined.
9
-
10
- ## Getting Started
11
-
12
- ### Prerequisites
13
-
14
- Tested on Node v16 with npm v7.
15
-
16
- ### Installation
17
-
18
- ```sh
19
- npm install test-smtp-server --save-dev
20
- ```
21
-
22
- ### Usage
23
-
24
- See [test code](
25
- https://github.com/webstech/test-smtp-server/blob/main/test/index.ts) for an example.
26
-
27
- ```js
28
- import { testSmtpServer } from "test-smtp-server";
29
-
30
- (async (): Promise<void> => {
31
- const smtpserver = new testSmtpServer();
32
- await smtpserver.startServer(); // start listening
33
-
34
- // send some emails capturing ids ..
35
- messageId.push( await sendMail(email, smtpOptions));
36
-
37
- // get emails in sent order
38
- const mails = smtpserver.getEmails();
39
-
40
- // validate/dump emails
41
-
42
- if (mails.length) {
43
- let entry = 0;
44
- for (const mail of mails) {
45
- console.log(`Checking mail entry <${entry}>`);
46
- console.log(mail.envelope);
47
- const parsed = await mail.getParsed();
48
- if (parsed.messageId !== messageId[entry]) {
49
- throw new Error(`Messageids do not match for email ${
50
- entry} <${parsed.messageId}> <${messageId[entry]}>`);
51
- }
52
-
53
- console.log(parsed);
54
- entry++;
55
- }
56
- } else {
57
- throw new Error("No emails captured when expected");
58
- }
59
-
60
- await smtpserver.stopServer(); // terminate server
61
- ```
62
-
63
- ### Security
64
-
65
- The server is started as secure but that may not be possible in the testing
66
- environment. If the server does not have a valid certificate, the connection
67
- will fail from the client side. Some clients
68
- (e.g. nodemailer/SMTP-Transport options) allow connections to non-secure
69
- servers. Node allows connections through an
70
- environment variable that turns off certificate authorization checking. See
71
- [node_tls_reject_unauthorizedvalue](
72
- https://nodejs.org/api/cli.html#node_tls_reject_unauthorizedvalue)
73
- for more information. This may be insecure if other ports are used.
74
-
75
- ## License
76
-
77
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
1
+ # Test SMTP Server
2
+
3
+ Test SMTP Server is a lightweight wrapper for
4
+ [smtp-server](<https://nodemailer.com/extras/smtp-server/>).
5
+ It is primarily intended for development and testing. The test code can start the server, run email tests and then validate the email contents. It can replace the use of external fake SMTP services which may have availablility issues.
6
+
7
+ All received emails are stored in an array in the order received. The emails
8
+ may be viewed as raw data or a parsed object that is easily examined.
9
+
10
+ ## Getting Started
11
+
12
+ ### Prerequisites
13
+
14
+ Tested on Node v18 with npm v9.
15
+
16
+ ### Installation
17
+
18
+ ```sh
19
+ npm install test-smtp-server --save-dev
20
+ ```
21
+
22
+ ### Usage
23
+
24
+ See [test code](
25
+ https://github.com/webstech/test-smtp-server/blob/main/test/index.ts) for an example.
26
+
27
+ ```js
28
+ import { testSmtpServer } from "test-smtp-server";
29
+
30
+ (async (): Promise<void> => {
31
+ const smtpserver = new testSmtpServer();
32
+ await smtpserver.startServer(); // start listening
33
+
34
+ // send some emails capturing ids ..
35
+ messageId.push( await sendMail(email, smtpOptions));
36
+
37
+ // get emails in sent order
38
+ const mails = smtpserver.getEmails();
39
+
40
+ // validate/dump emails
41
+
42
+ if (mails.length) {
43
+ let entry = 0;
44
+ for (const mail of mails) {
45
+ console.log(`Checking mail entry <${entry}>`);
46
+ console.log(mail.envelope);
47
+ const parsed = await mail.getParsed();
48
+ if (parsed.messageId !== messageId[entry]) {
49
+ throw new Error(`Messageids do not match for email ${
50
+ entry} <${parsed.messageId}> <${messageId[entry]}>`);
51
+ }
52
+
53
+ console.log(parsed);
54
+ entry++;
55
+ }
56
+ } else {
57
+ throw new Error("No emails captured when expected");
58
+ }
59
+
60
+ await smtpserver.stopServer(); // terminate server
61
+ ```
62
+
63
+ ### Security
64
+
65
+ The server is started as secure but that may not be possible in the testing
66
+ environment. If the server does not have a valid certificate, the connection
67
+ will fail from the client side. Some clients
68
+ (e.g. nodemailer/SMTP-Transport options) allow connections to non-secure
69
+ servers. Node allows connections through an
70
+ environment variable that turns off certificate authorization checking. See
71
+ [node_tls_reject_unauthorizedvalue](
72
+ https://nodejs.org/api/cli.html#node_tls_reject_unauthorizedvalue)
73
+ for more information. This may be insecure if other ports are used.
74
+
75
+ ## License
76
+
77
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
@@ -1,69 +1,69 @@
1
- /// <reference types="node" />
2
- import { SMTPServerEnvelope } from "smtp-server";
3
- import { ParsedMail } from "mailparser";
4
- /**
5
- * Class to describe an email. The `envelope` contains the SMTP routing
6
- * information. This may not match the `to/cc/bcc` information in the
7
- * email contaents. The buffer contains the raw email content. To easily
8
- * access parts of the email, `getParsed` should be used.
9
- */
10
- export declare class eMail {
11
- envelope: SMTPServerEnvelope;
12
- buffer: Buffer | null;
13
- length: number;
14
- constructor(envelope: SMTPServerEnvelope, buffer: Buffer);
15
- /**
16
- * Return a parsed email as formatted by `simpleParser`.
17
- *
18
- * @returns Promise<ParsedMail> See
19
- * https://nodemailer.com/extras/mailparser/ for the structure.
20
- */
21
- getParsed(): Promise<ParsedMail>;
22
- }
23
- /**
24
- * testSmtpServer optional parameters
25
- */
26
- export type testSmtpServerOptions = {
27
- /** the port number to use (default: 1025) */
28
- smtpPort?: number;
29
- /** restrict ip addresses to localhost */
30
- localhostOnly?: boolean;
31
- /** logging function like console.log() */
32
- debug?: (message?: unknown, ...optionalParams: any[]) => void;
33
- };
34
- /**
35
- * Create a testSmtpServer. This provides a wrapper to SMTPServer that
36
- * can be used for testing. The emails are stored in an array that
37
- * can be examined to validate the content.
38
- */
39
- export declare class testSmtpServer {
40
- private debug;
41
- private emails;
42
- private isDebugging;
43
- private localhostOnly;
44
- private port;
45
- private server;
46
- constructor(options?: testSmtpServerOptions | undefined);
47
- /**
48
- * Clear the set of emails.
49
- *
50
- * @returns number of emails deleted
51
- */
52
- clearEmails(): number;
53
- /**
54
- * Retrieve the set of emails in order from oldest to most recent.
55
- *
56
- * @returns array of eMail objects
57
- */
58
- getEmails(): eMail[];
59
- /**
60
- * Query for the port number used by the server.
61
- *
62
- * @returns the port number being used
63
- */
64
- getPort(): number;
65
- /** Start the server */
66
- startServer(): void;
67
- /** Stop the server */
68
- stopServer(): void;
69
- }
1
+ /// <reference types="node" />
2
+ import { SMTPServerEnvelope } from "smtp-server";
3
+ import { ParsedMail } from "mailparser";
4
+ /**
5
+ * Class to describe an email. The `envelope` contains the SMTP routing
6
+ * information. This may not match the `to/cc/bcc` information in the
7
+ * email contaents. The buffer contains the raw email content. To easily
8
+ * access parts of the email, `getParsed` should be used.
9
+ */
10
+ export declare class eMail {
11
+ envelope: SMTPServerEnvelope;
12
+ buffer: Buffer | null;
13
+ length: number;
14
+ constructor(envelope: SMTPServerEnvelope, buffer: Buffer);
15
+ /**
16
+ * Return a parsed email as formatted by `simpleParser`.
17
+ *
18
+ * @returns Promise<ParsedMail> See
19
+ * https://nodemailer.com/extras/mailparser/ for the structure.
20
+ */
21
+ getParsed(): Promise<ParsedMail>;
22
+ }
23
+ /**
24
+ * testSmtpServer optional parameters
25
+ */
26
+ export type testSmtpServerOptions = {
27
+ /** the port number to use (default: 1025) */
28
+ smtpPort?: number;
29
+ /** restrict ip addresses to localhost */
30
+ localhostOnly?: boolean;
31
+ /** logging function like console.log() */
32
+ debug?: (message?: unknown, ...optionalParams: any[]) => void;
33
+ };
34
+ /**
35
+ * Create a testSmtpServer. This provides a wrapper to SMTPServer that
36
+ * can be used for testing. The emails are stored in an array that
37
+ * can be examined to validate the content.
38
+ */
39
+ export declare class testSmtpServer {
40
+ private debug;
41
+ private emails;
42
+ private isDebugging;
43
+ private localhostOnly;
44
+ private port;
45
+ private server;
46
+ constructor(options?: testSmtpServerOptions | undefined);
47
+ /**
48
+ * Clear the set of emails.
49
+ *
50
+ * @returns number of emails deleted
51
+ */
52
+ clearEmails(): number;
53
+ /**
54
+ * Retrieve the set of emails in order from oldest to most recent.
55
+ *
56
+ * @returns array of eMail objects
57
+ */
58
+ getEmails(): eMail[];
59
+ /**
60
+ * Query for the port number used by the server.
61
+ *
62
+ * @returns the port number being used
63
+ */
64
+ getPort(): number;
65
+ /** Start the server */
66
+ startServer(): void;
67
+ /** Stop the server */
68
+ stopServer(): void;
69
+ }
@@ -1,146 +1,146 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.testSmtpServer = exports.eMail = void 0;
4
- const smtp_server_1 = require("smtp-server");
5
- const mailparser_1 = require("mailparser");
6
- const stream_1 = require("stream");
7
- /**
8
- * Class to describe an email. The `envelope` contains the SMTP routing
9
- * information. This may not match the `to/cc/bcc` information in the
10
- * email contaents. The buffer contains the raw email content. To easily
11
- * access parts of the email, `getParsed` should be used.
12
- */
13
- class eMail {
14
- constructor(envelope, buffer) {
15
- this.buffer = null;
16
- this.length = 0;
17
- this.envelope = envelope;
18
- this.buffer = buffer;
19
- }
20
- /**
21
- * Return a parsed email as formatted by `simpleParser`.
22
- *
23
- * @returns Promise<ParsedMail> See
24
- * https://nodemailer.com/extras/mailparser/ for the structure.
25
- */
26
- async getParsed() {
27
- if (this.buffer) {
28
- const stream = stream_1.Readable.from(this.buffer);
29
- const options = {
30
- skipHtmlToText: true,
31
- skipTextLinks: true,
32
- skipTextToHtml: true
33
- };
34
- return (0, mailparser_1.simpleParser)(stream, options);
35
- }
36
- else {
37
- throw new Error("Empty email buffer");
38
- }
39
- }
40
- }
41
- exports.eMail = eMail;
42
- /**
43
- * Create a testSmtpServer. This provides a wrapper to SMTPServer that
44
- * can be used for testing. The emails are stored in an array that
45
- * can be examined to validate the content.
46
- */
47
- class testSmtpServer {
48
- constructor(options) {
49
- // eslint-disable-next-line @typescript-eslint/no-empty-function
50
- this.debug = (_message, ..._optionalParams) => { };
51
- this.emails = [];
52
- this.isDebugging = false;
53
- this.localhostOnly = true;
54
- this.port = 1025;
55
- if (options) {
56
- if (options.smtpPort) {
57
- this.port = options.smtpPort;
58
- }
59
- if (options.localhostOnly) {
60
- this.localhostOnly = options.localhostOnly;
61
- }
62
- if (options.debug) {
63
- this.debug = options.debug;
64
- }
65
- }
66
- // eslint-disable-next-line @typescript-eslint/no-this-alias
67
- const that = this; // preserve for use in other objects
68
- this.server = new smtp_server_1.SMTPServer({
69
- authOptional: true,
70
- onConnect(session, callback) {
71
- // 172.17 prefix is a linux docker container
72
- if (that.localhostOnly && !session.remoteAddress.match(/^172.17|127.0.0.1|::1$/)) {
73
- return callback(new Error("Only connections from localhost allowed"));
74
- }
75
- return callback(); // Accept the connection
76
- },
77
- onAuth(auth, _session, callback) {
78
- that.debug(`SMTP login for user: ${auth.username}`);
79
- callback(null, { user: auth.username });
80
- },
81
- onData(stream, session, callback) {
82
- const buffers = [];
83
- const writer = new stream_1.Writable({
84
- write(data, _encoding, writerCallback) {
85
- buffers.push(data);
86
- writerCallback();
87
- },
88
- });
89
- stream.pipe(writer);
90
- stream.on("end", () => {
91
- const buffer = Buffer.concat(buffers);
92
- const email = new eMail(session.envelope, buffer);
93
- that.emails.push(email);
94
- if (that.isDebugging) {
95
- that.debug(JSON.stringify(email, (key, value) => {
96
- if ("buffer" === key) {
97
- return buffer.toString();
98
- }
99
- else {
100
- return value;
101
- }
102
- }, 2));
103
- }
104
- callback();
105
- });
106
- },
107
- secure: true,
108
- });
109
- }
110
- /**
111
- * Clear the set of emails.
112
- *
113
- * @returns number of emails deleted
114
- */
115
- clearEmails() {
116
- const count = this.emails.length;
117
- this.emails.length = 0;
118
- return count;
119
- }
120
- /**
121
- * Retrieve the set of emails in order from oldest to most recent.
122
- *
123
- * @returns array of eMail objects
124
- */
125
- getEmails() {
126
- return this.emails;
127
- }
128
- /**
129
- * Query for the port number used by the server.
130
- *
131
- * @returns the port number being used
132
- */
133
- getPort() {
134
- return this.port;
135
- }
136
- /** Start the server */
137
- startServer() {
138
- this.server.listen(this.port);
139
- }
140
- /** Stop the server */
141
- stopServer() {
142
- this.server.close();
143
- }
144
- }
145
- exports.testSmtpServer = testSmtpServer;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.testSmtpServer = exports.eMail = void 0;
4
+ const smtp_server_1 = require("smtp-server");
5
+ const mailparser_1 = require("mailparser");
6
+ const stream_1 = require("stream");
7
+ /**
8
+ * Class to describe an email. The `envelope` contains the SMTP routing
9
+ * information. This may not match the `to/cc/bcc` information in the
10
+ * email contaents. The buffer contains the raw email content. To easily
11
+ * access parts of the email, `getParsed` should be used.
12
+ */
13
+ class eMail {
14
+ constructor(envelope, buffer) {
15
+ this.buffer = null;
16
+ this.length = 0;
17
+ this.envelope = envelope;
18
+ this.buffer = buffer;
19
+ }
20
+ /**
21
+ * Return a parsed email as formatted by `simpleParser`.
22
+ *
23
+ * @returns Promise<ParsedMail> See
24
+ * https://nodemailer.com/extras/mailparser/ for the structure.
25
+ */
26
+ async getParsed() {
27
+ if (this.buffer) {
28
+ const stream = stream_1.Readable.from(this.buffer);
29
+ const options = {
30
+ skipHtmlToText: true,
31
+ skipTextLinks: true,
32
+ skipTextToHtml: true
33
+ };
34
+ return (0, mailparser_1.simpleParser)(stream, options);
35
+ }
36
+ else {
37
+ throw new Error("Empty email buffer");
38
+ }
39
+ }
40
+ }
41
+ exports.eMail = eMail;
42
+ /**
43
+ * Create a testSmtpServer. This provides a wrapper to SMTPServer that
44
+ * can be used for testing. The emails are stored in an array that
45
+ * can be examined to validate the content.
46
+ */
47
+ class testSmtpServer {
48
+ constructor(options) {
49
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
50
+ this.debug = (_message, ..._optionalParams) => { };
51
+ this.emails = [];
52
+ this.isDebugging = false;
53
+ this.localhostOnly = true;
54
+ this.port = 1025;
55
+ if (options) {
56
+ if (options.smtpPort) {
57
+ this.port = options.smtpPort;
58
+ }
59
+ if (options.localhostOnly) {
60
+ this.localhostOnly = options.localhostOnly;
61
+ }
62
+ if (options.debug) {
63
+ this.debug = options.debug;
64
+ }
65
+ }
66
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
67
+ const that = this; // preserve for use in other objects
68
+ this.server = new smtp_server_1.SMTPServer({
69
+ authOptional: true,
70
+ onConnect(session, callback) {
71
+ // 172.17 prefix is a linux docker container
72
+ if (that.localhostOnly && !session.remoteAddress.match(/^172.17|127.0.0.1|::1$/)) {
73
+ return callback(new Error("Only connections from localhost allowed"));
74
+ }
75
+ return callback(); // Accept the connection
76
+ },
77
+ onAuth(auth, _session, callback) {
78
+ that.debug(`SMTP login for user: ${auth.username}`);
79
+ callback(null, { user: auth.username });
80
+ },
81
+ onData(stream, session, callback) {
82
+ const buffers = [];
83
+ const writer = new stream_1.Writable({
84
+ write(data, _encoding, writerCallback) {
85
+ buffers.push(data);
86
+ writerCallback();
87
+ },
88
+ });
89
+ stream.pipe(writer);
90
+ stream.on("end", () => {
91
+ const buffer = Buffer.concat(buffers);
92
+ const email = new eMail(session.envelope, buffer);
93
+ that.emails.push(email);
94
+ if (that.isDebugging) {
95
+ that.debug(JSON.stringify(email, (key, value) => {
96
+ if ("buffer" === key) {
97
+ return buffer.toString();
98
+ }
99
+ else {
100
+ return value;
101
+ }
102
+ }, 2));
103
+ }
104
+ callback();
105
+ });
106
+ },
107
+ secure: true,
108
+ });
109
+ }
110
+ /**
111
+ * Clear the set of emails.
112
+ *
113
+ * @returns number of emails deleted
114
+ */
115
+ clearEmails() {
116
+ const count = this.emails.length;
117
+ this.emails.length = 0;
118
+ return count;
119
+ }
120
+ /**
121
+ * Retrieve the set of emails in order from oldest to most recent.
122
+ *
123
+ * @returns array of eMail objects
124
+ */
125
+ getEmails() {
126
+ return this.emails;
127
+ }
128
+ /**
129
+ * Query for the port number used by the server.
130
+ *
131
+ * @returns the port number being used
132
+ */
133
+ getPort() {
134
+ return this.port;
135
+ }
136
+ /** Start the server */
137
+ startServer() {
138
+ this.server.listen(this.port);
139
+ }
140
+ /** Stop the server */
141
+ stopServer() {
142
+ this.server.close();
143
+ }
144
+ }
145
+ exports.testSmtpServer = testSmtpServer;
146
146
  //# sourceMappingURL=test-smtp-server.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "test-smtp-server",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
4
4
  "description": "The test-smtp-server package allows internal testing of projects needing an SMTP server.",
5
5
  "main": "./build/lib/test-smtp-server.js",
6
6
  "types": "./build/lib/test-smtp-server.d.ts",
@@ -17,7 +17,9 @@
17
17
  "lint": "eslint --ignore-path .gitignore -c .eslintrc.js --ext .ts,.js \"{lib,test}/**/*.{ts,tsx,mjs,js}\"",
18
18
  "test": "npm run test:ts && npm run test:js",
19
19
  "test:ts": "node build/test/index.js",
20
- "test:js": "node test/jstest.mjs"
20
+ "test:js": "node test/jstest.mjs",
21
+ "preversion": "npm run build && npm test",
22
+ "postversion": "git push --follow-tags"
21
23
  },
22
24
  "bugs": {
23
25
  "url": "https://github.com/webstech/test-smtp-server/issues"
@@ -44,21 +46,21 @@
44
46
  "url": "git+https://github.com/webstech/test-smtp-server"
45
47
  },
46
48
  "devDependencies": {
47
- "@types/nodemailer": "^6.4.7",
49
+ "@types/nodemailer": "^6.4.9",
48
50
  "@types/smtp-server": "^3.5.7",
49
- "@typescript-eslint/eslint-plugin": "^5.47.0",
50
- "@typescript-eslint/parser": "^5.47.0",
51
- "commander": "^9.4.1",
52
- "eslint": "^8.30.0",
53
- "eslint-config-prettier": "^8.5.0",
54
- "eslint-plugin-jsdoc": "^39.6.4",
55
- "nodemailer": "^6.7.5",
56
- "typescript": "^4.9.4"
51
+ "@typescript-eslint/eslint-plugin": "^6.2.1",
52
+ "@typescript-eslint/parser": "^6.2.1",
53
+ "commander": "^11.0.0",
54
+ "eslint": "^8.46.0",
55
+ "eslint-config-prettier": "^8.9.0",
56
+ "eslint-plugin-jsdoc": "^46.4.5",
57
+ "nodemailer": "^6.9.4",
58
+ "typescript": "^5.1.6"
57
59
  },
58
60
  "dependencies": {
59
61
  "@types/mailparser": "^3.4.0",
60
- "mailparser": "^3.6.2",
61
- "smtp-server": "^3.11.0"
62
+ "mailparser": "^3.6.5",
63
+ "smtp-server": "^3.12.0"
62
64
  },
63
65
  "engines": {
64
66
  "node": ">= 16.0.0"