aiplang 2.0.0 → 2.1.0

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 (53) hide show
  1. package/bin/aiplang.js +7 -7
  2. package/package.json +7 -5
  3. package/server/node_modules/.package-lock.json +9 -0
  4. package/server/node_modules/nodemailer/.gitattributes +6 -0
  5. package/server/node_modules/nodemailer/.ncurc.js +9 -0
  6. package/server/node_modules/nodemailer/.prettierignore +8 -0
  7. package/server/node_modules/nodemailer/.prettierrc +12 -0
  8. package/server/node_modules/nodemailer/.prettierrc.js +10 -0
  9. package/server/node_modules/nodemailer/.release-please-config.json +9 -0
  10. package/server/node_modules/nodemailer/CHANGELOG.md +976 -0
  11. package/server/node_modules/nodemailer/CODE_OF_CONDUCT.md +76 -0
  12. package/server/node_modules/nodemailer/LICENSE +16 -0
  13. package/server/node_modules/nodemailer/README.md +86 -0
  14. package/server/node_modules/nodemailer/SECURITY.txt +22 -0
  15. package/server/node_modules/nodemailer/eslint.config.js +88 -0
  16. package/server/node_modules/nodemailer/lib/addressparser/index.js +382 -0
  17. package/server/node_modules/nodemailer/lib/base64/index.js +140 -0
  18. package/server/node_modules/nodemailer/lib/dkim/index.js +245 -0
  19. package/server/node_modules/nodemailer/lib/dkim/message-parser.js +154 -0
  20. package/server/node_modules/nodemailer/lib/dkim/relaxed-body.js +154 -0
  21. package/server/node_modules/nodemailer/lib/dkim/sign.js +116 -0
  22. package/server/node_modules/nodemailer/lib/errors.js +58 -0
  23. package/server/node_modules/nodemailer/lib/fetch/cookies.js +276 -0
  24. package/server/node_modules/nodemailer/lib/fetch/index.js +278 -0
  25. package/server/node_modules/nodemailer/lib/json-transport/index.js +82 -0
  26. package/server/node_modules/nodemailer/lib/mail-composer/index.js +599 -0
  27. package/server/node_modules/nodemailer/lib/mailer/index.js +446 -0
  28. package/server/node_modules/nodemailer/lib/mailer/mail-message.js +312 -0
  29. package/server/node_modules/nodemailer/lib/mime-funcs/index.js +610 -0
  30. package/server/node_modules/nodemailer/lib/mime-funcs/mime-types.js +2109 -0
  31. package/server/node_modules/nodemailer/lib/mime-node/index.js +1334 -0
  32. package/server/node_modules/nodemailer/lib/mime-node/last-newline.js +33 -0
  33. package/server/node_modules/nodemailer/lib/mime-node/le-unix.js +40 -0
  34. package/server/node_modules/nodemailer/lib/mime-node/le-windows.js +49 -0
  35. package/server/node_modules/nodemailer/lib/nodemailer.js +151 -0
  36. package/server/node_modules/nodemailer/lib/punycode/index.js +460 -0
  37. package/server/node_modules/nodemailer/lib/qp/index.js +230 -0
  38. package/server/node_modules/nodemailer/lib/sendmail-transport/index.js +205 -0
  39. package/server/node_modules/nodemailer/lib/ses-transport/index.js +223 -0
  40. package/server/node_modules/nodemailer/lib/shared/index.js +698 -0
  41. package/server/node_modules/nodemailer/lib/smtp-connection/data-stream.js +105 -0
  42. package/server/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +144 -0
  43. package/server/node_modules/nodemailer/lib/smtp-connection/index.js +1903 -0
  44. package/server/node_modules/nodemailer/lib/smtp-pool/index.js +641 -0
  45. package/server/node_modules/nodemailer/lib/smtp-pool/pool-resource.js +256 -0
  46. package/server/node_modules/nodemailer/lib/smtp-transport/index.js +402 -0
  47. package/server/node_modules/nodemailer/lib/stream-transport/index.js +135 -0
  48. package/server/node_modules/nodemailer/lib/well-known/index.js +47 -0
  49. package/server/node_modules/nodemailer/lib/well-known/services.json +619 -0
  50. package/server/node_modules/nodemailer/lib/xoauth2/index.js +436 -0
  51. package/server/node_modules/nodemailer/package.json +48 -0
  52. package/server/server.js +686 -865
  53. /package/{FLUX-PROJECT-KNOWLEDGE.md → aiplang-knowledge.md} +0 -0
