@timshel_npm/maildev 3.2.17 → 3.2.19

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.
Files changed (39) hide show
  1. package/README.md +2 -2
  2. package/dist/app/components/angular/angular.js +5537 -3622
  3. package/dist/app/components/angular/angular.min.js +213 -196
  4. package/dist/app/components/angular/angular.min.js.map +4 -4
  5. package/dist/app/components/angular-cookies/angular-cookies.js +183 -179
  6. package/dist/app/components/angular-cookies/angular-cookies.min.js +5 -5
  7. package/dist/app/components/angular-cookies/angular-cookies.min.js.map +7 -7
  8. package/dist/app/components/angular-resource/angular-resource.js +129 -48
  9. package/dist/app/components/angular-resource/angular-resource.min.js +8 -7
  10. package/dist/app/components/angular-resource/angular-resource.min.js.map +3 -3
  11. package/dist/app/components/angular-route/angular-route.js +246 -216
  12. package/dist/app/components/angular-route/angular-route.min.js +9 -9
  13. package/dist/app/components/angular-route/angular-route.min.js.map +2 -2
  14. package/dist/app/components/angular-sanitize/angular-sanitize.js +122 -90
  15. package/dist/app/components/angular-sanitize/angular-sanitize.min.js +10 -9
  16. package/dist/app/components/angular-sanitize/angular-sanitize.min.js.map +3 -3
  17. package/dist/app/components/socket.io/socket.io.min.js +3 -3
  18. package/dist/app/index.html +13 -14
  19. package/dist/app/styles/style.css +998 -37
  20. package/dist/app/views/item.html +64 -82
  21. package/dist/lib/mailserver.d.ts +1 -1
  22. package/dist/lib/mailserver.js +12 -11
  23. package/dist/lib/routes.js +2 -3
  24. package/package.json +15 -17
  25. package/dist/app/webfonts/fa-brands-400.eot +0 -0
  26. package/dist/app/webfonts/fa-brands-400.svg +0 -3717
  27. package/dist/app/webfonts/fa-brands-400.ttf +0 -0
  28. package/dist/app/webfonts/fa-brands-400.woff +0 -0
  29. package/dist/app/webfonts/fa-brands-400.woff2 +0 -0
  30. package/dist/app/webfonts/fa-regular-400.eot +0 -0
  31. package/dist/app/webfonts/fa-regular-400.svg +0 -801
  32. package/dist/app/webfonts/fa-regular-400.ttf +0 -0
  33. package/dist/app/webfonts/fa-regular-400.woff +0 -0
  34. package/dist/app/webfonts/fa-regular-400.woff2 +0 -0
  35. package/dist/app/webfonts/fa-solid-900.eot +0 -0
  36. package/dist/app/webfonts/fa-solid-900.svg +0 -5028
  37. package/dist/app/webfonts/fa-solid-900.ttf +0 -0
  38. package/dist/app/webfonts/fa-solid-900.woff +0 -0
  39. package/dist/app/webfonts/fa-solid-900.woff2 +0 -0
@@ -7,61 +7,60 @@
7
7
  ng-click="toggleDropdown($event, 'display')"
8
8
  ng-class="{ open: dropdownOpen == 'display' }"
9
9
  >
10
- <span ng-if="!panelVisibility || panelVisibility === 'html'"><i class="fas fa-file-code"></i> HTML</span>
11
- <span ng-if="panelVisibility === 'plain'"><i class="fas fa-file-alt"></i> Text</span>
12
- <span ng-if="panelVisibility === 'attachments'"><i class="fas fa-paperclip"></i> Attachments</span>
13
- <span ng-if="panelVisibility === 'headers'"><i class="fas fa-th-list"></i> Headers</span>
14
- <span ng-if="panelVisibility === 'source'"><i class="fas fa-code"></i> Source</span>
10
+ <span ng-if="!panelVisibility || panelVisibility === 'html'" class="fa7 fa7-solid--file-code"></span>
11
+ <span ng-if="!panelVisibility || panelVisibility === 'html'">HTML</span>
12
+
13
+ <span ng-if="panelVisibility === 'plain'" class="fa7 fa7-solid--file-alt"></span>
14
+ <span ng-if="panelVisibility === 'plain'">Text</span>
15
+
16
+ <span ng-if="panelVisibility === 'attachments'" class="fa7 fa7-solid--paperclip"></span>
17
+ <span ng-if="panelVisibility === 'attachments'">Attachments</span>
18
+
19
+ <span ng-if="panelVisibility === 'headers'" class="fa7 fa7-solid--th-list"></span>
20
+ <span ng-if="panelVisibility === 'headers'">Headers</span>
21
+
22
+ <span ng-if="panelVisibility === 'source'" class="fa7 fa7-solid--code"></span>
23
+ <span ng-if="panelVisibility === 'source'">Source</span>
15
24
  </a>
