@nocobase/plugin-workflow-mailer 1.3.0-alpha.20240710084543 → 1.3.0-alpha.20240710155619

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 (57) hide show
  1. package/dist/client/MailerInstruction.d.ts +352 -0
  2. package/dist/client/index.d.ts +14 -0
  3. package/dist/client/index.js +16 -0
  4. package/dist/externalVersion.js +16 -0
  5. package/dist/index.d.ts +10 -0
  6. package/dist/index.js +48 -0
  7. package/dist/locale/en-US.json +19 -0
  8. package/dist/locale/index.d.ts +11 -0
  9. package/dist/locale/index.js +48 -0
  10. package/dist/locale/zh-CN.json +19 -0
  11. package/dist/node_modules/nodemailer/.gitattributes +6 -0
  12. package/dist/node_modules/nodemailer/.ncurc.js +7 -0
  13. package/dist/node_modules/nodemailer/.prettierrc.js +8 -0
  14. package/dist/node_modules/nodemailer/LICENSE +16 -0
  15. package/dist/node_modules/nodemailer/SECURITY.txt +22 -0
  16. package/dist/node_modules/nodemailer/lib/addressparser/index.js +313 -0
  17. package/dist/node_modules/nodemailer/lib/base64/index.js +142 -0
  18. package/dist/node_modules/nodemailer/lib/dkim/index.js +251 -0
  19. package/dist/node_modules/nodemailer/lib/dkim/message-parser.js +155 -0
  20. package/dist/node_modules/nodemailer/lib/dkim/relaxed-body.js +154 -0
  21. package/dist/node_modules/nodemailer/lib/dkim/sign.js +117 -0
  22. package/dist/node_modules/nodemailer/lib/fetch/cookies.js +281 -0
  23. package/dist/node_modules/nodemailer/lib/fetch/index.js +274 -0
  24. package/dist/node_modules/nodemailer/lib/json-transport/index.js +82 -0
  25. package/dist/node_modules/nodemailer/lib/mail-composer/index.js +565 -0
  26. package/dist/node_modules/nodemailer/lib/mailer/index.js +429 -0
  27. package/dist/node_modules/nodemailer/lib/mailer/mail-message.js +315 -0
  28. package/dist/node_modules/nodemailer/lib/mime-funcs/index.js +625 -0
  29. package/dist/node_modules/nodemailer/lib/mime-funcs/mime-types.js +2102 -0
  30. package/dist/node_modules/nodemailer/lib/mime-node/index.js +1314 -0
  31. package/dist/node_modules/nodemailer/lib/mime-node/last-newline.js +33 -0
  32. package/dist/node_modules/nodemailer/lib/mime-node/le-unix.js +43 -0
  33. package/dist/node_modules/nodemailer/lib/mime-node/le-windows.js +52 -0
  34. package/dist/node_modules/nodemailer/lib/nodemailer.js +1 -0
  35. package/dist/node_modules/nodemailer/lib/punycode/index.js +460 -0
  36. package/dist/node_modules/nodemailer/lib/qp/index.js +219 -0
  37. package/dist/node_modules/nodemailer/lib/sendmail-transport/index.js +210 -0
  38. package/dist/node_modules/nodemailer/lib/ses-transport/index.js +349 -0
  39. package/dist/node_modules/nodemailer/lib/shared/index.js +688 -0
  40. package/dist/node_modules/nodemailer/lib/smtp-connection/data-stream.js +108 -0
  41. package/dist/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +143 -0
  42. package/dist/node_modules/nodemailer/lib/smtp-connection/index.js +1825 -0
  43. package/dist/node_modules/nodemailer/lib/smtp-pool/index.js +648 -0
  44. package/dist/node_modules/nodemailer/lib/smtp-pool/pool-resource.js +253 -0
  45. package/dist/node_modules/nodemailer/lib/smtp-transport/index.js +416 -0
  46. package/dist/node_modules/nodemailer/lib/stream-transport/index.js +135 -0
  47. package/dist/node_modules/nodemailer/lib/well-known/index.js +47 -0
  48. package/dist/node_modules/nodemailer/lib/well-known/services.json +343 -0
  49. package/dist/node_modules/nodemailer/lib/xoauth2/index.js +376 -0
  50. package/dist/node_modules/nodemailer/package.json +1 -0
  51. package/dist/server/MailerInstruction.d.ts +13 -0
  52. package/dist/server/MailerInstruction.js +119 -0
  53. package/dist/server/Plugin.d.ts +12 -0
  54. package/dist/server/Plugin.js +50 -0
  55. package/dist/server/index.d.ts +9 -0
  56. package/dist/server/index.js +42 -0
  57. package/package.json +2 -2
