@timshel_npm/maildev 3.2.7 → 3.2.9

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
@@ -30,8 +30,8 @@ Or can be installed using [Github](https://docs.npmjs.com/cli/v10/configuring-np
30
30
  Ex:
31
31
  ```json
32
32
  "devDependencies": {
33
- "maildev": "github:timshel/maildev#3.2.7",
34
- "maildev": "npm:@timshel_npm/maildev@^3.2.7"
33
+ "maildev": "github:timshel/maildev#3.2.9",
34
+ "maildev": "npm:@timshel_npm/maildev@^3.2.9"
35
35
  }
36
36
  ```
37
37
 
@@ -148,9 +148,9 @@ Usage: maildev [options]
148
148
  | `--disable-web` | `MAILDEV_DISABLE_WEB` | Disable the use of the web interface. Useful for unit testing |
149
149
  | `--hide-extensions <extensions>` | `MAILDEV_HIDE_EXTENSIONS` | Comma separated list of SMTP extensions to NOT advertise (SMTPUTF8, PIPELINING, 8BITMIME) |
150
150
  | `-o, --open` | | Open the Web GUI after startup |
151
- | `-v, --verbose` | | |
152
- | `--silent` | | |
153
- | `--log-mail-contents` | | Log a JSON representation of each incoming mail |
151
+ | `-v, --verbose` | `MAILDEV_VERBOSE` | Display log level message |
152
+ | `--silent` | `MAILDEV_SILENT` | Display only error level message (ignored if `verbose` is active) |
153
+ | `--log-mail-contents` | `MAILDEV_LOG_CONTENT` | Log a JSON representation of each incoming mail |
154
154
 
155
155
 
156
156
  ## Outgoing email
@@ -1,2 +1 @@
1
- declare function _exports(str: any, now: any): number | false;
2
- export = _exports;
1
+ export function strtotime(str: any, now: any): number | false;
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  // From: https://raw.githubusercontent.com/locutusjs/locutus/main/src/php/datetime/strtotime.js
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.strtotime = strtotime;
3
5
  const reSpace = "[ \\t]+";
4
6
  const reSpaceOpt = "[ \\t]*";
5
7
  const reMeridian = "(?:([ap])\\.?m\\.?([\\t ]|$))";
@@ -1178,7 +1180,7 @@ const resultProto = {
1178
1180
  return result;
1179
1181
  },
1180
1182
  };
1181
- module.exports = function strtotime(str, now) {
1183
+ function strtotime(str, now) {
1182
1184
  // discuss at: https://locutus.io/php/strtotime/
1183
1185
  // original by: Caio Ariede (https://caioariede.com)
1184
1186
  // improved by: Kevin van Zonneveld (https://kvz.io)
@@ -1298,4 +1300,4 @@ module.exports = function strtotime(str, now) {
1298
1300
  longestMatch = null;
1299
1301
  }
1300
1302
  return Math.floor(result.toDate(new Date(now * 1000)) / 1000);
1301
- };
1303
+ }
@@ -1,2 +1,11 @@
1
1
  export function setLevel(level: any): void;
2
+ /**
3
+ * The error method will always log to the console
4
+ */
5
+ export function error(...args: any[]): void;
6
+ /**
7
+ * Log only when set to verbose (2)
8
+ */
9
+ export function log(...args: any[]): void;
2
10
  export function info(...args: any[]): void;
11
+ export function warn(...args: any[]): void;
@@ -1,30 +1,38 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setLevel = setLevel;
4
+ exports.error = error;
5
+ exports.log = log;
6
+ exports.info = info;
7
+ exports.warn = warn;
2
8
  /**
3
9
  * MailDev - logger.js
4
10
  */
5
11
  let logLevel = 1;
6
- module.exports = {};
12
+ function setLevel(level) {
13
+ logLevel = level;
14
+ }
7
15
  /**
8
- * Initialize the logger
16
+ * The error method will always log to the console
9
17
  */
10
- module.exports.setLevel = function (level) {
11
- logLevel = level;
12
- };
18
+ function error() {
19
+ console.error.apply(console, arguments);
20
+ }
13
21
  /**
14
- * The info method will always log to the console
22
+ * Log only when set to verbose (2)
15
23
  */
