@nocobase/plugin-workflow-mailer 2.4.0-alpha.1 → 2.4.0-alpha.10
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/dist/cjs/addressparser/index.d.ts +59 -0
- package/dist/node_modules/nodemailer/dist/cjs/addressparser/index.js +790 -0
- package/dist/node_modules/nodemailer/dist/cjs/base64/index.d.ts +36 -0
- package/dist/node_modules/nodemailer/dist/cjs/base64/index.js +119 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/index.d.ts +52 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/index.js +228 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.d.ts +48 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.js +180 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.d.ts +36 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.js +148 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.d.ts +52 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.js +165 -0
- package/dist/node_modules/nodemailer/dist/cjs/errors.d.ts +96 -0
- package/dist/node_modules/nodemailer/dist/cjs/errors.js +70 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.d.ts +107 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.js +282 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/index.js +384 -0
- package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.d.ts +64 -0
- package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.js +99 -0
- package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.d.ts +174 -0
- package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.js +613 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/index.d.ts +237 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/index.js +415 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.d.ts +97 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.js +342 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.d.ts +161 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.js +787 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.d.ts +2 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.js +2103 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.d.ts +333 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.js +1493 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.d.ts +5 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.js +32 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.d.ts +9 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.js +40 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.d.ts +10 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.js +47 -0
- package/dist/node_modules/nodemailer/dist/cjs/nodemailer.d.ts +124 -0
- package/dist/node_modules/nodemailer/dist/cjs/nodemailer.js +1 -0
- package/dist/node_modules/nodemailer/dist/cjs/package-info.d.ts +3 -0
- package/dist/node_modules/nodemailer/dist/cjs/package-info.js +7 -0
- package/dist/node_modules/nodemailer/dist/cjs/package.json +3 -0
- package/dist/node_modules/nodemailer/dist/cjs/punycode/index.d.ts +73 -0
- package/dist/node_modules/nodemailer/{lib → dist/cjs}/punycode/index.js +63 -112
- package/dist/node_modules/nodemailer/dist/cjs/qp/index.d.ts +32 -0
- package/dist/node_modules/nodemailer/dist/cjs/qp/index.js +207 -0
- package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.d.ts +69 -0
- package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.js +210 -0
- package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.d.ts +112 -0
- package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.js +252 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/index.d.ts +260 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/index.js +680 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/objects.d.ts +23 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/objects.js +43 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/url.d.ts +21 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/url.js +255 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.d.ts +15 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.js +108 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.d.ts +47 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.js +189 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.d.ts +416 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.js +1837 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.d.ts +133 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.js +569 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.d.ts +62 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.js +257 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.d.ts +156 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.js +371 -0
- package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.js +146 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/index.d.ts +35 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/index.js +41 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/services.d.ts +2 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/services.js +674 -0
- package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.d.ts +201 -0
- package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.js +426 -0
- package/dist/node_modules/nodemailer/dist/esm/addressparser/index.d.ts +59 -0
- package/dist/node_modules/nodemailer/dist/esm/addressparser/index.js +786 -0
- package/dist/node_modules/nodemailer/dist/esm/base64/index.d.ts +36 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/base64/index.js +39 -68
- package/dist/node_modules/nodemailer/dist/esm/dkim/index.d.ts +52 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/dkim/index.js +62 -92
- package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.d.ts +48 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.js +176 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.d.ts +36 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.js +141 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/sign.d.ts +52 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/sign.js +125 -0
- package/dist/node_modules/nodemailer/dist/esm/errors.d.ts +96 -0
- package/dist/node_modules/nodemailer/dist/esm/errors.js +67 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.d.ts +107 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.js +242 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/index.js +344 -0
- package/dist/node_modules/nodemailer/dist/esm/json-transport/index.d.ts +64 -0
- package/dist/node_modules/nodemailer/dist/esm/json-transport/index.js +62 -0
- package/dist/node_modules/nodemailer/dist/esm/mail-composer/index.d.ts +174 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mail-composer/index.js +283 -275
- package/dist/node_modules/nodemailer/dist/esm/mailer/index.d.ts +237 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/index.js +151 -205
- package/dist/node_modules/nodemailer/dist/esm/mailer/mail-message.d.ts +97 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/mail-message.js +111 -125
- package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.d.ts +161 -0
- package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.js +738 -0
- package/dist/node_modules/nodemailer/dist/esm/mime-funcs/mime-types.d.ts +2 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-funcs/mime-types.js +43 -49
- package/dist/node_modules/nodemailer/dist/esm/mime-node/index.d.ts +333 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/index.js +576 -437
- package/dist/node_modules/nodemailer/dist/esm/mime-node/last-newline.d.ts +5 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/last-newline.js +4 -10
- package/dist/node_modules/nodemailer/dist/esm/mime-node/le-unix.d.ts +9 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-unix.js +7 -15
- package/dist/node_modules/nodemailer/dist/esm/mime-node/le-windows.d.ts +10 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-windows.js +6 -16
- package/dist/node_modules/nodemailer/dist/esm/nodemailer.d.ts +124 -0
- package/dist/node_modules/nodemailer/dist/esm/nodemailer.js +166 -0
- package/dist/node_modules/nodemailer/dist/esm/package-info.d.ts +3 -0
- package/dist/node_modules/nodemailer/dist/esm/package-info.js +4 -0
- package/dist/node_modules/nodemailer/dist/esm/package.json +3 -0
- package/dist/node_modules/nodemailer/dist/esm/punycode/index.d.ts +73 -0
- package/dist/node_modules/nodemailer/dist/esm/punycode/index.js +405 -0
- package/dist/node_modules/nodemailer/dist/esm/qp/index.d.ts +32 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/qp/index.js +59 -77
- package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.d.ts +69 -0
- package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.js +170 -0
- package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.d.ts +112 -0
- package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.js +212 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/index.d.ts +260 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/index.js +631 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/objects.d.ts +23 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/objects.js +38 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/url.d.ts +21 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/url.js +214 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.d.ts +15 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.js +103 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.d.ts +47 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.js +149 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.d.ts +416 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.js +1797 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-pool/index.d.ts +133 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/index.js +195 -314
- package/dist/node_modules/nodemailer/dist/esm/smtp-pool/pool-resource.d.ts +62 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/pool-resource.js +70 -107
- package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.d.ts +156 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.js +331 -0
- package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.js +106 -0
- package/dist/node_modules/nodemailer/dist/esm/well-known/index.d.ts +35 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/well-known/index.js +12 -23
- package/dist/node_modules/nodemailer/dist/esm/well-known/services.d.ts +2 -0
- package/dist/node_modules/nodemailer/dist/esm/well-known/services.js +671 -0
- package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.d.ts +201 -0
- package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.js +386 -0
- package/dist/node_modules/nodemailer/dist/well-known/services.json +640 -0
- package/dist/node_modules/nodemailer/package.json +1 -1
- package/package.json +4 -4
- package/dist/node_modules/nodemailer/.gitattributes +0 -6
- package/dist/node_modules/nodemailer/.ncurc.js +0 -7
- package/dist/node_modules/nodemailer/.prettierrc.js +0 -8
- package/dist/node_modules/nodemailer/lib/addressparser/index.js +0 -313
- package/dist/node_modules/nodemailer/lib/dkim/message-parser.js +0 -155
- package/dist/node_modules/nodemailer/lib/dkim/relaxed-body.js +0 -154
- package/dist/node_modules/nodemailer/lib/dkim/sign.js +0 -117
- package/dist/node_modules/nodemailer/lib/fetch/cookies.js +0 -281
- package/dist/node_modules/nodemailer/lib/fetch/index.js +0 -274
- package/dist/node_modules/nodemailer/lib/json-transport/index.js +0 -82
- package/dist/node_modules/nodemailer/lib/mime-funcs/index.js +0 -625
- package/dist/node_modules/nodemailer/lib/nodemailer.js +0 -1
- package/dist/node_modules/nodemailer/lib/sendmail-transport/index.js +0 -210
- package/dist/node_modules/nodemailer/lib/ses-transport/index.js +0 -349
- package/dist/node_modules/nodemailer/lib/shared/index.js +0 -688
- package/dist/node_modules/nodemailer/lib/smtp-connection/data-stream.js +0 -108
- package/dist/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +0 -143
- package/dist/node_modules/nodemailer/lib/smtp-connection/index.js +0 -1825
- package/dist/node_modules/nodemailer/lib/smtp-transport/index.js +0 -416
- package/dist/node_modules/nodemailer/lib/stream-transport/index.js +0 -135
- package/dist/node_modules/nodemailer/lib/well-known/services.json +0 -343
- package/dist/node_modules/nodemailer/lib/xoauth2/index.js +0 -376
|
@@ -1,188 +1,185 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import * as shared from '../shared/index.js';
|
|
2
|
+
import MimeNode from '../mime-node/index.js';
|
|
3
|
+
import * as mimeFuncs from '../mime-funcs/index.js';
|
|
4
|
+
// Only an own key counts as already set. `key in obj` also matches every member of
|
|
5
|
+
// Object.prototype, which silently drops a transporter default legitimately named
|
|
6
|
+
// toString or constructor.
|
|
7
|
+
const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
|
|
8
|
+
export default class MailMessage {
|
|
8
9
|
constructor(mailer, data) {
|
|
9
10
|
this.mailer = mailer;
|
|
10
11
|
this.data = {};
|
|
11
12
|
this.message = null;
|
|
12
|
-
|
|
13
13
|
data = data || {};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Object.keys(data).forEach(key => {
|
|
18
|
-
this.data[key] = data[key];
|
|
19
|
-
});
|
|
20
|
-
|
|
14
|
+
const options = mailer.options || {};
|
|
15
|
+
const defaults = mailer._defaults || {};
|
|
16
|
+
shared.copyOwnKeys(this.data, data);
|
|
21
17
|
this.data.headers = this.data.headers || {};
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} else if (key === 'headers') {
|
|
28
|
-
// headers is a special case. Allow setting individual default headers
|
|
29
|
-
Object.keys(defaults.headers).forEach(key => {
|
|
30
|
-
if (!(key in this.data.headers)) {
|
|
31
|
-
this.data.headers[key] = defaults.headers[key];
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
18
|
+
// Apply defaults. `_defaults` is caller supplied too, it is the second argument of
|
|
19
|
+
// createTransport, so it needs the same treatment as `data` above
|
|
20
|
+
shared.copyOwnKeys(this.data, defaults, key => hasOwn(this.data, key));
|
|
21
|
+
// headers is a special case. Allow setting individual default headers
|
|
22
|
+
shared.copyOwnKeys(this.data.headers, defaults.headers, key => hasOwn(this.data.headers, key));
|
|
37
23
|
// force specific keys from transporter options
|
|
38
|
-
['disableFileAccess', 'disableUrlAccess', 'normalizeHeaderKey'].forEach(key => {
|
|
24
|
+
['disableFileAccess', 'disableUrlAccess', 'normalizeHeaderKey', 'maxRecipients'].forEach(key => {
|
|
39
25
|
if (key in options) {
|
|
40
26
|
this.data[key] = options[key];
|
|
41
27
|
}
|
|
42
28
|
});
|
|
29
|
+
// The access flags are a sandbox rather than a message field, so `defaults` counts as
|
|
30
|
+
// transporter configuration for them. For a transporter plugin it is the only channel
|
|
31
|
+
// there is, createTransport leaves `options` undefined for one, and the defaults copy
|
|
32
|
+
// above yields to anything the message already set, which let message data switch the
|
|
33
|
+
// sandbox back off. Closing is one way here, same as in resolveContent below: either
|
|
34
|
+
// side may switch a flag on, neither can switch off what the other closed.
|
|
35
|
+
['disableFileAccess', 'disableUrlAccess'].forEach(key => {
|
|
36
|
+
if (!(key in options) && hasOwn(defaults, key)) {
|
|
37
|
+
this.data[key] = this.data[key] || defaults[key];
|
|
38
|
+
}
|
|
39
|
+
});
|
|
43
40
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
resolveContent(data, key, options, callback) {
|
|
42
|
+
// Most plugins call this with the legacy (data, key, callback) signature, which carries
|
|
43
|
+
// no access policy. The policy belongs to the message, so apply it here. Explicit
|
|
44
|
+
// options may only tighten it, never reopen what the transporter closed.
|
|
45
|
+
if (!callback && typeof options === 'function') {
|
|
46
|
+
callback = options;
|
|
47
|
+
options = false;
|
|
48
|
+
}
|
|
49
|
+
options = options || {};
|
|
50
|
+
const policy = {
|
|
51
|
+
disableFileAccess: this.data.disableFileAccess || options.disableFileAccess,
|
|
52
|
+
disableUrlAccess: this.data.disableUrlAccess || options.disableUrlAccess
|
|
53
|
+
};
|
|
54
|
+
return shared.resolveContent(data, key, policy, callback);
|
|
47
55
|
}
|
|
48
|
-
|
|
49
56
|
resolveAll(callback) {
|
|
50
|
-
|
|
57
|
+
const keys = [
|
|
51
58
|
[this.data, 'html'],
|
|
52
59
|
[this.data, 'text'],
|
|
53
60
|
[this.data, 'watchHtml'],
|
|
54
61
|
[this.data, 'amp'],
|
|
55
62
|
[this.data, 'icalEvent']
|
|
56
63
|
];
|
|
57
|
-
|
|
58
64
|
if (this.data.alternatives && this.data.alternatives.length) {
|
|
59
65
|
this.data.alternatives.forEach((alternative, i) => {
|
|
60
66
|
keys.push([this.data.alternatives, i]);
|
|
61
67
|
});
|
|
62
68
|
}
|
|
63
|
-
|
|
64
69
|
if (this.data.attachments && this.data.attachments.length) {
|
|
65
70
|
this.data.attachments.forEach((attachment, i) => {
|
|
66
71
|
if (!attachment.filename) {
|
|
67
|
-
|
|
72
|
+
// a backslash separates as well, so a Windows path does not put the sender's directories in the headers
|
|
73
|
+
attachment.filename =
|
|
74
|
+
(attachment.path || attachment.href || '').split(/[/\\]/).pop().split('?').shift() ||
|
|
75
|
+
'attachment-' + (i + 1);
|
|
68
76
|
if (attachment.filename.indexOf('.') < 0) {
|
|
69
77
|
attachment.filename += '.' + mimeFuncs.detectExtension(attachment.contentType);
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
|
-
|
|
73
80
|
if (!attachment.contentType) {
|
|
74
81
|
attachment.contentType = mimeFuncs.detectMimeType(attachment.filename || attachment.path || attachment.href || 'bin');
|
|
75
82
|
}
|
|
76
|
-
|
|
77
83
|
keys.push([this.data.attachments, i]);
|
|
78
84
|
});
|
|
79
85
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
let addressKeys = ['from', 'to', 'cc', 'bcc', 'sender', 'replyTo'];
|
|
84
|
-
|
|
86
|
+
const mimeNode = new MimeNode();
|
|
87
|
+
const addressKeys = ['from', 'to', 'cc', 'bcc', 'sender', 'replyTo'];
|
|
85
88
|
addressKeys.forEach(address => {
|
|
86
89
|
let value;
|
|
87
90
|
if (this.message) {
|
|
88
91
|
value = [].concat(mimeNode._parseAddresses(this.message.getHeader(address === 'replyTo' ? 'reply-to' : address)) || []);
|
|
89
|
-
}
|
|
92
|
+
}
|
|
93
|
+
else if (this.data[address]) {
|
|
90
94
|
value = [].concat(mimeNode._parseAddresses(this.data[address]) || []);
|
|
91
95
|
}
|
|
92
96
|
if (value && value.length) {
|
|
93
97
|
this.data[address] = value;
|
|
94
|
-
}
|
|
98
|
+
}
|
|
99
|
+
else if (address in this.data) {
|
|
95
100
|
this.data[address] = null;
|
|
96
101
|
}
|
|
97
102
|
});
|
|
98
|
-
|
|
99
|
-
let singleKeys = ['from', 'sender'];
|
|
103
|
+
const singleKeys = ['from', 'sender'];
|
|
100
104
|
singleKeys.forEach(address => {
|
|
101
105
|
if (this.data[address]) {
|
|
102
106
|
this.data[address] = this.data[address].shift();
|
|
103
107
|
}
|
|
104
108
|
});
|
|
105
|
-
|
|
106
109
|
let pos = 0;
|
|
107
|
-
|
|
110
|
+
const resolveNext = () => {
|
|
108
111
|
if (pos >= keys.length) {
|
|
109
112
|
return callback(null, this.data);
|
|
110
113
|
}
|
|
111
|
-
|
|
114
|
+
const args = keys[pos++];
|
|
112
115
|
if (!args[0] || !args[0][args[1]]) {
|
|
113
116
|
return resolveNext();
|
|
114
117
|
}
|
|
115
|
-
shared.resolveContent(...args, (err, value) => {
|
|
118
|
+
shared.resolveContent(...args, { disableFileAccess: this.data.disableFileAccess, disableUrlAccess: this.data.disableUrlAccess }, (err, value) => {
|
|
116
119
|
if (err) {
|
|
117
120
|
return callback(err);
|
|
118
121
|
}
|
|
119
|
-
|
|
120
|
-
let node = {
|
|
122
|
+
const node = {
|
|
121
123
|
content: value
|
|
122
124
|
};
|
|
123
125
|
if (args[0][args[1]] && typeof args[0][args[1]] === 'object' && !Buffer.isBuffer(args[0][args[1]])) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
// The keys are the caller's, so copying them takes the same "__proto__"
|
|
127
|
+
// rule as the constructor. `key in node` stays as the already-set test
|
|
128
|
+
// here, unlike for the defaults: it also skips the Object.prototype
|
|
129
|
+
// member names, and letting message data land a `toString` string on a
|
|
130
|
+
// node only buys a TypeError the first time something stringifies it.
|
|
131
|
+
shared.copyOwnKeys(node, args[0][args[1]], key => key in node || ['content', 'path', 'href', 'raw'].includes(key));
|
|
129
132
|
}
|
|
130
|
-
|
|
131
133
|
args[0][args[1]] = node;
|
|
132
134
|
resolveNext();
|
|
133
135
|
});
|
|
134
136
|
};
|
|
135
|
-
|
|
136
137
|
setImmediate(() => resolveNext());
|
|
137
138
|
}
|
|
138
|
-
|
|
139
139
|
normalize(callback) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
const envelope = this.message.getEnvelope();
|
|
141
|
+
const messageId = this.message.messageId();
|
|
143
142
|
this.resolveAll((err, data) => {
|
|
144
143
|
if (err) {
|
|
145
144
|
return callback(err);
|
|
146
145
|
}
|
|
147
|
-
|
|
148
146
|
data.envelope = envelope;
|
|
149
147
|
data.messageId = messageId;
|
|
150
|
-
|
|
151
148
|
['html', 'text', 'watchHtml', 'amp'].forEach(key => {
|
|
152
149
|
if (data[key] && data[key].content) {
|
|
153
150
|
if (typeof data[key].content === 'string') {
|
|
154
151
|
data[key] = data[key].content;
|
|
155
|
-
}
|
|
152
|
+
}
|
|
153
|
+
else if (Buffer.isBuffer(data[key].content)) {
|
|
156
154
|
data[key] = data[key].content.toString();
|
|
157
155
|
}
|
|
158
156
|
}
|
|
159
157
|
});
|
|
160
|
-
|
|
161
158
|
if (data.icalEvent && Buffer.isBuffer(data.icalEvent.content)) {
|
|
162
159
|
data.icalEvent.content = data.icalEvent.content.toString('base64');
|
|
163
160
|
data.icalEvent.encoding = 'base64';
|
|
164
161
|
}
|
|
165
|
-
|
|
166
162
|
if (data.alternatives && data.alternatives.length) {
|
|
167
|
-
data.alternatives.forEach(alternative => {
|
|
163
|
+
data.alternatives.forEach((alternative) => {
|
|
168
164
|
if (alternative && alternative.content && Buffer.isBuffer(alternative.content)) {
|
|
169
165
|
alternative.content = alternative.content.toString('base64');
|
|
170
166
|
alternative.encoding = 'base64';
|
|
171
167
|
}
|
|
172
168
|
});
|
|
173
169
|
}
|
|
174
|
-
|
|
175
170
|
if (data.attachments && data.attachments.length) {
|
|
176
|
-
data.attachments.forEach(attachment => {
|
|
171
|
+
data.attachments.forEach((attachment) => {
|
|
177
172
|
if (attachment && attachment.content && Buffer.isBuffer(attachment.content)) {
|
|
178
173
|
attachment.content = attachment.content.toString('base64');
|
|
179
174
|
attachment.encoding = 'base64';
|
|
180
175
|
}
|
|
181
176
|
});
|
|
182
177
|
}
|
|
183
|
-
|
|
184
178
|
data.normalizedHeaders = {};
|
|
185
179
|
Object.keys(data.headers || {}).forEach(key => {
|
|
180
|
+
if (shared.isProtoKey(key)) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
186
183
|
let value = [].concat(data.headers[key] || []).shift();
|
|
187
184
|
value = (value && value.value) || value;
|
|
188
185
|
if (value) {
|
|
@@ -192,33 +189,27 @@ class MailMessage {
|
|
|
192
189
|
data.normalizedHeaders[key] = value;
|
|
193
190
|
}
|
|
194
191
|
});
|
|
195
|
-
|
|
196
192
|
if (data.list && typeof data.list === 'object') {
|
|
197
|
-
|
|
193
|
+
const listHeaders = this._getListHeaders(data.list);
|
|
198
194
|
listHeaders.forEach(entry => {
|
|
199
195
|
data.normalizedHeaders[entry.key] = entry.value.map(val => (val && val.value) || val).join(', ');
|
|
200
196
|
});
|
|
201
197
|
}
|
|
202
|
-
|
|
203
198
|
if (data.references) {
|
|
204
199
|
data.normalizedHeaders.references = this.message._encodeHeaderValue('references', data.references);
|
|
205
200
|
}
|
|
206
|
-
|
|
207
201
|
if (data.inReplyTo) {
|
|
208
202
|
data.normalizedHeaders['in-reply-to'] = this.message._encodeHeaderValue('in-reply-to', data.inReplyTo);
|
|
209
203
|
}
|
|
210
|
-
|
|
211
204
|
return callback(null, data);
|
|
212
205
|
});
|
|
213
206
|
}
|
|
214
|
-
|
|
215
207
|
setMailerHeader() {
|
|
216
208
|
if (!this.message || !this.data.xMailer) {
|
|
217
209
|
return;
|
|
218
210
|
}
|
|
219
211
|
this.message.setHeader('X-Mailer', this.data.xMailer);
|
|
220
212
|
}
|
|
221
|
-
|
|
222
213
|
setPriorityHeaders() {
|
|
223
214
|
if (!this.message || !this.data.priority) {
|
|
224
215
|
return;
|
|
@@ -238,21 +229,18 @@ class MailMessage {
|
|
|
238
229
|
// do not add anything, since all messages are 'Normal' by default
|
|
239
230
|
}
|
|
240
231
|
}
|
|
241
|
-
|
|
242
232
|
setListHeaders() {
|
|
243
233
|
if (!this.message || !this.data.list || typeof this.data.list !== 'object') {
|
|
244
234
|
return;
|
|
245
235
|
}
|
|
246
236
|
// add optional List-* headers
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
this.message.addHeader(listHeader.key, value);
|
|
251
|
-
});
|
|
237
|
+
this._getListHeaders(this.data.list).forEach(listHeader => {
|
|
238
|
+
listHeader.value.forEach(value => {
|
|
239
|
+
this.message.addHeader(listHeader.key, value);
|
|
252
240
|
});
|
|
253
|
-
}
|
|
241
|
+
});
|
|
254
242
|
}
|
|
255
|
-
|
|
243
|
+
/** @internal */
|
|
256
244
|
_getListHeaders(listData) {
|
|
257
245
|
// make sure an url looks like <protocol:url>
|
|
258
246
|
return Object.keys(listData).map(key => ({
|
|
@@ -263,53 +251,51 @@ class MailMessage {
|
|
|
263
251
|
value: []
|
|
264
252
|
.concat(value || [])
|
|
265
253
|
.map(value => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// List-*: <http://domain> (comment)
|
|
286
|
-
let comment = value.comment || '';
|
|
287
|
-
if (!mimeFuncs.isPlainText(comment)) {
|
|
288
|
-
comment = mimeFuncs.encodeWord(comment);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return this._formatListUrl(value.url) + (value.comment ? ' (' + comment + ')' : '');
|
|
254
|
+
if (typeof value === 'string') {
|
|
255
|
+
value = {
|
|
256
|
+
url: value
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (value && value.url) {
|
|
260
|
+
// strip CR/LF so a comment can't inject extra header lines. DEL is neither
|
|
261
|
+
// qtext nor ctext, so it can not be carried literally by either construct
|
|
262
|
+
// and has to become an encoded word like any other non-plaintext value
|
|
263
|
+
let comment = (value.comment || '').toString().replace(/\r?\n|\r/g, ' ');
|
|
264
|
+
const needsEncoding = !mimeFuncs.isPlainText(comment) || /\x7f/.test(comment);
|
|
265
|
+
if (key.toLowerCase().trim() === 'id') {
|
|
266
|
+
// List-ID: "comment" <domain>, where an unescaped quote or a trailing
|
|
267
|
+
// backslash in the comment would swallow the <domain> behind it
|
|
268
|
+
comment = needsEncoding ? mimeFuncs.encodeWord(comment) : mimeFuncs.quoteString(comment);
|
|
269
|
+
// List-ID expects a bare domain-like identifier, so strip the
|
|
270
|
+
// scheme prefix that _formatListUrl adds or passes through
|
|
271
|
+
return ((value.comment ? comment + ' ' : '') + this._formatListUrl(value.url).replace(/^<[^:]+:\/{0,2}/, '<'));
|
|
292
272
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
273
|
+
// List-*: <http://domain> (comment)
|
|
274
|
+
// the ctext specials go out as quoted-pairs, otherwise a ")" closes the
|
|
275
|
+
// comment early and leaves the rest as junk, an unpaired "(" opens a
|
|
276
|
+
// nested comment that never closes, and a trailing backslash escapes
|
|
277
|
+
// the closing ")" so the comment swallows whatever follows it
|
|
278
|
+
comment = needsEncoding ? mimeFuncs.encodeWord(comment) : comment.replace(/[()\\]/g, '\\$&');
|
|
279
|
+
return this._formatListUrl(value.url) + (value.comment ? ' (' + comment + ')' : '');
|
|
280
|
+
}
|
|
281
|
+
return '';
|
|
282
|
+
})
|
|
296
283
|
.filter(value => value)
|
|
297
284
|
.join(', ')
|
|
298
285
|
}))
|
|
299
286
|
}));
|
|
300
287
|
}
|
|
301
|
-
|
|
288
|
+
/** @internal */
|
|
302
289
|
_formatListUrl(url) {
|
|
303
|
-
url
|
|
290
|
+
// a url has no way to carry a control char or DEL, and the angle brackets around it
|
|
291
|
+
// are not a quoting construct, so anything left here lands in the header raw
|
|
292
|
+
url = url.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, '').replace(/[\s<]+|[\s>]+/g, '');
|
|
304
293
|
if (/^(https?|mailto|ftp):/.test(url)) {
|
|
305
294
|
return '<' + url + '>';
|
|
306
295
|
}
|
|
307
296
|
if (/^[^@]+@[^@]+$/.test(url)) {
|
|
308
297
|
return '<mailto:' + url + '>';
|
|
309
298
|
}
|
|
310
|
-
|
|
311
299
|
return '<http://' + url + '>';
|
|
312
300
|
}
|
|
313
301
|
}
|
|
314
|
-
|
|
315
|
-
module.exports = MailMessage;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A header value split into the value token and its parameters, the result of parseHeaderValue
|
|
3
|
+
*/
|
|
4
|
+
export interface ParsedHeaderValue {
|
|
5
|
+
/** The value ahead of the parameters, for example the content type, an empty string when there is none */
|
|
6
|
+
value: string;
|
|
7
|
+
/** Parameter values keyed by lowercase parameter name */
|
|
8
|
+
params: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Header value structure accepted by buildHeaderValue
|
|
12
|
+
*/
|
|
13
|
+
export interface StructuredHeaderValue {
|
|
14
|
+
/** The value ahead of the parameters, for example the content type */
|
|
15
|
+
value: string | false;
|
|
16
|
+
/** Parameter values keyed by parameter name */
|
|
17
|
+
params?: Record<string, string> | undefined;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A single key=value pair of an rfc2231 encoded header parameter
|
|
21
|
+
*/
|
|
22
|
+
export interface EncodedHeaderParam {
|
|
23
|
+
/** Parameter name with the continuation suffix, for example title*0* */
|
|
24
|
+
key: string;
|
|
25
|
+
/** Parameter value of this part */
|
|
26
|
+
value: string;
|
|
27
|
+
}
|
|
28
|
+
/** The names @types/nodemailer used for the two types above */
|
|
29
|
+
export type HeaderValue = StructuredHeaderValue;
|
|
30
|
+
export type ParsedHeaderParam = EncodedHeaderParam;
|
|
31
|
+
/**
|
|
32
|
+
* Checks if a value is plaintext string (uses only printable 7bit chars)
|
|
33
|
+
*
|
|
34
|
+
* When isParam is set the value is destined for a header parameter, so HT, CR and LF
|
|
35
|
+
* are not plaintext either: a header parameter has no way to carry them. HT is a valid
|
|
36
|
+
* fold point, so folding and unfolding a header would rewrite it as a space, and CR/LF
|
|
37
|
+
* cannot appear in a header value at all. DEL is neither a token character nor qtext,
|
|
38
|
+
* so it can not be carried bare or quoted. Such values have to go through the rfc2231
|
|
39
|
+
* parameter continuation encoding instead, the same way a quote already does.
|
|
40
|
+
*
|
|
41
|
+
* @param value String to be tested
|
|
42
|
+
* @param [isParam] Set to true if the value is a header parameter value
|
|
43
|
+
* @returns true if it is a plaintext string
|
|
44
|
+
*/
|
|
45
|
+
export declare function isPlainText(value: unknown, isParam?: boolean): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Wraps a value into a quoted-string. Inside one a quote would end the string early
|
|
48
|
+
* and a backslash would escape whatever follows it, so both go out as quoted-pairs.
|
|
49
|
+
*
|
|
50
|
+
* @param value String to be quoted
|
|
51
|
+
* @returns The value as a quoted-string, quotes included
|
|
52
|
+
*/
|
|
53
|
+
export declare function quoteString(value?: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Checks if a multi line string containes lines longer than the selected value.
|
|
56
|
+
*
|
|
57
|
+
* Useful when detecting if a mail message needs any processing at all:
|
|
58
|
+
* if only plaintext characters are used and lines are short, then there is
|
|
59
|
+
* no need to encode the values in any way. If the value is plaintext but has
|
|
60
|
+
* longer lines then allowed, then use format=flowed
|
|
61
|
+
*
|
|
62
|
+
* @param str Multi line string to check
|
|
63
|
+
* @param lineLength Max line length to check for
|
|
64
|
+
* @returns Returns true if there is at least one line longer than lineLength chars
|
|
65
|
+
*/
|
|
66
|
+
export declare function hasLongerLines(str: string, lineLength: number): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Encodes a string or an Buffer to an UTF-8 MIME Word (rfc2047)
|
|
69
|
+
*
|
|
70
|
+
* @param data String to be encoded
|
|
71
|
+
* @param mimeWordEncoding='Q' Encoding for the mime word, either Q or B
|
|
72
|
+
* @param [maxLength=0] If set, split mime words into several chunks if needed
|
|
73
|
+
* @return Single or several mime words joined together
|
|
74
|
+
*/
|
|
75
|
+
export declare function encodeWord(data: string | Buffer, mimeWordEncoding?: string, maxLength?: number): string;
|
|
76
|
+
/**
|
|
77
|
+
* Finds word sequences with non ascii text and converts these to mime words
|
|
78
|
+
*
|
|
79
|
+
* @param value String to be encoded
|
|
80
|
+
* @param mimeWordEncoding='Q' Encoding for the mime word, either Q or B
|
|
81
|
+
* @param [maxLength=0] If set, split mime words into several chunks if needed
|
|
82
|
+
* @param [encodeAll=false] If true and the value needs encoding then encodes entire string, not just the smallest match
|
|
83
|
+
* @return String with possible mime words
|
|
84
|
+
*/
|
|
85
|
+
export declare function encodeWords(value: string, mimeWordEncoding?: string, maxLength?: number, encodeAll?: boolean): string;
|
|
86
|
+
/**
|
|
87
|
+
* Joins parsed header value together as 'value; param1=value1; param2=value2'
|
|
88
|
+
* PS: We are following RFC 822 for the list of special characters that we need to keep in quotes.
|
|
89
|
+
* Refer: https://www.w3.org/Protocols/rfc1341/4_Content-Type.html
|
|
90
|
+
* @param structured Parsed header value
|
|
91
|
+
* @return joined header value
|
|
92
|
+
*/
|
|
93
|
+
export declare function buildHeaderValue(structured: StructuredHeaderValue): string;
|
|
94
|
+
/**
|
|
95
|
+
* Encodes a string or an Buffer to an UTF-8 Parameter Value Continuation encoding (rfc2231)
|
|
96
|
+
* Useful for splitting long parameter values.
|
|
97
|
+
*
|
|
98
|
+
* For example
|
|
99
|
+
* title="unicode string"
|
|
100
|
+
* becomes
|
|
101
|
+
* title*0*=utf-8''unicode
|
|
102
|
+
* title*1*=%20string
|
|
103
|
+
*
|
|
104
|
+
* @param key Parameter name the generated keys are built from, for example title
|
|
105
|
+
* @param data String to be encoded
|
|
106
|
+
* @param [maxLength=50] Max length for generated chunks
|
|
107
|
+
* @return A list of encoded keys and headers
|
|
108
|
+
*/
|
|
109
|
+
export declare function buildHeaderParam(key: string, data: string | Buffer, maxLength?: number): EncodedHeaderParam[];
|
|
110
|
+
/**
|
|
111
|
+
* Parses a header value with key=value arguments into a structured
|
|
112
|
+
* object.
|
|
113
|
+
*
|
|
114
|
+
* parseHeaderValue('content-type: text/plain; CHARSET='UTF-8'') ->
|
|
115
|
+
* {
|
|
116
|
+
* 'value': 'text/plain',
|
|
117
|
+
* 'params': {
|
|
118
|
+
* 'charset': 'UTF-8'
|
|
119
|
+
* }
|
|
120
|
+
* }
|
|
121
|
+
*
|
|
122
|
+
* @param str Header value
|
|
123
|
+
* @return Header value as a parsed structure
|
|
124
|
+
*/
|
|
125
|
+
export declare function parseHeaderValue(str: string): ParsedHeaderValue;
|
|
126
|
+
/**
|
|
127
|
+
* Returns file extension for a content type string. If no suitable extensions
|
|
128
|
+
* are found, 'bin' is used as the default extension
|
|
129
|
+
*
|
|
130
|
+
* @param mimeType Content type to be checked for
|
|
131
|
+
* @return File extension
|
|
132
|
+
*/
|
|
133
|
+
export declare function detectExtension(mimeType?: string | false): string;
|
|
134
|
+
/**
|
|
135
|
+
* Returns content type for a file extension. If no suitable content types
|
|
136
|
+
* are found, 'application/octet-stream' is used as the default content type
|
|
137
|
+
*
|
|
138
|
+
* @param extension Extension to be checked for
|
|
139
|
+
* @return File extension
|
|
140
|
+
*/
|
|
141
|
+
export declare function detectMimeType(extension?: string | false): string;
|
|
142
|
+
/**
|
|
143
|
+
* Folds long lines, useful for folding header lines (afterSpace=false) and
|
|
144
|
+
* flowed text (afterSpace=true)
|
|
145
|
+
*
|
|
146
|
+
* @param str String to be folded
|
|
147
|
+
* @param [lineLength=76] Maximum length of a line
|
|
148
|
+
* @param afterSpace If true, leave a space in th end of a line
|
|
149
|
+
* @return String with folded lines
|
|
150
|
+
*/
|
|
151
|
+
export declare function foldLines(str: string, lineLength?: number, afterSpace?: boolean): string;
|
|
152
|
+
/**
|
|
153
|
+
* Splits a mime encoded string. Needed for dividing mime words into smaller chunks
|
|
154
|
+
*
|
|
155
|
+
* @param str Mime encoded string to be split up
|
|
156
|
+
* @param maxlen Maximum length of characters for one part (minimum 12)
|
|
157
|
+
* @return Split string
|
|
158
|
+
*/
|
|
159
|
+
export declare function splitMimeEncodedString(str: string, maxlen?: number): string[];
|
|
160
|
+
export declare function encodeURICharComponent(chr: string): string;
|
|
161
|
+
export declare function safeEncodeURIComponent(str: string): string;
|