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