16
- module.exports.info = function () {
24
+ function log() {
25
+ if (logLevel > 1) {
26
+ console.log.apply(console, arguments);
27
+ }
28
+ }
29
+ function info() {
17
30
  if (logLevel > 0) {
18
31
  console.info.apply(console, arguments);
19
32
  }
20
- };
21
- /**
22
- * Extend the basic console.x functions, checking if the logging is on
23
- */
24
- ["log", "dir", "warn", "error"].forEach(function (fn) {
25
- module.exports[fn] = function () {
26
- if (logLevel > 1) {
27
- console[fn].apply(console, arguments);
28
- }
29
- };
30
- });
33
+ }
34
+ function warn() {
35
+ if (logLevel > 0) {
36
+ console.warn.apply(console, arguments);
37
+ }
38
+ }
@@ -11,9 +11,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.parse = parse;
13
13
  const mime_1 = require("mime");
14
- const simpleParser = require("mailparser").simpleParser;
15
- const strtotime = require("./helpers/strtotime");
14
+ const strtotime_1 = require("./helpers/strtotime");
16
15
  const logger = require("./logger");
16
+ const simpleParser = require("mailparser").simpleParser;
17
17
  function parse(input) {
18
18
  return __awaiter(this, void 0, void 0, function* () {
19
19
  return simpleParser(input, {}).then((parsed) => {
@@ -237,7 +237,7 @@ function parseDateString(value) {
237
237
  if (Object.prototype.toString.call(date) !== "[object Date]" ||
238
238
  date.toString() === "Invalid Date") {
239
239
  try {
240
- date = strtotime(value);
240
+ date = (0, strtotime_1.strtotime)(value);
241
241
  }
242
242
  catch (E) {
243
243
  return false;
@@ -35,6 +35,7 @@ export declare class MailServer {
35
35
  mailEventSubjectMapper: (Mail: any) => string | undefined;
36
36
  smtp: typeof SMTPServer;
37
37
  outgoing: Outgoing | undefined;
38
+ private _reloadInProgress;
38
39
  /**
39
40
  * Extend Event Emitter methods
40
41
  * events:
@@ -111,5 +112,6 @@ export declare class MailServer {
111
112
  * Download a given email
112
113
  */
113
114
  getEmailEml(id: any): Promise<[string, string, ReadStream]>;
114
- loadMailsFromDirectory(): Promise<void[]>;
115
+ loadMailsFromDirectory(): Promise<void>;
116
+ private _loadMailsFromDirectory;
115
117
  }
@@ -28,14 +28,14 @@ const smtp_1 = require("./helpers/smtp");
28
28
  const mailbuffer_1 = require("./mailbuffer");
29
29
  const mailparser_1 = require("./mailparser");
30
30
  const outgoing_1 = require("./outgoing");
31
+ const logger = require("./logger");
32
+ const utils = require("./utils");
31
33
  const smtp_server_1 = require("smtp-server");
32
34
  const fs_1 = require("fs");
33
35
  const events = require("events");
34
36
  const fs = require("fs");
35
37
  const os = require("os");
36
38
  const path = require("path");
37
- const utils = require("./utils");
38
- const logger = require("./logger");
39
39
  const createDOMPurify = require("dompurify");
40
40
  const { JSDOM } = require("jsdom");
41
41
  const defaultPort = 1025;
@@ -107,6 +107,7 @@ class MailServer {
107
107
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
108
108
  this.store = [];
109
109
  this.eventEmitter = new events.EventEmitter();
110
+ this._reloadInProgress = undefined;
110
111
  /**
111
112
  * Extend Event Emitter methods
112
113
  * events:
@@ -379,6 +380,19 @@ class MailServer {
379
380
  });
380
381
  }
381
382
  loadMailsFromDirectory() {
383
+ return __awaiter(this, void 0, void 0, function* () {
384
+ if (this._reloadInProgress == undefined) {
385
+ this._reloadInProgress = this._loadMailsFromDirectory().finally(() => {
386
+ this._reloadInProgress = undefined;
387
+ });
388
+ return this._reloadInProgress;
389
+ }
390
+ else {
391
+ return this._reloadInProgress;
392
+ }
393
+ });
394
+ }
395
+ _loadMailsFromDirectory() {
382
396
  return __awaiter(this, void 0, void 0, function* () {
383
397
  const self = this;
384
398
  const persistencePath = yield fs_1.promises.realpath(this.mailDir);
@@ -387,14 +401,19 @@ class MailServer {
387
401
  throw new Error(`Error during reading of the mailDir ${persistencePath}`);
388
402
  });
389
403
  this.store.length = 0;
390
- const saved = files.map(function (file) {
391
- return __awaiter(this, void 0, void 0, function* () {
392
- const id = path.parse(file).name;
393
- const email = yield getDiskEmail(self.mailDir, id);
394
- return saveEmailToStore(self, email);
404
+ this.eventEmitter.emit("delete", { id: "all" });
405
+ const concurrency = 20;
406
+ for (let i = 0; i < files.length; i += concurrency) {
407
+ const chunk = files.slice(i, i + concurrency);
408
+ let saved = chunk.map(function (file) {
409
+ return __awaiter(this, void 0, void 0, function* () {
410
+ const id = path.parse(file).name;
411
+ const email = yield getDiskEmail(self.mailDir, id);
412
+ return saveEmailToStore(self, email);
413
+ });
395
414
  });
396
- });
397
- return Promise.all(saved);
415
+ yield Promise.all(saved);
416
+ }
398
417
  });
399
418
  }
400
419
  }
@@ -5,18 +5,40 @@ exports.cliOptions = cliOptions;
5
5
  const program = require("commander").program;
6
6
  const pkg = require("../../package.json");
7
7
  const fs = require("fs");
8
+ /*
9
+ * Converts a string to a bool.
10
+ * - match 'true', 'on', or '1' as true.
11
+ * - ignore all white-space padding
12
+ * - ignore capitalization (case).
13
+ */
14
+ function parseBoolean(s) {
15
+ let regex = /^\s*(true|1|on)\s*$/i;
16
+ return regex.test(s);
17
+ }
8
18
  const options = [
9
19
  // General config
10
- ["-v, --verbose"],
11
- ["--silent"],
12
- ["--log-mail-contents", "Log a JSON representation of each incoming email"],
20
+ ["-v, --verbose", "MAILDEV_VERBOSE", "Display log level message", false, parseBoolean],
21
+ ["--silent", "MAILDEV_SILENT", "Display only error level message", false, parseBoolean],
22
+ [
23
+ "--log-mail-contents",
24
+ "MAILDEV_LOG_CONTENT",
25
+ "Log a JSON representation of each incoming email",
26
+ false,
27
+ parseBoolean,
28
+ ],
13
29
  // SMTP server parameters
14
- ["-s, --smtp <port>", "MAILDEV_SMTP_PORT", "SMTP port to catch emails", 1025, (x) => parseInt(x)],
30
+ ["-s, --smtp <port>", "MAILDEV_SMTP_PORT", "SMTP port to catch emails", 1025, parseInt],
15
31
  ["--ip <ip address>", "MAILDEV_IP", "IP Address to bind SMTP service to", "0.0.0.0"],
16
32
  ["--mail-directory <path>", "MAILDEV_MAIL_DIRECTORY", "Directory for persisting mails"],
17
33
  ["--incoming-user <user>", "MAILDEV_INCOMING_USER", "SMTP user for incoming emails"],
18
34
  ["--incoming-pass <pass>", "MAILDEV_INCOMING_PASS", "SMTP password for incoming emails"],
19
- ["--incoming-secure", "MAILDEV_INCOMING_SECURE", "Use SMTP SSL for incoming emails", false],
35
+ [
36
+ "--incoming-secure",
37
+ "MAILDEV_INCOMING_SECURE",
38
+ "Use SMTP SSL for incoming emails",
39
+ false,
40
+ parseBoolean,
41
+ ],
20
42
  ["--incoming-cert <path>", "MAILDEV_INCOMING_CERT", "Cert file location for incoming SSL"],
21
43
  ["--incoming-key <path>", "MAILDEV_INCOMING_KEY", "Key file location for incoming SSL"],
22
44
  [
@@ -33,15 +55,16 @@ const options = [
33
55
  "Use auto-relay mode. Optional relay email address",
34
56
  ],
35
57
  ["--outgoing-host <host>", "MAILDEV_OUTGOING_HOST", "SMTP host for outgoing emails"],
36
- [
37
- "--outgoing-port <port>",
38
- "MAILDEV_OUTGOING_PORT",
39
- "SMTP port for outgoing emails",
40
- (x) => parseInt(x),
41
- ],
58
+ ["--outgoing-port <port>", "MAILDEV_OUTGOING_PORT", "SMTP port for outgoing emails", parseInt],
42
59
  ["--outgoing-user <user>", "MAILDEV_OUTGOING_USER", "SMTP user for outgoing emails"],
43
60
  ["--outgoing-pass <password>", "MAILDEV_OUTGOING_PASS", "SMTP password for outgoing emails"],
44
- ["--outgoing-secure", "MAILDEV_OUTGOING_SECURE", "Use SMTP SSL for outgoing emails", false],
61
+ [
62
+ "--outgoing-secure",
63
+ "MAILDEV_OUTGOING_SECURE",
64
+ "Use SMTP SSL for outgoing emails",
65
+ false,
66
+ parseBoolean,
67
+ ],
45
68
  ["--auto-relay-rules <file>", "MAILDEV_AUTO_RELAY_RULES", "Filter rules for auto relay mode"],
46
69
  // Web app config
47
70
  [
@@ -49,8 +72,9 @@ const options = [
49
72
  "MAILDEV_DISABLE_WEB",
50
73
  "Disable the use of the web interface. Useful for unit testing",
51
74
  false,
75
+ parseBoolean,
52
76
  ],
53
- ["-w, --web <port>", "MAILDEV_WEB_PORT", "Port to run the Web GUI", 1080, (x) => parseInt(x)],
77
+ ["-w, --web <port>", "MAILDEV_WEB_PORT", "Port to run the Web GUI", 1080, parseInt],
54
78
  [
55
79
  "--web-ip <ip address>",
56
80
  "MAILDEV_WEB_IP",
@@ -64,19 +88,24 @@ const options = [
64
88
  'External domain name (used for socket CORS, "*" otherwise)',
65
89
  ],
66
90
  ["--base-pathname <path>", "MAILDEV_BASE_PATHNAME", "Base path for URLs"],
67
- ["--https", "MAILDEV_HTTPS", "Switch from http to https protocol", false],
91
+ ["--https", "MAILDEV_HTTPS", "Switch from http to https protocol", false, parseBoolean],
68
92
  ["--https-key <file>", "MAILDEV_HTTPS_KEY", "The file path to the ssl private key"],
69
93
  ["--https-cert <file>", "MAILDEV_HTTPS_CERT", "The file path to the ssl cert file"],
70
94
  ];
71
95
  function appendOptions(program, options) {
72
96
  return options.reduce(function (chain, option) {
73
- var _a;
74
97
  const flag = option[0];
75
- const envVariable = typeof option[1] === "string" ? option[1] : undefined;
76
- const description = typeof option[2] === "string" ? option[2] : undefined;
77
- const defaultValue = envVariable ? ((_a = process.env[envVariable]) !== null && _a !== void 0 ? _a : option[3]) : option[3];
98
+ const envVariable = option[1];
99
+ const description = option[2];
78
100
  const fn = option[4];
79
- return fn
101
+ const defaultValue = envVariable
102
+ ? process.env[envVariable]
103
+ ? fn
104
+ ? fn(process.env[envVariable])
105
+ : process.env[envVariable]
106
+ : option[3]
107
+ : option[3];
108
+ return fn && fn != parseBoolean
80
109
  ? chain.option(flag, description, fn, defaultValue)
81
110
  : chain.option(flag, description, defaultValue);
82
111
  }, program);
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Outgoing = void 0;
4
+ const logger = require("./logger");
4
5
  const SMTPConnection = require("nodemailer/lib/smtp-connection");
5
6
  const async = require("async");
6
7
  const fs = require("fs");
7
- const logger = require("./logger");
8
8
  const wildstring = require("wildstring");
9
9
  class Outgoing {
10
10
  constructor(options) {
@@ -1,13 +1,22 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.routes = routes;
13
+ const utils_1 = require("./utils");
4
14
  /**
5
15
  * MailDev - routes
6
16
  */
7
17
  const express = require("express");
8
18
  const compression = require("compression");
9
19
  const pkg = require("../../package.json");
10
- const { filterEmails } = require("./utils");
11
20
  const emailRegexp = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
12
21
  function routes(app, mailserver, basePathname) {
13
22
  const router = express.Router();
@@ -19,7 +28,7 @@ function routes(app, mailserver, basePathname) {
19
28
  router.get("/email", compression(), function (req, res) {
20
29
  mailserver
21
30
  .getAllEmail()
22
- .then((mails) => res.status(200).json(req.query ? filterEmails(mails, req.query) : mails))
31
+ .then((mails) => res.status(200).json(req.query ? (0, utils_1.filterEmails)(mails, req.query) : mails))
23
32
  .catch((err) => res.status(500).json({ error: err.message }));
24
33
  });
25
34
  // Get single email
@@ -132,8 +141,10 @@ function routes(app, mailserver, basePathname) {
132
141
  res.status(200).json(true);
133
142
  });
134
143
  router.get("/reloadMailsFromDirectory", function (req, res) {
135
- mailserver.loadMailsFromDirectory();
136
- res.status(200).json(true);
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ yield mailserver.loadMailsFromDirectory();
146
+ res.status(200).json(true);
147
+ });
137
148
  });
138
149
  app.use(basePathname, router);
139
150
  }
@@ -1,4 +1,5 @@
1
+ import type { Mail } from "./type";
1
2
  export declare function makeId(): string;
2
3
  export declare function formatBytes(bytes: number, decimals?: number): string;
3
- export declare function filterEmails(emails: string[], query: any): string[];
4
+ export declare function filterEmails(emails: Mail[], query: any): Mail[];
4
5
  export declare function delay(ms: any): Promise<void>;
package/dist/lib/web.js CHANGED
@@ -2,14 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Web = void 0;
4
4
  const routes_1 = require("./routes");
5
+ const auth_1 = require("./auth");
6
+ const logger = require("./logger");
5
7
  const express = require("express");
6
8
  const cors = require("cors");
7
9
  const fs = require("fs");
8
10
  const http = require("http");
9
11
  const https = require("https");
10
12
  const socketio = require("socket.io");
11
- const auth = require("./auth");
12
- const logger = require("./logger");
13
13
  const path = require("path");
14
14
  class Web {
15
15
  constructor(mailserver, options) {
@@ -30,7 +30,7 @@ class Web {
30
30
  }, app)
31
31
  : http.createServer(app);
32
32
  if (options === null || options === void 0 ? void 0 : options.auth) {
33
- app.use(auth((_d = options === null || options === void 0 ? void 0 : options.auth) === null || _d === void 0 ? void 0 : _d.user, (_e = options === null || options === void 0 ? void 0 : options.auth) === null || _e === void 0 ? void 0 : _e.pass));
33
+ app.use((0, auth_1.auth)((_d = options === null || options === void 0 ? void 0 : options.auth) === null || _d === void 0 ? void 0 : _d.user, (_e = options === null || options === void 0 ? void 0 : options.auth) === null || _e === void 0 ? void 0 : _e.pass));
34
34
  }
35
35
  this.io = socketio({
36
36
  path: path.posix.join(this.basePathname, "/socket.io"),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@timshel_npm/maildev",
3
3
  "description": "SMTP Server with async API and Web Interface for viewing and testing emails during development",
4
- "version": "3.2.7",
4
+ "version": "3.2.9",
5
5
  "keywords": [
6
6
  "email",
7
7
  "e-mail",
@@ -60,18 +60,19 @@
60
60
  "async": "3.2.6",
61
61
  "commander": "14.0.2",
62
62
  "compression": "1.8.1",
63
- "cors": "2.8.5",
63
+ "cors": "2.8.6",
64
64
  "dompurify": "3.3.1",
65
65
  "express": "5.2.1",
66
66
  "jsdom": "27.4.0",
67
67
  "mailparser": "3.9.1",
68
68
  "mime": "4.1.0",
69
- "nodemailer": "7.0.12",
69
+ "nodemailer": "7.0.13",
70
70
  "smtp-server": "3.18.0",
71
71
  "socket.io": "4.8.3",
72
72
  "wildstring": "1.0.9"
73
73
  },
74
74
  "overrides": {
75
+ "diff": "8.0.3",
75
76
  "socket.io-adapter": "2.5.5",
76
77
  "qs": "6.14.1"
77
78
  },
@@ -85,8 +86,8 @@
85
86
  "mocha": "11.7.5",
86
87
  "nodemon": "3.1.11",
87
88
  "nyc": "17.1.0",
88
- "prettier": "3.7.4",
89
- "sass": "1.97.2",
89
+ "prettier": "3.8.1",
90
+ "sass": "1.97.3",
90
91
  "ts-node": "10.9.2",
91
92
  "ts-node-dev": "2.0.0",
92
93
  "typescript": "5.9.3"