test-smtp-server 0.9.7 → 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 +77 -77
- package/build/lib/test-smtp-server.d.ts +69 -69
- package/build/lib/test-smtp-server.js +145 -145
- package/package.json +12 -12
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 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
|
+
# 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.
|
|
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",
|
|
@@ -46,21 +46,21 @@
|
|
|
46
46
|
"url": "git+https://github.com/webstech/test-smtp-server"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@types/nodemailer": "^6.4.
|
|
49
|
+
"@types/nodemailer": "^6.4.9",
|
|
50
50
|
"@types/smtp-server": "^3.5.7",
|
|
51
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
52
|
-
"@typescript-eslint/parser": "^
|
|
53
|
-
"commander": "^
|
|
54
|
-
"eslint": "^8.
|
|
55
|
-
"eslint-config-prettier": "^8.
|
|
56
|
-
"eslint-plugin-jsdoc": "^
|
|
57
|
-
"nodemailer": "^6.
|
|
58
|
-
"typescript": "^
|
|
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"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@types/mailparser": "^3.4.0",
|
|
62
|
-
"mailparser": "^3.6.
|
|
63
|
-
"smtp-server": "^3.
|
|
62
|
+
"mailparser": "^3.6.5",
|
|
63
|
+
"smtp-server": "^3.12.0"
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">= 16.0.0"
|