16
25
  <ul class="dropdown-menu">
17
26
  <li>
18
27
  <a href="" class=""
19
28
  ng-click="show('html')"
20
29
  ng-class="{ active: panelVisibility == 'html', disabled: !item.html }">
21
- <span>
22
- <i class="fas fa-file-code"></i>
23
- HTML
24
- </span>
30
+ <span class="fa7 fa7-solid--file-code"></span>
31
+ <span>HTML</span>
25
32
  </a>
26
33
  </li>
27
34
  <li>
28
35
  <a href="" class=""
29
36
  ng-click="show('plain')"
30
37
  ng-class="{ active: panelVisibility == 'plain', disabled: !item.text }">
31
- <span>
32
- <i class="fas fa-file-alt"></i>
33
- Text
34
- </span>
38
+ <span class="fa7 fa7-solid--file-alt"></span>
39
+ <span>Text</span>
35
40
  </a>
36
41
  </li>
37
42
  <li>
38
43
  <a href="" class=""
39
44
  ng-click="show('attachments')"
40
45
  ng-class="{ active: panelVisibility == 'attachments', disabled: !item.attachments }">
41
- <span>
42
- <i class="fas fa-paperclip"></i>
43
- Attachments
44
- </span>
46
+ <span class="fa7 fa7-solid--paperclip"></span>
47
+ <span>Attachments</span>
45
48
  </a>
46
49
  </li>
47
50
  <li>
48
51
  <a href="" class=""
49
52
  ng-click="show('headers')"
50
53
  ng-class="{ active: panelVisibility == 'headers' }">
51
- <span>
52
- <i class="fas fa-th-list"></i>
53
- Headers
54
- </span>
54
+ <span class="fa7 fa7-solid--th-list"></span>
55
+ <span>Headers</span>
55
56
  </a>
56
57
  </li>
57
58
  <li>
58
59
  <a href="" class=""
59
60
  ng-click="show('source')"
60
61
  ng-class="{ active: panelVisibility == 'source' }">
61
- <span>
62
- <i class="fas fa-code"></i>
63
- Source ({{item.sizeHuman}})
64
- </span>
62
+ <span class="fa7 fa7-solid--code"></span>
63
+ <span>Source ({{item.sizeHuman}})</span>
65
64
  </a>
66
65
  </li>
67
66
  </ul>
@@ -73,15 +72,22 @@
73
72
  <a href="" class="dropdown-trigger"
74
73
  ng-click="toggleDropdown($event, 'viewport')"
75
74
  ng-class="{ open: dropdownOpen == 'viewport', disabled: panelVisibility != 'html' }">