@@ -0,0 +1,210 @@
1
+ 'use strict';
2
+
3
+ const spawn = require('child_process').spawn;
4
+ const packageData = require('../../package.json');
5
+ const shared = require('../shared');
6
+
7
+ /**
8
+ * Generates a Transport object for Sendmail
9
+ *
10
+ * Possible options can be the following:
11
+ *
12
+ * * **path** optional path to sendmail binary
13
+ * * **newline** either 'windows' or 'unix'
14
+ * * **args** an array of arguments for the sendmail binary
15
+ *
16
+ * @constructor
17
+ * @param {Object} optional config parameter for Sendmail
18
+ */
19
+ class SendmailTransport {
20
+ constructor(options) {
21
+ options = options || {};
22
+
23
+ // use a reference to spawn for mocking purposes
24
+ this._spawn = spawn;
25
+
26
+ this.options = options || {};
27
+
28
+ this.name = 'Sendmail';
29
+ this.version = packageData.version;
30
+
31
+ this.path = 'sendmail';
32
+ this.args = false;
33
+ this.winbreak = false;
34
+
35
+ this.logger = shared.getLogger(this.options, {
36
+ component: this.options.component || 'sendmail'
37
+ });
38
+
39
+ if (options) {
40
+ if (typeof options === 'string') {
41
+ this.path = options;
42
+ } else if (typeof options === 'object') {
43
+ if (options.path) {
44
+ this.path = options.path;
45
+ }
46
+ if (Array.isArray(options.args)) {
47
+ this.args = options.args;
48
+ }
49
+ this.winbreak = ['win', 'windows', 'dos', '\r\n'].includes((options.newline || '').toString().toLowerCase());
50
+ }
51
+ }
52
+ }
53
+
54
+ /**
55
+ * <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
56
+ *
57
+ * @param {Object} emailMessage MailComposer object
58
+ * @param {Function} callback Callback function to run when the sending is completed
59
+ */
60
+ send(mail, done) {
61
+ // Sendmail strips this header line by itself
62
+ mail.message.keepBcc = true;
63
+
64
+ let envelope = mail.data.envelope || mail.message.getEnvelope();
65
+ let messageId = mail.message.messageId();
66
+ let args;
67
+ let sendmail;
68
+ let returned;
69
+
70
+ const hasInvalidAddresses = []
71
+ .concat(envelope.from || [])
72
+ .concat(envelope.to || [])
73
+ .some(addr => /^-/.test(addr));
74
+ if (hasInvalidAddresses) {
75
+ return done(new Error('Can not send mail. Invalid envelope addresses.'));
76
+ }
77
+
78
+ if (this.args) {
79
+ // force -i to keep single dots
80
+ args = ['-i'].concat(this.args).concat(envelope.to);
81
+ } else {
82
+ args = ['-i'].concat(envelope.from ? ['-f', envelope.from] : []).concat(envelope.to);
83
+ }
84
+
85
+ let callback = err => {
86
+ if (returned) {
87
+ // ignore any additional responses, already done
88
+ return;
89
+ }
90
+ returned = true;
91
+ if (typeof done === 'function') {
92
+ if (err) {
93
+ return done(err);
94
+ } else {
95
+ return done(null, {
96
+ envelope: mail.data.envelope || mail.message.getEnvelope(),
97
+ messageId,
98
+ response: 'Messages queued for delivery'
99
+ });
100
+ }
101
+ }
102
+ };
103
+
104
+ try {
105
+ sendmail = this._spawn(this.path, args);
106
+ } catch (E) {
107
+ this.logger.error(
108
+ {
109
+ err: E,
110
+ tnx: 'spawn',
111
+ messageId
112
+ },
113
+ 'Error occurred while spawning sendmail. %s',
114
+ E.message
115
+ );
116
+ return callback(E);
117
+ }
118
+
119
+ if (sendmail) {
120
+ sendmail.on('error', err => {
121
+ this.logger.error(
122
+ {
123
+ err,
124
+ tnx: 'spawn',
125
+ messageId
126
+ },
127
+ 'Error occurred when sending message %s. %s',
128
+ messageId,
129
+ err.message
130
+ );
131
+ callback(err);
132
+ });
133
+
134
+ sendmail.once('exit', code => {
135
+ if (!code) {
136
+ return callback();
137
+ }
138
+ let err;
139
+ if (code === 127) {
140
+ err = new Error('Sendmail command not found, process exited with code ' + code);
141
+ } else {
142
+ err = new Error('Sendmail exited with code ' + code);
143
+ }
144
+
145
+ this.logger.error(
146
+ {
147
+ err,
148
+ tnx: 'stdin',
149
+ messageId
150
+ },
151
+ 'Error sending message %s to sendmail. %s',
152
+ messageId,
153
+ err.message
154
+ );
155
+ callback(err);
156
+ });
157
+ sendmail.once('close', callback);
158
+
159
+ sendmail.stdin.on('error', err => {
160
+ this.logger.error(
161
+ {
162
+ err,
163
+ tnx: 'stdin',
164
+ messageId
165
+ },
166
+ 'Error occurred when piping message %s to sendmail. %s',
167
+ messageId,
168
+ err.message
169
+ );
170
+ callback(err);
171
+ });
172
+
173
+ let recipients = [].concat(envelope.to || []);
174
+ if (recipients.length > 3) {
175
+ recipients.push('...and ' + recipients.splice(2).length + ' more');
176
+ }
177
+ this.logger.info(
178
+ {
179
+ tnx: 'send',
180
+ messageId
181
+ },
182
+ 'Sending message %s to <%s>',
183
+ messageId,
184
+ recipients.join(', ')
185
+ );
186
+
187
+ let sourceStream = mail.message.createReadStream();
188
+ sourceStream.once('error', err => {
189
+ this.logger.error(
190
+ {
191
+ err,
192
+ tnx: 'stdin',
193
+ messageId
194
+ },
195
+ 'Error occurred when generating message %s. %s',
196
+ messageId,
197
+ err.message
198
+ );
199
+ sendmail.kill('SIGINT'); // do not deliver the message
200
+ callback(err);
201
+ });
202
+
203
+ sourceStream.pipe(sendmail.stdin);
204
+ } else {
205
+ return callback(new Error('sendmail was not found'));
206
+ }
207
+ }
208
+ }
209
+
210
+ module.exports = SendmailTransport;
@@ -0,0 +1,349 @@
1
+ 'use strict';
2
+
3
+ const EventEmitter = require('events');
4
+ const packageData = require('../../package.json');
5
+ const shared = require('../shared');
6
+ const LeWindows = require('../mime-node/le-windows');
7
+
8
+ /**
9
+ * Generates a Transport object for AWS SES
10
+ *
11
+ * Possible options can be the following:
12
+ *
13
+ * * **sendingRate** optional Number specifying how many messages per second should be delivered to SES
14
+ * * **maxConnections** optional Number specifying max number of parallel connections to SES
15
+ *
16
+ * @constructor
17
+ * @param {Object} optional config parameter
18
+ */
19
+ class SESTransport extends EventEmitter {
20
+ constructor(options) {
21
+ super();
22
+ options = options || {};
23
+
24
+ this.options = options || {};
25
+ this.ses = this.options.SES;
26
+
27
+ this.name = 'SESTransport';
28
+ this.version = packageData.version;
29
+
30
+ this.logger = shared.getLogger(this.options, {
31
+ component: this.options.component || 'ses-transport'
32
+ });
33
+
34
+ // parallel sending connections
35
+ this.maxConnections = Number(this.options.maxConnections) || Infinity;
36
+ this.connections = 0;
37
+
38
+ // max messages per second
39
+ this.sendingRate = Number(this.options.sendingRate) || Infinity;
40
+ this.sendingRateTTL = null;
41
+ this.rateInterval = 1000; // milliseconds
42
+ this.rateMessages = [];
43
+
44
+ this.pending = [];
45
+
46
+ this.idling = true;
47
+
48
+ setImmediate(() => {
49
+ if (this.idling) {
50
+ this.emit('idle');
51
+ }
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Schedules a sending of a message
57
+ *
58
+ * @param {Object} emailMessage MailComposer object
59
+ * @param {Function} callback Callback function to run when the sending is completed
60
+ */
61
+ send(mail, callback) {
62
+ if (this.connections >= this.maxConnections) {
63
+ this.idling = false;
64
+ return this.pending.push({
65
+ mail,
66
+ callback
67
+ });
68
+ }
69
+
70
+ if (!this._checkSendingRate()) {
71
+ this.idling = false;
72
+ return this.pending.push({
73
+ mail,
74
+ callback
75
+ });
76
+ }
77
+
78
+ this._send(mail, (...args) => {
79
+ setImmediate(() => callback(...args));
80
+ this._sent();
81
+ });
82
+ }
83
+
84
+ _checkRatedQueue() {
85
+ if (this.connections >= this.maxConnections || !this._checkSendingRate()) {
86
+ return;
87
+ }
88
+
89
+ if (!this.pending.length) {
90
+ if (!this.idling) {
91
+ this.idling = true;
92
+ this.emit('idle');
93
+ }
94
+ return;
95
+ }
96
+
97
+ let next = this.pending.shift();
98
+ this._send(next.mail, (...args) => {
99
+ setImmediate(() => next.callback(...args));
100
+ this._sent();
101
+ });
102
+ }
103
+
104
+ _checkSendingRate() {
105
+ clearTimeout(this.sendingRateTTL);
106
+
107
+ let now = Date.now();
108
+ let oldest = false;
109
+ // delete older messages
110
+ for (let i = this.rateMessages.length - 1; i >= 0; i--) {
111
+ if (this.rateMessages[i].ts >= now - this.rateInterval && (!oldest || this.rateMessages[i].ts < oldest)) {
112
+ oldest = this.rateMessages[i].ts;
113
+ }
114
+
115
+ if (this.rateMessages[i].ts < now - this.rateInterval && !this.rateMessages[i].pending) {
116
+ this.rateMessages.splice(i, 1);
117
+ }
118
+ }
119
+
120
+ if (this.rateMessages.length < this.sendingRate) {
121
+ return true;
122
+ }
123
+
124
+ let delay = Math.max(oldest + 1001, now + 20);
125
+ this.sendingRateTTL = setTimeout(() => this._checkRatedQueue(), now - delay);
126
+
127
+ try {
128
+ this.sendingRateTTL.unref();
129
+ } catch (E) {
130
+ // Ignore. Happens on envs with non-node timer implementation
131
+ }
132
+
133
+ return false;
134
+ }
135
+
136
+ _sent() {
137
+ this.connections--;
138
+ this._checkRatedQueue();
139
+ }
140
+
141
+ /**
142
+ * Returns true if there are free slots in the queue
143
+ */
144
+ isIdle() {
145
+ return this.idling;
146
+ }
147
+
148
+ /**
149
+ * Compiles a mailcomposer message and forwards it to SES
150
+ *
151
+ * @param {Object} emailMessage MailComposer object
152
+ * @param {Function} callback Callback function to run when the sending is completed
153
+ */
154
+ _send(mail, callback) {
155
+ let statObject = {
156
+ ts: Date.now(),
157
+ pending: true
158
+ };
159
+ this.connections++;
160
+ this.rateMessages.push(statObject);
161
+
162
+ let envelope = mail.data.envelope || mail.message.getEnvelope();
163
+ let messageId = mail.message.messageId();
164
+
165
+ let recipients = [].concat(envelope.to || []);
166
+ if (recipients.length > 3) {
167
+ recipients.push('...and ' + recipients.splice(2).length + ' more');
168
+ }
169
+ this.logger.info(
170
+ {
171
+ tnx: 'send',
172
+ messageId
173
+ },
174
+ 'Sending message %s to <%s>',
175
+ messageId,
176
+ recipients.join(', ')
177
+ );
178
+
179
+ let getRawMessage = next => {
180
+ // do not use Message-ID and Date in DKIM signature
181
+ if (!mail.data._dkim) {
182
+ mail.data._dkim = {};
183
+ }
184
+ if (mail.data._dkim.skipFields && typeof mail.data._dkim.skipFields === 'string') {
185
+ mail.data._dkim.skipFields += ':date:message-id';
186
+ } else {
187
+ mail.data._dkim.skipFields = 'date:message-id';
188
+ }
189
+
190
+ let sourceStream = mail.message.createReadStream();
191
+ let stream = sourceStream.pipe(new LeWindows());
192
+ let chunks = [];
193
+ let chunklen = 0;
194
+
195
+ stream.on('readable', () => {
196
+ let chunk;
197
+ while ((chunk = stream.read()) !== null) {
198
+ chunks.push(chunk);
199
+ chunklen += chunk.length;
200
+ }
201
+ });
202
+
203
+ sourceStream.once('error', err => stream.emit('error', err));
204
+
205
+ stream.once('error', err => {
206
+ next(err);
207
+ });
208
+
209
+ stream.once('end', () => next(null, Buffer.concat(chunks, chunklen)));
210
+ };
211
+
212
+ setImmediate(() =>
213
+ getRawMessage((err, raw) => {
214
+ if (err) {
215
+ this.logger.error(
216
+ {
217
+ err,
218
+ tnx: 'send',
219
+ messageId
220
+ },
221
+ 'Failed creating message for %s. %s',
222
+ messageId,
223
+ err.message
224
+ );
225
+ statObject.pending = false;
226
+ return callback(err);
227
+ }
228
+
229
+ let sesMessage = {
230
+ RawMessage: {
231
+ // required
232
+ Data: raw // required
233
+ },
234
+ Source: envelope.from,
235
+ Destinations: envelope.to
236
+ };
237
+
238
+ Object.keys(mail.data.ses || {}).forEach(key => {
239
+ sesMessage[key] = mail.data.ses[key];
240
+ });
241
+
242
+ let ses = (this.ses.aws ? this.ses.ses : this.ses) || {};
243
+ let aws = this.ses.aws || {};
244
+
245
+ let getRegion = cb => {
246
+ if (ses.config && typeof ses.config.region === 'function') {
247
+ // promise
248
+ return ses.config
249
+ .region()
250
+ .then(region => cb(null, region))
251
+ .catch(err => cb(err));
252
+ }
253
+ return cb(null, (ses.config && ses.config.region) || 'us-east-1');
254
+ };
255
+
256
+ getRegion((err, region) => {
257
+ if (err || !region) {
258
+ region = 'us-east-1';
259
+ }
260
+
261
+ let sendPromise;
262
+ if (typeof ses.send === 'function' && aws.SendRawEmailCommand) {
263
+ // v3 API
264
+ sendPromise = ses.send(new aws.SendRawEmailCommand(sesMessage));
265
+ } else {
266
+ // v2 API
267
+ sendPromise = ses.sendRawEmail(sesMessage).promise();
268
+ }
269
+
270
+ sendPromise
271
+ .then(data => {
272
+ if (region === 'us-east-1') {
273
+ region = 'email';
274
+ }
275
+
276
+ statObject.pending = false;
277
+ callback(null, {
278
+ envelope: {
279
+ from: envelope.from,
280
+ to: envelope.to
281
+ },
282
+ messageId: '<' + data.MessageId + (!/@/.test(data.MessageId) ? '@' + region + '.amazonses.com' : '') + '>',
283
+ response: data.MessageId,
284
+ raw
285
+ });
286
+ })
287
+ .catch(err => {
288
+ this.logger.error(
289
+ {
290
+ err,
291
+ tnx: 'send'
292
+ },
293
+ 'Send error for %s: %s',
294
+ messageId,
295
+ err.message
296
+ );
297
+ statObject.pending = false;
298
+ callback(err);
299
+ });
300
+ });
301
+ })
302
+ );
303
+ }
304
+
305
+ /**
306
+ * Verifies SES configuration
307
+ *
308
+ * @param {Function} callback Callback function
309
+ */
310
+ verify(callback) {
311
+ let promise;
312
+ let ses = (this.ses.aws ? this.ses.ses : this.ses) || {};
313
+ let aws = this.ses.aws || {};
314
+
315
+ const sesMessage = {
316
+ RawMessage: {
317
+ // required
318
+ Data: 'From: invalid@invalid\r\nTo: invalid@invalid\r\n Subject: Invalid\r\n\r\nInvalid'
319
+ },
320
+ Source: 'invalid@invalid',
321
+ Destinations: ['invalid@invalid']
322
+ };
323
+
324
+ if (!callback) {
325
+ promise = new Promise((resolve, reject) => {
326
+ callback = shared.callbackPromise(resolve, reject);
327
+ });
328
+ }
329
+ const cb = err => {
330
+ if (err && (err.code || err.Code) !== 'InvalidParameterValue') {
331
+ return callback(err);
332
+ }
333
+ return callback(null, true);
334
+ };
335
+
336
+ if (typeof ses.send === 'function' && aws.SendRawEmailCommand) {
337
+ // v3 API
338
+ sesMessage.RawMessage.Data = Buffer.from(sesMessage.RawMessage.Data);
339
+ ses.send(new aws.SendRawEmailCommand(sesMessage), cb);
340
+ } else {
341
+ // v2 API
342
+ ses.sendRawEmail(sesMessage, cb);
343
+ }
344
+
345
+ return promise;
346
+ }
347
+ }
348
+
349
+ module.exports = SESTransport;