@nocobase/plugin-workflow-mailer 2.2.17 → 2.2.18
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/dist/externalVersion.js +6 -6
- package/dist/node_modules/joi/dist/joi-browser.min.js +1 -1
- package/dist/node_modules/joi/lib/index.js +1 -1
- package/dist/node_modules/joi/lib/messages.js +35 -6
- package/dist/node_modules/joi/lib/types/keys.js +18 -1
- package/dist/node_modules/joi/lib/types/link.js +18 -2
- package/dist/node_modules/joi/lib/types/string.js +2 -2
- package/dist/node_modules/joi/package.json +1 -1
- package/dist/node_modules/nodemailer/.ncurc.js +2 -0
- package/dist/node_modules/nodemailer/.prettierignore +8 -0
- package/dist/node_modules/nodemailer/.prettierrc +12 -0
- package/dist/node_modules/nodemailer/.prettierrc.js +2 -0
- package/dist/node_modules/nodemailer/.release-please-config.json +9 -0
- package/dist/node_modules/nodemailer/eslint.config.js +88 -0
- package/dist/node_modules/nodemailer/lib/addressparser/index.js +314 -71
- package/dist/node_modules/nodemailer/lib/base64/index.js +9 -13
- package/dist/node_modules/nodemailer/lib/dkim/index.js +17 -18
- package/dist/node_modules/nodemailer/lib/dkim/message-parser.js +12 -13
- package/dist/node_modules/nodemailer/lib/dkim/relaxed-body.js +3 -3
- package/dist/node_modules/nodemailer/lib/dkim/sign.js +22 -18
- package/dist/node_modules/nodemailer/lib/errors.js +59 -0
- package/dist/node_modules/nodemailer/lib/fetch/cookies.js +14 -19
- package/dist/node_modules/nodemailer/lib/fetch/index.js +164 -27
- package/dist/node_modules/nodemailer/lib/json-transport/index.js +4 -4
- package/dist/node_modules/nodemailer/lib/mail-composer/index.js +229 -155
- package/dist/node_modules/nodemailer/lib/mailer/index.js +106 -54
- package/dist/node_modules/nodemailer/lib/mailer/mail-message.js +106 -68
- package/dist/node_modules/nodemailer/lib/mime-funcs/index.js +105 -59
- package/dist/node_modules/nodemailer/lib/mime-funcs/mime-types.js +21 -14
- package/dist/node_modules/nodemailer/lib/mime-node/index.js +389 -137
- package/dist/node_modules/nodemailer/lib/mime-node/last-newline.js +1 -1
- package/dist/node_modules/nodemailer/lib/mime-node/le-unix.js +4 -7
- package/dist/node_modules/nodemailer/lib/mime-node/le-windows.js +1 -4
- package/dist/node_modules/nodemailer/lib/nodemailer.js +1 -1
- package/dist/node_modules/nodemailer/lib/punycode/index.js +1 -1
- package/dist/node_modules/nodemailer/lib/qp/index.js +33 -22
- package/dist/node_modules/nodemailer/lib/sendmail-transport/index.js +54 -44
- package/dist/node_modules/nodemailer/lib/ses-transport/index.js +110 -193
- package/dist/node_modules/nodemailer/lib/shared/index.js +299 -240
- package/dist/node_modules/nodemailer/lib/shared/objects.js +42 -0
- package/dist/node_modules/nodemailer/lib/shared/url.js +151 -0
- package/dist/node_modules/nodemailer/lib/smtp-connection/data-stream.js +3 -6
- package/dist/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +50 -19
- package/dist/node_modules/nodemailer/lib/smtp-connection/index.js +415 -223
- package/dist/node_modules/nodemailer/lib/smtp-pool/index.js +27 -34
- package/dist/node_modules/nodemailer/lib/smtp-pool/pool-resource.js +19 -16
- package/dist/node_modules/nodemailer/lib/smtp-transport/index.js +66 -53
- package/dist/node_modules/nodemailer/lib/stream-transport/index.js +16 -7
- package/dist/node_modules/nodemailer/lib/well-known/index.js +7 -7
- package/dist/node_modules/nodemailer/lib/well-known/services.json +328 -38
- package/dist/node_modules/nodemailer/lib/xoauth2/index.js +105 -33
- package/dist/node_modules/nodemailer/package.json +1 -1
- package/package.json +4 -4
|
@@ -5,21 +5,37 @@
|
|
|
5
5
|
const base64 = require('../base64');
|
|
6
6
|
const qp = require('../qp');
|
|
7
7
|
const mimeTypes = require('./mime-types');
|
|
8
|
+
const { isProtoKey } = require('../shared/objects');
|
|
8
9
|
|
|
9
10
|
module.exports = {
|
|
10
11
|
/**
|
|
11
12
|
* Checks if a value is plaintext string (uses only printable 7bit chars)
|
|
12
13
|
*
|
|
14
|
+
* When isParam is set the value is destined for a header parameter, so HT, CR and LF
|
|
15
|
+
* are not plaintext either: a header parameter has no way to carry them. HT is a valid
|
|
16
|
+
* fold point, so folding and unfolding a header would rewrite it as a space, and CR/LF
|
|
17
|
+
* cannot appear in a header value at all. DEL is neither a token character nor qtext,
|
|
18
|
+
* so it can not be carried bare or quoted. Such values have to go through the rfc2231
|
|
19
|
+
* parameter continuation encoding instead, the same way a quote already does.
|
|
20
|
+
*
|
|
13
21
|
* @param {String} value String to be tested
|
|
22
|
+
* @param {Boolean} [isParam] Set to true if the value is a header parameter value
|
|
14
23
|
* @returns {Boolean} true if it is a plaintext string
|
|
15
24
|
*/
|
|
16
25
|
isPlainText(value, isParam) {
|
|
17
|
-
const re = isParam ? /[\x00-\
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
const re = isParam ? /[\x00-\x1f\x7f"\u0080-\uFFFF]/ : /[\x00-\x08\x0b\x0c\x0e-\x1f\u0080-\uFFFF]/;
|
|
27
|
+
return typeof value === 'string' && !re.test(value);
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Wraps a value into a quoted-string. Inside one a quote would end the string early
|
|
32
|
+
* and a backslash would escape whatever follows it, so both go out as quoted-pairs.
|
|
33
|
+
*
|
|
34
|
+
* @param {String} value String to be quoted
|
|
35
|
+
* @returns {String} The value as a quoted-string, quotes included
|
|
36
|
+
*/
|
|
37
|
+
quoteString(value) {
|
|
38
|
+
return '"' + (value || '').toString().replace(/["\\]/g, '\\$&') + '"';
|
|
23
39
|
},
|
|
24
40
|
|
|
25
41
|
/**
|
|
@@ -54,7 +70,7 @@ module.exports = {
|
|
|
54
70
|
maxLength = maxLength || 0;
|
|
55
71
|
|
|
56
72
|
let encodedStr;
|
|
57
|
-
|
|
73
|
+
const toCharset = 'UTF-8';
|
|
58
74
|
|
|
59
75
|
if (maxLength && maxLength > 7 + toCharset.length) {
|
|
60
76
|
maxLength -= 7 + toCharset.length;
|
|
@@ -63,12 +79,11 @@ module.exports = {
|
|
|
63
79
|
if (mimeWordEncoding === 'Q') {
|
|
64
80
|
// https://tools.ietf.org/html/rfc2047#section-5 rule (3)
|
|
65
81
|
encodedStr = qp.encode(data).replace(/[^a-z0-9!*+\-/=]/gi, chr => {
|
|
66
|
-
|
|
82
|
+
const ord = chr.charCodeAt(0).toString(16).toUpperCase();
|
|
67
83
|
if (chr === ' ') {
|
|
68
84
|
return '_';
|
|
69
|
-
} else {
|
|
70
|
-
return '=' + (ord.length === 1 ? '0' + ord : ord);
|
|
71
85
|
}
|
|
86
|
+
return '=' + (ord.length === 1 ? '0' + ord : ord);
|
|
72
87
|
});
|
|
73
88
|
} else if (mimeWordEncoding === 'B') {
|
|
74
89
|
encodedStr = typeof data === 'string' ? data : base64.encode(data);
|
|
@@ -80,13 +95,15 @@ module.exports = {
|
|
|
80
95
|
encodedStr = this.splitMimeEncodedString(encodedStr, maxLength).join('?= =?' + toCharset + '?' + mimeWordEncoding + '?');
|
|
81
96
|
} else {
|
|
82
97
|
// RFC2047 6.3 (2) states that encoded-word must include an integral number of characters, so no chopping unicode sequences
|
|
83
|
-
|
|
98
|
+
const parts = [];
|
|
84
99
|
let lpart = '';
|
|
85
100
|
for (let i = 0, len = encodedStr.length; i < len; i++) {
|
|
86
101
|
let chr = encodedStr.charAt(i);
|
|
87
102
|
|
|
88
|
-
if (/[\
|
|
89
|
-
//
|
|
103
|
+
if (/[\ud800-\udbff]/.test(chr) && /[\udc00-\udfff]/.test(encodedStr.charAt(i + 1))) {
|
|
104
|
+
// leading surrogate, so add the trailing surrogate as well
|
|
105
|
+
// an unpaired one must not swallow the next unit, that would destroy
|
|
106
|
+
// a valid pair following it
|
|
90
107
|
chr += encodedStr.charAt(++i);
|
|
91
108
|
}
|
|
92
109
|
|
|
@@ -129,42 +146,38 @@ module.exports = {
|
|
|
129
146
|
encodeWords(value, mimeWordEncoding, maxLength, encodeAll) {
|
|
130
147
|
maxLength = maxLength || 0;
|
|
131
148
|
|
|
132
|
-
let encodedValue;
|
|
133
|
-
|
|
134
149
|
// find first word with a non-printable ascii or special symbol in it
|
|
135
|
-
|
|
150
|
+
const firstMatch = value.match(/(?:^|\s)([^\s]*["\u0080-\uFFFF])/);
|
|
136
151
|
if (!firstMatch) {
|
|
137
152
|
return value;
|
|
138
153
|
}
|
|
139
154
|
|
|
140
155
|
if (encodeAll) {
|
|
141
156
|
// if it is requested to encode everything or the string contains something that resebles encoded word, then encode everything
|
|
142
|
-
|
|
143
157
|
return this.encodeWord(value, mimeWordEncoding, maxLength);
|
|
144
158
|
}
|
|
145
159
|
|
|
146
160
|
// find the last word with a non-printable ascii in it
|
|
147
|
-
|
|
161
|
+
const lastMatch = value.match(/(["\u0080-\uFFFF][^\s]*)[^"\u0080-\uFFFF]*$/);
|
|
148
162
|
if (!lastMatch) {
|
|
149
163
|
// should not happen
|
|
150
164
|
return value;
|
|
151
165
|
}
|
|
152
166
|
|
|
153
|
-
|
|
167
|
+
const startIndex =
|
|
154
168
|
firstMatch.index +
|
|
155
169
|
(
|
|
156
170
|
firstMatch[0].match(/[^\s]/) || {
|
|
157
171
|
index: 0
|
|
158
172
|
}
|
|
159
173
|
).index;
|
|
160
|
-
|
|
174
|
+
const endIndex = lastMatch.index + (lastMatch[1] || '').length;
|
|
161
175
|
|
|
162
|
-
|
|
176
|
+
return (
|
|
163
177
|
(startIndex ? value.substr(0, startIndex) : '') +
|
|
164
178
|
this.encodeWord(value.substring(startIndex, endIndex), mimeWordEncoding || 'Q', maxLength) +
|
|
165
|
-
(endIndex < value.length ? value.substr(endIndex) : '')
|
|
166
|
-
|
|
167
|
-
return encodedValue;
|
|
179
|
+
(endIndex < value.length ? value.substr(endIndex) : '')
|
|
180
|
+
);
|
|
168
181
|
},
|
|
169
182
|
|
|
170
183
|
/**
|
|
@@ -175,12 +188,14 @@ module.exports = {
|
|
|
175
188
|
* @return {String} joined header value
|
|
176
189
|
*/
|
|
177
190
|
buildHeaderValue(structured) {
|
|
178
|
-
|
|
191
|
+
const paramsArray = [];
|
|
179
192
|
|
|
180
|
-
Object.keys(structured.params || {}).forEach(
|
|
193
|
+
Object.keys(structured.params || {}).forEach(key => {
|
|
181
194
|
// filename might include unicode characters so it is a special case
|
|
182
195
|
// other values probably do not
|
|
183
|
-
|
|
196
|
+
const value = structured.params[key];
|
|
197
|
+
// a parameter name is a token too and it is emitted without any quoting around it
|
|
198
|
+
const param = key.replace(/[\x00-\x1f\x7f]/g, '');
|
|
184
199
|
if (!this.isPlainText(value, true) || value.length >= 75) {
|
|
185
200
|
this.buildHeaderParam(param, value, 50).forEach(encodedParam => {
|
|
186
201
|
if (!/[\s"\\;:/=(),<>@[\]?]|^[-']|'$/.test(encodedParam.value) || encodedParam.key.substr(-1) === '*') {
|
|
@@ -196,7 +211,11 @@ module.exports = {
|
|
|
196
211
|
}
|
|
197
212
|
});
|
|
198
213
|
|
|
199
|
-
|
|
214
|
+
// the value ahead of the parameters is a token, it has no way to carry a control
|
|
215
|
+
// char or DEL and there is no quoting construct around it to escape one into
|
|
216
|
+
const value = typeof structured.value === 'string' ? structured.value.replace(/[\x00-\x1f\x7f]/g, '') : structured.value;
|
|
217
|
+
|
|
218
|
+
return value + (paramsArray.length ? '; ' + paramsArray.join('; ') : '');
|
|
200
219
|
},
|
|
201
220
|
|
|
202
221
|
/**
|
|
@@ -215,10 +234,9 @@ module.exports = {
|
|
|
215
234
|
* @return {Array} A list of encoded keys and headers
|
|
216
235
|
*/
|
|
217
236
|
buildHeaderParam(key, data, maxLength) {
|
|
218
|
-
|
|
237
|
+
const list = [];
|
|
219
238
|
let encodedStr = typeof data === 'string' ? data : (data || '').toString();
|
|
220
|
-
let
|
|
221
|
-
let chr, ord;
|
|
239
|
+
let chr;
|
|
222
240
|
let line;
|
|
223
241
|
let startPos = 0;
|
|
224
242
|
let i, len;
|
|
@@ -252,11 +270,12 @@ module.exports = {
|
|
|
252
270
|
} else {
|
|
253
271
|
if (/[\uD800-\uDBFF]/.test(encodedStr)) {
|
|
254
272
|
// string containts surrogate pairs, so normalize it to an array of bytes
|
|
255
|
-
encodedStrArr = [];
|
|
273
|
+
const encodedStrArr = [];
|
|
256
274
|
for (i = 0, len = encodedStr.length; i < len; i++) {
|
|
257
275
|
chr = encodedStr.charAt(i);
|
|
258
|
-
|
|
259
|
-
|
|
276
|
+
if (/[\ud800-\udbff]/.test(chr) && /[\udc00-\udfff]/.test(encodedStr.charAt(i + 1))) {
|
|
277
|
+
// an unpaired leading surrogate must not consume the next unit, that
|
|
278
|
+
// would tear apart a valid pair following it
|
|
260
279
|
chr += encodedStr.charAt(i + 1);
|
|
261
280
|
encodedStrArr.push(chr);
|
|
262
281
|
i++;
|
|
@@ -269,7 +288,7 @@ module.exports = {
|
|
|
269
288
|
|
|
270
289
|
// first line includes the charset and language info and needs to be encoded
|
|
271
290
|
// even if it does not contain any unicode characters
|
|
272
|
-
line =
|
|
291
|
+
line = "utf-8''";
|
|
273
292
|
let encoded = true;
|
|
274
293
|
startPos = 0;
|
|
275
294
|
|
|
@@ -294,8 +313,11 @@ module.exports = {
|
|
|
294
313
|
line,
|
|
295
314
|
encoded
|
|
296
315
|
});
|
|
316
|
+
// the line we start here holds an encoded char, so it has to be
|
|
317
|
+
// flagged as one. otherwise it gets an unstarred continuation key
|
|
318
|
+
// and a receiver reads the percent escapes as literal text
|
|
297
319
|
line = '';
|
|
298
|
-
|
|
320
|
+
encoded = true;
|
|
299
321
|
} else {
|
|
300
322
|
encoded = true;
|
|
301
323
|
i = startPos;
|
|
@@ -356,10 +378,20 @@ module.exports = {
|
|
|
356
378
|
* @return {Object} Header value as a parsed structure
|
|
357
379
|
*/
|
|
358
380
|
parseHeaderValue(str) {
|
|
359
|
-
|
|
381
|
+
const response = {
|
|
360
382
|
value: false,
|
|
361
383
|
params: {}
|
|
362
384
|
};
|
|
385
|
+
|
|
386
|
+
// Parameter names come from a caller supplied contentType/contentDisposition. A
|
|
387
|
+
// "__proto__" name would target the prototype chain of the params object instead of
|
|
388
|
+
// an own property of it, and read back as Object.prototype, so it is dropped.
|
|
389
|
+
const setParam = (name, value) => {
|
|
390
|
+
if (!isProtoKey(name)) {
|
|
391
|
+
response.params[name] = value;
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
|
|
363
395
|
let key = false;
|
|
364
396
|
let value = '';
|
|
365
397
|
let type = 'value';
|
|
@@ -391,7 +423,7 @@ module.exports = {
|
|
|
391
423
|
if (key === false) {
|
|
392
424
|
response.value = value.trim();
|
|
393
425
|
} else {
|
|
394
|
-
|
|
426
|
+
setParam(key, value.trim());
|
|
395
427
|
}
|
|
396
428
|
type = 'key';
|
|
397
429
|
value = '';
|
|
@@ -406,10 +438,10 @@ module.exports = {
|
|
|
406
438
|
if (key === false) {
|
|
407
439
|
response.value = value.trim();
|
|
408
440
|
} else {
|
|
409
|
-
|
|
441
|
+
setParam(key, value.trim());
|
|
410
442
|
}
|
|
411
443
|
} else if (value.trim()) {
|
|
412
|
-
|
|
444
|
+
setParam(value.trim().toLowerCase(), '');
|
|
413
445
|
}
|
|
414
446
|
|
|
415
447
|
// handle parameter value continuations
|
|
@@ -422,6 +454,14 @@ module.exports = {
|
|
|
422
454
|
actualKey = key.substr(0, match.index);
|
|
423
455
|
nr = Number(match[2] || match[3]) || 0;
|
|
424
456
|
|
|
457
|
+
if (isProtoKey(actualKey)) {
|
|
458
|
+
// see setParam. Reading it back would yield Object.prototype, which is
|
|
459
|
+
// an object, so the initializer below would be skipped and the write
|
|
460
|
+
// that follows would throw out of a header build the caller can not catch
|
|
461
|
+
delete response.params[key];
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
|
|
425
465
|
if (!response.params[actualKey] || typeof response.params[actualKey] !== 'object') {
|
|
426
466
|
response.params[actualKey] = {
|
|
427
467
|
charset: false,
|
|
@@ -458,12 +498,11 @@ module.exports = {
|
|
|
458
498
|
value
|
|
459
499
|
// fix invalidly encoded chars
|
|
460
500
|
.replace(/[=?_\s]/g, s => {
|
|
461
|
-
|
|
501
|
+
const c = s.charCodeAt(0).toString(16);
|
|
462
502
|
if (s === ' ') {
|
|
463
503
|
return '_';
|
|
464
|
-
} else {
|
|
465
|
-
return '%' + (c.length < 2 ? '0' : '') + c;
|
|
466
504
|
}
|
|
505
|
+
return '%' + (c.length < 2 ? '0' : '') + c;
|
|
467
506
|
})
|
|
468
507
|
// change from urlencoding to percent encoding
|
|
469
508
|
.replace(/%/g, '=') +
|
|
@@ -508,11 +547,10 @@ module.exports = {
|
|
|
508
547
|
str = (str || '').toString();
|
|
509
548
|
lineLength = lineLength || 76;
|
|
510
549
|
|
|
511
|
-
let pos = 0
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
match;
|
|
550
|
+
let pos = 0;
|
|
551
|
+
const len = str.length;
|
|
552
|
+
let result = '';
|
|
553
|
+
let line, match;
|
|
516
554
|
|
|
517
555
|
while (pos < len) {
|
|
518
556
|
line = str.substr(pos, lineLength);
|
|
@@ -549,11 +587,8 @@ module.exports = {
|
|
|
549
587
|
* @return {Array} Split string
|
|
550
588
|
*/
|
|
551
589
|
splitMimeEncodedString: (str, maxlen) => {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
chr,
|
|
555
|
-
done,
|
|
556
|
-
lines = [];
|
|
590
|
+
const lines = [];
|
|
591
|
+
let curLine, fallbackLine, match, chr, done;
|
|
557
592
|
|
|
558
593
|
// require at least 12 symbols to fit possible 4 octet UTF-8 sequences
|
|
559
594
|
maxlen = Math.max(maxlen || 0, 12);
|
|
@@ -566,8 +601,14 @@ module.exports = {
|
|
|
566
601
|
curLine = curLine.substr(0, match.index);
|
|
567
602
|
}
|
|
568
603
|
|
|
604
|
+
// Malformed input (a run of stray UTF-8 continuation bytes) has no split point
|
|
605
|
+
// that keeps a character sequence whole, so the loop below walks back to an
|
|
606
|
+
// empty line looking for one. Keep the widest chunk that at least does not cut
|
|
607
|
+
// a "=XX" escape in half, so the part stays a decodable encoded word.
|
|
608
|
+
fallbackLine = curLine.length ? curLine : str.substr(0, maxlen);
|
|
609
|
+
|
|
569
610
|
done = false;
|
|
570
|
-
while (!done) {
|
|
611
|
+
while (!done && curLine.length) {
|
|
571
612
|
done = true;
|
|
572
613
|
// check if not middle of a unicode char sequence
|
|
573
614
|
if ((match = str.substr(curLine.length).match(/^[=]([0-9A-F]{2})/i))) {
|
|
@@ -580,9 +621,11 @@ module.exports = {
|
|
|
580
621
|
}
|
|
581
622
|
}
|
|
582
623
|
|
|
583
|
-
if (curLine.length) {
|
|
584
|
-
|
|
624
|
+
if (!curLine.length) {
|
|
625
|
+
curLine = fallbackLine;
|
|
585
626
|
}
|
|
627
|
+
|
|
628
|
+
lines.push(curLine);
|
|
586
629
|
str = str.substr(curLine.length);
|
|
587
630
|
}
|
|
588
631
|
|
|
@@ -614,9 +657,12 @@ module.exports = {
|
|
|
614
657
|
try {
|
|
615
658
|
// might throw if we try to encode invalid sequences, eg. partial emoji
|
|
616
659
|
str = encodeURIComponent(str);
|
|
617
|
-
} catch (
|
|
618
|
-
//
|
|
619
|
-
|
|
660
|
+
} catch (_E) {
|
|
661
|
+
// an unpaired surrogate has no utf-8 representation, so run the value through a
|
|
662
|
+
// utf-8 roundtrip to get the same U+FFFD every other encoder here produces and
|
|
663
|
+
// retry. the value must never come back unencoded, it goes into a header parameter
|
|
664
|
+
// where a bare quote or semicolon would break it out into a parameter of its own
|
|
665
|
+
str = encodeURIComponent(Buffer.from(str, 'utf-8').toString('utf-8'));
|
|
620
666
|
}
|
|
621
667
|
|
|
622
668
|
// ensure chars that are not handled by encodeURICompent are converted as well
|
|
@@ -44,6 +44,7 @@ const mimeTypes = new Map([
|
|
|
44
44
|
['application/fractals', 'fif'],
|
|
45
45
|
['application/freeloader', 'frl'],
|
|
46
46
|
['application/futuresplash', 'spl'],
|
|
47
|
+
['application/geo+json', 'geojson'],
|
|
47
48
|
['application/gnutar', 'tgz'],
|
|
48
49
|
['application/groupwise', 'vew'],
|
|
49
50
|
['application/hlp', 'hlp'],
|
|
@@ -1101,7 +1102,10 @@ const extensions = new Map([
|
|
|
1101
1102
|
['bdm', 'application/vnd.syncml.dm+wbxml'],
|
|
1102
1103
|
['bed', 'application/vnd.realvnc.bed'],
|
|
1103
1104
|
['bh2', 'application/vnd.fujitsu.oasysprs'],
|
|
1104
|
-
[
|
|
1105
|
+
[
|
|
1106
|
+
'bin',
|
|
1107
|
+
['application/octet-stream', 'application/mac-binary', 'application/macbinary', 'application/x-macbinary', 'application/x-binary']
|
|
1108
|
+
],
|
|
1105
1109
|
['bm', 'image/bmp'],
|
|
1106
1110
|
['bmi', 'application/vnd.bmi'],
|
|
1107
1111
|
['bmp', ['image/bmp', 'image/x-windows-bmp']],
|
|
@@ -1146,7 +1150,10 @@ const extensions = new Map([
|
|
|
1146
1150
|
['cii', 'application/vnd.anser-web-certificate-issue-initiation'],
|
|
1147
1151
|
['cil', 'application/vnd.ms-artgalry'],
|
|
1148
1152
|
['cla', 'application/vnd.claymore'],
|
|
1149
|
-
[
|
|
1153
|
+
[
|
|
1154
|
+
'class',
|
|
1155
|
+
['application/octet-stream', 'application/java', 'application/java-byte-code', 'application/java-vm', 'application/x-java-class']
|
|
1156
|
+
],
|
|
1150
1157
|
['clkk', 'application/vnd.crick.clicker.keyboard'],
|
|
1151
1158
|
['clkp', 'application/vnd.crick.clicker.palette'],
|
|
1152
1159
|
['clkt', 'application/vnd.crick.clicker.template'],
|
|
@@ -1287,6 +1294,7 @@ const extensions = new Map([
|
|
|
1287
1294
|
['gac', 'application/vnd.groove-account'],
|
|
1288
1295
|
['gdl', 'model/vnd.gdl'],
|
|
1289
1296
|
['geo', 'application/vnd.dynageo'],
|
|
1297
|
+
['geojson', 'application/geo+json'],
|
|
1290
1298
|
['gex', 'application/vnd.geometry-explorer'],
|
|
1291
1299
|
['ggb', 'application/vnd.geogebra.file'],
|
|
1292
1300
|
['ggt', 'application/vnd.geogebra.tool'],
|
|
@@ -1750,7 +1758,10 @@ const extensions = new Map([
|
|
|
1750
1758
|
['sbml', 'application/sbml+xml'],
|
|
1751
1759
|
['sc', 'application/vnd.ibm.secure-container'],
|
|
1752
1760
|
['scd', 'application/x-msschedule'],
|
|
1753
|
-
[
|
|
1761
|
+
[
|
|
1762
|
+
'scm',
|
|
1763
|
+
['application/vnd.lotus-screencam', 'video/x-scm', 'text/x-script.guile', 'application/x-lotusscreencam', 'text/x-script.scheme']
|
|
1764
|
+
],
|
|
1754
1765
|
['scq', 'application/scvp-cv-request'],
|
|
1755
1766
|
['scs', 'application/scvp-cv-response'],
|
|
1756
1767
|
['sct', 'text/scriptlet'],
|
|
@@ -2062,13 +2073,9 @@ module.exports = {
|
|
|
2062
2073
|
return defaultMimeType;
|
|
2063
2074
|
}
|
|
2064
2075
|
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
if (extensions.has(extension)) {
|
|
2070
|
-
value = extensions.get(extension);
|
|
2071
|
-
}
|
|
2076
|
+
const parsed = path.parse(filename);
|
|
2077
|
+
const extension = (parsed.ext.substr(1) || parsed.name || '').split('?').shift().trim().toLowerCase();
|
|
2078
|
+
const value = extensions.has(extension) ? extensions.get(extension) : defaultMimeType;
|
|
2072
2079
|
|
|
2073
2080
|
if (Array.isArray(value)) {
|
|
2074
2081
|
return value[0];
|
|
@@ -2080,12 +2087,12 @@ module.exports = {
|
|
|
2080
2087
|
if (!mimeType) {
|
|
2081
2088
|
return defaultExtension;
|
|
2082
2089
|
}
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2090
|
+
const parts = mimeType.toLowerCase().trim().split('/');
|
|
2091
|
+
const rootType = parts.shift().trim();
|
|
2092
|
+
const subType = parts.join('/').trim();
|
|
2086
2093
|
|
|
2087
2094
|
if (mimeTypes.has(rootType + '/' + subType)) {
|
|
2088
|
-
|
|
2095
|
+
const value = mimeTypes.get(rootType + '/' + subType);
|
|
2089
2096
|
if (Array.isArray(value)) {
|
|
2090
2097
|
return value[0];
|
|
2091
2098
|
}
|