76
- <!--
77
- <span ng-if="iframeSize == null"><i class="fas fa-ruler-combined"></i> 100%</span> -->
78
- <span ng-if="iframeSize == null"><i class="fas fa-desktop"></i> 100%</span>
79
- <span ng-if="iframeSize == '1440px'"><i class="fas fa-desktop"></i> 1440px</span>
80
- <span ng-if="iframeSize == '1024px'"><i class="fas fa-tablet-alt"></i> 1024px</span>
81
- <span ng-if="iframeSize == '768px'"><i class="fas fa-tablet-alt"></i> 768px</span>
82
- <span ng-if="iframeSize == '425px'"><i class="fas fa-mobile-alt"></i> 425px</span>
83
- <span ng-if="iframeSize == '375px'"><i class="fas fa-mobile-alt"></i> 375px</span>
84
- <span ng-if="iframeSize == '320px'"><i class="fas fa-mobile-alt"></i> 320px</span>
75
+ <span ng-if="iframeSize == null" class="fa7 fa7-solid--desktop"></span>
76
+ <span ng-if="iframeSize == null">100%</span>
77
+ <span ng-if="iframeSize == '1440px'" class="fa7 fa7-solid--desktop"></span>
78
+ <span ng-if="iframeSize == '1440px'">1440px</span>
79
+
80
+ <span ng-if="iframeSize == '1024px'" class="fa7 fa7-solid--tablet-alt"></span>
81
+ <span ng-if="iframeSize == '1024px'">1024px</span>
82
+ <span ng-if="iframeSize == '768px'" class="fa7 fa7-solid--tablet-alt">
83
+ <span ng-if="iframeSize == '768px'"></span> 768px</span>
84
+
85
+ <span ng-if="iframeSize == '425px'" class="fa7 fa7-solid--mobile-alt"></span>
86
+ <span ng-if="iframeSize == '425px'">425px</span>
87
+ <span ng-if="iframeSize == '375px'" class="fa7 fa7-solid--mobile-alt"></span>
88
+ <span ng-if="iframeSize == '375px'">375px</span>
89
+ <span ng-if="iframeSize == '320px'" class="fa7 fa7-solid--mobile-alt"></span>
90
+ <span ng-if="iframeSize == '320px'">320px</span>
85
91
 
86
92
  </a>
87
93
  <ul class="dropdown-menu">
@@ -90,70 +96,56 @@
90
96
  <a href="" class=""
91
97
  ng-click="resize()"
92
98
  ng-class="{ active: iframeSize == null }">
93
- <span>
94
- <i class="fas fa-desktop"></i>
95
- 100%
96
- </span>
99
+ <span class="fa7 fa7-solid--desktop"></span>
100
+ <span>100%</span>
97
101
  </a>
98
102
  </li>
99
103
  <li>
100
104
  <a href="" class=""
101
105
  ng-click="resize('1440px')"
102
106
  ng-class="{ active: iframeSize == '1440px' }">
103
- <span>
104
- <i class="fas fa-desktop"></i>
105
- 1440px
106
- </span>
107
+ <span class="fa7 fa7-solid--desktop"></span>
108
+ <span>1440px</span>
107
109
  </a>
108
110
  </li>
109
111
  <li>
110
112
  <a href="" class=""
111
113
  ng-click="resize('1024px')"
112
114
  ng-class="{ active: iframeSize == '1024px' }">
113
- <span>
114
- <i class="fas fa-tablet-alt"></i>
115
- 1024px
116
- </span>
115
+ <span class="fa7 fa7-solid--tablet-alt"></span>
116
+ <span>1024px</span>
117
117
  </a>
118
118
  </li>
119
119
  <li>
120
120
  <a href="" class=""
121
121
  ng-click="resize('768px')"
122
122
  ng-class="{ active: iframeSize == '768px' }">
123
- <span>
124
- <i class="fas fa-tablet-alt"></i>
125
- 768px
126
- </span>
123
+ <span class="fa7 fa7-solid--tablet-alt"></span>
124
+ <span>768px</span>
127
125
  </a>
128
126
  </li>
129
127
  <li>
130
128
  <a href="" class=""
131
129
  ng-click="resize('425px')"
132
130
  ng-class="{ active: iframeSize == '425px' }">
133
- <span>
134
- <i class="fas fa-mobile-alt"></i>
135
- 425px
136
- </span>
131
+ <span class="fa7 fa7-solid--mobile-alt"></span>
132
+ <span>425px</span>
137
133
  </a>
138
134
  </li>
139
135
  <li>
140
136
  <a href="" class=""
141
137
  ng-click="resize('375px')"
142
138
  ng-class="{ active: iframeSize == '375px' }">
143
- <span>
144
- <i class="fas fa-mobile-alt"></i>
145
- 375px
146
- </span>
139
+ <span class="fa7 fa7-solid--mobile-alt"></span>
140
+ <span>375px</span>
147
141
  </a>
148
142
  </li>
149
143
  <li>
150
144
  <a href="" class=""
151
145
  ng-click="resize('320px')"