@@ -0,0 +1,446 @@
1
+ 'use strict';
2
+
3
+ const EventEmitter = require('events');
4
+ const shared = require('../shared');
5
+ const mimeTypes = require('../mime-funcs/mime-types');
6
+ const MailComposer = require('../mail-composer');
7
+ const DKIM = require('../dkim');
8
+ const httpProxyClient = require('../smtp-connection/http-proxy-client');
9
+ const errors = require('../errors');
10
+ const util = require('util');
11
+ const urllib = require('url');
12
+ const packageData = require('../../package.json');
13
+ const MailMessage = require('./mail-message');
14
+ const net = require('net');
15
+ const dns = require('dns');
16
+ const crypto = require('crypto');
17
+
18
+ /**
19
+ * Creates an object for exposing the Mail API
20
+ *
21
+ * @constructor
22
+ * @param {Object} transporter Transport object instance to pass the mails to
23
+ */
24
+ class Mail extends EventEmitter {
25
+ constructor(transporter, options, defaults) {
26
+ super();
27
+
28
+ this.options = options || {};
29
+ this._defaults = defaults || {};
30
+
31
+ this._defaultPlugins = {
32
+ compile: [(...args) => this._convertDataImages(...args)],
33
+ stream: []
34
+ };
35
+
36
+ this._userPlugins = {
37
+ compile: [],
38
+ stream: []
39
+ };
40
+
41
+ this.meta = new Map();
42
+
43
+ this.dkim = this.options.dkim ? new DKIM(this.options.dkim) : false;
44
+
45
+ this.transporter = transporter;
46
+ this.transporter.mailer = this;
47
+
48
+ this.logger = shared.getLogger(this.options, {
49
+ component: this.options.component || 'mail'
50
+ });
51
+
52
+ this.logger.debug(
53
+ {
54
+ tnx: 'create'
55
+ },
56
+ 'Creating transport: %s',
57
+ this.getVersionString()
58
+ );
59
+
60
+ // setup emit handlers for the transporter
61
+ if (typeof this.transporter.on === 'function') {
62
+ // deprecated log interface
63
+ this.transporter.on('log', log => {
64
+ this.logger.debug(
65
+ {
66
+ tnx: 'transport'
67
+ },
68
+ '%s: %s',
69
+ log.type,
70
+ log.message
71
+ );
72
+ });
73
+
74
+ // transporter errors
75
+ this.transporter.on('error', err => {
76
+ this.logger.error(
77
+ {
78
+ err,
79
+ tnx: 'transport'
80
+ },
81
+ 'Transport Error: %s',
82
+ err.message
83
+ );
84
+ this.emit('error', err);
85
+ });
86
+
87
+ // indicates if the sender has became idle
88
+ this.transporter.on('idle', (...args) => {
89
+ this.emit('idle', ...args);
90
+ });
91
+
92
+ // indicates if the sender has became idle and all connections are terminated
93
+ this.transporter.on('clear', (...args) => {
94
+ this.emit('clear', ...args);
95
+ });
96
+ }
97
+
98
+ /**
99
+ * Optional methods passed to the underlying transport object
100
+ */
101
+ ['close', 'isIdle', 'verify'].forEach(method => {
102
+ this[method] = (...args) => {
103
+ if (typeof this.transporter[method] === 'function') {
104
+ if (method === 'verify' && typeof this.getSocket === 'function') {
105
+ this.transporter.getSocket = this.getSocket;
106
+ this.getSocket = false;
107
+ }
108
+ return this.transporter[method](...args);
109
+ }
110
+
111
+ this.logger.warn(
112
+ {
113
+ tnx: 'transport',
114
+ methodName: method
115
+ },
116
+ 'Non existing method %s called for transport',
117
+ method
118
+ );
119
+ return false;
120
+ };
121
+ });
122
+
123
+ // setup proxy handling
124
+ if (this.options.proxy && typeof this.options.proxy === 'string') {
125
+ this.setupProxy(this.options.proxy);
126
+ }
127
+ }
128
+
129
+ use(step, plugin) {
130
+ step = (step || '').toString();
131
+ if (!this._userPlugins.hasOwnProperty(step)) {
132
+ this._userPlugins[step] = [plugin];
133
+ } else {
134
+ this._userPlugins[step].push(plugin);
135
+ }
136
+
137
+ return this;
138
+ }
139
+
140
+ /**
141
+ * Sends an email using the preselected transport object
142
+ *
143
+ * @param {Object} data E-data description
144
+ * @param {Function?} callback Callback to run once the sending succeeded or failed
145
+ */
146
+ sendMail(data, callback = null) {
147
+ let promise;
148
+
149
+ if (!callback) {
150
+ promise = new Promise((resolve, reject) => {
151
+ callback = shared.callbackPromise(resolve, reject);
152
+ });
153
+ }
154
+
155
+ if (typeof this.getSocket === 'function') {
156
+ this.transporter.getSocket = this.getSocket;
157
+ this.getSocket = false;
158
+ }
159
+
160
+ const mail = new MailMessage(this, data);
161
+
162
+ this.logger.debug(
163
+ {
164
+ tnx: 'transport',
165
+ name: this.transporter.name,
166
+ version: this.transporter.version,
167
+ action: 'send'
168
+ },
169
+ 'Sending mail using %s/%s',
170
+ this.transporter.name,
171
+ this.transporter.version
172
+ );
173
+
174
+ this._processPlugins('compile', mail, err => {
175
+ if (err) {
176
+ this.logger.error(
177
+ {
178
+ err,
179
+ tnx: 'plugin',
180
+ action: 'compile'
181
+ },
182
+ 'PluginCompile Error: %s',
183
+ err.message
184
+ );
185
+ return callback(err);
186
+ }
187
+
188
+ mail.message = new MailComposer(mail.data).compile();
189
+
190
+ mail.setMailerHeader();
191
+ mail.setPriorityHeaders();
192
+ mail.setListHeaders();
193
+
194
+ this._processPlugins('stream', mail, err => {
195
+ if (err) {
196
+ this.logger.error(
197
+ {
198
+ err,
199
+ tnx: 'plugin',
200
+ action: 'stream'
201
+ },
202
+ 'PluginStream Error: %s',
203
+ err.message
204
+ );
205
+ return callback(err);
206
+ }
207
+
208
+ if (mail.data.dkim || this.dkim) {
209
+ mail.message.processFunc(input => {
210
+ const dkim = mail.data.dkim ? new DKIM(mail.data.dkim) : this.dkim;
211
+ this.logger.debug(
212
+ {
213
+ tnx: 'DKIM',
214
+ messageId: mail.message.messageId(),
215
+ dkimDomains: dkim.keys.map(key => key.keySelector + '.' + key.domainName).join(', ')
216
+ },
217
+ 'Signing outgoing message with %s keys',
218
+ dkim.keys.length
219
+ );
220
+ return dkim.sign(input, mail.data._dkim);
221
+ });
222
+ }
223
+
224
+ this.transporter.send(mail, (...args) => {
225
+ if (args[0]) {
226
+ this.logger.error(
227
+ {
228
+ err: args[0],
229
+ tnx: 'transport',
230
+ action: 'send'
231
+ },
232
+ 'Send Error: %s',
233
+ args[0].message
234
+ );
235
+ }
236
+ callback(...args);
237
+ });
238
+ });
239
+ });
240
+
241
+ return promise;
242
+ }
243
+
244
+ getVersionString() {
245
+ return util.format(
246
+ '%s (%s; +%s; %s/%s)',
247
+ packageData.name,
248
+ packageData.version,
249
+ packageData.homepage,
250
+ this.transporter.name,
251
+ this.transporter.version
252
+ );
253
+ }
254
+
255
+ _processPlugins(step, mail, callback) {
256
+ step = (step || '').toString();
257
+
258
+ if (!this._userPlugins.hasOwnProperty(step)) {
259
+ return callback();
260
+ }
261
+
262
+ const userPlugins = this._userPlugins[step] || [];
263
+ const defaultPlugins = this._defaultPlugins[step] || [];
264
+
265
+ if (userPlugins.length) {
266
+ this.logger.debug(
267
+ {
268
+ tnx: 'transaction',
269
+ pluginCount: userPlugins.length,
270
+ step
271
+ },
272
+ 'Using %s plugins for %s',
273
+ userPlugins.length,
274
+ step
275
+ );
276
+ }
277
+
278
+ if (userPlugins.length + defaultPlugins.length === 0) {
279
+ return callback();
280
+ }
281
+
282
+ let pos = 0;
283
+ let block = 'default';
284
+ const processPlugins = () => {
285
+ let curplugins = block === 'default' ? defaultPlugins : userPlugins;
286
+ if (pos >= curplugins.length) {
287
+ if (block === 'default' && userPlugins.length) {
288
+ block = 'user';
289
+ pos = 0;
290
+ curplugins = userPlugins;
291
+ } else {
292
+ return callback();
293
+ }
294
+ }
295
+ const plugin = curplugins[pos++];
296
+ plugin(mail, err => {
297
+ if (err) {
298
+ return callback(err);
299
+ }
300
+ processPlugins();
301
+ });
302
+ };
303
+
304
+ processPlugins();
305
+ }
306
+
307
+ /**
308
+ * Sets up proxy handler for a Nodemailer object
309
+ *
310
+ * @param {String} proxyUrl Proxy configuration url
311
+ */
312
+ setupProxy(proxyUrl) {
313
+ const proxy = urllib.parse(proxyUrl);
314
+
315
+ // setup socket handler for the mailer object
316
+ this.getSocket = (options, callback) => {
317
+ const protocol = proxy.protocol.replace(/:$/, '').toLowerCase();
318
+
319
+ if (this.meta.has('proxy_handler_' + protocol)) {
320
+ return this.meta.get('proxy_handler_' + protocol)(proxy, options, callback);
321
+ }
322
+
323
+ switch (protocol) {
324
+ // Connect using a HTTP CONNECT method
325
+ case 'http':
326
+ case 'https':
327
+ httpProxyClient(proxy.href, options.port, options.host, (err, socket) => {
328
+ if (err) {
329
+ return callback(err);
330
+ }
331
+ return callback(null, {
332
+ connection: socket
333
+ });
334
+ });
335
+ return;
336
+ case 'socks':
337
+ case 'socks5':
338
+ case 'socks4':
339
+ case 'socks4a': {
340
+ if (!this.meta.has('proxy_socks_module')) {
341
+ let err = new Error('Socks module not loaded');
342
+ err.code = errors.EPROXY;
343
+ return callback(err);
344
+ }
345
+ const connect = ipaddress => {
346
+ const proxyV2 = !!this.meta.get('proxy_socks_module').SocksClient;
347
+ const socksClient = proxyV2 ? this.meta.get('proxy_socks_module').SocksClient : this.meta.get('proxy_socks_module');
348
+ const proxyType = Number(proxy.protocol.replace(/\D/g, '')) || 5;
349
+ const connectionOpts = {
350
+ proxy: {
351
+ ipaddress,
352
+ port: Number(proxy.port),
353
+ type: proxyType
354
+ },
355
+ [proxyV2 ? 'destination' : 'target']: {
356
+ host: options.host,
357
+ port: options.port
358
+ },
359
+ command: 'connect'
360
+ };
361
+
362
+ if (proxy.auth) {
363
+ const username = decodeURIComponent(proxy.auth.split(':').shift());
364
+ const password = decodeURIComponent(proxy.auth.split(':').pop());
365
+ if (proxyV2) {
366
+ connectionOpts.proxy.userId = username;
367
+ connectionOpts.proxy.password = password;
368
+ } else if (proxyType === 4) {
369
+ connectionOpts.userid = username;
370
+ } else {
371
+ connectionOpts.authentication = {
372
+ username,
373
+ password
374
+ };
375
+ }
376
+ }
377
+
378
+ socksClient.createConnection(connectionOpts, (err, info) => {
379
+ if (err) {
380
+ return callback(err);
381
+ }
382
+ return callback(null, {
383
+ connection: info.socket || info
384
+ });
385
+ });
386
+ };
387
+
388
+ if (net.isIP(proxy.hostname)) {
389
+ return connect(proxy.hostname);
390
+ }
391
+
392
+ return dns.resolve(proxy.hostname, (err, address) => {
393
+ if (err) {
394
+ return callback(err);
395
+ }
396
+ connect(Array.isArray(address) ? address[0] : address);
397
+ });
398
+ }
399
+ }
400
+ let err = new Error('Unknown proxy configuration');
401
+ err.code = errors.EPROXY;
402
+ callback(err);
403
+ };
404
+ }
405
+
406
+ _convertDataImages(mail, callback) {
407
+ if ((!this.options.attachDataUrls && !mail.data.attachDataUrls) || !mail.data.html) {
408
+ return callback();
409
+ }
410
+ mail.resolveContent(mail.data, 'html', (err, html) => {
411
+ if (err) {
412
+ return callback(err);
413
+ }
414
+ let cidCounter = 0;
415
+ html = (html || '')
416
+ .toString()
417
+ .replace(/(<img\b[^<>]{0,1024} src\s{0,20}=[\s"']{0,20})(data:([^;]+);[^"'>\s]+)/gi, (match, prefix, dataUri, mimeType) => {
418
+ const cid = crypto.randomBytes(10).toString('hex') + '@localhost';
419
+ if (!mail.data.attachments) {
420
+ mail.data.attachments = [];
421
+ }
422
+ if (!Array.isArray(mail.data.attachments)) {
423
+ mail.data.attachments = [].concat(mail.data.attachments || []);
424
+ }
425
+ mail.data.attachments.push({
426
+ path: dataUri,
427
+ cid,
428
+ filename: 'image-' + ++cidCounter + '.' + mimeTypes.detectExtension(mimeType)
429
+ });
430
+ return prefix + 'cid:' + cid;
431
+ });
432
+ mail.data.html = html;
433
+ callback();
434
+ });
435
+ }
436
+
437
+ set(key, value) {
438
+ return this.meta.set(key, value);
439
+ }
440
+
441
+ get(key) {
442
+ return this.meta.get(key);
443
+ }
444
+ }
445
+
446
+ module.exports = Mail;