aiplang 2.0.1 → 2.1.1
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/README.md +86 -151
- package/aiplang-knowledge.md +172 -129
- package/bin/aiplang.js +4 -3
- package/package.json +3 -2
- package/runtime/aiplang-hydrate.js +1 -1
- package/server/node_modules/.package-lock.json +9 -0
- package/server/node_modules/nodemailer/.gitattributes +6 -0
- package/server/node_modules/nodemailer/.ncurc.js +9 -0
- package/server/node_modules/nodemailer/.prettierignore +8 -0
- package/server/node_modules/nodemailer/.prettierrc +12 -0
- package/server/node_modules/nodemailer/.prettierrc.js +10 -0
- package/server/node_modules/nodemailer/.release-please-config.json +9 -0
- package/server/node_modules/nodemailer/CHANGELOG.md +976 -0
- package/server/node_modules/nodemailer/CODE_OF_CONDUCT.md +76 -0
- package/server/node_modules/nodemailer/LICENSE +16 -0
- package/server/node_modules/nodemailer/README.md +86 -0
- package/server/node_modules/nodemailer/SECURITY.txt +22 -0
- package/server/node_modules/nodemailer/eslint.config.js +88 -0
- package/server/node_modules/nodemailer/lib/addressparser/index.js +382 -0
- package/server/node_modules/nodemailer/lib/base64/index.js +140 -0
- package/server/node_modules/nodemailer/lib/dkim/index.js +245 -0
- package/server/node_modules/nodemailer/lib/dkim/message-parser.js +154 -0
- package/server/node_modules/nodemailer/lib/dkim/relaxed-body.js +154 -0
- package/server/node_modules/nodemailer/lib/dkim/sign.js +116 -0
- package/server/node_modules/nodemailer/lib/errors.js +58 -0
- package/server/node_modules/nodemailer/lib/fetch/cookies.js +276 -0
- package/server/node_modules/nodemailer/lib/fetch/index.js +278 -0
- package/server/node_modules/nodemailer/lib/json-transport/index.js +82 -0
- package/server/node_modules/nodemailer/lib/mail-composer/index.js +599 -0
- package/server/node_modules/nodemailer/lib/mailer/index.js +446 -0
- package/server/node_modules/nodemailer/lib/mailer/mail-message.js +312 -0
- package/server/node_modules/nodemailer/lib/mime-funcs/index.js +610 -0
- package/server/node_modules/nodemailer/lib/mime-funcs/mime-types.js +2109 -0
- package/server/node_modules/nodemailer/lib/mime-node/index.js +1334 -0
- package/server/node_modules/nodemailer/lib/mime-node/last-newline.js +33 -0
- package/server/node_modules/nodemailer/lib/mime-node/le-unix.js +40 -0
- package/server/node_modules/nodemailer/lib/mime-node/le-windows.js +49 -0
- package/server/node_modules/nodemailer/lib/nodemailer.js +151 -0
- package/server/node_modules/nodemailer/lib/punycode/index.js +460 -0
- package/server/node_modules/nodemailer/lib/qp/index.js +230 -0
- package/server/node_modules/nodemailer/lib/sendmail-transport/index.js +205 -0
- package/server/node_modules/nodemailer/lib/ses-transport/index.js +223 -0
- package/server/node_modules/nodemailer/lib/shared/index.js +698 -0
- package/server/node_modules/nodemailer/lib/smtp-connection/data-stream.js +105 -0
- package/server/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +144 -0
- package/server/node_modules/nodemailer/lib/smtp-connection/index.js +1903 -0
- package/server/node_modules/nodemailer/lib/smtp-pool/index.js +641 -0
- package/server/node_modules/nodemailer/lib/smtp-pool/pool-resource.js +256 -0
- package/server/node_modules/nodemailer/lib/smtp-transport/index.js +402 -0
- package/server/node_modules/nodemailer/lib/stream-transport/index.js +135 -0
- package/server/node_modules/nodemailer/lib/well-known/index.js +47 -0
- package/server/node_modules/nodemailer/lib/well-known/services.json +619 -0
- package/server/node_modules/nodemailer/lib/xoauth2/index.js +436 -0
- package/server/node_modules/nodemailer/package.json +48 -0
- package/server/server.js +1008 -856
- package/bin/flux.js +0 -572
- package/runtime/flux-hydrate.js +0 -473
- package/runtime/flux-runtime.js +0 -1100
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const packageData = require('../../package.json');
|
|
5
|
+
const shared = require('../shared');
|
|
6
|
+
const errors = require('../errors');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generates a Transport object for Sendmail
|
|
10
|
+
*
|
|
11
|
+
* Possible options can be the following:
|
|
12
|
+
*
|
|
13
|
+
* * **path** optional path to sendmail binary
|
|
14
|
+
* * **newline** either 'windows' or 'unix'
|
|
15
|
+
* * **args** an array of arguments for the sendmail binary
|
|
16
|
+
*
|
|
17
|
+
* @constructor
|
|
18
|
+
* @param {Object} optional config parameter for Sendmail
|
|
19
|
+
*/
|
|
20
|
+
class SendmailTransport {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
options = options || {};
|
|
23
|
+
|
|
24
|
+
// use a reference to spawn for mocking purposes
|
|
25
|
+
this._spawn = spawn;
|
|
26
|
+
|
|
27
|
+
this.options = options;
|
|
28
|
+
|
|
29
|
+
this.name = 'Sendmail';
|
|
30
|
+
this.version = packageData.version;
|
|
31
|
+
|
|
32
|
+
this.path = 'sendmail';
|
|
33
|
+
this.args = false;
|
|
34
|
+
|
|
35
|
+
this.logger = shared.getLogger(this.options, {
|
|
36
|
+
component: this.options.component || 'sendmail'
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (typeof options === 'string') {
|
|
40
|
+
this.path = options;
|
|
41
|
+
} else if (typeof options === 'object') {
|
|
42
|
+
if (options.path) {
|
|
43
|
+
this.path = options.path;
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(options.args)) {
|
|
46
|
+
this.args = options.args;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
|
|
53
|
+
*
|
|
54
|
+
* @param {Object} emailMessage MailComposer object
|
|
55
|
+
* @param {Function} callback Callback function to run when the sending is completed
|
|
56
|
+
*/
|
|
57
|
+
send(mail, done) {
|
|
58
|
+
// Sendmail strips this header line by itself
|
|
59
|
+
mail.message.keepBcc = true;
|
|
60
|
+
|
|
61
|
+
const envelope = mail.data.envelope || mail.message.getEnvelope();
|
|
62
|
+
const messageId = mail.message.messageId();
|
|
63
|
+
let returned;
|
|
64
|
+
|
|
65
|
+
const hasInvalidAddresses = []
|
|
66
|
+
.concat(envelope.from || [])
|
|
67
|
+
.concat(envelope.to || [])
|
|
68
|
+
.some(addr => /^-/.test(addr));
|
|
69
|
+
if (hasInvalidAddresses) {
|
|
70
|
+
const err = new Error('Can not send mail. Invalid envelope addresses.');
|
|
71
|
+
err.code = errors.ESENDMAIL;
|
|
72
|
+
return done(err);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// force -i to keep single dots
|
|
76
|
+
const args = this.args
|
|
77
|
+
? ['-i'].concat(this.args).concat(envelope.to)
|
|
78
|
+
: ['-i'].concat(envelope.from ? ['-f', envelope.from] : []).concat(envelope.to);
|
|
79
|
+
|
|
80
|
+
const callback = err => {
|
|
81
|
+
if (returned) {
|
|
82
|
+
// ignore any additional responses, already done
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
returned = true;
|
|
86
|
+
if (typeof done === 'function') {
|
|
87
|
+
if (err) {
|
|
88
|
+
return done(err);
|
|
89
|
+
}
|
|
90
|
+
return done(null, {
|
|
91
|
+
envelope,
|
|
92
|
+
messageId,
|
|
93
|
+
response: 'Messages queued for delivery'
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
let sendmail;
|
|
99
|
+
try {
|
|
100
|
+
sendmail = this._spawn(this.path, args);
|
|
101
|
+
} catch (E) {
|
|
102
|
+
this.logger.error(
|
|
103
|
+
{
|
|
104
|
+
err: E,
|
|
105
|
+
tnx: 'spawn',
|
|
106
|
+
messageId
|
|
107
|
+
},
|
|
108
|
+
'Error occurred while spawning sendmail. %s',
|
|
109
|
+
E.message
|
|
110
|
+
);
|
|
111
|
+
return callback(E);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (sendmail) {
|
|
115
|
+
sendmail.on('error', err => {
|
|
116
|
+
this.logger.error(
|
|
117
|
+
{
|
|
118
|
+
err,
|
|
119
|
+
tnx: 'spawn',
|
|
120
|
+
messageId
|
|
121
|
+
},
|
|
122
|
+
'Error occurred when sending message %s. %s',
|
|
123
|
+
messageId,
|
|
124
|
+
err.message
|
|
125
|
+
);
|
|
126
|
+
callback(err);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
sendmail.once('exit', code => {
|
|
130
|
+
if (!code) {
|
|
131
|
+
return callback();
|
|
132
|
+
}
|
|
133
|
+
const err = new Error(
|
|
134
|
+
code === 127 ? 'Sendmail command not found, process exited with code ' + code : 'Sendmail exited with code ' + code
|
|
135
|
+
);
|
|
136
|
+
err.code = errors.ESENDMAIL;
|
|
137
|
+
|
|
138
|
+
this.logger.error(
|
|
139
|
+
{
|
|
140
|
+
err,
|
|
141
|
+
tnx: 'stdin',
|
|
142
|
+
messageId
|
|
143
|
+
},
|
|
144
|
+
'Error sending message %s to sendmail. %s',
|
|
145
|
+
messageId,
|
|
146
|
+
err.message
|
|
147
|
+
);
|
|
148
|
+
callback(err);
|
|
149
|
+
});
|
|
150
|
+
sendmail.once('close', callback);
|
|
151
|
+
|
|
152
|
+
sendmail.stdin.on('error', err => {
|
|
153
|
+
this.logger.error(
|
|
154
|
+
{
|
|
155
|
+
err,
|
|
156
|
+
tnx: 'stdin',
|
|
157
|
+
messageId
|
|
158
|
+
},
|
|
159
|
+
'Error occurred when piping message %s to sendmail. %s',
|
|
160
|
+
messageId,
|
|
161
|
+
err.message
|
|
162
|
+
);
|
|
163
|
+
callback(err);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const recipients = [].concat(envelope.to || []);
|
|
167
|
+
if (recipients.length > 3) {
|
|
168
|
+
recipients.push('...and ' + recipients.splice(2).length + ' more');
|
|
169
|
+
}
|
|
170
|
+
this.logger.info(
|
|
171
|
+
{
|
|
172
|
+
tnx: 'send',
|
|
173
|
+
messageId
|
|
174
|
+
},
|
|
175
|
+
'Sending message %s to <%s>',
|
|
176
|
+
messageId,
|
|
177
|
+
recipients.join(', ')
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const sourceStream = mail.message.createReadStream();
|
|
181
|
+
sourceStream.once('error', err => {
|
|
182
|
+
this.logger.error(
|
|
183
|
+
{
|
|
184
|
+
err,
|
|
185
|
+
tnx: 'stdin',
|
|
186
|
+
messageId
|
|
187
|
+
},
|
|
188
|
+
'Error occurred when generating message %s. %s',
|
|
189
|
+
messageId,
|
|
190
|
+
err.message
|
|
191
|
+
);
|
|
192
|
+
sendmail.kill('SIGINT'); // do not deliver the message
|
|
193
|
+
callback(err);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
sourceStream.pipe(sendmail.stdin);
|
|
197
|
+
} else {
|
|
198
|
+
const err = new Error('sendmail was not found');
|
|
199
|
+
err.code = errors.ESENDMAIL;
|
|
200
|
+
return callback(err);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
module.exports = SendmailTransport;
|
|
@@ -0,0 +1,223 @@
|
|
|
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
|
+
const MimeNode = require('../mime-node');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generates a Transport object for AWS SES
|
|
11
|
+
*
|
|
12
|
+
* @constructor
|
|
13
|
+
* @param {Object} optional config parameter
|
|
14
|
+
*/
|
|
15
|
+
class SESTransport extends EventEmitter {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
super();
|
|
18
|
+
options = options || {};
|
|
19
|
+
|
|
20
|
+
this.options = options;
|
|
21
|
+
this.ses = this.options.SES;
|
|
22
|
+
|
|
23
|
+
this.name = 'SESTransport';
|
|
24
|
+
this.version = packageData.version;
|
|
25
|
+
|
|
26
|
+
this.logger = shared.getLogger(this.options, {
|
|
27
|
+
component: this.options.component || 'ses-transport'
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getRegion(cb) {
|
|
32
|
+
if (this.ses.sesClient.config && typeof this.ses.sesClient.config.region === 'function') {
|
|
33
|
+
// promise
|
|
34
|
+
return this.ses.sesClient.config
|
|
35
|
+
.region()
|
|
36
|
+
.then(region => cb(null, region))
|
|
37
|
+
.catch(err => cb(err));
|
|
38
|
+
}
|
|
39
|
+
return cb(null, false);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Compiles a mailcomposer message and forwards it to SES
|
|
44
|
+
*
|
|
45
|
+
* @param {Object} emailMessage MailComposer object
|
|
46
|
+
* @param {Function} callback Callback function to run when the sending is completed
|
|
47
|
+
*/
|
|
48
|
+
send(mail, callback) {
|
|
49
|
+
let fromHeader = mail.message._headers.find(header => /^from$/i.test(header.key));
|
|
50
|
+
if (fromHeader) {
|
|
51
|
+
const mimeNode = new MimeNode('text/plain');
|
|
52
|
+
fromHeader = mimeNode._convertAddresses(mimeNode._parseAddresses(fromHeader.value));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const envelope = mail.data.envelope || mail.message.getEnvelope();
|
|
56
|
+
const messageId = mail.message.messageId();
|
|
57
|
+
|
|
58
|
+
const recipients = [].concat(envelope.to || []);
|
|
59
|
+
if (recipients.length > 3) {
|
|
60
|
+
recipients.push('...and ' + recipients.splice(2).length + ' more');
|
|
61
|
+
}
|
|
62
|
+
this.logger.info(
|
|
63
|
+
{
|
|
64
|
+
tnx: 'send',
|
|
65
|
+
messageId
|
|
66
|
+
},
|
|
67
|
+
'Sending message %s to <%s>',
|
|
68
|
+
messageId,
|
|
69
|
+
recipients.join(', ')
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const getRawMessage = next => {
|
|
73
|
+
// do not use Message-ID and Date in DKIM signature
|
|
74
|
+
if (!mail.data._dkim) {
|
|
75
|
+
mail.data._dkim = {};
|
|
76
|
+
}
|
|
77
|
+
if (mail.data._dkim.skipFields && typeof mail.data._dkim.skipFields === 'string') {
|
|
78
|
+
mail.data._dkim.skipFields += ':date:message-id';
|
|
79
|
+
} else {
|
|
80
|
+
mail.data._dkim.skipFields = 'date:message-id';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const sourceStream = mail.message.createReadStream();
|
|
84
|
+
const stream = sourceStream.pipe(new LeWindows());
|
|
85
|
+
const chunks = [];
|
|
86
|
+
let chunklen = 0;
|
|
87
|
+
|
|
88
|
+
stream.on('readable', () => {
|
|
89
|
+
let chunk;
|
|
90
|
+
while ((chunk = stream.read()) !== null) {
|
|
91
|
+
chunks.push(chunk);
|
|
92
|
+
chunklen += chunk.length;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
sourceStream.once('error', err => stream.emit('error', err));
|
|
97
|
+
|
|
98
|
+
stream.once('error', err => next(err));
|
|
99
|
+
|
|
100
|
+
stream.once('end', () => next(null, Buffer.concat(chunks, chunklen)));
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
setImmediate(() =>
|
|
104
|
+
getRawMessage((err, raw) => {
|
|
105
|
+
if (err) {
|
|
106
|
+
this.logger.error(
|
|
107
|
+
{
|
|
108
|
+
err,
|
|
109
|
+
tnx: 'send',
|
|
110
|
+
messageId
|
|
111
|
+
},
|
|
112
|
+
'Failed creating message for %s. %s',
|
|
113
|
+
messageId,
|
|
114
|
+
err.message
|
|
115
|
+
);
|
|
116
|
+
return callback(err);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const sesMessage = Object.assign(
|
|
120
|
+
{
|
|
121
|
+
Content: {
|
|
122
|
+
Raw: {
|
|
123
|
+
// required
|
|
124
|
+
Data: raw // required
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
FromEmailAddress: fromHeader || envelope.from,
|
|
128
|
+
Destination: {
|
|
129
|
+
ToAddresses: envelope.to
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
mail.data.ses || {}
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
this.getRegion((err, region) => {
|
|
136
|
+
if (err || !region) {
|
|
137
|
+
region = 'us-east-1';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const command = new this.ses.SendEmailCommand(sesMessage);
|
|
141
|
+
const sendPromise = this.ses.sesClient.send(command);
|
|
142
|
+
|
|
143
|
+
sendPromise
|
|
144
|
+
.then(data => {
|
|
145
|
+
if (region === 'us-east-1') {
|
|
146
|
+
region = 'email';
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
callback(null, {
|
|
150
|
+
envelope: {
|
|
151
|
+
from: envelope.from,
|
|
152
|
+
to: envelope.to
|
|
153
|
+
},
|
|
154
|
+
messageId: '<' + data.MessageId + (!/@/.test(data.MessageId) ? '@' + region + '.amazonses.com' : '') + '>',
|
|
155
|
+
response: data.MessageId,
|
|
156
|
+
raw
|
|
157
|
+
});
|
|
158
|
+
})
|
|
159
|
+
.catch(err => {
|
|
160
|
+
this.logger.error(
|
|
161
|
+
{
|
|
162
|
+
err,
|
|
163
|
+
tnx: 'send'
|
|
164
|
+
},
|
|
165
|
+
'Send error for %s: %s',
|
|
166
|
+
messageId,
|
|
167
|
+
err.message
|
|
168
|
+
);
|
|
169
|
+
callback(err);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
})
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Verifies SES configuration
|
|
178
|
+
*
|
|
179
|
+
* @param {Function} callback Callback function
|
|
180
|
+
*/
|
|
181
|
+
verify(callback) {
|
|
182
|
+
let promise;
|
|
183
|
+
if (!callback) {
|
|
184
|
+
promise = new Promise((resolve, reject) => {
|
|
185
|
+
callback = shared.callbackPromise(resolve, reject);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const cb = err => {
|
|
190
|
+
if (err && !['InvalidParameterValue', 'MessageRejected'].includes(err.code || err.Code || err.name)) {
|
|
191
|
+
return callback(err);
|
|
192
|
+
}
|
|
193
|
+
return callback(null, true);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const sesMessage = {
|
|
197
|
+
Content: {
|
|
198
|
+
Raw: {
|
|
199
|
+
Data: Buffer.from('From: <invalid@invalid>\r\nTo: <invalid@invalid>\r\n Subject: Invalid\r\n\r\nInvalid')
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
FromEmailAddress: 'invalid@invalid',
|
|
203
|
+
Destination: {
|
|
204
|
+
ToAddresses: ['invalid@invalid']
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
this.getRegion((err, region) => {
|
|
209
|
+
if (err || !region) {
|
|
210
|
+
region = 'us-east-1';
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const command = new this.ses.SendEmailCommand(sesMessage);
|
|
214
|
+
const sendPromise = this.ses.sesClient.send(command);
|
|
215
|
+
|
|
216
|
+
sendPromise.then(data => cb(null, data)).catch(err => cb(err));
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
return promise;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = SESTransport;
|