152
146
  ng-class="{ active: iframeSize == '320px' }">
153
- <span>
154
- <i class="fas fa-mobile-alt"></i>
155
- 320px
156
- </span>
147
+ <span class="fa7 fa7-solid--mobile-alt"></span>
148
+ <span>320px</span>
157
149
  </a>
158
150
  </li>
159
151
  </ul>
@@ -162,10 +154,8 @@
162
154
 
163
155
  <li>
164
156
  <a href="email/{{item.id}}/download" class="">
165
- <span>
166
- <i class="fas fa-cloud-download-alt"></i>
167
- Download
168
- </span>
157
+ <span class="fa7 fa7-solid--cloud-download-alt"></span>
158
+ <span>Download</span>
169
159
  </a>
170
160
  </li>
171
161
 
@@ -177,30 +167,24 @@
177
167
  ng-click="toggleDropdown($event, 'relay')"
178
168
  ng-class="{ open: dropdownOpen == 'relay', disabled: !config.isOutgoingEnabled }"
179
169
  >
180
- <span>
181
- <i class="fas fa-paper-plane"></i>
182
- Relay
183
- </span>
170
+ <span class="fa7 fa7-solid--paper-plane"></span>
171
+ <span>Relay</span>
184
172
  </a>
185
173
  <ul class="dropdown-menu">
186
174
  <li>
187
175
  <a href="" class=""
188
176
  ng-click="relay(item)"
189
177
  ng-class="{ disabled: !config.isOutgoingEnabled }">
190
- <span>
191
- <i class="fas fa-paper-plane"></i>
192
- Relay
193
- </span>
178
+ <span class="fa7 fa7-solid--paper-plane"></span>
179
+ <span>Relay</span>
194
180
  </a>
195
181
  </li>
196
182
  <li>
197
183
  <a href="" class=""
198
184
  ng-click="relayTo(item)"
199
185
  ng-class="{ disabled: !config.isOutgoingEnabled }">
200
- <span>
201
- <i class="fas fa-paper-plane"></i>
202
- Relay to...
203
- </span>
186
+ <span class="fa7 fa7-solid--paper-plane"></span>
187
+ <span>Relay to...</span>
204
188
  </a>
205
189
  </li>
206
190
  </ul>
@@ -212,10 +196,8 @@
212
196
  <a href="" class=""
213
197
  ng-click="delete(item)"
214
198
  >
215
- <span>
216
- <i class="fas fa-trash-alt"></i>
217
- Delete
218
- </span>
199
+ <span class="fa7 fa7-solid--trash-alt"></span>
200
+ <span>Delete</span>
219
201
  </a>
220
202
  </li>
221
203
 
