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,256 @@
1
+ 'use strict';
2
+
3
+ const SMTPConnection = require('../smtp-connection');
4
+ const assign = require('../shared').assign;
5
+ const XOAuth2 = require('../xoauth2');
6
+ const errors = require('../errors');
7
+ const EventEmitter = require('events');
8
+
9
+ /**
10
+ * Creates an element for the pool
11
+ *
12
+ * @constructor
13
+ * @param {Object} options SMTPPool instance
14
+ */
15
+ class PoolResource extends EventEmitter {
16
+ constructor(pool) {
17
+ super();
18
+
19
+ this.pool = pool;
20
+ this.options = pool.options;
21
+ this.logger = this.pool.logger;
22
+
23
+ if (this.options.auth) {
24
+ switch ((this.options.auth.type || '').toString().toUpperCase()) {
25
+ case 'OAUTH2': {
26
+ const oauth2 = new XOAuth2(this.options.auth, this.logger);
27
+ oauth2.provisionCallback =
28
+ (this.pool.mailer && this.pool.mailer.get('oauth2_provision_cb')) || oauth2.provisionCallback;
29
+ this.auth = {
30
+ type: 'OAUTH2',
31
+ user: this.options.auth.user,
32
+ oauth2,
33
+ method: 'XOAUTH2'
34
+ };
35
+ oauth2.on('token', token => this.pool.mailer.emit('token', token));
36
+ oauth2.on('error', err => this.emit('error', err));
37
+ break;
38
+ }
39
+ default:
40
+ if (!this.options.auth.user && !this.options.auth.pass) {
41
+ break;
42
+ }
43
+ this.auth = {
44
+ type: (this.options.auth.type || '').toString().toUpperCase() || 'LOGIN',
45
+ user: this.options.auth.user,
46
+ credentials: {
47
+ user: this.options.auth.user || '',
48
+ pass: this.options.auth.pass,
49
+ options: this.options.auth.options
50
+ },
51
+ method: (this.options.auth.method || '').trim().toUpperCase() || this.options.authMethod || false
52
+ };
53
+ }
54
+ }
55
+
56
+ this._connection = false;
57
+ this._connected = false;
58
+
59
+ this.messages = 0;
60
+ this.available = true;
61
+ }
62
+
63
+ /**
64
+ * Initiates a connection to the SMTP server
65
+ *
66
+ * @param {Function} callback Callback function to run once the connection is established or failed
67
+ */
68
+ connect(callback) {
69
+ this.pool.getSocket(this.options, (err, socketOptions) => {
70
+ if (err) {
71
+ return callback(err);
72
+ }
73
+
74
+ let returned = false;
75
+ let options = this.options;
76
+ if (socketOptions && socketOptions.connection) {
77
+ this.logger.info(
78
+ {
79
+ tnx: 'proxy',
80
+ remoteAddress: socketOptions.connection.remoteAddress,
81
+ remotePort: socketOptions.connection.remotePort,
82
+ destHost: options.host || '',
83
+ destPort: options.port || '',
84
+ action: 'connected'
85
+ },
86
+ 'Using proxied socket from %s:%s to %s:%s',
87
+ socketOptions.connection.remoteAddress,
88
+ socketOptions.connection.remotePort,
89
+ options.host || '',
90
+ options.port || ''
91
+ );
92
+
93
+ options = Object.assign(assign(false, options), socketOptions);
94
+ }
95
+
96
+ this.connection = new SMTPConnection(options);
97
+
98
+ this.connection.once('error', err => {
99
+ this.emit('error', err);
100
+ if (returned) {
101
+ return;
102
+ }
103
+ returned = true;
104
+ return callback(err);
105
+ });
106
+
107
+ this.connection.once('end', () => {
108
+ this.close();
109
+ if (returned) {
110
+ return;
111
+ }
112
+ returned = true;
113
+
114
+ const timer = setTimeout(() => {
115
+ if (returned) {
116
+ return;
117
+ }
118
+ // still have not returned, this means we have an unexpected connection close
119
+ const err = new Error('Unexpected socket close');
120
+ if (this.connection && this.connection._socket && this.connection._socket.upgrading) {
121
+ // starttls connection errors
122
+ err.code = errors.ETLS;
123
+ }
124
+ callback(err);
125
+ }, 1000);
126
+
127
+ try {
128
+ timer.unref();
129
+ } catch (_E) {
130
+ // Ignore. Happens on envs with non-node timer implementation
131
+ }
132
+ });
133
+
134
+ this.connection.connect(() => {
135
+ if (returned) {
136
+ return;
137
+ }
138
+
139
+ if (this.auth && (this.connection.allowsAuth || options.forceAuth)) {
140
+ this.connection.login(this.auth, err => {
141
+ if (returned) {
142
+ return;
143
+ }
144
+ returned = true;
145
+
146
+ if (err) {
147
+ this.connection.close();
148
+ this.emit('error', err);
149
+ return callback(err);
150
+ }
151
+
152
+ this._connected = true;
153
+ callback(null, true);
154
+ });
155
+ } else {
156
+ returned = true;
157
+ this._connected = true;
158
+ return callback(null, true);
159
+ }
160
+ });
161
+ });
162
+ }
163
+
164
+ /**
165
+ * Sends an e-mail to be sent using the selected settings
166
+ *
167
+ * @param {Object} mail Mail object
168
+ * @param {Function} callback Callback function
169
+ */
170
+ send(mail, callback) {
171
+ if (!this._connected) {
172
+ return this.connect(err => {
173
+ if (err) {
174
+ return callback(err);
175
+ }
176
+ return this.send(mail, callback);
177
+ });
178
+ }
179
+
180
+ const envelope = mail.message.getEnvelope();
181
+ const messageId = mail.message.messageId();
182
+
183
+ const recipients = [].concat(envelope.to || []);
184
+ if (recipients.length > 3) {
185
+ recipients.push('...and ' + recipients.splice(2).length + ' more');
186
+ }
187
+ this.logger.info(
188
+ {
189
+ tnx: 'send',
190
+ messageId,
191
+ cid: this.id
192
+ },
193
+ 'Sending message %s using #%s to <%s>',
194
+ messageId,
195
+ this.id,
196
+ recipients.join(', ')
197
+ );
198
+
199
+ if (mail.data.dsn) {
200
+ envelope.dsn = mail.data.dsn;
201
+ }
202
+
203
+ // RFC 8689: Pass requireTLSExtensionEnabled to envelope for MAIL FROM parameter
204
+ if (mail.data.requireTLSExtensionEnabled) {
205
+ envelope.requireTLSExtensionEnabled = mail.data.requireTLSExtensionEnabled;
206
+ }
207
+
208
+ this.connection.send(envelope, mail.message.createReadStream(), (err, info) => {
209
+ this.messages++;
210
+
211
+ if (err) {
212
+ this.connection.close();
213
+ this.emit('error', err);
214
+ return callback(err);
215
+ }
216
+
217
+ info.envelope = {
218
+ from: envelope.from,
219
+ to: envelope.to
220
+ };
221
+ info.messageId = messageId;
222
+
223
+ setImmediate(() => {
224
+ if (this.messages >= this.options.maxMessages) {
225
+ const err = new Error('Resource exhausted');
226
+ err.code = errors.EMAXLIMIT;
227
+ this.connection.close();
228
+ this.emit('error', err);
229
+ } else {
230
+ this.pool._checkRateLimit(() => {
231
+ this.available = true;
232
+ this.emit('available');
233
+ });
234
+ }
235
+ });
236
+
237
+ callback(null, info);
238
+ });
239
+ }
240
+
241
+ /**
242
+ * Closes the connection
243
+ */
244
+ close() {
245
+ this._connected = false;
246
+ if (this.auth && this.auth.oauth2) {
247
+ this.auth.oauth2.removeAllListeners();
248
+ }
249
+ if (this.connection) {
250
+ this.connection.close();
251
+ }
252
+ this.emit('close');
253
+ }
254
+ }
255
+
256
+ module.exports = PoolResource;
@@ -0,0 +1,402 @@
1
+ 'use strict';
2
+
3
+ const EventEmitter = require('events');
4
+ const SMTPConnection = require('../smtp-connection');
5
+ const wellKnown = require('../well-known');
6
+ const shared = require('../shared');
7
+ const XOAuth2 = require('../xoauth2');
8
+ const errors = require('../errors');
9
+ const packageData = require('../../package.json');
10
+
11
+ /**
12
+ * Creates a SMTP transport object for Nodemailer
13
+ *
14
+ * @constructor
15
+ * @param {Object} options Connection options
16
+ */
17
+ class SMTPTransport extends EventEmitter {
18
+ constructor(options) {
19
+ super();
20
+
21
+ options = options || {};
22
+
23
+ if (typeof options === 'string') {
24
+ options = {
25
+ url: options
26
+ };
27
+ }
28
+
29
+ let urlData;
30
+ let service = options.service;
31
+
32
+ if (typeof options.getSocket === 'function') {
33
+ this.getSocket = options.getSocket;
34
+ }
35
+
36
+ if (options.url) {
37
+ urlData = shared.parseConnectionUrl(options.url);
38
+ service = service || urlData.service;
39
+ }
40
+
41
+ this.options = shared.assign(
42
+ false, // create new object
43
+ options, // regular options
44
+ urlData, // url options
45
+ service && wellKnown(service) // wellknown options
46
+ );
47
+
48
+ this.logger = shared.getLogger(this.options, {
49
+ component: this.options.component || 'smtp-transport'
50
+ });
51
+
52
+ this.name = 'SMTP';
53
+ this.version = packageData.version + '[client:' + packageData.version + ']';
54
+
55
+ if (this.options.auth) {
56
+ this.auth = this.getAuth({});
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Placeholder function for creating proxy sockets. This method immediatelly returns
62
+ * without a socket
63
+ *
64
+ * @param {Object} options Connection options
65
+ * @param {Function} callback Callback function to run with the socket keys
66
+ */
67
+ getSocket(options, callback) {
68
+ // return immediatelly
69
+ return setImmediate(() => callback(null, false));
70
+ }
71
+
72
+ getAuth(authOpts) {
73
+ if (!authOpts) {
74
+ return this.auth;
75
+ }
76
+
77
+ const authData = Object.assign(
78
+ {},
79
+ this.options.auth && typeof this.options.auth === 'object' ? this.options.auth : {},
80
+ authOpts && typeof authOpts === 'object' ? authOpts : {}
81
+ );
82
+
83
+ if (Object.keys(authData).length === 0) {
84
+ return false;
85
+ }
86
+
87
+ switch ((authData.type || '').toString().toUpperCase()) {
88
+ case 'OAUTH2': {
89
+ if (!authData.service && !authData.user) {
90
+ return false;
91
+ }
92
+ const oauth2 = new XOAuth2(authData, this.logger);
93
+ oauth2.provisionCallback = (this.mailer && this.mailer.get('oauth2_provision_cb')) || oauth2.provisionCallback;
94
+ oauth2.on('token', token => this.mailer.emit('token', token));
95
+ oauth2.on('error', err => this.emit('error', err));
96
+ return {
97
+ type: 'OAUTH2',
98
+ user: authData.user,
99
+ oauth2,
100
+ method: 'XOAUTH2'
101
+ };
102
+ }
103
+ default:
104
+ return {
105
+ type: (authData.type || '').toString().toUpperCase() || 'LOGIN',
106
+ user: authData.user,
107
+ credentials: {
108
+ user: authData.user || '',
109
+ pass: authData.pass,
110
+ options: authData.options
111
+ },
112
+ method: (authData.method || '').trim().toUpperCase() || this.options.authMethod || false
113
+ };
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Sends an e-mail using the selected settings
119
+ *
120
+ * @param {Object} mail Mail object
121
+ * @param {Function} callback Callback function
122
+ */
123
+ send(mail, callback) {
124
+ this.getSocket(this.options, (err, socketOptions) => {
125
+ if (err) {
126
+ return callback(err);
127
+ }
128
+
129
+ let returned = false;
130
+ let options = this.options;
131
+ if (socketOptions && socketOptions.connection) {
132
+ this.logger.info(
133
+ {
134
+ tnx: 'proxy',
135
+ remoteAddress: socketOptions.connection.remoteAddress,
136
+ remotePort: socketOptions.connection.remotePort,
137
+ destHost: options.host || '',
138
+ destPort: options.port || '',
139
+ action: 'connected'
140
+ },
141
+ 'Using proxied socket from %s:%s to %s:%s',
142
+ socketOptions.connection.remoteAddress,
143
+ socketOptions.connection.remotePort,
144
+ options.host || '',
145
+ options.port || ''
146
+ );
147
+
148
+ // only copy options if we need to modify it
149
+ options = Object.assign(shared.assign(false, options), socketOptions);
150
+ }
151
+
152
+ const connection = new SMTPConnection(options);
153
+
154
+ connection.once('error', err => {
155
+ if (returned) {
156
+ return;
157
+ }
158
+ returned = true;
159
+ connection.close();
160
+ return callback(err);
161
+ });
162
+
163
+ connection.once('end', () => {
164
+ if (returned) {
165
+ return;
166
+ }
167
+
168
+ const timer = setTimeout(() => {
169
+ if (returned) {
170
+ return;
171
+ }
172
+ returned = true;
173
+ // still have not returned, this means we have an unexpected connection close
174
+ const err = new Error('Unexpected socket close');
175
+ if (connection && connection._socket && connection._socket.upgrading) {
176
+ // starttls connection errors
177
+ err.code = errors.ETLS;
178
+ }
179
+ callback(err);
180
+ }, 1000);
181
+
182
+ try {
183
+ timer.unref();
184
+ } catch (_E) {
185
+ // Ignore. Happens on envs with non-node timer implementation
186
+ }
187
+ });
188
+
189
+ const sendMessage = () => {
190
+ const envelope = mail.message.getEnvelope();
191
+ const messageId = mail.message.messageId();
192
+
193
+ const recipients = [].concat(envelope.to || []);
194
+ if (recipients.length > 3) {
195
+ recipients.push('...and ' + recipients.splice(2).length + ' more');
196
+ }
197
+
198
+ if (mail.data.dsn) {
199
+ envelope.dsn = mail.data.dsn;
200
+ }
201
+
202
+ // RFC 8689: Pass requireTLSExtensionEnabled to envelope for MAIL FROM parameter
203
+ if (mail.data.requireTLSExtensionEnabled) {
204
+ envelope.requireTLSExtensionEnabled = mail.data.requireTLSExtensionEnabled;
205
+ }
206
+
207
+ this.logger.info(
208
+ {
209
+ tnx: 'send',
210
+ messageId
211
+ },
212
+ 'Sending message %s to <%s>',
213
+ messageId,
214
+ recipients.join(', ')
215
+ );
216
+
217
+ connection.send(envelope, mail.message.createReadStream(), (err, info) => {
218
+ returned = true;
219
+ connection.close();
220
+ if (err) {
221
+ this.logger.error(
222
+ {
223
+ err,
224
+ tnx: 'send'
225
+ },
226
+ 'Send error for %s: %s',
227
+ messageId,
228
+ err.message
229
+ );
230
+ return callback(err);
231
+ }
232
+ info.envelope = {
233
+ from: envelope.from,
234
+ to: envelope.to
235
+ };
236
+ info.messageId = messageId;
237
+ try {
238
+ return callback(null, info);
239
+ } catch (E) {
240
+ this.logger.error(
241
+ {
242
+ err: E,
243
+ tnx: 'callback'
244
+ },
245
+ 'Callback error for %s: %s',
246
+ messageId,
247
+ E.message
248
+ );
249
+ }
250
+ });
251
+ };
252
+
253
+ connection.connect(() => {
254
+ if (returned) {
255
+ return;
256
+ }
257
+
258
+ const auth = this.getAuth(mail.data.auth);
259
+
260
+ if (auth && (connection.allowsAuth || options.forceAuth)) {
261
+ connection.login(auth, err => {
262
+ if (auth && auth !== this.auth && auth.oauth2) {
263
+ auth.oauth2.removeAllListeners();
264
+ }
265
+ if (returned) {
266
+ return;
267
+ }
268
+
269
+ if (err) {
270
+ returned = true;
271
+ connection.close();
272
+ return callback(err);
273
+ }
274
+
275
+ sendMessage();
276
+ });
277
+ } else {
278
+ sendMessage();
279
+ }
280
+ });
281
+ });
282
+ }
283
+
284
+ /**
285
+ * Verifies SMTP configuration
286
+ *
287
+ * @param {Function} callback Callback function
288
+ */
289
+ verify(callback) {
290
+ let promise;
291
+
292
+ if (!callback) {
293
+ promise = new Promise((resolve, reject) => {
294
+ callback = shared.callbackPromise(resolve, reject);
295
+ });
296
+ }
297
+
298
+ this.getSocket(this.options, (err, socketOptions) => {
299
+ if (err) {
300
+ return callback(err);
301
+ }
302
+
303
+ let options = this.options;
304
+ if (socketOptions && socketOptions.connection) {
305
+ this.logger.info(
306
+ {
307
+ tnx: 'proxy',
308
+ remoteAddress: socketOptions.connection.remoteAddress,
309
+ remotePort: socketOptions.connection.remotePort,
310
+ destHost: options.host || '',
311
+ destPort: options.port || '',
312
+ action: 'connected'
313
+ },
314
+ 'Using proxied socket from %s:%s to %s:%s',
315
+ socketOptions.connection.remoteAddress,
316
+ socketOptions.connection.remotePort,
317
+ options.host || '',
318
+ options.port || ''
319
+ );
320
+
321
+ options = Object.assign(shared.assign(false, options), socketOptions);
322
+ }
323
+
324
+ const connection = new SMTPConnection(options);
325
+ let returned = false;
326
+
327
+ connection.once('error', err => {
328
+ if (returned) {
329
+ return;
330
+ }
331
+ returned = true;
332
+ connection.close();
333
+ return callback(err);
334
+ });
335
+
336
+ connection.once('end', () => {
337
+ if (returned) {
338
+ return;
339
+ }
340
+ returned = true;
341
+ return callback(new Error('Connection closed'));
342
+ });
343
+
344
+ const finalize = () => {
345
+ if (returned) {
346
+ return;
347
+ }
348
+ returned = true;
349
+ connection.quit();
350
+ return callback(null, true);
351
+ };
352
+
353
+ connection.connect(() => {
354
+ if (returned) {
355
+ return;
356
+ }
357
+
358
+ const authData = this.getAuth({});
359
+
360
+ if (authData && (connection.allowsAuth || options.forceAuth)) {
361
+ connection.login(authData, err => {
362
+ if (returned) {
363
+ return;
364
+ }
365
+
366
+ if (err) {
367
+ returned = true;
368
+ connection.close();
369
+ return callback(err);
370
+ }
371
+
372
+ finalize();
373
+ });
374
+ } else if (!authData && connection.allowsAuth && options.forceAuth) {
375
+ const err = new Error('Authentication info was not provided');
376
+ err.code = errors.ENOAUTH;
377
+
378
+ returned = true;
379
+ connection.close();
380
+ return callback(err);
381
+ } else {
382
+ finalize();
383
+ }
384
+ });
385
+ });
386
+
387
+ return promise;
388
+ }
389
+
390
+ /**
391
+ * Releases resources
392
+ */
393
+ close() {
394
+ if (this.auth && this.auth.oauth2) {
395
+ this.auth.oauth2.removeAllListeners();
396
+ }
397
+ this.emit('close');
398
+ }
399
+ }
400
+
401
+ // expose to the world
402
+ module.exports = SMTPTransport;