@nocobase/plugin-notification-email 1.4.0-alpha.20240928155737
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/LICENSE.txt +123 -0
- package/README.md +1 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/ConfigForm.d.ts +10 -0
- package/dist/client/MessageConfigForm.d.ts +12 -0
- package/dist/client/hooks/useTranslation.d.ts +9 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.js +16 -0
- package/dist/constant.d.ts +10 -0
- package/dist/constant.js +39 -0
- package/dist/externalVersion.js +17 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/en-US.json +22 -0
- package/dist/locale/zh-CN.json +22 -0
- package/dist/node_modules/nodemailer/.gitattributes +6 -0
- package/dist/node_modules/nodemailer/.ncurc.js +7 -0
- package/dist/node_modules/nodemailer/.prettierrc.js +8 -0
- package/dist/node_modules/nodemailer/LICENSE +16 -0
- package/dist/node_modules/nodemailer/SECURITY.txt +22 -0
- package/dist/node_modules/nodemailer/lib/addressparser/index.js +313 -0
- package/dist/node_modules/nodemailer/lib/base64/index.js +142 -0
- package/dist/node_modules/nodemailer/lib/dkim/index.js +251 -0
- package/dist/node_modules/nodemailer/lib/dkim/message-parser.js +155 -0
- package/dist/node_modules/nodemailer/lib/dkim/relaxed-body.js +154 -0
- package/dist/node_modules/nodemailer/lib/dkim/sign.js +117 -0
- package/dist/node_modules/nodemailer/lib/fetch/cookies.js +281 -0
- package/dist/node_modules/nodemailer/lib/fetch/index.js +274 -0
- package/dist/node_modules/nodemailer/lib/json-transport/index.js +82 -0
- package/dist/node_modules/nodemailer/lib/mail-composer/index.js +565 -0
- package/dist/node_modules/nodemailer/lib/mailer/index.js +427 -0
- package/dist/node_modules/nodemailer/lib/mailer/mail-message.js +315 -0
- package/dist/node_modules/nodemailer/lib/mime-funcs/index.js +625 -0
- package/dist/node_modules/nodemailer/lib/mime-funcs/mime-types.js +2102 -0
- package/dist/node_modules/nodemailer/lib/mime-node/index.js +1305 -0
- package/dist/node_modules/nodemailer/lib/mime-node/last-newline.js +33 -0
- package/dist/node_modules/nodemailer/lib/mime-node/le-unix.js +43 -0
- package/dist/node_modules/nodemailer/lib/mime-node/le-windows.js +52 -0
- package/dist/node_modules/nodemailer/lib/nodemailer.js +1 -0
- package/dist/node_modules/nodemailer/lib/qp/index.js +219 -0
- package/dist/node_modules/nodemailer/lib/sendmail-transport/index.js +210 -0
- package/dist/node_modules/nodemailer/lib/ses-transport/index.js +349 -0
- package/dist/node_modules/nodemailer/lib/shared/index.js +638 -0
- package/dist/node_modules/nodemailer/lib/smtp-connection/data-stream.js +108 -0
- package/dist/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +143 -0
- package/dist/node_modules/nodemailer/lib/smtp-connection/index.js +1812 -0
- package/dist/node_modules/nodemailer/lib/smtp-pool/index.js +648 -0
- package/dist/node_modules/nodemailer/lib/smtp-pool/pool-resource.js +253 -0
- package/dist/node_modules/nodemailer/lib/smtp-transport/index.js +416 -0
- package/dist/node_modules/nodemailer/lib/stream-transport/index.js +135 -0
- package/dist/node_modules/nodemailer/lib/well-known/index.js +47 -0
- package/dist/node_modules/nodemailer/lib/well-known/services.json +338 -0
- package/dist/node_modules/nodemailer/lib/xoauth2/index.js +376 -0
- package/dist/node_modules/nodemailer/package.json +1 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/mail-server.d.ts +14 -0
- package/dist/server/mail-server.js +78 -0
- package/dist/server/plugin.d.ts +19 -0
- package/dist/server/plugin.js +69 -0
- package/package.json +23 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
- package/tsconfig.json +7 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const urllib = require('url');
|
|
6
|
+
const zlib = require('zlib');
|
|
7
|
+
const PassThrough = require('stream').PassThrough;
|
|
8
|
+
const Cookies = require('./cookies');
|
|
9
|
+
const packageData = require('../../package.json');
|
|
10
|
+
const net = require('net');
|
|
11
|
+
|
|
12
|
+
const MAX_REDIRECTS = 5;
|
|
13
|
+
|
|
14
|
+
module.exports = function (url, options) {
|
|
15
|
+
return nmfetch(url, options);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports.Cookies = Cookies;
|
|
19
|
+
|
|
20
|
+
function nmfetch(url, options) {
|
|
21
|
+
options = options || {};
|
|
22
|
+
|
|
23
|
+
options.fetchRes = options.fetchRes || new PassThrough();
|
|
24
|
+
options.cookies = options.cookies || new Cookies();
|
|
25
|
+
options.redirects = options.redirects || 0;
|
|
26
|
+
options.maxRedirects = isNaN(options.maxRedirects) ? MAX_REDIRECTS : options.maxRedirects;
|
|
27
|
+
|
|
28
|
+
if (options.cookie) {
|
|
29
|
+
[].concat(options.cookie || []).forEach(cookie => {
|
|
30
|
+
options.cookies.set(cookie, url);
|
|
31
|
+
});
|
|
32
|
+
options.cookie = false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let fetchRes = options.fetchRes;
|
|
36
|
+
let parsed = urllib.parse(url);
|
|
37
|
+
let method = (options.method || '').toString().trim().toUpperCase() || 'GET';
|
|
38
|
+
let finished = false;
|
|
39
|
+
let cookies;
|
|
40
|
+
let body;
|
|
41
|
+
|
|
42
|
+
let handler = parsed.protocol === 'https:' ? https : http;
|
|
43
|
+
|
|
44
|
+
let headers = {
|
|
45
|
+
'accept-encoding': 'gzip,deflate',
|
|
46
|
+
'user-agent': 'nodemailer/' + packageData.version
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
Object.keys(options.headers || {}).forEach(key => {
|
|
50
|
+
headers[key.toLowerCase().trim()] = options.headers[key];
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
if (options.userAgent) {
|
|
54
|
+
headers['user-agent'] = options.userAgent;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (parsed.auth) {
|
|
58
|
+
headers.Authorization = 'Basic ' + Buffer.from(parsed.auth).toString('base64');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if ((cookies = options.cookies.get(url))) {
|
|
62
|
+
headers.cookie = cookies;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options.body) {
|
|
66
|
+
if (options.contentType !== false) {
|
|
67
|
+
headers['Content-Type'] = options.contentType || 'application/x-www-form-urlencoded';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (typeof options.body.pipe === 'function') {
|
|
71
|
+
// it's a stream
|
|
72
|
+
headers['Transfer-Encoding'] = 'chunked';
|
|
73
|
+
body = options.body;
|
|
74
|
+
body.on('error', err => {
|
|
75
|
+
if (finished) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
finished = true;
|
|
79
|
+
err.type = 'FETCH';
|
|
80
|
+
err.sourceUrl = url;
|
|
81
|
+
fetchRes.emit('error', err);
|
|
82
|
+
});
|
|
83
|
+
} else {
|
|
84
|
+
if (options.body instanceof Buffer) {
|
|
85
|
+
body = options.body;
|
|
86
|
+
} else if (typeof options.body === 'object') {
|
|
87
|
+
try {
|
|
88
|
+
// encodeURIComponent can fail on invalid input (partial emoji etc.)
|
|
89
|
+
body = Buffer.from(
|
|
90
|
+
Object.keys(options.body)
|
|
91
|
+
.map(key => {
|
|
92
|
+
let value = options.body[key].toString().trim();
|
|
93
|
+
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
94
|
+
})
|
|
95
|
+
.join('&')
|
|
96
|
+
);
|
|
97
|
+
} catch (E) {
|
|
98
|
+
if (finished) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
finished = true;
|
|
102
|
+
E.type = 'FETCH';
|
|
103
|
+
E.sourceUrl = url;
|
|
104
|
+
fetchRes.emit('error', E);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
body = Buffer.from(options.body.toString().trim());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
headers['Content-Type'] = options.contentType || 'application/x-www-form-urlencoded';
|
|
112
|
+
headers['Content-Length'] = body.length;
|
|
113
|
+
}
|
|
114
|
+
// if method is not provided, use POST instead of GET
|
|
115
|
+
method = (options.method || '').toString().trim().toUpperCase() || 'POST';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let req;
|
|
119
|
+
let reqOptions = {
|
|
120
|
+
method,
|
|
121
|
+
host: parsed.hostname,
|
|
122
|
+
path: parsed.path,
|
|
123
|
+
port: parsed.port ? parsed.port : parsed.protocol === 'https:' ? 443 : 80,
|
|
124
|
+
headers,
|
|
125
|
+
rejectUnauthorized: false,
|
|
126
|
+
agent: false
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
if (options.tls) {
|
|
130
|
+
Object.keys(options.tls).forEach(key => {
|
|
131
|
+
reqOptions[key] = options.tls[key];
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (parsed.protocol === 'https:' && parsed.hostname && parsed.hostname !== reqOptions.host && !net.isIP(parsed.hostname) && !reqOptions.servername) {
|
|
136
|
+
reqOptions.servername = parsed.hostname;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
req = handler.request(reqOptions);
|
|
141
|
+
} catch (E) {
|
|
142
|
+
finished = true;
|
|
143
|
+
setImmediate(() => {
|
|
144
|
+
E.type = 'FETCH';
|
|
145
|
+
E.sourceUrl = url;
|
|
146
|
+
fetchRes.emit('error', E);
|
|
147
|
+
});
|
|
148
|
+
return fetchRes;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (options.timeout) {
|
|
152
|
+
req.setTimeout(options.timeout, () => {
|
|
153
|
+
if (finished) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
finished = true;
|
|
157
|
+
req.abort();
|
|
158
|
+
let err = new Error('Request Timeout');
|
|
159
|
+
err.type = 'FETCH';
|
|
160
|
+
err.sourceUrl = url;
|
|
161
|
+
fetchRes.emit('error', err);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
req.on('error', err => {
|
|
166
|
+
if (finished) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
finished = true;
|
|
170
|
+
err.type = 'FETCH';
|
|
171
|
+
err.sourceUrl = url;
|
|
172
|
+
fetchRes.emit('error', err);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
req.on('response', res => {
|
|
176
|
+
let inflate;
|
|
177
|
+
|
|
178
|
+
if (finished) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
switch (res.headers['content-encoding']) {
|
|
183
|
+
case 'gzip':
|
|
184
|
+
case 'deflate':
|
|
185
|
+
inflate = zlib.createUnzip();
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (res.headers['set-cookie']) {
|
|
190
|
+
[].concat(res.headers['set-cookie'] || []).forEach(cookie => {
|
|
191
|
+
options.cookies.set(cookie, url);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if ([301, 302, 303, 307, 308].includes(res.statusCode) && res.headers.location) {
|
|
196
|
+
// redirect
|
|
197
|
+
options.redirects++;
|
|
198
|
+
if (options.redirects > options.maxRedirects) {
|
|
199
|
+
finished = true;
|
|
200
|
+
let err = new Error('Maximum redirect count exceeded');
|
|
201
|
+
err.type = 'FETCH';
|
|
202
|
+
err.sourceUrl = url;
|
|
203
|
+
fetchRes.emit('error', err);
|
|
204
|
+
req.abort();
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// redirect does not include POST body
|
|
208
|
+
options.method = 'GET';
|
|
209
|
+
options.body = false;
|
|
210
|
+
return nmfetch(urllib.resolve(url, res.headers.location), options);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
fetchRes.statusCode = res.statusCode;
|
|
214
|
+
fetchRes.headers = res.headers;
|
|
215
|
+
|
|
216
|
+
if (res.statusCode >= 300 && !options.allowErrorResponse) {
|
|
217
|
+
finished = true;
|
|
218
|
+
let err = new Error('Invalid status code ' + res.statusCode);
|
|
219
|
+
err.type = 'FETCH';
|
|
220
|
+
err.sourceUrl = url;
|
|
221
|
+
fetchRes.emit('error', err);
|
|
222
|
+
req.abort();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
res.on('error', err => {
|
|
227
|
+
if (finished) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
finished = true;
|
|
231
|
+
err.type = 'FETCH';
|
|
232
|
+
err.sourceUrl = url;
|
|
233
|
+
fetchRes.emit('error', err);
|
|
234
|
+
req.abort();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
if (inflate) {
|
|
238
|
+
res.pipe(inflate).pipe(fetchRes);
|
|
239
|
+
inflate.on('error', err => {
|
|
240
|
+
if (finished) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
finished = true;
|
|
244
|
+
err.type = 'FETCH';
|
|
245
|
+
err.sourceUrl = url;
|
|
246
|
+
fetchRes.emit('error', err);
|
|
247
|
+
req.abort();
|
|
248
|
+
});
|
|
249
|
+
} else {
|
|
250
|
+
res.pipe(fetchRes);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
setImmediate(() => {
|
|
255
|
+
if (body) {
|
|
256
|
+
try {
|
|
257
|
+
if (typeof body.pipe === 'function') {
|
|
258
|
+
return body.pipe(req);
|
|
259
|
+
} else {
|
|
260
|
+
req.write(body);
|
|
261
|
+
}
|
|
262
|
+
} catch (err) {
|
|
263
|
+
finished = true;
|
|
264
|
+
err.type = 'FETCH';
|
|
265
|
+
err.sourceUrl = url;
|
|
266
|
+
fetchRes.emit('error', err);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
req.end();
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
return fetchRes;
|
|
274
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const packageData = require('../../package.json');
|
|
4
|
+
const shared = require('../shared');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generates a Transport object to generate JSON output
|
|
8
|
+
*
|
|
9
|
+
* @constructor
|
|
10
|
+
* @param {Object} optional config parameter
|
|
11
|
+
*/
|
|
12
|
+
class JSONTransport {
|
|
13
|
+
constructor(options) {
|
|
14
|
+
options = options || {};
|
|
15
|
+
|
|
16
|
+
this.options = options || {};
|
|
17
|
+
|
|
18
|
+
this.name = 'JSONTransport';
|
|
19
|
+
this.version = packageData.version;
|
|
20
|
+
|
|
21
|
+
this.logger = shared.getLogger(this.options, {
|
|
22
|
+
component: this.options.component || 'json-transport'
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
|
|
28
|
+
*
|
|
29
|
+
* @param {Object} emailMessage MailComposer object
|
|
30
|
+
* @param {Function} callback Callback function to run when the sending is completed
|
|
31
|
+
*/
|
|
32
|
+
send(mail, done) {
|
|
33
|
+
// Sendmail strips this header line by itself
|
|
34
|
+
mail.message.keepBcc = true;
|
|
35
|
+
|
|
36
|
+
let envelope = mail.data.envelope || mail.message.getEnvelope();
|
|
37
|
+
let messageId = mail.message.messageId();
|
|
38
|
+
|
|
39
|
+
let recipients = [].concat(envelope.to || []);
|
|
40
|
+
if (recipients.length > 3) {
|
|
41
|
+
recipients.push('...and ' + recipients.splice(2).length + ' more');
|
|
42
|
+
}
|
|
43
|
+
this.logger.info(
|
|
44
|
+
{
|
|
45
|
+
tnx: 'send',
|
|
46
|
+
messageId
|
|
47
|
+
},
|
|
48
|
+
'Composing JSON structure of %s to <%s>',
|
|
49
|
+
messageId,
|
|
50
|
+
recipients.join(', ')
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
setImmediate(() => {
|
|
54
|
+
mail.normalize((err, data) => {
|
|
55
|
+
if (err) {
|
|
56
|
+
this.logger.error(
|
|
57
|
+
{
|
|
58
|
+
err,
|
|
59
|
+
tnx: 'send',
|
|
60
|
+
messageId
|
|
61
|
+
},
|
|
62
|
+
'Failed building JSON structure for %s. %s',
|
|
63
|
+
messageId,
|
|
64
|
+
err.message
|
|
65
|
+
);
|
|
66
|
+
return done(err);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
delete data.envelope;
|
|
70
|
+
delete data.normalizedHeaders;
|
|
71
|
+
|
|
72
|
+
return done(null, {
|
|
73
|
+
envelope,
|
|
74
|
+
messageId,
|
|
75
|
+
message: this.options.skipEncoding ? data : JSON.stringify(data)
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = JSONTransport;
|