@@ -83,7 +83,7 @@ export declare class MailServer {
83
83
  /**
84
84
  * Get an email by id
85
85
  */
86
- getEmail(id: string): Promise<Mail>;
86
+ getEmail(id: string, setRead: boolean): Promise<Mail>;
87
87
  /**
88
88
  * Returns a readable stream of the raw email
89
89
  */
@@ -255,13 +255,14 @@ class MailServer {
255
255
  /**
256
256
  * Get an email by id
257
257
  */
258
- getEmail(id) {
258
+ getEmail(id, setRead) {
259
259
  return __awaiter(this, void 0, void 0, function* () {
260
260
  const envelope = this.store.find(function (elt) {
261
261
  return elt.id === id;
262
262
  });
263
263
  if (envelope) {
264
- return getDiskEmail(this.mailDir, envelope.id).then((mail) => {
264
+ envelope.isRead = setRead || envelope.isRead;
265
+ return getDiskEmail(this.mailDir, envelope.id, envelope.isRead).then((mail) => {
265
266
  if (mail.html) {
266
267
  // sanitize html
267
268
  const window = new JSDOM("").window;
@@ -301,7 +302,7 @@ class MailServer {
301
302
  getEmailHTML(id_1) {
302
303
  return __awaiter(this, arguments, void 0, function* (id, baseUrl = "") {
303
304
  baseUrl = baseUrl ? "//" + baseUrl : "";
304
- const mail = yield this.getEmail(id);
305
+ const mail = yield this.getEmail(id, false);
305
306
  if (typeof mail.html === "string") {
306
307
  var html = mail.html;
307
308
  const getFileUrl = function (filename) {
@@ -337,7 +338,7 @@ class MailServer {
337
338
  }
338
339
  getAllEmail() {
339
340
  const emails = this.store.map((elt) => {
340
- return this.getEmail(elt.id);
341
+ return this.getEmail(elt.id, false);
341
342
  });
342
343
  return Promise.all(emails);
343
344
  }
@@ -391,7 +392,7 @@ class MailServer {
391
392
  */
392
393
  getEmailAttachment(id, filename) {
393
394
  return __awaiter(this, void 0, void 0, function* () {
394
- const mail = yield this.getEmail(id);
395
+ const mail = yield this.getEmail(id, false);
395
396
  if (mail.attachments.length === 0) {
396
397
  throw new Error("Email has no attachments");
397
398
  }
@@ -442,7 +443,7 @@ class MailServer {
442
443
  let saved = chunk.map(function (file) {
443
444
  return __awaiter(this, void 0, void 0, function* () {
444
445
  const id = path.parse(file).name;
445
- const email = yield getDiskEmail(self.mailDir, id);
446
+ const email = yield getDiskEmail(self.mailDir, id, false);
446
447
  return saveEmailToStore(self, email);
447
448
  });
448
449
  });
@@ -470,16 +471,16 @@ function createMailDir(mailDir) {
470
471
  fs.mkdirSync(mailDir, { recursive: true });
471
472
  logger.info("MailDev using directory %s", mailDir);
472
473
  }
473
- function getDiskEmail(mailDir, id) {
474
+ function getDiskEmail(mailDir, id, isRead) {
474
475
  return __awaiter(this, void 0, void 0, function* () {
475
476
  const emlPath = path.join(mailDir, id + ".eml");
476
477
  const data = yield fs_1.promises.readFile(emlPath, "utf8");
477
478
  const stat = yield fs_1.promises.stat(emlPath);
478
479
  const parsedMail = yield (0, mailparser_1.parse)(data);
479
- return buildMail(id, parsedMail, stat.size);
480
+ return buildMail(id, parsedMail, stat.size, isRead);
480
481
  });
481
482
  }
482
- function buildMail(id, parsedMail, size) {
483
+ function buildMail(id, parsedMail, size, isRead) {
483
484
  return __awaiter(this, void 0, void 0, function* () {
484
485
  const envelope = {
485
486
  id: id,
@@ -488,7 +489,7 @@ function buildMail(id, parsedMail, size) {
488
489
  date: parsedMail.date,
489
490
  subject: parsedMail.subject,
490
491
  hasAttachment: parsedMail.attachments.length > 0,
491
- isRead: false,
492
+ isRead,
492
493
  };
493
494
  return Object.assign({ id: envelope.id, envelope, calculatedBcc: (0, bcc_1.calculateBcc)(envelope.to, parsedMail.to, parsedMail.cc), size, sizeHuman: utils.formatBytes(size) }, parsedMail);
494
495
  });
@@ -541,7 +542,7 @@ function handleDataStream(mailServer, stream, session, callback) {
541
542
  });
542
543
  const parsed = yield (0, mailparser_1.parse)(stream.pipe(pt));
543
544
  yield streamEnd;
544
- const mail = yield buildMail(id, parsed, size);
545
+ const mail = yield buildMail(id, parsed, size, false);
545
546
  return saveEmailToStore(mailServer, mail);
546
547
  });
547
548
  }
@@ -34,9 +34,8 @@ function routes(app, mailserver, basePathname) {
34
34
  // Get single email
35
35
  router.get("/email/:id", function (req, res) {
36
36
  mailserver
37
- .getEmail(req.params.id)
37
+ .getEmail(req.params.id, true)
38
38
  .then((mail) => {
39
- mail.envelope.isRead = true; // Mark the email as 'read'
40
39
  res.status(200).json(mail);
41
40
  })
42
41
  .catch((err) => res.status(404).json({ error: err.message }));
@@ -116,7 +115,7 @@ function routes(app, mailserver, basePathname) {
116
115
  // Relay the email
117
116
  router.post("/email/:id/relay{/:relayTo}", function (req, res) {
118
117
  mailserver
119
- .getEmail(req.params.id)
118
+ .getEmail(req.params.id, false)
120
119
  .then((mail) => {
121
120
  if (req.params.relayTo) {
122
121
  if (emailRegexp.test(req.params.relayTo)) {
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.17",
4
+ "version": "3.2.19",
5
5
  "keywords": [
6
6
  "email",
7
7
  "e-mail",
@@ -28,17 +28,15 @@
28
28
  },
29
29
  "scripts": {
30
30
  "clean": "rm -rf dist coverage tsconfig.tsbuildinfo",
31
- "build": "tsc --build && npm run copy-app && npm run css",
32
- "copy-app": "mkdir -p dist && cp -r ./src/app ./dist/ && rm -rf ./dist/app/styles",
31
+ "build": "tsc --build && npm run copy-app",
32
+ "copy-app": "mkdir -p dist && cp -r ./src/app ./dist",
33
33
  "start": "npm run build && node ./bin/maildev",
34
34
  "test": "prettier . -c && npm run build && nyc _mocha --exit --timeout 5000",
35
35
  "test:debug": "npm run build && nyc _mocha --exit --timeout 5000",
36
36
  "test:only": "nyc _mocha --exit --timeout 5000",
37
37
  "lint": "prettier . -c",
38
38
  "lint:fix": "prettier . -w",
39
- "dev": "npm run build && node ./scripts/dev.js && npm run css-watch",
40
- "css": "sass --style=compressed --no-source-map src/app/styles/style.scss:dist/app/styles/style.css",
41
- "css-watch": "sass --watch --style=compressed --no-source-map src/app/styles/style.scss:dist/app/styles/style.css",
39
+ "dev": "npm run build && node ./scripts/dev.js",
42
40
  "docker-build": "./src/scripts/dockerBuild.sh",
43
41
  "docker-run": "docker run --rm -p 1080:1080 -p 1025:1025 maildev/maildev:$npm_package_version",
44
42
  "docker-push": "./src/scripts/dockerPush.sh",
@@ -62,24 +60,25 @@
62
60
  "commander": "14.0.3",
63
61
  "compression": "1.8.1",
64
62
  "cors": "2.8.6",
65
- "dompurify": "3.3.3",
63
+ "dompurify": "3.4.1",
66
64
  "express": "5.2.1",
67
- "jsdom": "29.0.1",
68
- "mailparser": "3.9.5",
65
+ "jsdom": "29.1.0",
66
+ "mailparser": "3.9.8",
69
67
  "mime": "4.1.0",
70
- "nodemailer": "8.0.3",
71
- "smtp-server": "3.18.2",
68
+ "nodemailer": "8.0.7",
69
+ "smtp-server": "3.18.4",
72
70
  "socket.io": "4.8.3",
73
71
  "wildstring": "1.0.9"
74
72
  },
75
73
  "overrides": {
76
74
  "diff": "8.0.4",
77
- "serialize-javascript": "7.0.4",
78
- "socket.io-parser": "4.2.6"
75
+ "follow-redirects": "1.16.0",
76
+ "serialize-javascript": "7.0.5",
77
+ "uuid": "14.0.0"
79
78
  },
80
79
  "devDependencies": {
81
80
  "@types/express": "5.0.6",
82
- "@types/node": "20.19.11",
81
+ "@types/node": "20.19.39",
83
82
  "expect": "30.3.0",
84
83
  "http-proxy-middleware": "3.0.5",
85
84
  "jest": "30.3.0",
@@ -87,11 +86,10 @@
87
86
  "mocha": "11.7.5",
88
87
  "nodemon": "3.1.14",
89
88
  "nyc": "18.0.0",
90
- "prettier": "3.8.1",
91
- "sass": "1.98.0",
89
+ "prettier": "3.8.3",
92
90
  "ts-node": "10.9.2",
93
91
  "ts-node-dev": "2.0.0",
94
- "typescript": "6.0.2"
92
+ "typescript": "6.0.3"
95
93
  },
96
94
  "engines": {
97
95
  "node": ">=20.0.0"
Binary file